static const WCHAR cszDatabase[]={'D','A','T','A','B','A','S','E',0};
const WCHAR cszSourceDir[] = {'S','o','u','r','c','e','D','i','r',0};
-const WCHAR szProductCode[]= {'P','r','o','d','u','c','t','C','o','d','e',0};
const WCHAR cszRootDrive[] = {'R','O','O','T','D','R','I','V','E',0};
const WCHAR cszbs[]={'\\',0};
return rc;
}
-UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name,
- LPWSTR *FilePath)
+LPWSTR build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name )
{
- LPWSTR ProductCode;
- LPWSTR SystemFolder;
- LPWSTR dest;
- UINT rc;
+ LPWSTR SystemFolder, dest, FilePath;
static const WCHAR szInstaller[] =
{'M','i','c','r','o','s','o','f','t','\\',
static const WCHAR szFolder[] =
{'A','p','p','D','a','t','a','F','o','l','d','e','r',0};
- ProductCode = load_dynamic_property(package,szProductCode,&rc);
- if (!ProductCode)
- return rc;
-
- SystemFolder = load_dynamic_property(package,szFolder,NULL);
+ SystemFolder = msi_dup_property( package, szFolder );
- dest = build_directory_name(3, SystemFolder, szInstaller, ProductCode);
+ dest = build_directory_name(3, SystemFolder, szInstaller, package->ProductCode);
create_full_pathW(dest);
- *FilePath = build_directory_name(2, dest, icon_name);
+ FilePath = build_directory_name(2, dest, icon_name);
- HeapFree(GetProcessHeap(),0,SystemFolder);
- HeapFree(GetProcessHeap(),0,ProductCode);
- HeapFree(GetProcessHeap(),0,dest);
- return ERROR_SUCCESS;
+ msi_free(SystemFolder);
+ msi_free(dest);
+ return FilePath;
}
-WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index)
+LPWSTR msi_dup_record_field( MSIRECORD *row, INT index )
{
- UINT rc;
- DWORD sz;
- LPWSTR ret;
-
- sz = 0;
- if (MSI_RecordIsNull(row,index))
- return NULL;
-
- rc = MSI_RecordGetStringW(row,index,NULL,&sz);
-
- /* having an empty string is different than NULL */
- if (sz == 0)
- {
- ret = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR));
- ret[0] = 0;
- return ret;
- }
-
- sz ++;
- ret = HeapAlloc(GetProcessHeap(),0,sz * sizeof (WCHAR));
- rc = MSI_RecordGetStringW(row,index,ret,&sz);
- if (rc!=ERROR_SUCCESS)
- {
- ERR("Unable to load dynamic string\n");
- HeapFree(GetProcessHeap(), 0, ret);
- ret = NULL;
- }
- return ret;
+ return strdupW( MSI_RecordGetString(row,index) );
}
-LPWSTR load_dynamic_property(MSIPACKAGE *package, LPCWSTR prop, UINT* rc)
+LPWSTR msi_dup_property(MSIPACKAGE *package, LPCWSTR prop)
{
DWORD sz = 0;
LPWSTR str;
r = MSI_GetPropertyW(package, prop, NULL, &sz);
if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
- {
- if (rc)
- *rc = r;
return NULL;
- }
+
sz++;
- str = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR));
+ str = msi_alloc(sz*sizeof(WCHAR));
r = MSI_GetPropertyW(package, prop, str, &sz);
if (r != ERROR_SUCCESS)
{
- HeapFree(GetProcessHeap(),0,str);
+ msi_free(str);
str = NULL;
}
- if (rc)
- *rc = r;
return str;
}
-int get_loaded_component(MSIPACKAGE* package, LPCWSTR Component )
+MSICOMPONENT* get_loaded_component( MSIPACKAGE* package, LPCWSTR Component )
{
- int rc = -1;
- DWORD i;
+ MSICOMPONENT *comp;
- for (i = 0; i < package->loaded_components; i++)
+ LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
{
- if (strcmpW(Component,package->components[i].Component)==0)
- {
- rc = i;
- break;
- }
+ if (lstrcmpW(Component,comp->Component)==0)
+ return comp;
}
- return rc;
+ return NULL;
}
-int get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature )
+MSIFEATURE* get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature )
{
- int rc = -1;
- DWORD i;
+ MSIFEATURE *feature;
- for (i = 0; i < package->loaded_features; i++)
+ LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
- if (strcmpW(Feature,package->features[i].Feature)==0)
- {
- rc = i;
- break;
- }
+ if (lstrcmpW( Feature, feature->Feature )==0)
+ return feature;
}
- return rc;
+ return NULL;
}
-int get_loaded_file(MSIPACKAGE* package, LPCWSTR file)
+MSIFILE* get_loaded_file( MSIPACKAGE* package, LPCWSTR key )
{
- int rc = -1;
- DWORD i;
+ MSIFILE *file;
- for (i = 0; i < package->loaded_files; i++)
+ LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
{
- if (strcmpW(file,package->files[i].File)==0)
- {
- rc = i;
- break;
- }
+ if (lstrcmpW( key, file->File )==0)
+ return file;
}
- return rc;
+ return NULL;
}
-int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path)
+int track_tempfile( MSIPACKAGE *package, LPCWSTR name, LPCWSTR path )
{
- DWORD i;
- DWORD index;
-
- if (!package)
- return -2;
+ MSITEMPFILE *temp;
- for (i=0; i < package->loaded_files; i++)
- if (strcmpW(package->files[i].File,name)==0)
+ LIST_FOR_EACH_ENTRY( temp, &package->tempfiles, MSITEMPFILE, entry )
+ {
+ if (lstrcmpW( name, temp->File )==0)
+ {
+ TRACE("tempfile %s already exists with path %s\n",
+ debugstr_w(temp->File), debugstr_w(temp->Path));
return -1;
+ }
+ }
- index = package->loaded_files;
- package->loaded_files++;
- if (package->loaded_files== 1)
- package->files = HeapAlloc(GetProcessHeap(),0,sizeof(MSIFILE));
- else
- package->files = HeapReAlloc(GetProcessHeap(),0,
- package->files , package->loaded_files * sizeof(MSIFILE));
+ temp = msi_alloc_zero( sizeof (MSITEMPFILE) );
+ if (!temp)
+ return -1;
- memset(&package->files[index],0,sizeof(MSIFILE));
+ list_add_head( &package->tempfiles, &temp->entry );
- package->files[index].File = strdupW(name);
- package->files[index].TargetPath = strdupW(path);
- package->files[index].Temporary = TRUE;
+ temp->File = strdupW( name );
+ temp->Path = strdupW( path );
- TRACE("Tracking tempfile (%s)\n",debugstr_w(package->files[index].File));
+ TRACE("adding tempfile %s with path %s\n",
+ debugstr_w(temp->File), debugstr_w(temp->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;
+}
+
+static LPWSTR get_source_root( MSIPACKAGE *package )
+{
+ LPWSTR path, p;
+
+ path = msi_dup_property( package, cszSourceDir );
+ if (path)
+ return path;
+
+ path = msi_dup_property( package, cszDatabase );
+ if (path)
+ {
+ p = strrchrW(path,'\\');
+ if (p)
+ *(p+1) = 0;
+ }
+ return path;
+}
+
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));
if (!source)
{
LPWSTR check_path;
- check_path = load_dynamic_property(package,cszTargetDir,NULL);
+ check_path = msi_dup_property( package, cszTargetDir );
if (!check_path)
{
- check_path = load_dynamic_property(package,cszRootDrive,NULL);
+ check_path = msi_dup_property( package, cszRootDrive );
if (set_prop)
MSI_SetPropertyW(package,cszTargetDir,check_path);
}
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;
+ msi_free(check_path);
}
else
- {
- path = load_dynamic_property(package,cszSourceDir,NULL);
- if (!path)
- {
- path = load_dynamic_property(package,cszDatabase,NULL);
- if (path)
- {
- p = strrchrW(path,'\\');
- if (p)
- *(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;
- }
- }
-
- for (i = 0; i < package->loaded_folders; i++)
- {
- if (strcmpW(package->folders[i].Directory,name)==0)
- break;
+ path = get_source_root( package );
+ if (folder)
+ *folder = get_loaded_folder( package, name );
+ return path;
}
- 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);
- TRACE(" resolved into %s\n",debugstr_w(path));
+ path = build_directory_name( 3, p, f->TargetDefault, NULL );
+ f->ResolvedTarget = strdupW( path );
+ TRACE("target -> %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);
+ TRACE("source -> %s\n", debugstr_w(path));
+
+ /* if the directory doesn't exist, use the root */
+ if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path ))
+ {
+ msi_free( path );
+ path = get_source_root( package );
+ TRACE("defaulting to %s\n", debugstr_w(path));
+ }
+ else
+ f->ResolvedSource = strdupW( path );
}
- HeapFree(GetProcessHeap(),0,p);
+ msi_free(p);
}
return path;
}
if (size >= 0)
{
size++;
- *data = HeapAlloc(GetProcessHeap(),0,size*sizeof(WCHAR));
+ *data = msi_alloc(size*sizeof(WCHAR));
if (size > 1)
MSI_FormatRecordW(package,rec,*data,&size);
else
count = package->script->ActionCount[script];
package->script->ActionCount[script]++;
if (count != 0)
- newbuf = HeapReAlloc(GetProcessHeap(),0,
- package->script->Actions[script],
+ newbuf = msi_realloc( package->script->Actions[script],
package->script->ActionCount[script]* sizeof(LPWSTR));
else
- newbuf = HeapAlloc(GetProcessHeap(),0, sizeof(LPWSTR));
+ newbuf = msi_alloc( sizeof(LPWSTR));
newbuf[count] = strdupW(action);
package->script->Actions[script] = newbuf;
static void remove_tracked_tempfiles(MSIPACKAGE* package)
{
- DWORD i;
+ struct list *item, *cursor;
- if (!package)
- return;
+ LIST_FOR_EACH_SAFE( item, cursor, &package->tempfiles )
+ {
+ MSITEMPFILE *temp = LIST_ENTRY( item, MSITEMPFILE, entry );
+
+ list_remove( &temp->entry );
+ TRACE("deleting temp file %s\n", debugstr_w( temp->Path ));
+ DeleteFileW( temp->Path );
+ msi_free( temp->File );
+ msi_free( temp->Path );
+ msi_free( temp );
+ }
+}
- for (i = 0; i < package->loaded_files; i++)
+static void free_feature( MSIFEATURE *feature )
+{
+ struct list *item, *cursor;
+
+ LIST_FOR_EACH_SAFE( item, cursor, &feature->Components )
{
- if (package->files[i].Temporary)
- {
- TRACE("Cleaning up %s\n",debugstr_w(package->files[i].TargetPath));
- DeleteFileW(package->files[i].TargetPath);
- }
+ ComponentList *cl = LIST_ENTRY( item, ComponentList, entry );
+ list_remove( &cl->entry );
+ msi_free( cl );
+ }
+ msi_free( feature->Feature );
+ msi_free( feature->Feature_Parent );
+ msi_free( feature->Directory );
+ msi_free( feature->Description );
+ msi_free( feature->Title );
+ msi_free( feature );
+}
+void free_extension( MSIEXTENSION *ext )
+{
+ struct list *item, *cursor;
+
+ LIST_FOR_EACH_SAFE( item, cursor, &ext->verbs )
+ {
+ MSIVERB *verb = LIST_ENTRY( item, MSIVERB, entry );
+
+ list_remove( &verb->entry );
+ msi_free( verb->Verb );
+ msi_free( verb->Command );
+ msi_free( verb->Argument );
+ msi_free( verb );
}
+
+ msi_free( ext->Extension );
+ msi_free( ext->ProgIDText );
+ msi_free( ext );
}
/* Called when the package is being closed */
void ACTION_free_package_structures( MSIPACKAGE* package)
{
INT i;
+ struct list *item, *cursor;
TRACE("Freeing package action data\n");
remove_tracked_tempfiles(package);
- /* No dynamic buffers in features */
- if (package->features && package->loaded_features > 0)
- HeapFree(GetProcessHeap(),0,package->features);
-
- for (i = 0; i < package->loaded_folders; i++)
+ LIST_FOR_EACH_SAFE( item, cursor, &package->features )
{
- 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);
+ MSIFEATURE *feature = LIST_ENTRY( item, MSIFEATURE, entry );
+ list_remove( &feature->entry );
+ free_feature( feature );
}
- if (package->folders && package->loaded_folders > 0)
- HeapFree(GetProcessHeap(),0,package->folders);
-
- for (i = 0; i < package->loaded_components; i++)
- HeapFree(GetProcessHeap(),0,package->components[i].FullKeypath);
-
- if (package->components && package->loaded_components > 0)
- HeapFree(GetProcessHeap(),0,package->components);
- for (i = 0; i < package->loaded_files; i++)
+ LIST_FOR_EACH_SAFE( item, cursor, &package->folders )
{
- HeapFree(GetProcessHeap(),0,package->files[i].File);
- HeapFree(GetProcessHeap(),0,package->files[i].FileName);
- HeapFree(GetProcessHeap(),0,package->files[i].ShortName);
- HeapFree(GetProcessHeap(),0,package->files[i].Version);
- HeapFree(GetProcessHeap(),0,package->files[i].Language);
- HeapFree(GetProcessHeap(),0,package->files[i].SourcePath);
- HeapFree(GetProcessHeap(),0,package->files[i].TargetPath);
+ MSIFOLDER *folder = LIST_ENTRY( item, MSIFOLDER, entry );
+
+ list_remove( &folder->entry );
+ msi_free( folder->Directory );
+ msi_free( folder->TargetDefault );
+ msi_free( folder->SourceDefault );
+ msi_free( folder->ResolvedTarget );
+ msi_free( folder->ResolvedSource );
+ msi_free( folder->Property );
+ msi_free( folder );
}
- if (package->files && package->loaded_files > 0)
- HeapFree(GetProcessHeap(),0,package->files);
-
- /* clean up extension, progid, class and verb structures */
- for (i = 0; i < package->loaded_classes; i++)
+ LIST_FOR_EACH_SAFE( item, cursor, &package->components )
{
- HeapFree(GetProcessHeap(),0,package->classes[i].Description);
- HeapFree(GetProcessHeap(),0,package->classes[i].FileTypeMask);
- HeapFree(GetProcessHeap(),0,package->classes[i].IconPath);
- HeapFree(GetProcessHeap(),0,package->classes[i].DefInprocHandler);
- HeapFree(GetProcessHeap(),0,package->classes[i].DefInprocHandler32);
- HeapFree(GetProcessHeap(),0,package->classes[i].Argument);
- HeapFree(GetProcessHeap(),0,package->classes[i].ProgIDText);
+ MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry );
+
+ list_remove( &comp->entry );
+ msi_free( comp->Component );
+ msi_free( comp->ComponentId );
+ msi_free( comp->Directory );
+ msi_free( comp->Condition );
+ msi_free( comp->KeyPath );
+ msi_free( comp->FullKeypath );
+ msi_free( comp );
}
- if (package->classes && package->loaded_classes > 0)
- HeapFree(GetProcessHeap(),0,package->classes);
-
- for (i = 0; i < package->loaded_extensions; i++)
+ LIST_FOR_EACH_SAFE( item, cursor, &package->files )
{
- HeapFree(GetProcessHeap(),0,package->extensions[i].ProgIDText);
+ MSIFILE *file = LIST_ENTRY( item, MSIFILE, entry );
+
+ list_remove( &file->entry );
+ msi_free( file->File );
+ msi_free( file->FileName );
+ msi_free( file->ShortName );
+ msi_free( file->Version );
+ msi_free( file->Language );
+ msi_free( file->SourcePath );
+ msi_free( file->TargetPath );
+ msi_free( file );
}
- if (package->extensions && package->loaded_extensions > 0)
- HeapFree(GetProcessHeap(),0,package->extensions);
-
- for (i = 0; i < package->loaded_progids; i++)
+ /* clean up extension, progid, class and verb structures */
+ LIST_FOR_EACH_SAFE( item, cursor, &package->classes )
{
- HeapFree(GetProcessHeap(),0,package->progids[i].ProgID);
- HeapFree(GetProcessHeap(),0,package->progids[i].Description);
- HeapFree(GetProcessHeap(),0,package->progids[i].IconPath);
+ MSICLASS *cls = LIST_ENTRY( item, MSICLASS, entry );
+
+ list_remove( &cls->entry );
+ msi_free( cls->clsid );
+ msi_free( cls->Context );
+ msi_free( cls->Description );
+ msi_free( cls->FileTypeMask );
+ msi_free( cls->IconPath );
+ msi_free( cls->DefInprocHandler );
+ msi_free( cls->DefInprocHandler32 );
+ msi_free( cls->Argument );
+ msi_free( cls->ProgIDText );
+ msi_free( cls );
}
- if (package->progids && package->loaded_progids > 0)
- HeapFree(GetProcessHeap(),0,package->progids);
-
- for (i = 0; i < package->loaded_verbs; i++)
+ LIST_FOR_EACH_SAFE( item, cursor, &package->extensions )
{
- HeapFree(GetProcessHeap(),0,package->verbs[i].Verb);
- HeapFree(GetProcessHeap(),0,package->verbs[i].Command);
- HeapFree(GetProcessHeap(),0,package->verbs[i].Argument);
- }
+ MSIEXTENSION *ext = LIST_ENTRY( item, MSIEXTENSION, entry );
- if (package->verbs && package->loaded_verbs > 0)
- HeapFree(GetProcessHeap(),0,package->verbs);
+ list_remove( &ext->entry );
+ free_extension( ext );
+ }
- for (i = 0; i < package->loaded_mimes; i++)
- HeapFree(GetProcessHeap(),0,package->mimes[i].ContentType);
+ LIST_FOR_EACH_SAFE( item, cursor, &package->progids )
+ {
+ MSIPROGID *progid = LIST_ENTRY( item, MSIPROGID, entry );
- if (package->mimes && package->loaded_mimes > 0)
- HeapFree(GetProcessHeap(),0,package->mimes);
+ list_remove( &progid->entry );
+ msi_free( progid->ProgID );
+ msi_free( progid->Description );
+ msi_free( progid->IconPath );
+ msi_free( progid );
+ }
- for (i = 0; i < package->loaded_appids; i++)
+ LIST_FOR_EACH_SAFE( item, cursor, &package->mimes )
{
- HeapFree(GetProcessHeap(),0,package->appids[i].RemoteServerName);
- HeapFree(GetProcessHeap(),0,package->appids[i].LocalServer);
- HeapFree(GetProcessHeap(),0,package->appids[i].ServiceParameters);
- HeapFree(GetProcessHeap(),0,package->appids[i].DllSurrogate);
+ MSIMIME *mt = LIST_ENTRY( item, MSIMIME, entry );
+
+ list_remove( &mt->entry );
+ msi_free( mt->clsid );
+ msi_free( mt->ContentType );
+ msi_free( mt );
}
- if (package->appids && package->loaded_appids > 0)
- HeapFree(GetProcessHeap(),0,package->appids);
+ LIST_FOR_EACH_SAFE( item, cursor, &package->appids )
+ {
+ MSIAPPID *appid = LIST_ENTRY( item, MSIAPPID, entry );
+
+ list_remove( &appid->entry );
+ msi_free( appid->AppID );
+ msi_free( appid->RemoteServerName );
+ msi_free( appid->LocalServer );
+ msi_free( appid->ServiceParameters );
+ msi_free( appid->DllSurrogate );
+ msi_free( appid );
+ }
if (package->script)
{
{
int j;
for (j = 0; j < package->script->ActionCount[i]; j++)
- HeapFree(GetProcessHeap(),0,package->script->Actions[i][j]);
+ msi_free(package->script->Actions[i][j]);
- HeapFree(GetProcessHeap(),0,package->script->Actions[i]);
+ msi_free(package->script->Actions[i]);
}
- HeapFree(GetProcessHeap(),0,package->script);
+
+ for (i = 0; i < package->script->UniqueActionsCount; i++)
+ msi_free(package->script->UniqueActions[i]);
+
+ msi_free(package->script->UniqueActions);
+ msi_free(package->script);
}
- HeapFree(GetProcessHeap(),0,package->PackagePath);
+ msi_free(package->PackagePath);
+ msi_free(package->ProductCode);
+ msi_free(package->ActionFormat);
+ msi_free(package->LastAction);
/* cleanup control event subscriptions */
ControlEvent_CleanupSubscriptions(package);
}
va_end(va);
- dir = HeapAlloc(GetProcessHeap(), 0, sz*sizeof(WCHAR));
+ dir = msi_alloc(sz*sizeof(WCHAR));
dir[0]=0;
va_start(va,count);
int len;
WCHAR *new_path;
- new_path = HeapAlloc(GetProcessHeap(), 0, (strlenW(path) + 1) *
- sizeof(WCHAR));
+ new_path = msi_alloc( (strlenW(path) + 1) * sizeof(WCHAR));
strcpyW(new_path, path);
new_path[len] = '\\';
}
- HeapFree(GetProcessHeap(), 0, new_path);
+ msi_free(new_path);
return ret;
}
}
/* update the cached actionformat */
- HeapFree(GetProcessHeap(),0,package->ActionFormat);
- package->ActionFormat = load_dynamic_stringW(row,3);
+ msi_free(package->ActionFormat);
+ package->ActionFormat = msi_dup_record_field(row,3);
- HeapFree(GetProcessHeap(),0,package->LastAction);
+ msi_free(package->LastAction);
package->LastAction = strdupW(action);
msiobj_release(&row->hdr);
msiobj_release(&row->hdr);
}
-BOOL ACTION_VerifyComponentForAction(MSIPACKAGE* package, INT index,
- INSTALLSTATE check )
+BOOL ACTION_VerifyComponentForAction( MSICOMPONENT* comp, INSTALLSTATE check )
{
- if (package->components[index].Installed == check)
+ if (!comp)
return FALSE;
- if (package->components[index].ActionRequest == check)
+ if (comp->Installed == check)
+ return FALSE;
+
+ if (comp->ActionRequest == check)
return TRUE;
else
return FALSE;
}
-BOOL ACTION_VerifyFeatureForAction(MSIPACKAGE* package, INT index,
- INSTALLSTATE check )
+BOOL ACTION_VerifyFeatureForAction( MSIFEATURE* feature, INSTALLSTATE check )
{
- if (package->features[index].Installed == check)
+ if (!feature)
+ return FALSE;
+
+ if (feature->Installed == check)
return FALSE;
- if (package->features[index].ActionRequest == check)
+ if (feature->ActionRequest == check)
return TRUE;
else
return FALSE;
LPWSTR create_component_advertise_string(MSIPACKAGE* package,
MSICOMPONENT* component, LPCWSTR feature)
{
- LPWSTR productid=NULL;
GUID clsid;
WCHAR productid_85[21];
WCHAR component_85[21];
memset(productid_85,0,sizeof(productid_85));
memset(component_85,0,sizeof(component_85));
- productid = load_dynamic_property(package,szProductCode,NULL);
- CLSIDFromString(productid, &clsid);
+ CLSIDFromString(package->ProductCode, &clsid);
encode_base85_guid(&clsid,productid_85);
sz+=3;
sz *= sizeof(WCHAR);
- output = HeapAlloc(GetProcessHeap(),0,sz);
+ output = msi_alloc(sz);
memset(output,0,sz);
if (component)
sprintfW(output,fmt2,productid_85,feature,component_85);
else
sprintfW(output,fmt1,productid_85,feature);
-
- HeapFree(GetProcessHeap(),0,productid);
return output;
}
/* update compoennt state based on a feature change */
void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
{
- int i;
INSTALLSTATE newstate;
MSIFEATURE *feature;
+ ComponentList *cl;
- i = get_loaded_feature(package,szFeature);
- if (i < 0)
+ feature = get_loaded_feature(package,szFeature);
+ if (!feature)
return;
- feature = &package->features[i];
newstate = feature->ActionRequest;
- for( i = 0; i < feature->ComponentCount; i++)
+ LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
{
- MSICOMPONENT* component = &package->components[feature->Components[i]];
-
+ MSICOMPONENT* component = cl->component;
+
TRACE("MODIFYING(%i): Component %s (Installed %i, Action %i, Request %i)\n",
newstate, debugstr_w(component->Component), component->Installed,
component->Action, component->ActionRequest);
if (!component->Enabled)
continue;
- else
+
+ if (newstate == INSTALLSTATE_LOCAL)
{
- if (newstate == INSTALLSTATE_LOCAL)
- {
- component->ActionRequest = INSTALLSTATE_LOCAL;
- component->Action = INSTALLSTATE_LOCAL;
- }
- else
- {
- int j,k;
+ component->ActionRequest = INSTALLSTATE_LOCAL;
+ component->Action = INSTALLSTATE_LOCAL;
+ }
+ else
+ {
+ ComponentList *clist;
+ MSIFEATURE *f;
- component->ActionRequest = newstate;
- component->Action = newstate;
+ component->ActionRequest = newstate;
+ component->Action = newstate;
+
+ /*if any other feature wants is local we need to set it local*/
+ LIST_FOR_EACH_ENTRY( f, &package->features, MSIFEATURE, entry )
+ {
+ if ( component->ActionRequest != INSTALLSTATE_LOCAL )
+ break;
- /*if any other feature wants is local we need to set it local*/
- for (j = 0;
- j < package->loaded_features &&
- component->ActionRequest != INSTALLSTATE_LOCAL;
- j++)
+ LIST_FOR_EACH_ENTRY( clist, &f->Components, ComponentList, entry )
{
- for (k = 0; k < package->features[j].ComponentCount; k++)
- if ( package->features[j].Components[k] ==
- feature->Components[i] )
+ if ( clist->component == component )
+ {
+ if (f->ActionRequest == INSTALLSTATE_LOCAL)
{
- if (package->features[j].ActionRequest ==
- INSTALLSTATE_LOCAL)
- {
- TRACE("Saved by %s\n", debugstr_w(package->features[j].Feature));
- component->ActionRequest = INSTALLSTATE_LOCAL;
- component->Action = INSTALLSTATE_LOCAL;
- }
- break;
+ TRACE("Saved by %s\n", debugstr_w(f->Feature));
+ component->ActionRequest = INSTALLSTATE_LOCAL;
+ component->Action = INSTALLSTATE_LOCAL;
}
+ break;
+ }
}
}
}
component->Action, component->ActionRequest);
}
}
+
+UINT register_unique_action(MSIPACKAGE *package, LPCWSTR action)
+{
+ UINT count;
+ LPWSTR *newbuf = NULL;
+
+ if (!package->script)
+ return FALSE;
+
+ TRACE("Registering Action %s as having fun\n",debugstr_w(action));
+
+ count = package->script->UniqueActionsCount;
+ package->script->UniqueActionsCount++;
+ if (count != 0)
+ newbuf = msi_realloc( package->script->UniqueActions,
+ package->script->UniqueActionsCount* sizeof(LPWSTR));
+ else
+ newbuf = msi_alloc( sizeof(LPWSTR));
+
+ newbuf[count] = strdupW(action);
+ package->script->UniqueActions = newbuf;
+
+ return ERROR_SUCCESS;
+}
+
+BOOL check_unique_action(MSIPACKAGE *package, LPCWSTR action)
+{
+ INT i;
+
+ if (!package->script)
+ return FALSE;
+
+ for (i = 0; i < package->script->UniqueActionsCount; i++)
+ if (!strcmpW(package->script->UniqueActions[i],action))
+ return TRUE;
+
+ return FALSE;
+}
+
+WCHAR* generate_error_string(MSIPACKAGE *package, UINT error, DWORD count, ... )
+{
+ static const WCHAR query[] = {'S','E','L','E','C','T',' ','`','M','e','s','s','a','g','e','`',' ','F','R','O','M',' ','`','E','r','r','o','r','`',' ','W','H','E','R','E',' ','`','E','r','r','o','r','`',' ','=',' ','%','i',0};
+
+ MSIRECORD *rec;
+ MSIRECORD *row;
+ DWORD size = 0;
+ DWORD i;
+ va_list va;
+ LPCWSTR str;
+ LPWSTR data;
+
+ row = MSI_QueryGetRecord(package->db, query, error);
+ if (!row)
+ return 0;
+
+ rec = MSI_CreateRecord(count+2);
+
+ str = MSI_RecordGetString(row,1);
+ MSI_RecordSetStringW(rec,0,str);
+ msiobj_release( &row->hdr );
+ MSI_RecordSetInteger(rec,1,error);
+
+ va_start(va,count);
+ for (i = 0; i < count; i++)
+ {
+ str = va_arg(va,LPCWSTR);
+ MSI_RecordSetStringW(rec,(i+2),str);
+ }
+ va_end(va);
+
+ MSI_FormatRecordW(package,rec,NULL,&size);
+ if (size >= 0)
+ {
+ size++;
+ data = msi_alloc(size*sizeof(WCHAR));
+ if (size > 1)
+ MSI_FormatRecordW(package,rec,data,&size);
+ else
+ data[0] = 0;
+ msiobj_release( &rec->hdr );
+ return data;
+ }
+
+ msiobj_release( &rec->hdr );
+ data = NULL;
+ return data;
+}