msi: Load all folders in one query, rather one per query.
This commit is contained in:
parent
cf0c21af47
commit
7eb270265f
|
@ -1439,6 +1439,89 @@ static UINT load_all_files(MSIPACKAGE *package)
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT load_folder( MSIRECORD *row, LPVOID param )
|
||||||
|
{
|
||||||
|
MSIPACKAGE *package = param;
|
||||||
|
static const WCHAR szDot[] = { '.',0 };
|
||||||
|
static WCHAR szEmpty[] = { 0 };
|
||||||
|
LPWSTR p, tgt_short, tgt_long, src_short, src_long;
|
||||||
|
MSIFOLDER *folder;
|
||||||
|
|
||||||
|
folder = msi_alloc_zero( sizeof (MSIFOLDER) );
|
||||||
|
if (!folder)
|
||||||
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
|
||||||
|
folder->Directory = msi_dup_record_field( row, 1 );
|
||||||
|
|
||||||
|
TRACE("%s\n", debugstr_w(folder->Directory));
|
||||||
|
|
||||||
|
p = msi_dup_record_field(row, 3);
|
||||||
|
|
||||||
|
/* split src and target dir */
|
||||||
|
tgt_short = p;
|
||||||
|
src_short = folder_split_path( p, ':' );
|
||||||
|
|
||||||
|
/* split the long and short paths */
|
||||||
|
tgt_long = folder_split_path( tgt_short, '|' );
|
||||||
|
src_long = folder_split_path( src_short, '|' );
|
||||||
|
|
||||||
|
/* check for no-op dirs */
|
||||||
|
if (!lstrcmpW(szDot, tgt_short))
|
||||||
|
tgt_short = szEmpty;
|
||||||
|
if (!lstrcmpW(szDot, src_short))
|
||||||
|
src_short = szEmpty;
|
||||||
|
|
||||||
|
if (!tgt_long)
|
||||||
|
tgt_long = tgt_short;
|
||||||
|
|
||||||
|
if (!src_short) {
|
||||||
|
src_short = tgt_short;
|
||||||
|
src_long = tgt_long;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!src_long)
|
||||||
|
src_long = src_short;
|
||||||
|
|
||||||
|
/* FIXME: use the target short path too */
|
||||||
|
folder->TargetDefault = strdupW(tgt_long);
|
||||||
|
folder->SourceShortPath = strdupW(src_short);
|
||||||
|
folder->SourceLongPath = strdupW(src_long);
|
||||||
|
msi_free(p);
|
||||||
|
|
||||||
|
TRACE("TargetDefault = %s\n",debugstr_w( folder->TargetDefault ));
|
||||||
|
TRACE("SourceLong = %s\n", debugstr_w( folder->SourceLongPath ));
|
||||||
|
TRACE("SourceShort = %s\n", debugstr_w( folder->SourceShortPath ));
|
||||||
|
|
||||||
|
folder->Parent = msi_dup_record_field( row, 2 );
|
||||||
|
|
||||||
|
folder->Property = msi_dup_property( package, folder->Directory );
|
||||||
|
|
||||||
|
list_add_tail( &package->folders, &folder->entry );
|
||||||
|
|
||||||
|
TRACE("returning %p\n", folder);
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT load_all_folders( MSIPACKAGE *package )
|
||||||
|
{
|
||||||
|
static const WCHAR query[] = {
|
||||||
|
'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ',
|
||||||
|
'`','D','i','r','e','c','t','o','r','y','`',0 };
|
||||||
|
MSIQUERY *view;
|
||||||
|
UINT r;
|
||||||
|
|
||||||
|
if (!list_empty(&package->folders))
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
r = MSI_DatabaseOpenViewW( package->db, query, &view );
|
||||||
|
if (r != ERROR_SUCCESS)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = MSI_IterateRecords(view, NULL, load_folder, package);
|
||||||
|
msiobj_release(&view->hdr);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* I am not doing any of the costing functionality yet.
|
* I am not doing any of the costing functionality yet.
|
||||||
|
@ -1468,6 +1551,7 @@ static UINT ACTION_CostInitialize(MSIPACKAGE *package)
|
||||||
load_all_components( package );
|
load_all_components( package );
|
||||||
load_all_features( package );
|
load_all_features( package );
|
||||||
load_all_files( package );
|
load_all_files( package );
|
||||||
|
load_all_folders( package );
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1504,98 +1588,6 @@ static UINT ACTION_FileCost(MSIPACKAGE *package)
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MSIFOLDER *load_folder( MSIPACKAGE *package, LPCWSTR dir )
|
|
||||||
{
|
|
||||||
static const WCHAR Query[] =
|
|
||||||
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
|
||||||
'`','D','i','r','e','c', 't','o','r','y','`',' ',
|
|
||||||
'W','H','E','R','E',' ', '`', 'D','i','r','e','c','t', 'o','r','y','`',
|
|
||||||
' ','=',' ','\'','%','s','\'',
|
|
||||||
0};
|
|
||||||
static const WCHAR szDot[] = { '.',0 };
|
|
||||||
static WCHAR szEmpty[] = { 0 };
|
|
||||||
LPWSTR p, tgt_short, tgt_long, src_short, src_long;
|
|
||||||
LPCWSTR parent;
|
|
||||||
MSIRECORD *row;
|
|
||||||
MSIFOLDER *folder;
|
|
||||||
|
|
||||||
TRACE("Looking for dir %s\n",debugstr_w(dir));
|
|
||||||
|
|
||||||
folder = get_loaded_folder( package, dir );
|
|
||||||
if (folder)
|
|
||||||
return folder;
|
|
||||||
|
|
||||||
TRACE("Working to load %s\n",debugstr_w(dir));
|
|
||||||
|
|
||||||
row = MSI_QueryGetRecord(package->db, Query, dir);
|
|
||||||
if (!row)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
folder = msi_alloc_zero( sizeof (MSIFOLDER) );
|
|
||||||
if (!folder)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
folder->Directory = strdupW(dir);
|
|
||||||
|
|
||||||
p = msi_dup_record_field(row, 3);
|
|
||||||
|
|
||||||
/* split src and target dir */
|
|
||||||
tgt_short = p;
|
|
||||||
src_short = folder_split_path( p, ':' );
|
|
||||||
|
|
||||||
/* split the long and short paths */
|
|
||||||
tgt_long = folder_split_path( tgt_short, '|' );
|
|
||||||
src_long = folder_split_path( src_short, '|' );
|
|
||||||
|
|
||||||
/* check for no-op dirs */
|
|
||||||
if (!lstrcmpW(szDot, tgt_short))
|
|
||||||
tgt_short = szEmpty;
|
|
||||||
if (!lstrcmpW(szDot, src_short))
|
|
||||||
src_short = szEmpty;
|
|
||||||
|
|
||||||
if (!tgt_long)
|
|
||||||
tgt_long = tgt_short;
|
|
||||||
|
|
||||||
if (!src_short) {
|
|
||||||
src_short = tgt_short;
|
|
||||||
src_long = tgt_long;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!src_long)
|
|
||||||
src_long = src_short;
|
|
||||||
|
|
||||||
/* FIXME: use the target short path too */
|
|
||||||
folder->TargetDefault = strdupW(tgt_long);
|
|
||||||
folder->SourceShortPath = strdupW(src_short);
|
|
||||||
folder->SourceLongPath = strdupW(src_long);
|
|
||||||
msi_free(p);
|
|
||||||
|
|
||||||
TRACE("TargetDefault = %s\n",debugstr_w( folder->TargetDefault ));
|
|
||||||
TRACE("SourceLong = %s\n", debugstr_w( folder->SourceLongPath ));
|
|
||||||
TRACE("SourceShort = %s\n", debugstr_w( folder->SourceShortPath ));
|
|
||||||
|
|
||||||
parent = MSI_RecordGetString(row, 2);
|
|
||||||
if (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));
|
|
||||||
}
|
|
||||||
|
|
||||||
folder->Property = msi_dup_property( package, dir );
|
|
||||||
|
|
||||||
msiobj_release(&row->hdr);
|
|
||||||
|
|
||||||
list_add_tail( &package->folders, &folder->entry );
|
|
||||||
|
|
||||||
TRACE("%s returning %p\n",debugstr_w(dir),folder);
|
|
||||||
|
|
||||||
return folder;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ACTION_GetComponentInstallStates(MSIPACKAGE *package)
|
static void ACTION_GetComponentInstallStates(MSIPACKAGE *package)
|
||||||
{
|
{
|
||||||
MSICOMPONENT *comp;
|
MSICOMPONENT *comp;
|
||||||
|
@ -1873,7 +1865,6 @@ static UINT ITERATE_CostFinalizeDirectories(MSIRECORD *row, LPVOID param)
|
||||||
|
|
||||||
/* This helper function now does ALL the work */
|
/* This helper function now does ALL the work */
|
||||||
TRACE("Dir %s ...\n",debugstr_w(name));
|
TRACE("Dir %s ...\n",debugstr_w(name));
|
||||||
load_folder(package,name);
|
|
||||||
path = resolve_folder(package,name,FALSE,TRUE,NULL);
|
path = resolve_folder(package,name,FALSE,TRUE,NULL);
|
||||||
TRACE("resolves to %s\n",debugstr_w(path));
|
TRACE("resolves to %s\n",debugstr_w(path));
|
||||||
msi_free(path);
|
msi_free(path);
|
||||||
|
|
|
@ -293,7 +293,7 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
|
||||||
if (!f->Parent)
|
if (!f->Parent)
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
parent = f->Parent->Directory;
|
parent = f->Parent;
|
||||||
|
|
||||||
TRACE(" ! Parent is %s\n", debugstr_w(parent));
|
TRACE(" ! Parent is %s\n", debugstr_w(parent));
|
||||||
|
|
||||||
|
@ -496,6 +496,7 @@ void ACTION_free_package_structures( MSIPACKAGE* package)
|
||||||
MSIFOLDER *folder = LIST_ENTRY( item, MSIFOLDER, entry );
|
MSIFOLDER *folder = LIST_ENTRY( item, MSIFOLDER, entry );
|
||||||
|
|
||||||
list_remove( &folder->entry );
|
list_remove( &folder->entry );
|
||||||
|
msi_free( folder->Parent );
|
||||||
msi_free( folder->Directory );
|
msi_free( folder->Directory );
|
||||||
msi_free( folder->TargetDefault );
|
msi_free( folder->TargetDefault );
|
||||||
msi_free( folder->SourceLongPath );
|
msi_free( folder->SourceLongPath );
|
||||||
|
@ -509,7 +510,7 @@ void ACTION_free_package_structures( MSIPACKAGE* package)
|
||||||
LIST_FOR_EACH_SAFE( item, cursor, &package->components )
|
LIST_FOR_EACH_SAFE( item, cursor, &package->components )
|
||||||
{
|
{
|
||||||
MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry );
|
MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry );
|
||||||
|
|
||||||
list_remove( &comp->entry );
|
list_remove( &comp->entry );
|
||||||
msi_free( comp->Component );
|
msi_free( comp->Component );
|
||||||
msi_free( comp->ComponentId );
|
msi_free( comp->ComponentId );
|
||||||
|
|
|
@ -318,6 +318,7 @@ typedef struct tagMSIFOLDER
|
||||||
{
|
{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
LPWSTR Directory;
|
LPWSTR Directory;
|
||||||
|
LPWSTR Parent;
|
||||||
LPWSTR TargetDefault;
|
LPWSTR TargetDefault;
|
||||||
LPWSTR SourceLongPath;
|
LPWSTR SourceLongPath;
|
||||||
LPWSTR SourceShortPath;
|
LPWSTR SourceShortPath;
|
||||||
|
@ -325,7 +326,6 @@ typedef struct tagMSIFOLDER
|
||||||
LPWSTR ResolvedTarget;
|
LPWSTR ResolvedTarget;
|
||||||
LPWSTR ResolvedSource;
|
LPWSTR ResolvedSource;
|
||||||
LPWSTR Property; /* initially set property */
|
LPWSTR Property; /* initially set property */
|
||||||
struct tagMSIFOLDER *Parent;
|
|
||||||
INT State;
|
INT State;
|
||||||
/* 0 = uninitialized */
|
/* 0 = uninitialized */
|
||||||
/* 1 = existing */
|
/* 1 = existing */
|
||||||
|
|
Loading…
Reference in New Issue