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)
}
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));
memset(&package->folders[index],0,sizeof(MSIFOLDER));
folder = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (MSIFOLDER) );
if (!folder)
return NULL;
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
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);
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]);
}
return path;
}
if (folder)
*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;
......
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