- build a standard Wine list of folders instead of using an array
- use folder pointers instead of array indexes
This commit is contained in:
parent
279836cc6a
commit
979511fe6d
|
@ -1291,7 +1291,7 @@ static UINT ACTION_FileCost(MSIPACKAGE *package)
|
|||
}
|
||||
|
||||
|
||||
static INT load_folder(MSIPACKAGE *package, const WCHAR* dir)
|
||||
static MSIFOLDER *load_folder( MSIPACKAGE *package, LPCWSTR dir )
|
||||
{
|
||||
static const WCHAR Query[] =
|
||||
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||
|
@ -1303,38 +1303,25 @@ static INT load_folder(MSIPACKAGE *package, const WCHAR* dir)
|
|||
LPCWSTR parent;
|
||||
LPWSTR shortname = NULL;
|
||||
MSIRECORD * row = 0;
|
||||
INT index = -1;
|
||||
DWORD i;
|
||||
MSIFOLDER *folder;
|
||||
|
||||
TRACE("Looking for dir %s\n",debugstr_w(dir));
|
||||
|
||||
for (i = 0; i < package->loaded_folders; i++)
|
||||
{
|
||||
if (strcmpW(package->folders[i].Directory,dir)==0)
|
||||
{
|
||||
TRACE(" %s retuning on index %lu\n",debugstr_w(dir),i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
folder = get_loaded_folder( package, dir );
|
||||
if (folder)
|
||||
return folder;
|
||||
|
||||
TRACE("Working to load %s\n",debugstr_w(dir));
|
||||
|
||||
index = package->loaded_folders++;
|
||||
if (package->loaded_folders==1)
|
||||
package->folders = HeapAlloc(GetProcessHeap(),0,
|
||||
sizeof(MSIFOLDER));
|
||||
else
|
||||
package->folders= HeapReAlloc(GetProcessHeap(),0,
|
||||
package->folders, package->loaded_folders*
|
||||
sizeof(MSIFOLDER));
|
||||
folder = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (MSIFOLDER) );
|
||||
if (!folder)
|
||||
return NULL;
|
||||
|
||||
memset(&package->folders[index],0,sizeof(MSIFOLDER));
|
||||
|
||||
package->folders[index].Directory = strdupW(dir);
|
||||
folder->Directory = strdupW(dir);
|
||||
|
||||
row = MSI_QueryGetRecord(package->db, Query, dir);
|
||||
if (!row)
|
||||
return -1;
|
||||
return NULL;
|
||||
|
||||
ptargetdir = targetdir = load_dynamic_stringW(row,3);
|
||||
|
||||
|
@ -1370,37 +1357,39 @@ static INT load_folder(MSIPACKAGE *package, const WCHAR* dir)
|
|||
if (targetdir)
|
||||
{
|
||||
TRACE(" TargetDefault = %s\n",debugstr_w(targetdir));
|
||||
HeapFree(GetProcessHeap(),0, package->folders[index].TargetDefault);
|
||||
package->folders[index].TargetDefault = strdupW(targetdir);
|
||||
HeapFree(GetProcessHeap(),0, folder->TargetDefault);
|
||||
folder->TargetDefault = strdupW(targetdir);
|
||||
}
|
||||
|
||||
if (srcdir)
|
||||
package->folders[index].SourceDefault = strdupW(srcdir);
|
||||
folder->SourceDefault = strdupW(srcdir);
|
||||
else if (shortname)
|
||||
package->folders[index].SourceDefault = strdupW(shortname);
|
||||
folder->SourceDefault = strdupW(shortname);
|
||||
else if (targetdir)
|
||||
package->folders[index].SourceDefault = strdupW(targetdir);
|
||||
folder->SourceDefault = strdupW(targetdir);
|
||||
HeapFree(GetProcessHeap(), 0, ptargetdir);
|
||||
TRACE(" SourceDefault = %s\n",debugstr_w(package->folders[index].SourceDefault));
|
||||
TRACE(" SourceDefault = %s\n", debugstr_w( folder->SourceDefault ));
|
||||
|
||||
parent = MSI_RecordGetString(row,2);
|
||||
if (parent)
|
||||
{
|
||||
i = load_folder(package,parent);
|
||||
package->folders[index].ParentIndex = i;
|
||||
TRACE("Parent is index %i... %s %s\n",
|
||||
package->folders[index].ParentIndex,
|
||||
debugstr_w(package->folders[package->folders[index].ParentIndex].Directory),
|
||||
debugstr_w(parent));
|
||||
}
|
||||
folder->Parent = load_folder( package, parent );
|
||||
if ( folder->Parent )
|
||||
TRACE("loaded parent %p %s\n", folder->Parent,
|
||||
debugstr_w(folder->Parent->Directory));
|
||||
else
|
||||
package->folders[index].ParentIndex = -2;
|
||||
ERR("failed to load parent folder %s\n", debugstr_w(parent));
|
||||
}
|
||||
|
||||
package->folders[index].Property = load_dynamic_property(package, dir,NULL);
|
||||
folder->Property = load_dynamic_property( package, dir, NULL );
|
||||
|
||||
msiobj_release(&row->hdr);
|
||||
TRACE(" %s retuning on index %i\n",debugstr_w(dir),index);
|
||||
return index;
|
||||
|
||||
list_add_tail( &package->folders, &folder->entry );
|
||||
|
||||
TRACE("%s returning %p\n",debugstr_w(dir),folder);
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
/* scan for and update current install states */
|
||||
|
|
|
@ -74,6 +74,7 @@ typedef struct tagComponentList
|
|||
|
||||
typedef struct tagMSIFOLDER
|
||||
{
|
||||
struct list entry;
|
||||
LPWSTR Directory;
|
||||
LPWSTR TargetDefault;
|
||||
LPWSTR SourceDefault;
|
||||
|
@ -81,7 +82,7 @@ typedef struct tagMSIFOLDER
|
|||
LPWSTR ResolvedTarget;
|
||||
LPWSTR ResolvedSource;
|
||||
LPWSTR Property; /* initially set property */
|
||||
INT ParentIndex;
|
||||
struct tagMSIFOLDER *Parent;
|
||||
INT State;
|
||||
/* 0 = uninitialized */
|
||||
/* 1 = existing */
|
||||
|
@ -89,7 +90,7 @@ typedef struct tagMSIFOLDER
|
|||
/* 3 = created persist if empty */
|
||||
INT Cost;
|
||||
INT Space;
|
||||
}MSIFOLDER;
|
||||
} MSIFOLDER;
|
||||
|
||||
typedef struct tagMSIFILE
|
||||
{
|
||||
|
@ -240,6 +241,7 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
|
|||
MSICOMPONENT *get_loaded_component( MSIPACKAGE* package, LPCWSTR Component );
|
||||
MSIFEATURE *get_loaded_feature( MSIPACKAGE* package, LPCWSTR Feature );
|
||||
MSIFILE *get_loaded_file( MSIPACKAGE* package, LPCWSTR file );
|
||||
MSIFOLDER *get_loaded_folder( MSIPACKAGE *package, LPCWSTR dir );
|
||||
int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path);
|
||||
UINT schedule_action(MSIPACKAGE *package, UINT script, LPCWSTR action);
|
||||
UINT build_icon_path(MSIPACKAGE *, LPCWSTR, LPWSTR *);
|
||||
|
|
|
@ -225,10 +225,22 @@ int track_tempfile( MSIPACKAGE *package, LPCWSTR name, LPCWSTR path )
|
|||
return 0;
|
||||
}
|
||||
|
||||
MSIFOLDER *get_loaded_folder( MSIPACKAGE *package, LPCWSTR dir )
|
||||
{
|
||||
MSIFOLDER *folder;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( folder, &package->folders, MSIFOLDER, entry )
|
||||
{
|
||||
if (lstrcmpW( dir, folder->Directory )==0)
|
||||
return folder;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
|
||||
BOOL set_prop, MSIFOLDER **folder)
|
||||
{
|
||||
DWORD i;
|
||||
MSIFOLDER *f;
|
||||
LPWSTR p, path = NULL;
|
||||
|
||||
TRACE("Working to resolve %s\n",debugstr_w(name));
|
||||
|
@ -254,17 +266,6 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
|
|||
path = build_directory_name(2, check_path, NULL);
|
||||
if (strcmpiW(path,check_path)!=0)
|
||||
MSI_SetPropertyW(package,cszTargetDir,path);
|
||||
|
||||
if (folder)
|
||||
{
|
||||
for (i = 0; i < package->loaded_folders; i++)
|
||||
{
|
||||
if (strcmpW(package->folders[i].Directory,name)==0)
|
||||
break;
|
||||
}
|
||||
*folder = &(package->folders[i]);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -279,81 +280,66 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
|
|||
*(p+1) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (folder)
|
||||
{
|
||||
for (i = 0; i < package->loaded_folders; i++)
|
||||
{
|
||||
if (strcmpW(package->folders[i].Directory,name)==0)
|
||||
break;
|
||||
}
|
||||
*folder = &(package->folders[i]);
|
||||
}
|
||||
*folder = get_loaded_folder( package, name );
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < package->loaded_folders; i++)
|
||||
{
|
||||
if (strcmpW(package->folders[i].Directory,name)==0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= package->loaded_folders)
|
||||
f = get_loaded_folder( package, name );
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
if (folder)
|
||||
*folder = &(package->folders[i]);
|
||||
*folder = f;
|
||||
|
||||
if (!source && package->folders[i].ResolvedTarget)
|
||||
if (!source && f->ResolvedTarget)
|
||||
{
|
||||
path = strdupW(package->folders[i].ResolvedTarget);
|
||||
path = strdupW( f->ResolvedTarget );
|
||||
TRACE(" already resolved to %s\n",debugstr_w(path));
|
||||
return path;
|
||||
}
|
||||
else if (source && package->folders[i].ResolvedSource)
|
||||
else if (source && f->ResolvedSource)
|
||||
{
|
||||
path = strdupW(package->folders[i].ResolvedSource);
|
||||
path = strdupW( f->ResolvedSource );
|
||||
TRACE(" (source)already resolved to %s\n",debugstr_w(path));
|
||||
return path;
|
||||
}
|
||||
else if (!source && package->folders[i].Property)
|
||||
else if (!source && f->Property)
|
||||
{
|
||||
path = build_directory_name(2, package->folders[i].Property, NULL);
|
||||
path = build_directory_name( 2, f->Property, NULL );
|
||||
|
||||
TRACE(" internally set to %s\n",debugstr_w(path));
|
||||
if (set_prop)
|
||||
MSI_SetPropertyW(package,name,path);
|
||||
MSI_SetPropertyW( package, name, path );
|
||||
return path;
|
||||
}
|
||||
|
||||
if (package->folders[i].ParentIndex >= 0)
|
||||
if (f->Parent)
|
||||
{
|
||||
LPWSTR parent = package->folders[package->folders[i].ParentIndex].Directory;
|
||||
LPWSTR parent = f->Parent->Directory;
|
||||
|
||||
TRACE(" ! Parent is %s\n", debugstr_w(parent));
|
||||
|
||||
p = resolve_folder(package, parent, source, set_prop, NULL);
|
||||
if (!source)
|
||||
{
|
||||
TRACE(" TargetDefault = %s\n",
|
||||
debugstr_w(package->folders[i].TargetDefault));
|
||||
TRACE(" TargetDefault = %s\n", debugstr_w(f->TargetDefault));
|
||||
|
||||
path = build_directory_name(3, p,
|
||||
package->folders[i].TargetDefault, NULL);
|
||||
package->folders[i].ResolvedTarget = strdupW(path);
|
||||
path = build_directory_name( 3, p, f->TargetDefault, NULL );
|
||||
f->ResolvedTarget = strdupW( path );
|
||||
TRACE(" resolved into %s\n",debugstr_w(path));
|
||||
if (set_prop)
|
||||
MSI_SetPropertyW(package,name,path);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (package->folders[i].SourceDefault &&
|
||||
package->folders[i].SourceDefault[0]!='.')
|
||||
path = build_directory_name(3, p, package->folders[i].SourceDefault, NULL);
|
||||
if (f->SourceDefault && f->SourceDefault[0]!='.')
|
||||
path = build_directory_name( 3, p, f->SourceDefault, NULL );
|
||||
else
|
||||
path = strdupW(p);
|
||||
TRACE(" (source)resolved into %s\n",debugstr_w(path));
|
||||
package->folders[i].ResolvedSource = strdupW(path);
|
||||
f->ResolvedSource = strdupW( path );
|
||||
}
|
||||
HeapFree(GetProcessHeap(),0,p);
|
||||
}
|
||||
|
@ -462,17 +448,18 @@ void ACTION_free_package_structures( MSIPACKAGE* package)
|
|||
free_feature( feature );
|
||||
}
|
||||
|
||||
for (i = 0; i < package->loaded_folders; i++)
|
||||
LIST_FOR_EACH_SAFE( item, cursor, &package->folders )
|
||||
{
|
||||
HeapFree(GetProcessHeap(),0,package->folders[i].Directory);
|
||||
HeapFree(GetProcessHeap(),0,package->folders[i].TargetDefault);
|
||||
HeapFree(GetProcessHeap(),0,package->folders[i].SourceDefault);
|
||||
HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedTarget);
|
||||
HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedSource);
|
||||
HeapFree(GetProcessHeap(),0,package->folders[i].Property);
|
||||
MSIFOLDER *folder = LIST_ENTRY( item, MSIFOLDER, entry );
|
||||
|
||||
list_remove( &folder->entry );
|
||||
HeapFree( GetProcessHeap(), 0, folder->Directory );
|
||||
HeapFree( GetProcessHeap(), 0, folder->TargetDefault );
|
||||
HeapFree( GetProcessHeap(), 0, folder->SourceDefault );
|
||||
HeapFree( GetProcessHeap(), 0, folder->ResolvedTarget );
|
||||
HeapFree( GetProcessHeap(), 0, folder->ResolvedSource );
|
||||
HeapFree( GetProcessHeap(), 0, folder->Property );
|
||||
}
|
||||
if (package->folders && package->loaded_folders > 0)
|
||||
HeapFree(GetProcessHeap(),0,package->folders);
|
||||
|
||||
LIST_FOR_EACH_SAFE( item, cursor, &package->components )
|
||||
{
|
||||
|
|
|
@ -263,7 +263,6 @@ UINT WINAPI MsiSetTargetPathA(MSIHANDLE hInstall, LPCSTR szFolder,
|
|||
UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder,
|
||||
LPCWSTR szFolderPath)
|
||||
{
|
||||
DWORD i;
|
||||
DWORD attrib;
|
||||
LPWSTR path = NULL;
|
||||
LPWSTR path2 = NULL;
|
||||
|
@ -312,16 +311,17 @@ UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder,
|
|||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < package->loaded_folders; i++)
|
||||
MSIFOLDER *f;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
|
||||
{
|
||||
HeapFree(GetProcessHeap(),0,package->folders[i].ResolvedTarget);
|
||||
package->folders[i].ResolvedTarget=NULL;
|
||||
HeapFree( GetProcessHeap(),0,f->ResolvedTarget);
|
||||
f->ResolvedTarget=NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < package->loaded_folders; i++)
|
||||
LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
|
||||
{
|
||||
path2=resolve_folder(package, package->folders[i].Directory, FALSE,
|
||||
TRUE, NULL);
|
||||
path2 = resolve_folder(package, f->Directory, FALSE, TRUE, NULL);
|
||||
HeapFree(GetProcessHeap(),0,path2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,11 +186,10 @@ typedef struct tagMSIPACKAGE
|
|||
{
|
||||
MSIOBJECTHDR hdr;
|
||||
MSIDATABASE *db;
|
||||
struct tagMSIFOLDER *folders;
|
||||
UINT loaded_folders;
|
||||
struct list components;
|
||||
struct list features;
|
||||
struct list files;
|
||||
struct list folders;
|
||||
LPWSTR ActionFormat;
|
||||
LPWSTR LastAction;
|
||||
|
||||
|
|
|
@ -377,11 +377,10 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db )
|
|||
msiobj_addref( &db->hdr );
|
||||
|
||||
package->db = db;
|
||||
list_init( &package->features );
|
||||
package->folders = NULL;
|
||||
list_init( &package->components );
|
||||
list_init( &package->features );
|
||||
list_init( &package->files );
|
||||
package->loaded_folders = 0;
|
||||
list_init( &package->folders );
|
||||
package->ActionFormat = NULL;
|
||||
package->LastAction = NULL;
|
||||
package->dialog = NULL;
|
||||
|
|
Loading…
Reference in New Issue