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;
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -1468,6 +1551,7 @@ static UINT ACTION_CostInitialize(MSIPACKAGE *package)
|
|||
load_all_components( package );
|
||||
load_all_features( package );
|
||||
load_all_files( package );
|
||||
load_all_folders( package );
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
@ -1504,98 +1588,6 @@ static UINT ACTION_FileCost(MSIPACKAGE *package)
|
|||
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)
|
||||
{
|
||||
MSICOMPONENT *comp;
|
||||
|
@ -1873,7 +1865,6 @@ static UINT ITERATE_CostFinalizeDirectories(MSIRECORD *row, LPVOID param)
|
|||
|
||||
/* This helper function now does ALL the work */
|
||||
TRACE("Dir %s ...\n",debugstr_w(name));
|
||||
load_folder(package,name);
|
||||
path = resolve_folder(package,name,FALSE,TRUE,NULL);
|
||||
TRACE("resolves to %s\n",debugstr_w(path));
|
||||
msi_free(path);
|
||||
|
|
|
@ -293,7 +293,7 @@ LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source,
|
|||
if (!f->Parent)
|
||||
return path;
|
||||
|
||||
parent = f->Parent->Directory;
|
||||
parent = f->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 );
|
||||
|
||||
list_remove( &folder->entry );
|
||||
msi_free( folder->Parent );
|
||||
msi_free( folder->Directory );
|
||||
msi_free( folder->TargetDefault );
|
||||
msi_free( folder->SourceLongPath );
|
||||
|
@ -509,7 +510,7 @@ void ACTION_free_package_structures( MSIPACKAGE* package)
|
|||
LIST_FOR_EACH_SAFE( item, cursor, &package->components )
|
||||
{
|
||||
MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry );
|
||||
|
||||
|
||||
list_remove( &comp->entry );
|
||||
msi_free( comp->Component );
|
||||
msi_free( comp->ComponentId );
|
||||
|
|
|
@ -318,6 +318,7 @@ typedef struct tagMSIFOLDER
|
|||
{
|
||||
struct list entry;
|
||||
LPWSTR Directory;
|
||||
LPWSTR Parent;
|
||||
LPWSTR TargetDefault;
|
||||
LPWSTR SourceLongPath;
|
||||
LPWSTR SourceShortPath;
|
||||
|
@ -325,7 +326,6 @@ typedef struct tagMSIFOLDER
|
|||
LPWSTR ResolvedTarget;
|
||||
LPWSTR ResolvedSource;
|
||||
LPWSTR Property; /* initially set property */
|
||||
struct tagMSIFOLDER *Parent;
|
||||
INT State;
|
||||
/* 0 = uninitialized */
|
||||
/* 1 = existing */
|
||||
|
|
Loading…
Reference in New Issue