Commit 979511fe authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

- build a standard Wine list of folders instead of using an array

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