mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:23:01 +00:00
[MSI]
sync msi to wine 1.1.39 svn path=/trunk/; revision=45738
This commit is contained in:
parent
764beadd15
commit
b7a1c59029
19 changed files with 836 additions and 279 deletions
|
@ -886,10 +886,24 @@ static BOOL ACTION_HandleCustomAction( MSIPACKAGE* package, LPCWSTR action,
|
||||||
static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param)
|
static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param)
|
||||||
{
|
{
|
||||||
MSIPACKAGE *package = param;
|
MSIPACKAGE *package = param;
|
||||||
LPCWSTR dir;
|
LPCWSTR dir, component;
|
||||||
LPWSTR full_path;
|
LPWSTR full_path;
|
||||||
MSIRECORD *uirow;
|
MSIRECORD *uirow;
|
||||||
MSIFOLDER *folder;
|
MSIFOLDER *folder;
|
||||||
|
MSICOMPONENT *comp;
|
||||||
|
|
||||||
|
component = MSI_RecordGetString(row, 2);
|
||||||
|
comp = get_loaded_component(package, component);
|
||||||
|
if (!comp)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
|
||||||
|
{
|
||||||
|
TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
|
||||||
|
comp->Action = comp->Installed;
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
comp->Action = INSTALLSTATE_LOCAL;
|
||||||
|
|
||||||
dir = MSI_RecordGetString(row,1);
|
dir = MSI_RecordGetString(row,1);
|
||||||
if (!dir)
|
if (!dir)
|
||||||
|
@ -951,7 +965,7 @@ UINT msi_create_component_directories( MSIPACKAGE *package )
|
||||||
/* create all the folders required by the components are going to install */
|
/* create all the folders required by the components are going to install */
|
||||||
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
|
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
|
||||||
{
|
{
|
||||||
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL))
|
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
|
||||||
continue;
|
continue;
|
||||||
msi_create_directory( package, comp->Directory );
|
msi_create_directory( package, comp->Directory );
|
||||||
}
|
}
|
||||||
|
@ -983,10 +997,24 @@ static UINT ACTION_CreateFolders(MSIPACKAGE *package)
|
||||||
static UINT ITERATE_RemoveFolders( MSIRECORD *row, LPVOID param )
|
static UINT ITERATE_RemoveFolders( MSIRECORD *row, LPVOID param )
|
||||||
{
|
{
|
||||||
MSIPACKAGE *package = param;
|
MSIPACKAGE *package = param;
|
||||||
LPCWSTR dir;
|
LPCWSTR dir, component;
|
||||||
LPWSTR full_path;
|
LPWSTR full_path;
|
||||||
MSIRECORD *uirow;
|
MSIRECORD *uirow;
|
||||||
MSIFOLDER *folder;
|
MSIFOLDER *folder;
|
||||||
|
MSICOMPONENT *comp;
|
||||||
|
|
||||||
|
component = MSI_RecordGetString(row, 2);
|
||||||
|
comp = get_loaded_component(package, component);
|
||||||
|
if (!comp)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
|
||||||
|
{
|
||||||
|
TRACE("Component not scheduled for removal: %s\n", debugstr_w(component));
|
||||||
|
comp->Action = comp->Installed;
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
comp->Action = INSTALLSTATE_ABSENT;
|
||||||
|
|
||||||
dir = MSI_RecordGetString( row, 1 );
|
dir = MSI_RecordGetString( row, 1 );
|
||||||
if (!dir)
|
if (!dir)
|
||||||
|
@ -2231,16 +2259,12 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
|
||||||
if (!comp)
|
if (!comp)
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL))
|
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
|
||||||
{
|
{
|
||||||
TRACE("Skipping write due to disabled component %s\n",
|
TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
|
||||||
debugstr_w(component));
|
|
||||||
|
|
||||||
comp->Action = comp->Installed;
|
comp->Action = comp->Installed;
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
comp->Action = INSTALLSTATE_LOCAL;
|
comp->Action = INSTALLSTATE_LOCAL;
|
||||||
|
|
||||||
name = MSI_RecordGetString(row, 4);
|
name = MSI_RecordGetString(row, 4);
|
||||||
|
@ -2623,7 +2647,7 @@ static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp )
|
||||||
{
|
{
|
||||||
ComponentList *cl;
|
ComponentList *cl;
|
||||||
|
|
||||||
if (!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_LOCAL ))
|
if (feature->ActionRequest != INSTALLSTATE_LOCAL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
|
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
|
||||||
|
@ -2638,7 +2662,7 @@ static void ACTION_RefCountComponent( MSIPACKAGE* package, MSICOMPONENT *comp )
|
||||||
{
|
{
|
||||||
ComponentList *cl;
|
ComponentList *cl;
|
||||||
|
|
||||||
if (!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ABSENT ))
|
if (feature->ActionRequest != INSTALLSTATE_ABSENT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
|
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
|
||||||
|
@ -2704,8 +2728,8 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
|
||||||
debugstr_w(comp->FullKeypath),
|
debugstr_w(comp->FullKeypath),
|
||||||
comp->RefCount);
|
comp->RefCount);
|
||||||
|
|
||||||
if (ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL) ||
|
if (comp->ActionRequest == INSTALLSTATE_LOCAL ||
|
||||||
ACTION_VerifyComponentForAction( comp, INSTALLSTATE_SOURCE))
|
comp->ActionRequest == INSTALLSTATE_SOURCE)
|
||||||
{
|
{
|
||||||
if (!comp->FullKeypath)
|
if (!comp->FullKeypath)
|
||||||
continue;
|
continue;
|
||||||
|
@ -2771,7 +2795,7 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
|
||||||
}
|
}
|
||||||
RegCloseKey(hkey);
|
RegCloseKey(hkey);
|
||||||
}
|
}
|
||||||
else if (ACTION_VerifyComponentForAction(comp, INSTALLSTATE_ABSENT))
|
else if (comp->ActionRequest == INSTALLSTATE_ABSENT)
|
||||||
{
|
{
|
||||||
if (package->Context == MSIINSTALLCONTEXT_MACHINE)
|
if (package->Context == MSIINSTALLCONTEXT_MACHINE)
|
||||||
MSIREG_DeleteUserDataComponentKey(comp->ComponentId, szLocalSid);
|
MSIREG_DeleteUserDataComponentKey(comp->ComponentId, szLocalSid);
|
||||||
|
@ -2862,28 +2886,25 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
|
||||||
HMODULE module;
|
HMODULE module;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
static const WCHAR szTYPELIB[] = {'T','Y','P','E','L','I','B',0};
|
|
||||||
|
|
||||||
component = MSI_RecordGetString(row,3);
|
component = MSI_RecordGetString(row,3);
|
||||||
comp = get_loaded_component(package,component);
|
comp = get_loaded_component(package,component);
|
||||||
if (!comp)
|
if (!comp)
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL))
|
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
|
||||||
{
|
{
|
||||||
TRACE("Skipping typelib reg due to disabled component\n");
|
TRACE("Component not scheduled for installation: %s\n", debugstr_w(component));
|
||||||
|
|
||||||
comp->Action = comp->Installed;
|
comp->Action = comp->Installed;
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
comp->Action = INSTALLSTATE_LOCAL;
|
comp->Action = INSTALLSTATE_LOCAL;
|
||||||
|
|
||||||
file = get_loaded_file( package, comp->KeyPath );
|
file = get_loaded_file( package, comp->KeyPath );
|
||||||
if (!file)
|
if (!file)
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
ui_actiondata( package, szRegisterTypeLibraries, row );
|
||||||
|
|
||||||
module = LoadLibraryExW( file->TargetPath, NULL, LOAD_LIBRARY_AS_DATAFILE );
|
module = LoadLibraryExW( file->TargetPath, NULL, LOAD_LIBRARY_AS_DATAFILE );
|
||||||
if (module)
|
if (module)
|
||||||
{
|
{
|
||||||
|
@ -2913,11 +2934,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
|
||||||
ERR("Failed to register type library %s\n",
|
ERR("Failed to register type library %s\n",
|
||||||
debugstr_w(tl_struct.path));
|
debugstr_w(tl_struct.path));
|
||||||
else
|
else
|
||||||
{
|
|
||||||
ui_actiondata(package,szRegisterTypeLibraries,row);
|
|
||||||
|
|
||||||
TRACE("Registered %s\n", debugstr_w(tl_struct.path));
|
TRACE("Registered %s\n", debugstr_w(tl_struct.path));
|
||||||
}
|
|
||||||
|
|
||||||
ITypeLib_Release(tl_struct.ptLib);
|
ITypeLib_Release(tl_struct.ptLib);
|
||||||
msi_free(tl_struct.path);
|
msi_free(tl_struct.path);
|
||||||
|
@ -2935,7 +2952,7 @@ static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
ERR("Failed to load type library: %08x\n", hr);
|
ERR("Failed to load type library: %08x\n", hr);
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_INSTALL_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ITypeLib_Release(tlib);
|
ITypeLib_Release(tlib);
|
||||||
|
@ -2967,31 +2984,119 @@ static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT ITERATE_UnregisterTypeLibraries( MSIRECORD *row, LPVOID param )
|
||||||
|
{
|
||||||
|
MSIPACKAGE *package = param;
|
||||||
|
LPCWSTR component, guid;
|
||||||
|
MSICOMPONENT *comp;
|
||||||
|
GUID libid;
|
||||||
|
UINT version;
|
||||||
|
LCID language;
|
||||||
|
SYSKIND syskind;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
component = MSI_RecordGetString( row, 3 );
|
||||||
|
comp = get_loaded_component( package, component );
|
||||||
|
if (!comp)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
|
||||||
|
{
|
||||||
|
TRACE("Component not scheduled for removal %s\n", debugstr_w(component));
|
||||||
|
comp->Action = comp->Installed;
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
comp->Action = INSTALLSTATE_ABSENT;
|
||||||
|
|
||||||
|
ui_actiondata( package, szUnregisterTypeLibraries, row );
|
||||||
|
|
||||||
|
guid = MSI_RecordGetString( row, 1 );
|
||||||
|
CLSIDFromString( (LPWSTR)guid, &libid );
|
||||||
|
version = MSI_RecordGetInteger( row, 4 );
|
||||||
|
language = MSI_RecordGetInteger( row, 2 );
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
syskind = SYS_WIN64;
|
||||||
|
#else
|
||||||
|
syskind = SYS_WIN32;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hr = UnRegisterTypeLib( &libid, (version >> 8) & 0xffff, version & 0xff, language, syskind );
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
WARN("Failed to unregister typelib: %08x\n", hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT ACTION_UnregisterTypeLibraries( MSIPACKAGE *package )
|
||||||
|
{
|
||||||
|
UINT rc;
|
||||||
|
MSIQUERY *view;
|
||||||
|
static const WCHAR query[] =
|
||||||
|
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||||
|
'`','T','y','p','e','L','i','b','`',0};
|
||||||
|
|
||||||
|
rc = MSI_DatabaseOpenViewW( package->db, query, &view );
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
rc = MSI_IterateRecords( view, NULL, ITERATE_UnregisterTypeLibraries, package );
|
||||||
|
msiobj_release( &view->hdr );
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WCHAR *get_link_file( MSIPACKAGE *package, MSIRECORD *row )
|
||||||
|
{
|
||||||
|
static const WCHAR szlnk[] = {'.','l','n','k',0};
|
||||||
|
LPCWSTR directory, extension;
|
||||||
|
LPWSTR link_folder, link_file, filename;
|
||||||
|
|
||||||
|
directory = MSI_RecordGetString( row, 2 );
|
||||||
|
link_folder = resolve_folder( package, directory, FALSE, FALSE, TRUE, NULL );
|
||||||
|
|
||||||
|
/* may be needed because of a bug somewhere else */
|
||||||
|
create_full_pathW( link_folder );
|
||||||
|
|
||||||
|
filename = msi_dup_record_field( row, 3 );
|
||||||
|
reduce_to_longfilename( filename );
|
||||||
|
|
||||||
|
extension = strchrW( filename, '.' );
|
||||||
|
if (!extension || strcmpiW( extension, szlnk ))
|
||||||
|
{
|
||||||
|
int len = strlenW( filename );
|
||||||
|
filename = msi_realloc( filename, len * sizeof(WCHAR) + sizeof(szlnk) );
|
||||||
|
memcpy( filename + len, szlnk, sizeof(szlnk) );
|
||||||
|
}
|
||||||
|
link_file = build_directory_name( 2, link_folder, filename );
|
||||||
|
msi_free( link_folder );
|
||||||
|
msi_free( filename );
|
||||||
|
|
||||||
|
return link_file;
|
||||||
|
}
|
||||||
|
|
||||||
static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
|
static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
|
||||||
{
|
{
|
||||||
MSIPACKAGE *package = param;
|
MSIPACKAGE *package = param;
|
||||||
LPWSTR target_file, target_folder, filename;
|
LPWSTR link_file, deformated, path;
|
||||||
LPCWSTR buffer, extension;
|
LPCWSTR component, target;
|
||||||
MSICOMPONENT *comp;
|
MSICOMPONENT *comp;
|
||||||
static const WCHAR szlnk[]={'.','l','n','k',0};
|
|
||||||
IShellLinkW *sl = NULL;
|
IShellLinkW *sl = NULL;
|
||||||
IPersistFile *pf = NULL;
|
IPersistFile *pf = NULL;
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
|
|
||||||
buffer = MSI_RecordGetString(row,4);
|
component = MSI_RecordGetString(row, 4);
|
||||||
comp = get_loaded_component(package,buffer);
|
comp = get_loaded_component(package, component);
|
||||||
if (!comp)
|
if (!comp)
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL ))
|
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
|
||||||
{
|
{
|
||||||
TRACE("Skipping shortcut creation due to disabled component\n");
|
TRACE("Component not scheduled for installation %s\n", debugstr_w(component));
|
||||||
|
|
||||||
comp->Action = comp->Installed;
|
comp->Action = comp->Installed;
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
comp->Action = INSTALLSTATE_LOCAL;
|
comp->Action = INSTALLSTATE_LOCAL;
|
||||||
|
|
||||||
ui_actiondata(package,szCreateShortcuts,row);
|
ui_actiondata(package,szCreateShortcuts,row);
|
||||||
|
@ -3012,31 +3117,10 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = MSI_RecordGetString(row,2);
|
target = MSI_RecordGetString(row, 5);
|
||||||
target_folder = resolve_folder(package, buffer,FALSE,FALSE,TRUE,NULL);
|
if (strchrW(target, '['))
|
||||||
|
|
||||||
/* may be needed because of a bug somewhere else */
|
|
||||||
create_full_pathW(target_folder);
|
|
||||||
|
|
||||||
filename = msi_dup_record_field( row, 3 );
|
|
||||||
reduce_to_longfilename(filename);
|
|
||||||
|
|
||||||
extension = strchrW(filename,'.');
|
|
||||||
if (!extension || strcmpiW(extension,szlnk))
|
|
||||||
{
|
{
|
||||||
int len = strlenW(filename);
|
deformat_string(package, target, &deformated);
|
||||||
filename = msi_realloc(filename, len * sizeof(WCHAR) + sizeof(szlnk));
|
|
||||||
memcpy(filename + len, szlnk, sizeof(szlnk));
|
|
||||||
}
|
|
||||||
target_file = build_directory_name(2, target_folder, filename);
|
|
||||||
msi_free(target_folder);
|
|
||||||
msi_free(filename);
|
|
||||||
|
|
||||||
buffer = MSI_RecordGetString(row,5);
|
|
||||||
if (strchrW(buffer,'['))
|
|
||||||
{
|
|
||||||
LPWSTR deformated;
|
|
||||||
deformat_string(package,buffer,&deformated);
|
|
||||||
IShellLinkW_SetPath(sl,deformated);
|
IShellLinkW_SetPath(sl,deformated);
|
||||||
msi_free(deformated);
|
msi_free(deformated);
|
||||||
}
|
}
|
||||||
|
@ -3048,17 +3132,16 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
|
||||||
|
|
||||||
if (!MSI_RecordIsNull(row,6))
|
if (!MSI_RecordIsNull(row,6))
|
||||||
{
|
{
|
||||||
LPWSTR deformated;
|
LPCWSTR arguments = MSI_RecordGetString(row, 6);
|
||||||
buffer = MSI_RecordGetString(row,6);
|
deformat_string(package, arguments, &deformated);
|
||||||
deformat_string(package,buffer,&deformated);
|
|
||||||
IShellLinkW_SetArguments(sl,deformated);
|
IShellLinkW_SetArguments(sl,deformated);
|
||||||
msi_free(deformated);
|
msi_free(deformated);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MSI_RecordIsNull(row,7))
|
if (!MSI_RecordIsNull(row,7))
|
||||||
{
|
{
|
||||||
buffer = MSI_RecordGetString(row,7);
|
LPCWSTR description = MSI_RecordGetString(row, 7);
|
||||||
IShellLinkW_SetDescription(sl,buffer);
|
IShellLinkW_SetDescription(sl, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MSI_RecordIsNull(row,8))
|
if (!MSI_RecordIsNull(row,8))
|
||||||
|
@ -3066,20 +3149,18 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
|
||||||
|
|
||||||
if (!MSI_RecordIsNull(row,9))
|
if (!MSI_RecordIsNull(row,9))
|
||||||
{
|
{
|
||||||
LPWSTR Path;
|
|
||||||
INT index;
|
INT index;
|
||||||
|
LPCWSTR icon = MSI_RecordGetString(row, 9);
|
||||||
|
|
||||||
buffer = MSI_RecordGetString(row,9);
|
path = build_icon_path(package, icon);
|
||||||
|
|
||||||
Path = build_icon_path(package,buffer);
|
|
||||||
index = MSI_RecordGetInteger(row,10);
|
index = MSI_RecordGetInteger(row,10);
|
||||||
|
|
||||||
/* no value means 0 */
|
/* no value means 0 */
|
||||||
if (index == MSI_NULL_INTEGER)
|
if (index == MSI_NULL_INTEGER)
|
||||||
index = 0;
|
index = 0;
|
||||||
|
|
||||||
IShellLinkW_SetIconLocation(sl,Path,index);
|
IShellLinkW_SetIconLocation(sl, path, index);
|
||||||
msi_free(Path);
|
msi_free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MSI_RecordIsNull(row,11))
|
if (!MSI_RecordIsNull(row,11))
|
||||||
|
@ -3087,18 +3168,19 @@ static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
|
||||||
|
|
||||||
if (!MSI_RecordIsNull(row,12))
|
if (!MSI_RecordIsNull(row,12))
|
||||||
{
|
{
|
||||||
LPWSTR Path;
|
LPCWSTR wkdir = MSI_RecordGetString(row, 12);
|
||||||
buffer = MSI_RecordGetString(row,12);
|
path = resolve_folder(package, wkdir, FALSE, FALSE, TRUE, NULL);
|
||||||
Path = resolve_folder(package, buffer, FALSE, FALSE, TRUE, NULL);
|
if (path)
|
||||||
if (Path)
|
IShellLinkW_SetWorkingDirectory(sl, path);
|
||||||
IShellLinkW_SetWorkingDirectory(sl,Path);
|
msi_free(path);
|
||||||
msi_free(Path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("Writing shortcut to %s\n",debugstr_w(target_file));
|
link_file = get_link_file(package, row);
|
||||||
IPersistFile_Save(pf,target_file,FALSE);
|
|
||||||
|
|
||||||
msi_free(target_file);
|
TRACE("Writing shortcut to %s\n", debugstr_w(link_file));
|
||||||
|
IPersistFile_Save(pf, link_file, FALSE);
|
||||||
|
|
||||||
|
msi_free(link_file);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (pf)
|
if (pf)
|
||||||
|
@ -3133,6 +3215,58 @@ static UINT ACTION_CreateShortcuts(MSIPACKAGE *package)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT ITERATE_RemoveShortcuts( MSIRECORD *row, LPVOID param )
|
||||||
|
{
|
||||||
|
MSIPACKAGE *package = param;
|
||||||
|
LPWSTR link_file;
|
||||||
|
LPCWSTR component;
|
||||||
|
MSICOMPONENT *comp;
|
||||||
|
|
||||||
|
component = MSI_RecordGetString( row, 4 );
|
||||||
|
comp = get_loaded_component( package, component );
|
||||||
|
if (!comp)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (comp->ActionRequest != INSTALLSTATE_ABSENT)
|
||||||
|
{
|
||||||
|
TRACE("Component not scheduled for removal %s\n", debugstr_w(component));
|
||||||
|
comp->Action = comp->Installed;
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
comp->Action = INSTALLSTATE_ABSENT;
|
||||||
|
|
||||||
|
ui_actiondata( package, szRemoveShortcuts, row );
|
||||||
|
|
||||||
|
link_file = get_link_file( package, row );
|
||||||
|
|
||||||
|
TRACE("Removing shortcut file %s\n", debugstr_w( link_file ));
|
||||||
|
if (!DeleteFileW( link_file ))
|
||||||
|
{
|
||||||
|
WARN("Failed to remove shortcut file %u\n", GetLastError());
|
||||||
|
}
|
||||||
|
msi_free( link_file );
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT ACTION_RemoveShortcuts( MSIPACKAGE *package )
|
||||||
|
{
|
||||||
|
UINT rc;
|
||||||
|
MSIQUERY *view;
|
||||||
|
static const WCHAR query[] =
|
||||||
|
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||||
|
'`','S','h','o','r','t','c','u','t','`',0};
|
||||||
|
|
||||||
|
rc = MSI_DatabaseOpenViewW( package->db, query, &view );
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveShortcuts, package );
|
||||||
|
msiobj_release( &view->hdr );
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static UINT ITERATE_PublishIcon(MSIRECORD *row, LPVOID param)
|
static UINT ITERATE_PublishIcon(MSIRECORD *row, LPVOID param)
|
||||||
{
|
{
|
||||||
MSIPACKAGE* package = param;
|
MSIPACKAGE* package = param;
|
||||||
|
@ -3510,17 +3644,15 @@ static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
|
||||||
|
|
||||||
component = MSI_RecordGetString(row, 8);
|
component = MSI_RecordGetString(row, 8);
|
||||||
comp = get_loaded_component(package,component);
|
comp = get_loaded_component(package,component);
|
||||||
|
if (!comp)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL))
|
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
|
||||||
{
|
{
|
||||||
TRACE("Skipping ini file due to disabled component %s\n",
|
TRACE("Component not scheduled for installation %s\n", debugstr_w(component));
|
||||||
debugstr_w(component));
|
|
||||||
|
|
||||||
comp->Action = comp->Installed;
|
comp->Action = comp->Installed;
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
comp->Action = INSTALLSTATE_LOCAL;
|
comp->Action = INSTALLSTATE_LOCAL;
|
||||||
|
|
||||||
identifier = MSI_RecordGetString(row,1);
|
identifier = MSI_RecordGetString(row,1);
|
||||||
|
@ -3818,10 +3950,9 @@ static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
|
||||||
BOOL absent = FALSE;
|
BOOL absent = FALSE;
|
||||||
MSIRECORD *uirow;
|
MSIRECORD *uirow;
|
||||||
|
|
||||||
if (!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_LOCAL ) &&
|
if (feature->ActionRequest != INSTALLSTATE_LOCAL &&
|
||||||
!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_SOURCE ) &&
|
feature->ActionRequest != INSTALLSTATE_SOURCE &&
|
||||||
!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ADVERTISED ))
|
feature->ActionRequest != INSTALLSTATE_ADVERTISED) absent = TRUE;
|
||||||
absent = TRUE;
|
|
||||||
|
|
||||||
size = 1;
|
size = 1;
|
||||||
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
|
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
|
||||||
|
@ -4359,32 +4490,34 @@ static UINT ACTION_ExecuteAction(MSIPACKAGE *package)
|
||||||
static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param)
|
static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param)
|
||||||
{
|
{
|
||||||
MSIPACKAGE *package = param;
|
MSIPACKAGE *package = param;
|
||||||
LPCWSTR compgroupid=NULL;
|
LPCWSTR compgroupid, component, feature, qualifier, text;
|
||||||
LPCWSTR feature=NULL;
|
LPWSTR advertise = NULL, output = NULL;
|
||||||
LPCWSTR text = NULL;
|
|
||||||
LPCWSTR qualifier = NULL;
|
|
||||||
LPCWSTR component = NULL;
|
|
||||||
LPWSTR advertise = NULL;
|
|
||||||
LPWSTR output = NULL;
|
|
||||||
HKEY hkey;
|
HKEY hkey;
|
||||||
UINT rc = ERROR_SUCCESS;
|
UINT rc;
|
||||||
MSICOMPONENT *comp;
|
MSICOMPONENT *comp;
|
||||||
DWORD sz = 0;
|
MSIFEATURE *feat;
|
||||||
|
DWORD sz;
|
||||||
MSIRECORD *uirow;
|
MSIRECORD *uirow;
|
||||||
|
|
||||||
component = MSI_RecordGetString(rec,3);
|
feature = MSI_RecordGetString(rec, 5);
|
||||||
comp = get_loaded_component(package,component);
|
feat = get_loaded_feature(package, feature);
|
||||||
|
if (!feat)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL ) &&
|
if (feat->ActionRequest != INSTALLSTATE_LOCAL &&
|
||||||
!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_SOURCE ) &&
|
feat->ActionRequest != INSTALLSTATE_SOURCE &&
|
||||||
!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_ADVERTISED ))
|
feat->ActionRequest != INSTALLSTATE_ADVERTISED)
|
||||||
{
|
{
|
||||||
TRACE("Skipping: Component %s not scheduled for install\n",
|
TRACE("Feature %s not scheduled for installation\n", debugstr_w(feature));
|
||||||
debugstr_w(component));
|
feat->Action = feat->Installed;
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
component = MSI_RecordGetString(rec, 3);
|
||||||
|
comp = get_loaded_component(package, component);
|
||||||
|
if (!comp)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
compgroupid = MSI_RecordGetString(rec,1);
|
compgroupid = MSI_RecordGetString(rec,1);
|
||||||
qualifier = MSI_RecordGetString(rec,2);
|
qualifier = MSI_RecordGetString(rec,2);
|
||||||
|
|
||||||
|
@ -4393,8 +4526,6 @@ static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
text = MSI_RecordGetString(rec,4);
|
text = MSI_RecordGetString(rec,4);
|
||||||
feature = MSI_RecordGetString(rec,5);
|
|
||||||
|
|
||||||
advertise = create_component_advertise_string(package, comp, feature);
|
advertise = create_component_advertise_string(package, comp, feature);
|
||||||
|
|
||||||
sz = strlenW(advertise);
|
sz = strlenW(advertise);
|
||||||
|
@ -4452,6 +4583,80 @@ static UINT ACTION_PublishComponents(MSIPACKAGE *package)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT ITERATE_UnpublishComponent( MSIRECORD *rec, LPVOID param )
|
||||||
|
{
|
||||||
|
static const WCHAR szInstallerComponents[] = {
|
||||||
|
'S','o','f','t','w','a','r','e','\\',
|
||||||
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'I','n','s','t','a','l','l','e','r','\\',
|
||||||
|
'C','o','m','p','o','n','e','n','t','s','\\',0};
|
||||||
|
|
||||||
|
MSIPACKAGE *package = param;
|
||||||
|
LPCWSTR compgroupid, component, feature, qualifier;
|
||||||
|
MSICOMPONENT *comp;
|
||||||
|
MSIFEATURE *feat;
|
||||||
|
MSIRECORD *uirow;
|
||||||
|
WCHAR squashed[GUID_SIZE], keypath[MAX_PATH];
|
||||||
|
LONG res;
|
||||||
|
|
||||||
|
feature = MSI_RecordGetString( rec, 5 );
|
||||||
|
feat = get_loaded_feature( package, feature );
|
||||||
|
if (!feat)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (feat->ActionRequest != INSTALLSTATE_ABSENT)
|
||||||
|
{
|
||||||
|
TRACE("Feature %s not scheduled for removal\n", debugstr_w(feature));
|
||||||
|
feat->Action = feat->Installed;
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
component = MSI_RecordGetString( rec, 3 );
|
||||||
|
comp = get_loaded_component( package, component );
|
||||||
|
if (!comp)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
compgroupid = MSI_RecordGetString( rec, 1 );
|
||||||
|
qualifier = MSI_RecordGetString( rec, 2 );
|
||||||
|
|
||||||
|
squash_guid( compgroupid, squashed );
|
||||||
|
strcpyW( keypath, szInstallerComponents );
|
||||||
|
strcatW( keypath, squashed );
|
||||||
|
|
||||||
|
res = RegDeleteKeyW( HKEY_CURRENT_USER, keypath );
|
||||||
|
if (res != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
WARN("Unable to delete component key %d\n", res);
|
||||||
|
}
|
||||||
|
|
||||||
|
uirow = MSI_CreateRecord( 2 );
|
||||||
|
MSI_RecordSetStringW( uirow, 1, compgroupid );
|
||||||
|
MSI_RecordSetStringW( uirow, 2, qualifier );
|
||||||
|
ui_actiondata( package, szUnpublishComponents, uirow );
|
||||||
|
msiobj_release( &uirow->hdr );
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT ACTION_UnpublishComponents( MSIPACKAGE *package )
|
||||||
|
{
|
||||||
|
UINT rc;
|
||||||
|
MSIQUERY *view;
|
||||||
|
static const WCHAR query[] =
|
||||||
|
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||||
|
'`','P','u','b','l','i','s','h',
|
||||||
|
'C','o','m','p','o','n','e','n','t','`',0};
|
||||||
|
|
||||||
|
rc = MSI_DatabaseOpenViewW( package->db, query, &view );
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
rc = MSI_IterateRecords( view, NULL, ITERATE_UnpublishComponent, package );
|
||||||
|
msiobj_release( &view->hdr );
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param)
|
static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param)
|
||||||
{
|
{
|
||||||
MSIPACKAGE *package = param;
|
MSIPACKAGE *package = param;
|
||||||
|
@ -4597,7 +4802,7 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param)
|
||||||
{
|
{
|
||||||
MSIPACKAGE *package = param;
|
MSIPACKAGE *package = param;
|
||||||
MSICOMPONENT *comp;
|
MSICOMPONENT *comp;
|
||||||
SC_HANDLE scm, service = NULL;
|
SC_HANDLE scm = NULL, service = NULL;
|
||||||
LPCWSTR *vector = NULL;
|
LPCWSTR *vector = NULL;
|
||||||
LPWSTR name, args;
|
LPWSTR name, args;
|
||||||
DWORD event, numargs;
|
DWORD event, numargs;
|
||||||
|
@ -4612,7 +4817,10 @@ static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param)
|
||||||
event = MSI_RecordGetInteger(rec, 3);
|
event = MSI_RecordGetInteger(rec, 3);
|
||||||
|
|
||||||
if (!(event & msidbServiceControlEventStart))
|
if (!(event & msidbServiceControlEventStart))
|
||||||
return ERROR_SUCCESS;
|
{
|
||||||
|
r = ERROR_SUCCESS;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
|
scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
|
||||||
if (!scm)
|
if (!scm)
|
||||||
|
@ -4893,15 +5101,17 @@ static UINT ITERATE_InstallODBCDriver( MSIRECORD *rec, LPVOID param )
|
||||||
driver_file = msi_find_file(package, MSI_RecordGetString(rec, 4));
|
driver_file = msi_find_file(package, MSI_RecordGetString(rec, 4));
|
||||||
setup_file = msi_find_file(package, MSI_RecordGetString(rec, 5));
|
setup_file = msi_find_file(package, MSI_RecordGetString(rec, 5));
|
||||||
|
|
||||||
if (!driver_file || !setup_file)
|
if (!driver_file)
|
||||||
{
|
{
|
||||||
ERR("ODBC Driver entry not found!\n");
|
ERR("ODBC Driver entry not found!\n");
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = lstrlenW(desc) + lstrlenW(driver_fmt) + lstrlenW(driver_file->FileName) +
|
len = lstrlenW(desc) + lstrlenW(driver_fmt) + lstrlenW(driver_file->FileName);
|
||||||
lstrlenW(setup_fmt) + lstrlenW(setup_file->FileName) +
|
if (setup_file)
|
||||||
lstrlenW(usage_fmt) + 1;
|
len += lstrlenW(setup_fmt) + lstrlenW(setup_file->FileName);
|
||||||
|
len += lstrlenW(usage_fmt) + 1;
|
||||||
|
|
||||||
driver = msi_alloc(len * sizeof(WCHAR));
|
driver = msi_alloc(len * sizeof(WCHAR));
|
||||||
if (!driver)
|
if (!driver)
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
|
@ -4913,8 +5123,11 @@ static UINT ITERATE_InstallODBCDriver( MSIRECORD *rec, LPVOID param )
|
||||||
sprintfW(ptr, driver_fmt, driver_file->FileName);
|
sprintfW(ptr, driver_fmt, driver_file->FileName);
|
||||||
ptr += lstrlenW(ptr) + 1;
|
ptr += lstrlenW(ptr) + 1;
|
||||||
|
|
||||||
|
if (setup_file)
|
||||||
|
{
|
||||||
sprintfW(ptr, setup_fmt, setup_file->FileName);
|
sprintfW(ptr, setup_fmt, setup_file->FileName);
|
||||||
ptr += lstrlenW(ptr) + 1;
|
ptr += lstrlenW(ptr) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
lstrcpyW(ptr, usage_fmt);
|
lstrcpyW(ptr, usage_fmt);
|
||||||
ptr += lstrlenW(ptr) + 1;
|
ptr += lstrlenW(ptr) + 1;
|
||||||
|
@ -4957,14 +5170,16 @@ static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param )
|
||||||
translator_file = msi_find_file(package, MSI_RecordGetString(rec, 4));
|
translator_file = msi_find_file(package, MSI_RecordGetString(rec, 4));
|
||||||
setup_file = msi_find_file(package, MSI_RecordGetString(rec, 5));
|
setup_file = msi_find_file(package, MSI_RecordGetString(rec, 5));
|
||||||
|
|
||||||
if (!translator_file || !setup_file)
|
if (!translator_file)
|
||||||
{
|
{
|
||||||
ERR("ODBC Translator entry not found!\n");
|
ERR("ODBC Translator entry not found!\n");
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = lstrlenW(desc) + lstrlenW(translator_fmt) + lstrlenW(translator_file->FileName) +
|
len = lstrlenW(desc) + lstrlenW(translator_fmt) + lstrlenW(translator_file->FileName) + 1;
|
||||||
lstrlenW(setup_fmt) + lstrlenW(setup_file->FileName) + 1;
|
if (setup_file)
|
||||||
|
len += lstrlenW(setup_fmt) + lstrlenW(setup_file->FileName);
|
||||||
|
|
||||||
translator = msi_alloc(len * sizeof(WCHAR));
|
translator = msi_alloc(len * sizeof(WCHAR));
|
||||||
if (!translator)
|
if (!translator)
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
|
@ -4976,8 +5191,11 @@ static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param )
|
||||||
sprintfW(ptr, translator_fmt, translator_file->FileName);
|
sprintfW(ptr, translator_fmt, translator_file->FileName);
|
||||||
ptr += lstrlenW(ptr) + 1;
|
ptr += lstrlenW(ptr) + 1;
|
||||||
|
|
||||||
|
if (setup_file)
|
||||||
|
{
|
||||||
sprintfW(ptr, setup_fmt, setup_file->FileName);
|
sprintfW(ptr, setup_fmt, setup_file->FileName);
|
||||||
ptr += lstrlenW(ptr) + 1;
|
ptr += lstrlenW(ptr) + 1;
|
||||||
|
}
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
|
|
||||||
translator_path = strdupW(translator_file->TargetPath);
|
translator_path = strdupW(translator_file->TargetPath);
|
||||||
|
@ -5021,8 +5239,8 @@ static UINT ITERATE_InstallODBCDataSource( MSIRECORD *rec, LPVOID param )
|
||||||
if (!attrs)
|
if (!attrs)
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
|
|
||||||
sprintfW(attrs, attrs_fmt, desc);
|
len = sprintfW(attrs, attrs_fmt, desc);
|
||||||
attrs[len - 1] = '\0';
|
attrs[len + 1] = 0;
|
||||||
|
|
||||||
if (!SQLConfigDataSourceW(NULL, request, driver, attrs))
|
if (!SQLConfigDataSourceW(NULL, request, driver, attrs))
|
||||||
{
|
{
|
||||||
|
@ -5076,6 +5294,120 @@ static UINT ACTION_InstallODBC( MSIPACKAGE *package )
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT ITERATE_RemoveODBCDriver( MSIRECORD *rec, LPVOID param )
|
||||||
|
{
|
||||||
|
DWORD usage;
|
||||||
|
LPCWSTR desc;
|
||||||
|
|
||||||
|
desc = MSI_RecordGetString( rec, 3 );
|
||||||
|
if (!SQLRemoveDriverW( desc, FALSE, &usage ))
|
||||||
|
{
|
||||||
|
WARN("Failed to remove ODBC driver\n");
|
||||||
|
}
|
||||||
|
else if (!usage)
|
||||||
|
{
|
||||||
|
FIXME("Usage count reached 0\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT ITERATE_RemoveODBCTranslator( MSIRECORD *rec, LPVOID param )
|
||||||
|
{
|
||||||
|
DWORD usage;
|
||||||
|
LPCWSTR desc;
|
||||||
|
|
||||||
|
desc = MSI_RecordGetString( rec, 3 );
|
||||||
|
if (!SQLRemoveTranslatorW( desc, &usage ))
|
||||||
|
{
|
||||||
|
WARN("Failed to remove ODBC translator\n");
|
||||||
|
}
|
||||||
|
else if (!usage)
|
||||||
|
{
|
||||||
|
FIXME("Usage count reached 0\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT ITERATE_RemoveODBCDataSource( MSIRECORD *rec, LPVOID param )
|
||||||
|
{
|
||||||
|
LPWSTR attrs;
|
||||||
|
LPCWSTR desc, driver;
|
||||||
|
WORD request = ODBC_REMOVE_SYS_DSN;
|
||||||
|
INT registration;
|
||||||
|
DWORD len;
|
||||||
|
|
||||||
|
static const WCHAR attrs_fmt[] = {
|
||||||
|
'D','S','N','=','%','s',0 };
|
||||||
|
|
||||||
|
desc = MSI_RecordGetString( rec, 3 );
|
||||||
|
driver = MSI_RecordGetString( rec, 4 );
|
||||||
|
registration = MSI_RecordGetInteger( rec, 5 );
|
||||||
|
|
||||||
|
if (registration == msidbODBCDataSourceRegistrationPerMachine) request = ODBC_REMOVE_SYS_DSN;
|
||||||
|
else if (registration == msidbODBCDataSourceRegistrationPerUser) request = ODBC_REMOVE_DSN;
|
||||||
|
|
||||||
|
len = strlenW( attrs_fmt ) + strlenW( desc ) + 1 + 1;
|
||||||
|
attrs = msi_alloc( len * sizeof(WCHAR) );
|
||||||
|
if (!attrs)
|
||||||
|
return ERROR_OUTOFMEMORY;
|
||||||
|
|
||||||
|
FIXME("Use ODBCSourceAttribute table\n");
|
||||||
|
|
||||||
|
len = sprintfW( attrs, attrs_fmt, desc );
|
||||||
|
attrs[len + 1] = 0;
|
||||||
|
|
||||||
|
if (!SQLConfigDataSourceW( NULL, request, driver, attrs ))
|
||||||
|
{
|
||||||
|
WARN("Failed to remove ODBC data source\n");
|
||||||
|
}
|
||||||
|
msi_free( attrs );
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT ACTION_RemoveODBC( MSIPACKAGE *package )
|
||||||
|
{
|
||||||
|
UINT rc;
|
||||||
|
MSIQUERY *view;
|
||||||
|
|
||||||
|
static const WCHAR driver_query[] = {
|
||||||
|
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||||
|
'O','D','B','C','D','r','i','v','e','r',0 };
|
||||||
|
|
||||||
|
static const WCHAR translator_query[] = {
|
||||||
|
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||||
|
'O','D','B','C','T','r','a','n','s','l','a','t','o','r',0 };
|
||||||
|
|
||||||
|
static const WCHAR source_query[] = {
|
||||||
|
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||||
|
'O','D','B','C','D','a','t','a','S','o','u','r','c','e',0 };
|
||||||
|
|
||||||
|
rc = MSI_DatabaseOpenViewW( package->db, driver_query, &view );
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveODBCDriver, package );
|
||||||
|
msiobj_release( &view->hdr );
|
||||||
|
|
||||||
|
rc = MSI_DatabaseOpenViewW( package->db, translator_query, &view );
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveODBCTranslator, package );
|
||||||
|
msiobj_release( &view->hdr );
|
||||||
|
|
||||||
|
rc = MSI_DatabaseOpenViewW( package->db, source_query, &view );
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveODBCDataSource, package );
|
||||||
|
msiobj_release( &view->hdr );
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
#define ENV_ACT_SETALWAYS 0x1
|
#define ENV_ACT_SETALWAYS 0x1
|
||||||
#define ENV_ACT_SETABSENT 0x2
|
#define ENV_ACT_SETABSENT 0x2
|
||||||
#define ENV_ACT_REMOVE 0x4
|
#define ENV_ACT_REMOVE 0x4
|
||||||
|
@ -6125,6 +6457,30 @@ done:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT ACTION_ValidateProductID( MSIPACKAGE *package )
|
||||||
|
{
|
||||||
|
LPWSTR key, template, id;
|
||||||
|
UINT r = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
id = msi_dup_property( package, szProductID );
|
||||||
|
if (id)
|
||||||
|
{
|
||||||
|
msi_free( id );
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
template = msi_dup_property( package, szPIDTemplate );
|
||||||
|
key = msi_dup_property( package, szPIDKEY );
|
||||||
|
|
||||||
|
if (key && template)
|
||||||
|
{
|
||||||
|
FIXME( "partial stub: template %s key %s\n", debugstr_w(template), debugstr_w(key) );
|
||||||
|
r = MSI_SetPropertyW( package, szProductID, key );
|
||||||
|
}
|
||||||
|
msi_free( template );
|
||||||
|
msi_free( key );
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static UINT ACTION_ScheduleReboot( MSIPACKAGE *package )
|
static UINT ACTION_ScheduleReboot( MSIPACKAGE *package )
|
||||||
{
|
{
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
@ -6132,6 +6488,24 @@ static UINT ACTION_ScheduleReboot( MSIPACKAGE *package )
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT ACTION_AllocateRegistrySpace( MSIPACKAGE *package )
|
||||||
|
{
|
||||||
|
TRACE("%p\n", package);
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT ACTION_DisableRollback( MSIPACKAGE *package )
|
||||||
|
{
|
||||||
|
FIXME("%p\n", package);
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT ACTION_InstallAdminPackage( MSIPACKAGE *package )
|
||||||
|
{
|
||||||
|
FIXME("%p\n", package);
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static UINT msi_unimplemented_action_stub( MSIPACKAGE *package,
|
static UINT msi_unimplemented_action_stub( MSIPACKAGE *package,
|
||||||
LPCSTR action, LPCWSTR table )
|
LPCSTR action, LPCWSTR table )
|
||||||
{
|
{
|
||||||
|
@ -6156,12 +6530,6 @@ static UINT msi_unimplemented_action_stub( MSIPACKAGE *package,
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT ACTION_AllocateRegistrySpace( MSIPACKAGE *package )
|
|
||||||
{
|
|
||||||
TRACE("%p\n", package);
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static UINT ACTION_RemoveIniValues( MSIPACKAGE *package )
|
static UINT ACTION_RemoveIniValues( MSIPACKAGE *package )
|
||||||
{
|
{
|
||||||
static const WCHAR table[] =
|
static const WCHAR table[] =
|
||||||
|
@ -6194,13 +6562,6 @@ static UINT ACTION_MigrateFeatureStates( MSIPACKAGE *package )
|
||||||
return msi_unimplemented_action_stub( package, "MigrateFeatureStates", table );
|
return msi_unimplemented_action_stub( package, "MigrateFeatureStates", table );
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT ACTION_ValidateProductID( MSIPACKAGE *package )
|
|
||||||
{
|
|
||||||
static const WCHAR table[] = {
|
|
||||||
'P','r','o','d','u','c','t','I','D',0 };
|
|
||||||
return msi_unimplemented_action_stub( package, "ValidateProductID", table );
|
|
||||||
}
|
|
||||||
|
|
||||||
static UINT ACTION_RemoveEnvironmentStrings( MSIPACKAGE *package )
|
static UINT ACTION_RemoveEnvironmentStrings( MSIPACKAGE *package )
|
||||||
{
|
{
|
||||||
static const WCHAR table[] = {
|
static const WCHAR table[] = {
|
||||||
|
@ -6215,12 +6576,6 @@ static UINT ACTION_MsiUnpublishAssemblies( MSIPACKAGE *package )
|
||||||
return msi_unimplemented_action_stub( package, "MsiUnpublishAssemblies", table );
|
return msi_unimplemented_action_stub( package, "MsiUnpublishAssemblies", table );
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT ACTION_UnregisterFonts( MSIPACKAGE *package )
|
|
||||||
{
|
|
||||||
static const WCHAR table[] = { 'F','o','n','t',0 };
|
|
||||||
return msi_unimplemented_action_stub( package, "UnregisterFonts", table );
|
|
||||||
}
|
|
||||||
|
|
||||||
static UINT ACTION_RMCCPSearch( MSIPACKAGE *package )
|
static UINT ACTION_RMCCPSearch( MSIPACKAGE *package )
|
||||||
{
|
{
|
||||||
static const WCHAR table[] = { 'C','C','P','S','e','a','r','c','h',0 };
|
static const WCHAR table[] = { 'C','C','P','S','e','a','r','c','h',0 };
|
||||||
|
@ -6257,36 +6612,18 @@ static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package )
|
||||||
return msi_unimplemented_action_stub( package, "RemoveExistingProducts", table );
|
return msi_unimplemented_action_stub( package, "RemoveExistingProducts", table );
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT ACTION_RemoveODBC( MSIPACKAGE *package )
|
|
||||||
{
|
|
||||||
static const WCHAR table[] = { 'O','D','B','C','D','r','i','v','e','r',0 };
|
|
||||||
return msi_unimplemented_action_stub( package, "RemoveODBC", table );
|
|
||||||
}
|
|
||||||
|
|
||||||
static UINT ACTION_RemoveRegistryValues( MSIPACKAGE *package )
|
static UINT ACTION_RemoveRegistryValues( MSIPACKAGE *package )
|
||||||
{
|
{
|
||||||
static const WCHAR table[] = { 'R','e','m','o','v','e','R','e','g','i','s','t','r','y',0 };
|
static const WCHAR table[] = { 'R','e','m','o','v','e','R','e','g','i','s','t','r','y',0 };
|
||||||
return msi_unimplemented_action_stub( package, "RemoveRegistryValues", table );
|
return msi_unimplemented_action_stub( package, "RemoveRegistryValues", table );
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT ACTION_RemoveShortcuts( MSIPACKAGE *package )
|
|
||||||
{
|
|
||||||
static const WCHAR table[] = { 'S','h','o','r','t','c','u','t',0 };
|
|
||||||
return msi_unimplemented_action_stub( package, "RemoveShortcuts", table );
|
|
||||||
}
|
|
||||||
|
|
||||||
static UINT ACTION_SetODBCFolders( MSIPACKAGE *package )
|
static UINT ACTION_SetODBCFolders( MSIPACKAGE *package )
|
||||||
{
|
{
|
||||||
static const WCHAR table[] = { 'D','i','r','e','c','t','o','r','y',0 };
|
static const WCHAR table[] = { 'D','i','r','e','c','t','o','r','y',0 };
|
||||||
return msi_unimplemented_action_stub( package, "SetODBCFolders", table );
|
return msi_unimplemented_action_stub( package, "SetODBCFolders", table );
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT ACTION_UnpublishComponents( MSIPACKAGE *package )
|
|
||||||
{
|
|
||||||
static const WCHAR table[] = { 'P','u','b','l','i','s','h','C','o','m','p','o','n','e','n','t',0 };
|
|
||||||
return msi_unimplemented_action_stub( package, "UnpublishComponents", table );
|
|
||||||
}
|
|
||||||
|
|
||||||
static UINT ACTION_UnregisterClassInfo( MSIPACKAGE *package )
|
static UINT ACTION_UnregisterClassInfo( MSIPACKAGE *package )
|
||||||
{
|
{
|
||||||
static const WCHAR table[] = { 'A','p','p','I','d',0 };
|
static const WCHAR table[] = { 'A','p','p','I','d',0 };
|
||||||
|
@ -6311,12 +6648,6 @@ static UINT ACTION_UnregisterProgIdInfo( MSIPACKAGE *package )
|
||||||
return msi_unimplemented_action_stub( package, "UnregisterProgIdInfo", table );
|
return msi_unimplemented_action_stub( package, "UnregisterProgIdInfo", table );
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT ACTION_UnregisterTypeLibraries( MSIPACKAGE *package )
|
|
||||||
{
|
|
||||||
static const WCHAR table[] = { 'T','y','p','e','L','i','b',0 };
|
|
||||||
return msi_unimplemented_action_stub( package, "UnregisterTypeLibraries", table );
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*);
|
typedef UINT (*STANDARDACTIONHANDLER)(MSIPACKAGE*);
|
||||||
|
|
||||||
static const struct
|
static const struct
|
||||||
|
@ -6335,13 +6666,13 @@ StandardActions[] =
|
||||||
{ szCreateFolders, ACTION_CreateFolders },
|
{ szCreateFolders, ACTION_CreateFolders },
|
||||||
{ szCreateShortcuts, ACTION_CreateShortcuts },
|
{ szCreateShortcuts, ACTION_CreateShortcuts },
|
||||||
{ szDeleteServices, ACTION_DeleteServices },
|
{ szDeleteServices, ACTION_DeleteServices },
|
||||||
{ szDisableRollback, NULL },
|
{ szDisableRollback, ACTION_DisableRollback },
|
||||||
{ szDuplicateFiles, ACTION_DuplicateFiles },
|
{ szDuplicateFiles, ACTION_DuplicateFiles },
|
||||||
{ szExecuteAction, ACTION_ExecuteAction },
|
{ szExecuteAction, ACTION_ExecuteAction },
|
||||||
{ szFileCost, ACTION_FileCost },
|
{ szFileCost, ACTION_FileCost },
|
||||||
{ szFindRelatedProducts, ACTION_FindRelatedProducts },
|
{ szFindRelatedProducts, ACTION_FindRelatedProducts },
|
||||||
{ szForceReboot, ACTION_ForceReboot },
|
{ szForceReboot, ACTION_ForceReboot },
|
||||||
{ szInstallAdminPackage, NULL },
|
{ szInstallAdminPackage, ACTION_InstallAdminPackage },
|
||||||
{ szInstallExecute, ACTION_InstallExecute },
|
{ szInstallExecute, ACTION_InstallExecute },
|
||||||
{ szInstallExecuteAgain, ACTION_InstallExecute },
|
{ szInstallExecuteAgain, ACTION_InstallExecute },
|
||||||
{ szInstallFiles, ACTION_InstallFiles},
|
{ szInstallFiles, ACTION_InstallFiles},
|
||||||
|
|
|
@ -809,16 +809,17 @@ UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
feature = cls->Feature;
|
feature = cls->Feature;
|
||||||
|
if (!feature)
|
||||||
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MSDN says that these are based on Feature not on Component.
|
* MSDN says that these are based on Feature not on Component.
|
||||||
*/
|
*/
|
||||||
if (!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_LOCAL ) &&
|
if (feature->ActionRequest != INSTALLSTATE_LOCAL &&
|
||||||
!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ADVERTISED ))
|
feature->ActionRequest != INSTALLSTATE_ADVERTISED )
|
||||||
{
|
{
|
||||||
TRACE("Skipping class %s reg due to disabled feature %s\n",
|
TRACE("Feature %s not scheduled for installation, skipping regstration of class %s\n",
|
||||||
debugstr_w(cls->clsid), debugstr_w(feature->Feature));
|
debugstr_w(feature->Feature), debugstr_w(cls->clsid));
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1142,18 +1143,18 @@ UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
feature = ext->Feature;
|
feature = ext->Feature;
|
||||||
|
if (!feature)
|
||||||
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* yes. MSDN says that these are based on _Feature_ not on
|
* yes. MSDN says that these are based on _Feature_ not on
|
||||||
* Component. So verify the feature is to be installed
|
* Component. So verify the feature is to be installed
|
||||||
*/
|
*/
|
||||||
if ((!ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_LOCAL )) &&
|
if (feature->ActionRequest != INSTALLSTATE_LOCAL &&
|
||||||
!(install_on_demand &&
|
!(install_on_demand && feature->ActionRequest == INSTALLSTATE_ADVERTISED))
|
||||||
ACTION_VerifyFeatureForAction( feature, INSTALLSTATE_ADVERTISED )))
|
|
||||||
{
|
{
|
||||||
TRACE("Skipping extension %s reg due to disabled feature %s\n",
|
TRACE("Feature %s not scheduled for installation, skipping registration of extension %s\n",
|
||||||
debugstr_w(ext->Extension), debugstr_w(feature->Feature));
|
debugstr_w(feature->Feature), debugstr_w(ext->Extension));
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,20 +125,14 @@ static UINT clone_open_stream( MSIDATABASE *db, LPCWSTR name, IStream **stm )
|
||||||
|
|
||||||
UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
|
UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
|
||||||
{
|
{
|
||||||
LPWSTR encname;
|
|
||||||
HRESULT r;
|
HRESULT r;
|
||||||
|
|
||||||
encname = encode_streamname(FALSE, stname);
|
TRACE("%s\n", debugstr_w(stname));
|
||||||
|
|
||||||
TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname));
|
if (clone_open_stream( db, stname, stm ) == ERROR_SUCCESS)
|
||||||
|
|
||||||
if (clone_open_stream( db, encname, stm ) == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
msi_free( encname );
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
|
||||||
|
|
||||||
r = IStorage_OpenStream( db->storage, encname, NULL,
|
r = IStorage_OpenStream( db->storage, stname, NULL,
|
||||||
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
|
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
|
||||||
if( FAILED( r ) )
|
if( FAILED( r ) )
|
||||||
{
|
{
|
||||||
|
@ -147,15 +141,13 @@ UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
|
||||||
LIST_FOR_EACH_ENTRY( transform, &db->transforms, MSITRANSFORM, entry )
|
LIST_FOR_EACH_ENTRY( transform, &db->transforms, MSITRANSFORM, entry )
|
||||||
{
|
{
|
||||||
TRACE("looking for %s in transform storage\n", debugstr_w(stname) );
|
TRACE("looking for %s in transform storage\n", debugstr_w(stname) );
|
||||||
r = IStorage_OpenStream( transform->stg, encname, NULL,
|
r = IStorage_OpenStream( transform->stg, stname, NULL,
|
||||||
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
|
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
|
||||||
if (SUCCEEDED(r))
|
if (SUCCEEDED(r))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msi_free( encname );
|
|
||||||
|
|
||||||
if( SUCCEEDED(r) )
|
if( SUCCEEDED(r) )
|
||||||
{
|
{
|
||||||
MSISTREAM *stream;
|
MSISTREAM *stream;
|
||||||
|
@ -181,10 +173,15 @@ UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname,
|
||||||
ULONG sz, count;
|
ULONG sz, count;
|
||||||
IStream *stm = NULL;
|
IStream *stm = NULL;
|
||||||
STATSTG stat;
|
STATSTG stat;
|
||||||
|
LPWSTR encname;
|
||||||
|
|
||||||
|
encname = encode_streamname( FALSE, stname );
|
||||||
|
r = db_get_raw_stream( db, encname, &stm );
|
||||||
|
msi_free( encname );
|
||||||
|
|
||||||
r = db_get_raw_stream( db, stname, &stm );
|
|
||||||
if( r != ERROR_SUCCESS)
|
if( r != ERROR_SUCCESS)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
|
r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
|
||||||
if( FAILED( r ) )
|
if( FAILED( r ) )
|
||||||
{
|
{
|
||||||
|
@ -225,16 +222,6 @@ end:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void append_storage_to_db( MSIDATABASE *db, IStorage *stg )
|
|
||||||
{
|
|
||||||
MSITRANSFORM *t;
|
|
||||||
|
|
||||||
t = msi_alloc( sizeof *t );
|
|
||||||
t->stg = stg;
|
|
||||||
IStorage_AddRef( stg );
|
|
||||||
list_add_tail( &db->transforms, &t->entry );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void free_transforms( MSIDATABASE *db )
|
static void free_transforms( MSIDATABASE *db )
|
||||||
{
|
{
|
||||||
while( !list_empty( &db->transforms ) )
|
while( !list_empty( &db->transforms ) )
|
||||||
|
@ -259,6 +246,19 @@ static void free_streams( MSIDATABASE *db )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void append_storage_to_db( MSIDATABASE *db, IStorage *stg )
|
||||||
|
{
|
||||||
|
MSITRANSFORM *t;
|
||||||
|
|
||||||
|
t = msi_alloc( sizeof *t );
|
||||||
|
t->stg = stg;
|
||||||
|
IStorage_AddRef( stg );
|
||||||
|
list_add_tail( &db->transforms, &t->entry );
|
||||||
|
|
||||||
|
/* the transform may add or replace streams */
|
||||||
|
free_streams( db );
|
||||||
|
}
|
||||||
|
|
||||||
static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
|
static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
|
||||||
{
|
{
|
||||||
MSIDATABASE *db = (MSIDATABASE *) arg;
|
MSIDATABASE *db = (MSIDATABASE *) arg;
|
||||||
|
|
|
@ -386,9 +386,6 @@ static UINT ControlEvent_ReinstallMode(MSIPACKAGE *package, LPCWSTR argument,
|
||||||
static UINT ControlEvent_ValidateProductID(MSIPACKAGE *package, LPCWSTR argument,
|
static UINT ControlEvent_ValidateProductID(MSIPACKAGE *package, LPCWSTR argument,
|
||||||
msi_dialog *dialog)
|
msi_dialog *dialog)
|
||||||
{
|
{
|
||||||
static const WCHAR szProductID[] = {'P','r','o','d','u','c','t','I','D',0};
|
|
||||||
static const WCHAR szPIDTemplate[] = {'P','I','D','T','e','m','p','l','a','t','e',0};
|
|
||||||
static const WCHAR szPIDKEY[] = {'P','I','D','K','E','Y',0};
|
|
||||||
LPWSTR key, template;
|
LPWSTR key, template;
|
||||||
UINT ret = ERROR_SUCCESS;
|
UINT ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ static void schedule_install_files(MSIPACKAGE *package)
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(file, &package->files, MSIFILE, entry)
|
LIST_FOR_EACH_ENTRY(file, &package->files, MSIFILE, entry)
|
||||||
{
|
{
|
||||||
if (!ACTION_VerifyComponentForAction(file->Component, INSTALLSTATE_LOCAL))
|
if (file->Component->ActionRequest != INSTALLSTATE_LOCAL)
|
||||||
{
|
{
|
||||||
TRACE("File %s is not scheduled for install\n", debugstr_w(file->File));
|
TRACE("File %s is not scheduled for install\n", debugstr_w(file->File));
|
||||||
|
|
||||||
|
@ -358,19 +358,15 @@ static UINT ITERATE_DuplicateFiles(MSIRECORD *row, LPVOID param)
|
||||||
|
|
||||||
component = MSI_RecordGetString(row,2);
|
component = MSI_RecordGetString(row,2);
|
||||||
comp = get_loaded_component(package,component);
|
comp = get_loaded_component(package,component);
|
||||||
|
if (!comp)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL ))
|
if (comp->ActionRequest != INSTALLSTATE_LOCAL)
|
||||||
{
|
{
|
||||||
TRACE("Skipping copy due to disabled component %s\n",
|
TRACE("Component not scheduled for installation %s\n", debugstr_w(component));
|
||||||
debugstr_w(component));
|
|
||||||
|
|
||||||
/* the action taken was the same as the current install state */
|
|
||||||
if (comp)
|
|
||||||
comp->Action = comp->Installed;
|
comp->Action = comp->Installed;
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
comp->Action = INSTALLSTATE_LOCAL;
|
comp->Action = INSTALLSTATE_LOCAL;
|
||||||
|
|
||||||
file_key = MSI_RecordGetString(row,3);
|
file_key = MSI_RecordGetString(row,3);
|
||||||
|
|
|
@ -66,6 +66,21 @@ typedef struct _tagTT_NAME_RECORD {
|
||||||
|
|
||||||
static const WCHAR szRegisterFonts[] =
|
static const WCHAR szRegisterFonts[] =
|
||||||
{'R','e','g','i','s','t','e','r','F','o','n','t','s',0};
|
{'R','e','g','i','s','t','e','r','F','o','n','t','s',0};
|
||||||
|
static const WCHAR szUnregisterFonts[] =
|
||||||
|
{'U','n','r','e','g','i','s','t','e','r','F','o','n','t','s',0};
|
||||||
|
|
||||||
|
static const WCHAR regfont1[] =
|
||||||
|
{'S','o','f','t','w','a','r','e','\\',
|
||||||
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s',' ','N','T','\\',
|
||||||
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||||
|
'F','o','n','t','s',0};
|
||||||
|
static const WCHAR regfont2[] =
|
||||||
|
{'S','o','f','t','w','a','r','e','\\',
|
||||||
|
'M','i','c','r','o','s','o','f','t','\\',
|
||||||
|
'W','i','n','d','o','w','s','\\',
|
||||||
|
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||||
|
'F','o','n','t','s',0};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Code based off of code located here
|
* Code based off of code located here
|
||||||
|
@ -174,20 +189,7 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param)
|
||||||
LPWSTR name;
|
LPWSTR name;
|
||||||
LPCWSTR filename;
|
LPCWSTR filename;
|
||||||
MSIFILE *file;
|
MSIFILE *file;
|
||||||
static const WCHAR regfont1[] =
|
HKEY hkey1, hkey2;
|
||||||
{'S','o','f','t','w','a','r','e','\\',
|
|
||||||
'M','i','c','r','o','s','o','f','t','\\',
|
|
||||||
'W','i','n','d','o','w','s',' ','N','T','\\',
|
|
||||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
|
||||||
'F','o','n','t','s',0};
|
|
||||||
static const WCHAR regfont2[] =
|
|
||||||
{'S','o','f','t','w','a','r','e','\\',
|
|
||||||
'M','i','c','r','o','s','o','f','t','\\',
|
|
||||||
'W','i','n','d','o','w','s','\\',
|
|
||||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
|
||||||
'F','o','n','t','s',0};
|
|
||||||
HKEY hkey1;
|
|
||||||
HKEY hkey2;
|
|
||||||
MSIRECORD *uirow;
|
MSIRECORD *uirow;
|
||||||
LPWSTR uipath, p;
|
LPWSTR uipath, p;
|
||||||
|
|
||||||
|
@ -199,10 +201,9 @@ static UINT ITERATE_RegisterFonts(MSIRECORD *row, LPVOID param)
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check to make sure that component is installed */
|
if (file->Component->ActionRequest != INSTALLSTATE_LOCAL)
|
||||||
if (!ACTION_VerifyComponentForAction( file->Component, INSTALLSTATE_LOCAL))
|
|
||||||
{
|
{
|
||||||
TRACE("Skipping: Component not scheduled for install\n");
|
TRACE("Component not scheduled for installation\n");
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,3 +260,81 @@ UINT ACTION_RegisterFonts(MSIPACKAGE *package)
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT ITERATE_UnregisterFonts( MSIRECORD *row, LPVOID param )
|
||||||
|
{
|
||||||
|
MSIPACKAGE *package = param;
|
||||||
|
LPWSTR name;
|
||||||
|
LPCWSTR filename;
|
||||||
|
MSIFILE *file;
|
||||||
|
HKEY hkey1, hkey2;
|
||||||
|
MSIRECORD *uirow;
|
||||||
|
LPWSTR uipath, p;
|
||||||
|
|
||||||
|
filename = MSI_RecordGetString( row, 1 );
|
||||||
|
file = get_loaded_file( package, filename );
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
ERR("Unable to load file\n");
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file->Component->ActionRequest != INSTALLSTATE_ABSENT)
|
||||||
|
{
|
||||||
|
TRACE("Component not scheduled for removal\n");
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont1, &hkey1 );
|
||||||
|
RegCreateKeyW( HKEY_LOCAL_MACHINE, regfont2, &hkey2 );
|
||||||
|
|
||||||
|
if (MSI_RecordIsNull( row, 2 ))
|
||||||
|
name = load_ttfname_from( file->TargetPath );
|
||||||
|
else
|
||||||
|
name = msi_dup_record_field( row, 2 );
|
||||||
|
|
||||||
|
if (name)
|
||||||
|
{
|
||||||
|
RegDeleteValueW( hkey1, name );
|
||||||
|
RegDeleteValueW( hkey2, name );
|
||||||
|
}
|
||||||
|
|
||||||
|
msi_free( name );
|
||||||
|
RegCloseKey( hkey1 );
|
||||||
|
RegCloseKey( hkey2 );
|
||||||
|
|
||||||
|
/* the UI chunk */
|
||||||
|
uirow = MSI_CreateRecord( 1 );
|
||||||
|
uipath = strdupW( file->TargetPath );
|
||||||
|
p = strrchrW( uipath,'\\' );
|
||||||
|
if (p) p++;
|
||||||
|
else p = uipath;
|
||||||
|
MSI_RecordSetStringW( uirow, 1, p );
|
||||||
|
ui_actiondata( package, szUnregisterFonts, uirow );
|
||||||
|
msiobj_release( &uirow->hdr );
|
||||||
|
msi_free( uipath );
|
||||||
|
/* FIXME: call ui_progress? */
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT ACTION_UnregisterFonts( MSIPACKAGE *package )
|
||||||
|
{
|
||||||
|
UINT r;
|
||||||
|
MSIQUERY *view;
|
||||||
|
static const WCHAR query[] =
|
||||||
|
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||||
|
'`','F','o','n','t','`',0};
|
||||||
|
|
||||||
|
r = MSI_DatabaseOpenViewW( package->db, query, &view );
|
||||||
|
if (r != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
TRACE("MSI_DatabaseOpenViewW failed: %u\n", r);
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
MSI_IterateRecords( view, NULL, ITERATE_UnregisterFonts, package );
|
||||||
|
msiobj_release( &view->hdr );
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
|
@ -604,28 +604,6 @@ void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record)
|
||||||
msiobj_release(&row->hdr);
|
msiobj_release(&row->hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL ACTION_VerifyComponentForAction( const MSICOMPONENT* comp, INSTALLSTATE check )
|
|
||||||
{
|
|
||||||
if (!comp)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (comp->ActionRequest == check)
|
|
||||||
return TRUE;
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL ACTION_VerifyFeatureForAction( const MSIFEATURE* feature, INSTALLSTATE check )
|
|
||||||
{
|
|
||||||
if (!feature)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (feature->ActionRequest == check)
|
|
||||||
return TRUE;
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reduce_to_longfilename(WCHAR* filename)
|
void reduce_to_longfilename(WCHAR* filename)
|
||||||
{
|
{
|
||||||
LPWSTR p = strchrW(filename,'|');
|
LPWSTR p = strchrW(filename,'|');
|
||||||
|
|
|
@ -661,6 +661,8 @@ BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
|
||||||
MSIPACKAGE *package;
|
MSIPACKAGE *package;
|
||||||
BOOL r = FALSE;
|
BOOL r = FALSE;
|
||||||
|
|
||||||
|
TRACE("%d %d\n", hInstall, iRunMode);
|
||||||
|
|
||||||
package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
|
package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
|
||||||
if (!package)
|
if (!package)
|
||||||
{
|
{
|
||||||
|
@ -706,8 +708,16 @@ BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
|
||||||
r = package->commit_action_running;
|
r = package->commit_action_running;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSIRUNMODE_MAINTENANCE:
|
||||||
|
r = msi_get_property_int( package, szInstalled, 0 ) != 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSIRUNMODE_REBOOTATEND:
|
||||||
|
r = package->need_reboot;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FIXME("%d %d\n", hInstall, iRunMode);
|
FIXME("unimplemented run mode: %d\n", iRunMode);
|
||||||
r = TRUE;
|
r = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,8 +729,52 @@ BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
|
||||||
*/
|
*/
|
||||||
UINT WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState)
|
UINT WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState)
|
||||||
{
|
{
|
||||||
FIXME("%d %d %d\n", hInstall, iRunMode, fState);
|
MSIPACKAGE *package;
|
||||||
|
UINT r;
|
||||||
|
|
||||||
|
TRACE("%d %d %d\n", hInstall, iRunMode, fState);
|
||||||
|
|
||||||
|
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
|
||||||
|
if (!package)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
IWineMsiRemotePackage *remote_package;
|
||||||
|
|
||||||
|
remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
|
||||||
|
if (!remote_package)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
hr = IWineMsiRemotePackage_SetMode( remote_package, iRunMode, fState );
|
||||||
|
IWineMsiRemotePackage_Release( remote_package );
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
|
||||||
|
return HRESULT_CODE(hr);
|
||||||
|
|
||||||
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (iRunMode)
|
||||||
|
{
|
||||||
|
case MSIRUNMODE_REBOOTATEND:
|
||||||
|
package->need_reboot = 1;
|
||||||
|
r = ERROR_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSIRUNMODE_REBOOTNOW:
|
||||||
|
FIXME("unimplemented run mode: %d\n", iRunMode);
|
||||||
|
r = ERROR_FUNCTION_FAILED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
r = ERROR_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -1613,6 +1613,93 @@ done:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT WINAPI MsiGetPatchInfoA( LPCSTR patch, LPCSTR attr, LPSTR buffer, LPDWORD buflen )
|
||||||
|
{
|
||||||
|
UINT r = ERROR_OUTOFMEMORY;
|
||||||
|
DWORD size;
|
||||||
|
LPWSTR patchW = NULL, attrW = NULL, bufferW = NULL;
|
||||||
|
|
||||||
|
TRACE("%s %s %p %p\n", debugstr_a(patch), debugstr_a(attr), buffer, buflen);
|
||||||
|
|
||||||
|
if (!patch || !attr)
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (!(patchW = strdupAtoW( patch )))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (!(attrW = strdupAtoW( attr )))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
r = MsiGetPatchInfoW( patchW, attrW, NULL, &size );
|
||||||
|
if (r != ERROR_SUCCESS)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
size++;
|
||||||
|
if (!(bufferW = msi_alloc( size * sizeof(WCHAR) )))
|
||||||
|
{
|
||||||
|
r = ERROR_OUTOFMEMORY;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = MsiGetPatchInfoW( patchW, attrW, bufferW, &size );
|
||||||
|
if (r == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
int len = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
|
||||||
|
if (len > *buflen)
|
||||||
|
r = ERROR_MORE_DATA;
|
||||||
|
else if (buffer)
|
||||||
|
WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, *buflen, NULL, NULL );
|
||||||
|
|
||||||
|
*buflen = len - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
msi_free( patchW );
|
||||||
|
msi_free( attrW );
|
||||||
|
msi_free( bufferW );
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT WINAPI MsiGetPatchInfoW( LPCWSTR patch, LPCWSTR attr, LPWSTR buffer, LPDWORD buflen )
|
||||||
|
{
|
||||||
|
UINT r;
|
||||||
|
WCHAR product[GUID_SIZE];
|
||||||
|
DWORD index;
|
||||||
|
|
||||||
|
TRACE("%s %s %p %p\n", debugstr_w(patch), debugstr_w(attr), buffer, buflen);
|
||||||
|
|
||||||
|
if (!patch || !attr)
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (strcmpW( INSTALLPROPERTY_LOCALPACKAGEW, attr ))
|
||||||
|
return ERROR_UNKNOWN_PROPERTY;
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
r = MsiEnumProductsW( index, product );
|
||||||
|
if (r != ERROR_SUCCESS)
|
||||||
|
break;
|
||||||
|
|
||||||
|
r = MsiGetPatchInfoExW( patch, product, NULL, MSIINSTALLCONTEXT_USERMANAGED, attr, buffer, buflen );
|
||||||
|
if (r == ERROR_SUCCESS || r == ERROR_MORE_DATA)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = MsiGetPatchInfoExW( patch, product, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, attr, buffer, buflen );
|
||||||
|
if (r == ERROR_SUCCESS || r == ERROR_MORE_DATA)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = MsiGetPatchInfoExW( patch, product, NULL, MSIINSTALLCONTEXT_MACHINE, attr, buffer, buflen );
|
||||||
|
if (r == ERROR_SUCCESS || r == ERROR_MORE_DATA)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_UNKNOWN_PRODUCT;
|
||||||
|
}
|
||||||
|
|
||||||
UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
|
UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
|
||||||
{
|
{
|
||||||
LPWSTR szwLogFile = NULL;
|
LPWSTR szwLogFile = NULL;
|
||||||
|
|
|
@ -171,8 +171,8 @@
|
||||||
175 stdcall MsiApplyPatchW(wstr wstr long wstr)
|
175 stdcall MsiApplyPatchW(wstr wstr long wstr)
|
||||||
176 stdcall MsiAdvertiseScriptA(str long ptr long)
|
176 stdcall MsiAdvertiseScriptA(str long ptr long)
|
||||||
177 stdcall MsiAdvertiseScriptW(wstr long ptr long)
|
177 stdcall MsiAdvertiseScriptW(wstr long ptr long)
|
||||||
178 stub MsiGetPatchInfoA
|
178 stdcall MsiGetPatchInfoA(str str ptr ptr)
|
||||||
179 stub MsiGetPatchInfoW
|
179 stdcall MsiGetPatchInfoW(wstr wstr ptr ptr)
|
||||||
180 stdcall MsiEnumPatchesA(str long ptr ptr ptr)
|
180 stdcall MsiEnumPatchesA(str long ptr ptr ptr)
|
||||||
181 stdcall MsiEnumPatchesW(str long ptr ptr ptr)
|
181 stdcall MsiEnumPatchesW(str long ptr ptr ptr)
|
||||||
182 stdcall -private DllGetVersion(ptr)
|
182 stdcall -private DllGetVersion(ptr)
|
||||||
|
|
|
@ -20,17 +20,21 @@
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
|
|
||||||
|
/*UTF-8*/
|
||||||
|
#pragma code_page(65001)
|
||||||
|
|
||||||
LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
|
LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
|
||||||
|
|
||||||
STRINGTABLE DISCARDABLE
|
STRINGTABLE DISCARDABLE
|
||||||
{
|
{
|
||||||
4 "The specified installation package could not be opened. Please check the file path and try again."
|
4 "Impossibile aprire il pacchetto di installazione specificato. Per favore controlla l'indirizzo del file e riprova."
|
||||||
5 "percorso %s non trovato"
|
5 "percorso %s non trovato"
|
||||||
9 "inserire disco %s"
|
9 "inserire disco %s"
|
||||||
10 "parametri incorretti"
|
10 "parametri incorretti"
|
||||||
11 "immettere il nome della cartella che contiene %s"
|
11 "immettere il nome della cartella che contiene %s"
|
||||||
12 "sorgente di installazione per la funzionalità mancante"
|
12 "sorgente di installazione per la funzionalità mancante"
|
||||||
13 "periferica di rete per la funzionalità mancante"
|
13 "periferica di rete per la funzionalità mancante"
|
||||||
14 "funzionalità da:"
|
14 "funzionalità da:"
|
||||||
15 "selezionare la cartella che contiene %s"
|
15 "selezionare la cartella che contiene %s"
|
||||||
}
|
}
|
||||||
|
#pragma code_page(default)
|
||||||
|
|
|
@ -961,6 +961,7 @@ extern UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package);
|
||||||
extern UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package);
|
extern UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package);
|
||||||
extern UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package);
|
extern UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package);
|
||||||
extern UINT ACTION_RegisterFonts(MSIPACKAGE *package);
|
extern UINT ACTION_RegisterFonts(MSIPACKAGE *package);
|
||||||
|
extern UINT ACTION_UnregisterFonts(MSIPACKAGE *package);
|
||||||
|
|
||||||
/* Helpers */
|
/* Helpers */
|
||||||
extern DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data );
|
extern DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data );
|
||||||
|
@ -981,8 +982,6 @@ extern void msi_free_action_script(MSIPACKAGE *package, UINT script);
|
||||||
extern LPWSTR build_icon_path(MSIPACKAGE *, LPCWSTR);
|
extern LPWSTR build_icon_path(MSIPACKAGE *, LPCWSTR);
|
||||||
extern LPWSTR build_directory_name(DWORD , ...);
|
extern LPWSTR build_directory_name(DWORD , ...);
|
||||||
extern BOOL create_full_pathW(const WCHAR *path);
|
extern BOOL create_full_pathW(const WCHAR *path);
|
||||||
extern BOOL ACTION_VerifyComponentForAction(const MSICOMPONENT*, INSTALLSTATE);
|
|
||||||
extern BOOL ACTION_VerifyFeatureForAction(const MSIFEATURE*, INSTALLSTATE);
|
|
||||||
extern void reduce_to_longfilename(WCHAR*);
|
extern void reduce_to_longfilename(WCHAR*);
|
||||||
extern LPWSTR create_component_advertise_string(MSIPACKAGE*, MSICOMPONENT*, LPCWSTR);
|
extern LPWSTR create_component_advertise_string(MSIPACKAGE*, MSICOMPONENT*, LPCWSTR);
|
||||||
extern void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature);
|
extern void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature);
|
||||||
|
@ -1071,6 +1070,11 @@ static const WCHAR szFindRelatedProducts[] = {'F','i','n','d','R','e','l','a','t
|
||||||
static const WCHAR szAllUsers[] = {'A','L','L','U','S','E','R','S',0};
|
static const WCHAR szAllUsers[] = {'A','L','L','U','S','E','R','S',0};
|
||||||
static const WCHAR szCustomActionData[] = {'C','u','s','t','o','m','A','c','t','i','o','n','D','a','t','a',0};
|
static const WCHAR szCustomActionData[] = {'C','u','s','t','o','m','A','c','t','i','o','n','D','a','t','a',0};
|
||||||
static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
|
static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
|
||||||
|
static const WCHAR szProductID[] = {'P','r','o','d','u','c','t','I','D',0};
|
||||||
|
static const WCHAR szPIDTemplate[] = {'P','I','D','T','e','m','p','l','a','t','e',0};
|
||||||
|
static const WCHAR szPIDKEY[] = {'P','I','D','K','E','Y',0};
|
||||||
|
static const WCHAR szTYPELIB[] = {'T','Y','P','E','L','I','B',0};
|
||||||
|
static const WCHAR szSumInfo[] = {5 ,'S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0};
|
||||||
|
|
||||||
/* memory allocation macro functions */
|
/* memory allocation macro functions */
|
||||||
static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1);
|
static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1);
|
||||||
|
|
|
@ -64,6 +64,7 @@ interface IWineMsiRemotePackage : IUnknown
|
||||||
HRESULT SetTargetPath( [in] BSTR folder, [in] BSTR value );
|
HRESULT SetTargetPath( [in] BSTR folder, [in] BSTR value );
|
||||||
HRESULT GetSourcePath( [in] BSTR folder, [out] BSTR *value, [out] DWORD *size );
|
HRESULT GetSourcePath( [in] BSTR folder, [out] BSTR *value, [out] DWORD *size );
|
||||||
HRESULT GetMode( [in] MSIRUNMODE mode, [out] BOOL *ret );
|
HRESULT GetMode( [in] MSIRUNMODE mode, [out] BOOL *ret );
|
||||||
|
HRESULT SetMode( [in] MSIRUNMODE mode, [in] BOOL state );
|
||||||
HRESULT GetFeatureState( [in] BSTR feature, [out] INSTALLSTATE *installed, [out] INSTALLSTATE *action );
|
HRESULT GetFeatureState( [in] BSTR feature, [out] INSTALLSTATE *installed, [out] INSTALLSTATE *action );
|
||||||
HRESULT SetFeatureState( [in] BSTR feature, [in] INSTALLSTATE state );
|
HRESULT SetFeatureState( [in] BSTR feature, [in] INSTALLSTATE state );
|
||||||
HRESULT GetComponentState( [in] BSTR component, [out] INSTALLSTATE *installed, [out] INSTALLSTATE *action );
|
HRESULT GetComponentState( [in] BSTR component, [out] INSTALLSTATE *installed, [out] INSTALLSTATE *action );
|
||||||
|
|
|
@ -2104,6 +2104,13 @@ static HRESULT WINAPI mrp_GetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI mrp_SetMode( IWineMsiRemotePackage *iface, MSIRUNMODE mode, BOOL state )
|
||||||
|
{
|
||||||
|
msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
|
||||||
|
UINT r = MsiSetMode(This->package, mode, state);
|
||||||
|
return HRESULT_FROM_WIN32(r);
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI mrp_GetFeatureState( IWineMsiRemotePackage *iface, BSTR feature,
|
static HRESULT WINAPI mrp_GetFeatureState( IWineMsiRemotePackage *iface, BSTR feature,
|
||||||
INSTALLSTATE *installed, INSTALLSTATE *action )
|
INSTALLSTATE *installed, INSTALLSTATE *action )
|
||||||
{
|
{
|
||||||
|
@ -2196,6 +2203,7 @@ static const IWineMsiRemotePackageVtbl msi_remote_package_vtbl =
|
||||||
mrp_SetTargetPath,
|
mrp_SetTargetPath,
|
||||||
mrp_GetSourcePath,
|
mrp_GetSourcePath,
|
||||||
mrp_GetMode,
|
mrp_GetMode,
|
||||||
|
mrp_SetMode,
|
||||||
mrp_GetFeatureState,
|
mrp_GetFeatureState,
|
||||||
mrp_SetFeatureState,
|
mrp_SetFeatureState,
|
||||||
mrp_GetComponentState,
|
mrp_GetComponentState,
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
#include "wine/unicode.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(msidb);
|
WINE_DEFAULT_DEBUG_CHANNEL(msidb);
|
||||||
|
|
||||||
|
@ -486,7 +487,8 @@ static INT add_streams_to_table(MSISTREAMSVIEW *sv)
|
||||||
STATSTG stat;
|
STATSTG stat;
|
||||||
STREAM *stream = NULL;
|
STREAM *stream = NULL;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
UINT count = 0, size;
|
UINT r, count = 0, size;
|
||||||
|
LPWSTR encname;
|
||||||
|
|
||||||
hr = IStorage_EnumElements(sv->db->storage, 0, NULL, 0, &stgenum);
|
hr = IStorage_EnumElements(sv->db->storage, 0, NULL, 0, &stgenum);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
@ -505,7 +507,10 @@ static INT add_streams_to_table(MSISTREAMSVIEW *sv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (stat.type != STGTY_STREAM)
|
if (stat.type != STGTY_STREAM)
|
||||||
|
{
|
||||||
|
CoTaskMemFree(stat.pwcsName);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* table streams are not in the _Streams table */
|
/* table streams are not in the _Streams table */
|
||||||
if (*stat.pwcsName == 0x4840)
|
if (*stat.pwcsName == 0x4840)
|
||||||
|
@ -522,13 +527,22 @@ static INT add_streams_to_table(MSISTREAMSVIEW *sv)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = IStorage_OpenStream(sv->db->storage, stat.pwcsName, 0,
|
if (!strcmpW(stat.pwcsName, szSumInfo))
|
||||||
STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream);
|
{
|
||||||
|
/* summary information stream is not encoded */
|
||||||
|
r = db_get_raw_stream(sv->db, stat.pwcsName, &stream->stream);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
encname = encode_streamname(FALSE, stat.pwcsName);
|
||||||
|
r = db_get_raw_stream(sv->db, encname, &stream->stream);
|
||||||
|
msi_free(encname);
|
||||||
|
}
|
||||||
CoTaskMemFree(stat.pwcsName);
|
CoTaskMemFree(stat.pwcsName);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (r != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
WARN("failed to open stream: %08x\n", hr);
|
WARN("unable to get stream %u\n", r);
|
||||||
count = -1;
|
count = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,9 +86,6 @@ static HRESULT (WINAPI *pPropVariantChangeType)
|
||||||
|
|
||||||
#define SECT_HDR_SIZE (sizeof(PROPERTYSECTIONHEADER))
|
#define SECT_HDR_SIZE (sizeof(PROPERTYSECTIONHEADER))
|
||||||
|
|
||||||
static const WCHAR szSumInfo[] = { 5 ,'S','u','m','m','a','r','y',
|
|
||||||
'I','n','f','o','r','m','a','t','i','o','n',0 };
|
|
||||||
|
|
||||||
static void free_prop( PROPVARIANT *prop )
|
static void free_prop( PROPVARIANT *prop )
|
||||||
{
|
{
|
||||||
if (prop->vt == VT_LPSTR )
|
if (prop->vt == VT_LPSTR )
|
||||||
|
|
|
@ -1168,7 +1168,7 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
|
||||||
{
|
{
|
||||||
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
|
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
|
||||||
UINT r;
|
UINT r;
|
||||||
LPWSTR full_name = NULL;
|
LPWSTR encname, full_name = NULL;
|
||||||
|
|
||||||
if( !view->ops->fetch_int )
|
if( !view->ops->fetch_int )
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
@ -1180,11 +1180,13 @@ static UINT TABLE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, ISt
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = db_get_raw_stream( tv->db, full_name, stm );
|
encname = encode_streamname( FALSE, full_name );
|
||||||
|
r = db_get_raw_stream( tv->db, encname, stm );
|
||||||
if( r )
|
if( r )
|
||||||
ERR("fetching stream %s, error = %d\n",debugstr_w(full_name), r);
|
ERR("fetching stream %s, error = %d\n",debugstr_w(full_name), r);
|
||||||
msi_free( full_name );
|
|
||||||
|
|
||||||
|
msi_free( full_name );
|
||||||
|
msi_free( encname );
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,9 +166,9 @@ static int sqliteKeywordCode(const WCHAR *z, int n){
|
||||||
*/
|
*/
|
||||||
static const char isIdChar[] = {
|
static const char isIdChar[] = {
|
||||||
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
|
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */
|
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* 2x */
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */
|
||||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */
|
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */
|
||||||
|
|
|
@ -503,6 +503,10 @@ UINT WINAPI MsiGetPatchInfoExA(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR
|
||||||
UINT WINAPI MsiGetPatchInfoExW(LPCWSTR, LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, LPCWSTR, LPWSTR, LPDWORD);
|
UINT WINAPI MsiGetPatchInfoExW(LPCWSTR, LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, LPCWSTR, LPWSTR, LPDWORD);
|
||||||
#define MsiGetPatchInfoEx WINELIB_NAME_AW(MsiGetPatchInfoEx)
|
#define MsiGetPatchInfoEx WINELIB_NAME_AW(MsiGetPatchInfoEx)
|
||||||
|
|
||||||
|
UINT WINAPI MsiGetPatchInfoA(LPCSTR, LPCSTR, LPSTR, LPDWORD);
|
||||||
|
UINT WINAPI MsiGetPatchInfoW(LPCWSTR, LPCWSTR, LPWSTR, LPDWORD);
|
||||||
|
#define MsiGetPatchInfo WINELIB_NAME_AW(MsiGetPatchInfo)
|
||||||
|
|
||||||
UINT WINAPI MsiEnableLogA(DWORD, LPCSTR, DWORD);
|
UINT WINAPI MsiEnableLogA(DWORD, LPCSTR, DWORD);
|
||||||
UINT WINAPI MsiEnableLogW(DWORD, LPCWSTR, DWORD);
|
UINT WINAPI MsiEnableLogW(DWORD, LPCWSTR, DWORD);
|
||||||
#define MsiEnableLog WINELIB_NAME_AW(MsiEnableLog)
|
#define MsiEnableLog WINELIB_NAME_AW(MsiEnableLog)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue