registry.c \\r
regsvr.c \\r
select.c \\r
+ source.c \\r
string.c \\r
suminfo.c \\r
table.c \\r
*****************************************************/
UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
- LPCWSTR szCommandLine)
+ LPCWSTR szCommandLine, LPCWSTR msiFilePath)
{
DWORD sz;
WCHAR buffer[10];
package->script = HeapAlloc(GetProcessHeap(),0,sizeof(MSISCRIPT));
memset(package->script,0,sizeof(MSISCRIPT));
+ package->script->InWhatSequence = SEQUENCE_INSTALL;
+
+ package->msiFilePath= strdupW(msiFilePath);
+
if (szPackagePath)
{
LPWSTR p, check, path;
{
if (atoiW(buffer) >= INSTALLUILEVEL_REDUCED)
{
+ package->script->InWhatSequence |= SEQUENCE_UI;
rc = ACTION_ProcessUISequence(package);
ui = TRUE;
if (rc == ERROR_SUCCESS)
+ {
+ package->script->InWhatSequence |= SEQUENCE_EXEC;
rc = ACTION_ProcessExecSequence(package,TRUE);
+ }
}
else
rc = ACTION_ProcessExecSequence(package,FALSE);
else
rc = ACTION_PerformAction(iap->package,action,FALSE);
+ msi_dialog_check_messages( NULL );
+
+ if (iap->package->CurrentInstallState != ERROR_SUCCESS )
+ rc = iap->package->CurrentInstallState;
+
if (rc == ERROR_FUNCTION_NOT_CALLED)
rc = ERROR_SUCCESS;
return ret;
}
-static BOOL ACTION_HandleDialogBox( MSIPACKAGE *package, LPCWSTR dialog, UINT* rc )
-{
- BOOL ret = FALSE;
-
- if (ACTION_DialogBox(package,dialog) == ERROR_SUCCESS)
- {
- *rc = package->CurrentInstallState;
- ret = TRUE;
- }
- return ret;
-}
-
static BOOL ACTION_HandleCustomAction( MSIPACKAGE* package, LPCWSTR action,
UINT* rc, BOOL force )
{
rc = ERROR_FUNCTION_NOT_CALLED;
}
- package->CurrentInstallState = rc;
return rc;
}
if (!handled)
handled = ACTION_HandleCustomAction(package, action, &rc, FALSE);
- if (!handled)
- handled = ACTION_HandleDialogBox(package, action, &rc);
-
- msi_dialog_check_messages( NULL );
+ if( !handled && ACTION_DialogBox(package,action) == ERROR_SUCCESS )
+ handled = TRUE;
if (!handled)
{
rc = ERROR_FUNCTION_NOT_CALLED;
}
- package->CurrentInstallState = rc;
return rc;
}
if (targetdir[0] == '.' && targetdir[1] == 0)
targetdir = NULL;
- if (srcdir && srcdir[0] == '.' && srcdir[1] == 0)
- srcdir = NULL;
-
if (targetdir)
{
TRACE(" TargetDefault = %s\n",debugstr_w(targetdir));
static void ACTION_UpdateInstallStates(MSIPACKAGE *package)
{
int i;
- LPWSTR productcode;
-
- productcode = load_dynamic_property(package,szProductCode,NULL);
for (i = 0; i < package->loaded_components; i++)
{
INSTALLSTATE res;
- res = MsiGetComponentPathW(productcode,
+ res = MsiGetComponentPathW(package->ProductCode,
package->components[i].ComponentId , NULL, NULL);
if (res < 0)
res = INSTALLSTATE_ABSENT;
{
TRACE("Setting value %s of %s\n",debugstr_w(deformated),
debugstr_w(uikey));
- RegSetValueExW(hkey, deformated, 0, type, value_data, size);
+ RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value_data, size);
}
else
{
TRACE("Checked and setting value %s of %s\n",
debugstr_w(deformated), debugstr_w(uikey));
if (deformated || size)
- RegSetValueExW(hkey, deformated, 0, type, value_data, size);
+ RegSetValueExW(hkey, deformated, 0, type, (LPBYTE) value_data, size);
}
}
RegCloseKey(hkey);
*/
static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
{
- LPWSTR productcode;
WCHAR squished_pc[GUID_SIZE];
WCHAR squished_cc[GUID_SIZE];
UINT rc;
return ERROR_INVALID_HANDLE;
/* writes the Component and Features values to the registry */
- productcode = load_dynamic_property(package,szProductCode,&rc);
- if (!productcode)
- return rc;
rc = MSIREG_OpenComponents(&hkey);
if (rc != ERROR_SUCCESS)
goto end;
- squash_guid(productcode,squished_pc);
+ squash_guid(package->ProductCode,squished_pc);
ui_progress(package,1,COMPONENT_PROGRESS_VALUE,1,0);
for (i = 0; i < package->loaded_components; i++)
{
if (keypath)
{
- RegSetValueExW(hkey2,squished_pc,0,REG_SZ,(LPVOID)keypath,
+ RegSetValueExW(hkey2,squished_pc,0,REG_SZ,(LPBYTE)keypath,
(strlenW(keypath)+1)*sizeof(WCHAR));
if (package->components[i].Attributes &
'0','0','0','0','0','0','0','0',0};
RegSetValueExW(hkey2,szPermKey,0,REG_SZ,
- (LPVOID)keypath,
+ (LPBYTE)keypath,
(strlenW(keypath)+1)*sizeof(WCHAR));
}
/* UI stuff */
uirow = MSI_CreateRecord(3);
- MSI_RecordSetStringW(uirow,1,productcode);
+ MSI_RecordSetStringW(uirow,1,package->ProductCode);
MSI_RecordSetStringW(uirow,2,package->components[i].
ComponentId);
MSI_RecordSetStringW(uirow,3,keypath);
/* UI stuff */
uirow = MSI_CreateRecord(2);
- MSI_RecordSetStringW(uirow,1,productcode);
+ MSI_RecordSetStringW(uirow,1,package->ProductCode);
MSI_RecordSetStringW(uirow,2,package->components[i].
ComponentId);
ui_actiondata(package,szProcessComponents,uirow);
}
}
end:
- HeapFree(GetProcessHeap(), 0, productcode);
RegCloseKey(hkey);
return rc;
}
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','I','c','o','n','`',0};
/* for registry stuff */
- LPWSTR productcode;
HKEY hkey=0;
HKEY hukey=0;
- static const WCHAR szProductName[] =
- {'P','r','o','d','u','c','t','N','a','m','e',0};
- static const WCHAR szPackageCode[] =
- {'P','a','c','k','a','g','e','C','o','d','e',0};
- static const WCHAR szLanguage[] =
- {'L','a','n','g','u','a','g','e',0};
static const WCHAR szProductLanguage[] =
{'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
- static const WCHAR szProductIcon[] =
- {'P','r','o','d','u','c','t','I','c','o','n',0};
static const WCHAR szARPProductIcon[] =
{'A','R','P','P','R','O','D','U','C','T','I','C','O','N',0};
static const WCHAR szProductVersion[] =
{'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
- static const WCHAR szVersion[] =
- {'V','e','r','s','i','o','n',0};
DWORD langid;
LPWSTR buffer;
DWORD size;
/* ok there is a lot more done here but i need to figure out what */
- productcode = load_dynamic_property(package,szProductCode,&rc);
- if (!productcode)
- return rc;
-
- rc = MSIREG_OpenProductsKey(productcode,&hkey,TRUE);
+ rc = MSIREG_OpenProductsKey(package->ProductCode,&hkey,TRUE);
if (rc != ERROR_SUCCESS)
goto end;
- rc = MSIREG_OpenUserProductsKey(productcode,&hukey,TRUE);
+ rc = MSIREG_OpenUserProductsKey(package->ProductCode,&hukey,TRUE);
if (rc != ERROR_SUCCESS)
goto end;
- buffer = load_dynamic_property(package,szProductName,NULL);
+ buffer = load_dynamic_property(package,INSTALLPROPERTY_PRODUCTNAMEW,NULL);
size = strlenW(buffer)*sizeof(WCHAR);
- RegSetValueExW(hukey,szProductName,0,REG_SZ, (BYTE *)buffer,size);
+ RegSetValueExW(hukey,INSTALLPROPERTY_PRODUCTNAMEW,0,REG_SZ,
+ (LPBYTE)buffer,size);
HeapFree(GetProcessHeap(),0,buffer);
buffer = load_dynamic_property(package,szProductLanguage,NULL);
size = sizeof(DWORD);
langid = atoiW(buffer);
- RegSetValueExW(hukey,szLanguage,0,REG_DWORD, (BYTE *)&langid,size);
+ RegSetValueExW(hukey,INSTALLPROPERTY_LANGUAGEW,0,REG_DWORD,
+ (LPBYTE)&langid,size);
HeapFree(GetProcessHeap(),0,buffer);
buffer = load_dynamic_property(package,szARPProductIcon,NULL);
LPWSTR path;
build_icon_path(package,buffer,&path);
size = strlenW(path) * sizeof(WCHAR);
- RegSetValueExW(hukey,szProductIcon,0,REG_SZ, (BYTE *)path,size);
+ RegSetValueExW(hukey,INSTALLPROPERTY_PRODUCTICONW,0,REG_SZ,
+ (LPBYTE)path,size);
}
HeapFree(GetProcessHeap(),0,buffer);
{
DWORD verdword = build_version_dword(buffer);
size = sizeof(DWORD);
- RegSetValueExW(hukey,szVersion,0,REG_DWORD, (BYTE *)&verdword,size);
+ RegSetValueExW(hukey,INSTALLPROPERTY_VERSIONW,0,REG_DWORD, (LPBYTE
+ )&verdword,size);
}
HeapFree(GetProcessHeap(),0,buffer);
if (ptr) *ptr = 0;
squash_guid(guidbuffer,squashed);
size = strlenW(squashed)*sizeof(WCHAR);
- RegSetValueExW(hukey,szPackageCode,0,REG_SZ, (LPSTR)squashed,
- size);
+ RegSetValueExW(hukey,INSTALLPROPERTY_PACKAGECODEW,0,REG_SZ,
+ (LPBYTE)squashed, size);
}
else
{
end:
- HeapFree(GetProcessHeap(),0,productcode);
RegCloseKey(hkey);
RegCloseKey(hukey);
static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
{
- LPWSTR productcode;
UINT rc;
DWORD i;
HKEY hkey=0;
if (!package)
return ERROR_INVALID_HANDLE;
- productcode = load_dynamic_property(package,szProductCode,&rc);
- if (!productcode)
- return rc;
-
- rc = MSIREG_OpenFeaturesKey(productcode,&hkey,TRUE);
+ rc = MSIREG_OpenFeaturesKey(package->ProductCode,&hkey,TRUE);
if (rc != ERROR_SUCCESS)
goto end;
- rc = MSIREG_OpenUserFeaturesKey(productcode,&hukey,TRUE);
+ rc = MSIREG_OpenUserFeaturesKey(package->ProductCode,&hukey,TRUE);
if (rc != ERROR_SUCCESS)
goto end;
size = (strlenW(data)+1)*sizeof(WCHAR);
RegSetValueExW(hkey,package->features[i].Feature,0,REG_SZ,
- (LPSTR)data,size);
+ (LPBYTE)data,size);
HeapFree(GetProcessHeap(),0,data);
if (!absent)
{
size = strlenW(package->features[i].Feature_Parent)*sizeof(WCHAR);
RegSetValueExW(hukey,package->features[i].Feature,0,REG_SZ,
- (LPSTR)package->features[i].Feature_Parent,size);
+ (LPBYTE)package->features[i].Feature_Parent,size);
}
else
{
data[0] = 0x6;
strcpyW(&data[1],package->features[i].Feature_Parent);
RegSetValueExW(hukey,package->features[i].Feature,0,REG_SZ,
- (LPSTR)data,size);
+ (LPBYTE)data,size);
HeapFree(GetProcessHeap(),0,data);
}
}
end:
RegCloseKey(hkey);
RegCloseKey(hukey);
- HeapFree(GetProcessHeap(), 0, productcode);
return rc;
}
{
HKEY hkey=0;
LPWSTR buffer = NULL;
- LPWSTR productcode;
UINT rc,i;
DWORD size;
static WCHAR szNONE[] = {0};
'%','s','\\',
'I','n','s','t','a','l','l','e','r','\\',
'%','x','.','m','s','i',0};
- static const WCHAR szLocalPackage[]=
- {'L','o','c','a','l','P','a','c','k','a','g','e',0};
static const WCHAR szUpgradeCode[] =
{'U','p','g','r','a','d','e','C','o','d','e',0};
static const WCHAR modpath_fmt[] =
{'U','n','i','n','s','t','a','l','l','S','t','r','i','n','g',0};
static const WCHAR szEstimatedSize[] =
{'E','s','t','i','m','a','t','e','d','S','i','z','e',0};
- static const WCHAR szInstallDate[] =
- {'I','n','s','t','a','l','l','D','a','t','e',0};
- static const WCHAR szLanguage[] =
- {'L','a','n','g','u','a','g','e',0};
static const WCHAR szProductLanguage[] =
{'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
static const WCHAR szProductVersion[] =
{'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
- static const WCHAR szVersion[] =
- {'V','e','r','s','i','o','n',0};
- static const WCHAR szVersionMajor[] =
- {'V','e','r','s','i','o','n','M','a','j','o','r',0};
- static const WCHAR szVersionMinor[] =
- {'V','e','r','s','i','o','n','M','i','n','o','r',0};
SYSTEMTIME systime;
static const WCHAR date_fmt[] = {'%','i','%','i','%','i',0};
if (!package)
return ERROR_INVALID_HANDLE;
- productcode = load_dynamic_property(package,szProductCode,&rc);
- if (!productcode)
- return rc;
-
- rc = MSIREG_OpenUninstallKey(productcode,&hkey,TRUE);
+ rc = MSIREG_OpenUninstallKey(package->ProductCode,&hkey,TRUE);
if (rc != ERROR_SUCCESS)
goto end;
if (rc != ERROR_SUCCESS)
buffer = szNONE;
size = strlenW(buffer)*sizeof(WCHAR);
- RegSetValueExW(hkey,szRegKeys[i],0,REG_SZ,(LPSTR)buffer,size);
+ RegSetValueExW(hkey,szRegKeys[i],0,REG_SZ,(LPBYTE)buffer,size);
HeapFree(GetProcessHeap(),0,buffer);
i++;
}
rc = 0x1;
size = sizeof(rc);
- RegSetValueExW(hkey,szWindowsInstaler,0,REG_DWORD,(LPSTR)&rc,size);
+ RegSetValueExW(hkey,szWindowsInstaler,0,REG_DWORD,(LPBYTE)&rc,size);
/* copy the package locally */
num = GetTickCount() & 0xffff;
snprintfW(path,sizeof(path)/sizeof(path[0]),installerPathFmt,windir);
create_full_pathW(path);
TRACE("Copying to local package %s\n",debugstr_w(packagefile));
- if (!CopyFileW(package->PackagePath,packagefile,FALSE))
+ if (!CopyFileW(package->msiFilePath,packagefile,FALSE))
ERR("Unable to copy package (%s -> %s) (error %ld)\n",
- debugstr_w(package->PackagePath), debugstr_w(packagefile),
+ debugstr_w(package->msiFilePath), debugstr_w(packagefile),
GetLastError());
size = strlenW(packagefile)*sizeof(WCHAR);
- RegSetValueExW(hkey,szLocalPackage,0,REG_SZ,(LPSTR)packagefile,size);
+ RegSetValueExW(hkey,INSTALLPROPERTY_LOCALPACKAGEW,0,REG_SZ,
+ (LPBYTE)packagefile,size);
/* do ModifyPath and UninstallString */
size = deformat_string(package,modpath_fmt,&buffer);
- RegSetValueExW(hkey,szModifyPath,0,REG_EXPAND_SZ,(LPSTR)buffer,size);
- RegSetValueExW(hkey,szUninstallString,0,REG_EXPAND_SZ,(LPSTR)buffer,size);
+ RegSetValueExW(hkey,szModifyPath,0,REG_EXPAND_SZ,(LPBYTE)buffer,size);
+ RegSetValueExW(hkey,szUninstallString,0,REG_EXPAND_SZ,(LPBYTE)buffer,size);
HeapFree(GetProcessHeap(),0,buffer);
FIXME("Write real Estimated Size when we have it\n");
size = 0;
- RegSetValueExW(hkey,szEstimatedSize,0,REG_DWORD,(LPSTR)&size,sizeof(DWORD));
+ RegSetValueExW(hkey,szEstimatedSize,0,REG_DWORD,(LPBYTE)&size,sizeof(DWORD));
GetLocalTime(&systime);
size = 9*sizeof(WCHAR);
buffer= HeapAlloc(GetProcessHeap(),0,size);
sprintfW(buffer,date_fmt,systime.wYear,systime.wMonth,systime.wDay);
size = strlenW(buffer)*sizeof(WCHAR);
- RegSetValueExW(hkey,szInstallDate,0,REG_SZ,(LPSTR)buffer,size);
+ RegSetValueExW(hkey,INSTALLPROPERTY_INSTALLDATEW,0,REG_SZ,
+ (LPBYTE)buffer,size);
HeapFree(GetProcessHeap(),0,buffer);
buffer = load_dynamic_property(package,szProductLanguage,NULL);
size = atoiW(buffer);
- RegSetValueExW(hkey,szLanguage,0,REG_DWORD, (LPSTR)&size,sizeof(DWORD));
+ RegSetValueExW(hkey,INSTALLPROPERTY_LANGUAGEW,0,REG_DWORD,
+ (LPBYTE)&size,sizeof(DWORD));
HeapFree(GetProcessHeap(),1,buffer);
buffer = load_dynamic_property(package,szProductVersion,NULL);
DWORD vermajor = verdword>>24;
DWORD verminor = (verdword>>16)&0x00FF;
size = sizeof(DWORD);
- RegSetValueExW(hkey,szVersion,0,REG_DWORD,(LPSTR)&verdword,size);
- RegSetValueExW(hkey,szVersionMajor,0,REG_DWORD,(LPSTR)&vermajor,size);
- RegSetValueExW(hkey,szVersionMinor,0,REG_DWORD,(LPSTR)&verminor,size);
+ RegSetValueExW(hkey,INSTALLPROPERTY_VERSIONW,0,REG_DWORD,
+ (LPBYTE)&verdword,size);
+ RegSetValueExW(hkey,INSTALLPROPERTY_VERSIONMAJORW,0,REG_DWORD,
+ (LPBYTE)&vermajor,size);
+ RegSetValueExW(hkey,INSTALLPROPERTY_VERSIONMINORW,0,REG_DWORD,
+ (LPBYTE)&verminor,size);
}
HeapFree(GetProcessHeap(),0,buffer);
HKEY hkey2;
WCHAR squashed[33];
MSIREG_OpenUpgradeCodesKey(upgrade_code, &hkey2, TRUE);
- squash_guid(productcode,squashed);
+ squash_guid(package->ProductCode,squashed);
RegSetValueExW(hkey2, squashed, 0,REG_SZ,NULL,0);
RegCloseKey(hkey2);
MSIREG_OpenUserUpgradeCodesKey(upgrade_code, &hkey2, TRUE);
- squash_guid(productcode,squashed);
+ squash_guid(package->ProductCode,squashed);
RegSetValueExW(hkey2, squashed, 0,REG_SZ,NULL,0);
RegCloseKey(hkey2);
}
end:
- HeapFree(GetProcessHeap(),0,productcode);
RegCloseKey(hkey);
return ERROR_SUCCESS;
'A','F','T','E','R','R','E','B','O','O','T','=','1',' ',
'R','U','N','O','N','C','E','E','N','T','R','Y','=','\"','%','s','\"',0};
WCHAR buffer[256], sysdir[MAX_PATH];
- HKEY hkey,hukey;
- LPWSTR productcode;
+ HKEY hkey;
WCHAR squished_pc[100];
- INT rc;
DWORD size;
- static const WCHAR szLUS[] = {
- 'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
- static const WCHAR szSourceList[] = {
- 'S','o','u','r','c','e','L','i','s','t',0};
- static const WCHAR szPackageName[] = {
- 'P','a','c','k','a','g','e','N','a','m','e',0};
if (!package)
return ERROR_INVALID_HANDLE;
- productcode = load_dynamic_property(package,szProductCode,&rc);
- if (!productcode)
- return rc;
-
- squash_guid(productcode,squished_pc);
+ squash_guid(package->ProductCode,squished_pc);
GetSystemDirectoryW(sysdir, sizeof(sysdir)/sizeof(sysdir[0]));
RegCreateKeyW(HKEY_LOCAL_MACHINE,RunOnce,&hkey);
squished_pc);
size = strlenW(buffer)*sizeof(WCHAR);
- RegSetValueExW(hkey,squished_pc,0,REG_SZ,(LPSTR)buffer,size);
+ RegSetValueExW(hkey,squished_pc,0,REG_SZ,(LPBYTE)buffer,size);
RegCloseKey(hkey);
TRACE("Reboot command %s\n",debugstr_w(buffer));
RegCreateKeyW(HKEY_LOCAL_MACHINE,InstallRunOnce,&hkey);
- sprintfW(buffer,install_fmt,productcode,squished_pc);
+ sprintfW(buffer,install_fmt,package->ProductCode,squished_pc);
size = strlenW(buffer)*sizeof(WCHAR);
- RegSetValueExW(hkey,squished_pc,0,REG_SZ,(LPSTR)buffer,size);
+ RegSetValueExW(hkey,squished_pc,0,REG_SZ,(LPBYTE)buffer,size);
RegCloseKey(hkey);
- rc = MSIREG_OpenUserProductsKey(productcode,&hukey,TRUE);
- if (rc == ERROR_SUCCESS)
- {
- HKEY hukey2;
- LPWSTR buf;
- RegCreateKeyW(hukey, szSourceList, &hukey2);
- buf = load_dynamic_property(package,cszSourceDir,NULL);
- size = strlenW(buf)*sizeof(WCHAR);
- RegSetValueExW(hukey2,szLUS,0,REG_SZ,(LPSTR)buf,size);
- HeapFree(GetProcessHeap(),0,buf);
-
- buf = strrchrW(package->PackagePath,'\\');
- if (buf)
- {
- buf++;
- size = strlenW(buf)*sizeof(WCHAR);
- RegSetValueExW(hukey2,szPackageName,0,REG_SZ,(LPSTR)buf,size);
- }
-
- RegCloseKey(hukey2);
- }
- HeapFree(GetProcessHeap(),0,productcode);
-
return ERROR_INSTALL_SUSPEND;
}
static UINT ACTION_RegisterUser(MSIPACKAGE *package)
{
- static const WCHAR szProductID[]=
- {'P','r','o','d','u','c','t','I','D',0};
HKEY hkey=0;
LPWSTR buffer;
- LPWSTR productcode;
LPWSTR productid;
UINT rc,i;
DWORD size;
if (!package)
return ERROR_INVALID_HANDLE;
- productid = load_dynamic_property(package,szProductID,&rc);
+ productid = load_dynamic_property(package,INSTALLPROPERTY_PRODUCTIDW,
+ &rc);
if (!productid)
return ERROR_SUCCESS;
- productcode = load_dynamic_property(package,szProductCode,&rc);
- if (!productcode)
- return rc;
-
- rc = MSIREG_OpenUninstallKey(productcode,&hkey,TRUE);
+ rc = MSIREG_OpenUninstallKey(package->ProductCode,&hkey,TRUE);
if (rc != ERROR_SUCCESS)
goto end;
if (rc == ERROR_SUCCESS)
{
size = strlenW(buffer)*sizeof(WCHAR);
- RegSetValueExW(hkey,szRegKeys[i],0,REG_SZ,(LPSTR)buffer,size);
+ RegSetValueExW(hkey,szRegKeys[i],0,REG_SZ,(LPBYTE)buffer,size);
}
else
RegSetValueExW(hkey,szRegKeys[i],0,REG_SZ,NULL,0);
}
end:
- HeapFree(GetProcessHeap(),0,productcode);
HeapFree(GetProcessHeap(),0,productid);
RegCloseKey(hkey);
level = load_dynamic_property(package,szUILevel,NULL);
MSI_SetPropertyW(package,szUILevel,szTwo);
+ package->script->InWhatSequence |= SEQUENCE_EXEC;
rc = ACTION_ProcessExecSequence(package,FALSE);
MSI_SetPropertyW(package,szUILevel,level);
HeapFree(GetProcessHeap(),0,level);
TOTAL_SCRIPTS = 3
};
+#define SEQUENCE_UI 0x1
+#define SEQUENCE_EXEC 0x2
+#define SEQUENCE_INSTALL 0x10
+
typedef struct tagMSISCRIPT
{
LPWSTR *Actions[TOTAL_SCRIPTS];
UINT ActionCount[TOTAL_SCRIPTS];
BOOL ExecuteSequenceRun;
- BOOL FindRelatedProductsRun;
BOOL CurrentlyScripting;
+ UINT InWhatSequence;
+ LPWSTR *UniqueActions;
+ UINT UniqueActionsCount;
}MSISCRIPT;
void reduce_to_shortfilename(WCHAR*);
LPWSTR create_component_advertise_string(MSIPACKAGE*, MSICOMPONENT*, LPCWSTR);
void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature);
+UINT register_unique_action(MSIPACKAGE *, LPCWSTR);
+BOOL check_unique_action(MSIPACKAGE *, LPCWSTR);
+WCHAR* generate_error_string(MSIPACKAGE *, UINT, DWORD, ... );
/* control event stuff */
goto end;
}
+ /* bail out if the registry key is empty */
+ if (sz == 0)
+ {
+ rc = ERROR_SUCCESS;
+ goto end;
+ }
+
switch (regType)
{
case REG_SZ:
#include "wine/debug.h"
#include "fdi.h"
#include "msi.h"
+#include "msidefs.h"
#include "msiquery.h"
#include "fcntl.h"
#include "objbase.h"
static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action);
+
+static BOOL check_execution_scheduling_options(MSIPACKAGE *package, LPCWSTR action, UINT options)
+{
+ if (!package->script)
+ return TRUE;
+
+ if ((options & msidbCustomActionTypeClientRepeat) ==
+ msidbCustomActionTypeClientRepeat)
+ {
+ if (!(package->script->InWhatSequence & SEQUENCE_UI &&
+ package->script->InWhatSequence & SEQUENCE_EXEC))
+ {
+ TRACE("Skipping action due to dbCustomActionTypeClientRepeat option.\n");
+ return FALSE;
+ }
+ }
+ else if (options & msidbCustomActionTypeFirstSequence)
+ {
+ if (package->script->InWhatSequence & SEQUENCE_UI &&
+ package->script->InWhatSequence & SEQUENCE_EXEC )
+ {
+ TRACE("Skipping action due to msidbCustomActionTypeFirstSequence option.\n");
+ return FALSE;
+ }
+ }
+ else if (options & msidbCustomActionTypeOncePerProcess)
+ {
+ if (check_unique_action(package,action))
+ {
+ TRACE("Skipping action due to msidbCustomActionTypeOncePerProcess option.\n");
+ return FALSE;
+ }
+ else
+ register_unique_action(package,action);
+ }
+
+ return TRUE;
+}
+
UINT ACTION_CustomAction(MSIPACKAGE *package,LPCWSTR action, BOOL execute)
{
UINT rc = ERROR_SUCCESS;
debugstr_w(source), debugstr_w(target));
/* handle some of the deferred actions */
- if (type & 0x400)
+ if (type & msidbCustomActionTypeTSAware)
+ FIXME("msidbCustomActionTypeTSAware not handled\n");
+
+ if (type & msidbCustomActionTypeInScript)
{
- if (type & 0x100)
+ if (type & msidbCustomActionTypeNoImpersonate)
+ FIXME("msidbCustomActionTypeNoImpersonate not handled\n");
+
+ if (type & msidbCustomActionTypeRollback)
{
FIXME("Rollback only action... rollbacks not supported yet\n");
schedule_action(package, ROLLBACK_SCRIPT, action);
}
if (!execute)
{
- if (type & 0x200)
+ if (type & msidbCustomActionTypeCommit)
{
TRACE("Deferring Commit Action!\n");
schedule_action(package, COMMIT_SCRIPT, action);
static const WCHAR szActionData[] = {
'C','u','s','t','o','m','A','c','t','i','o','n','D','a','t','a',0};
+ static const WCHAR szBlank[] = {0};
LPWSTR actiondata = load_dynamic_property(package,action,NULL);
if (actiondata)
MSI_SetPropertyW(package,szActionData,actiondata);
+ else
+ MSI_SetPropertyW(package,szActionData,szBlank);
}
}
+ else if (!check_execution_scheduling_options(package,action,type))
+ return ERROR_SUCCESS;
switch (type & CUSTOM_ACTION_TYPE_MASK)
{
{
UINT rc = ERROR_SUCCESS;
- if (!(type & 0x80))
+ if (!(type & msidbCustomActionTypeAsync))
{
/* synchronous */
TRACE("Synchronous Execution of action %s\n",debugstr_w(Name));
else
msi_dialog_check_messages(ThreadHandle);
- if (!(type & 0x40))
+ if (!(type & msidbCustomActionTypeContinue))
{
if (ProcessHandle)
rc = process_action_return_value(2,ProcessHandle);
{
TRACE("Asynchronous Execution of action %s\n",debugstr_w(Name));
/* asynchronous */
- if (type & 0x40)
+ if (type & msidbCustomActionTypeContinue)
{
if (ProcessHandle)
{
msi_handler handler;
LPWSTR property;
LPWSTR value;
- IPicture *pic;
+ HBITMAP hBitmap;
HICON hIcon;
+ LPWSTR tabnext;
WCHAR name[1];
};
LPWSTR default_font;
msi_font *font_list;
msi_control *control_list;
+ HWND hWndFocus;
WCHAR name[1];
};
{
msi_control *control;
+ if( !name )
+ return NULL;
for( control = dialog->control_list; control; control = control->next )
if( !strcmpW( control->name, name ) ) /* FIXME: case sensitive? */
break;
control->handler = NULL;
control->property = NULL;
control->value = NULL;
- control->pic = NULL;
+ control->hBitmap = NULL;
control->hIcon = NULL;
+ control->tabnext = strdupW( MSI_RecordGetString( rec, 11) );
x = MSI_RecordGetInteger( rec, 4 );
y = MSI_RecordGetInteger( rec, 5 );
return control;
}
+static MSIRECORD *msi_get_binary_record( MSIDATABASE *db, LPCWSTR name )
+{
+ const static WCHAR query[] = {
+ 's','e','l','e','c','t',' ','*',' ',
+ 'f','r','o','m',' ','B','i','n','a','r','y',' ',
+ 'w','h','e','r','e',' ',
+ '`','N','a','m','e','`',' ','=',' ','\'','%','s','\'',0
+ };
+
+ return MSI_QueryGetRecord( db, query, name );
+}
+
+static LPWSTR msi_create_tmp_path(void)
+{
+ WCHAR tmp[MAX_PATH];
+ LPWSTR path = NULL;
+ static const WCHAR prefix[] = { 'm','s','i',0 };
+ DWORD len, r;
+
+ r = GetTempPathW( MAX_PATH, tmp );
+ if( !r )
+ return path;
+ len = lstrlenW( tmp ) + 20;
+ path = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
+ if( path )
+ {
+ r = GetTempFileNameW( tmp, prefix, 0, path );
+ if (!r)
+ {
+ HeapFree( GetProcessHeap(), 0, path );
+ path = NULL;
+ }
+ }
+ return path;
+}
+
+
+static HANDLE msi_load_image( MSIDATABASE *db, LPCWSTR name, UINT type,
+ UINT cx, UINT cy, UINT flags )
+{
+ MSIRECORD *rec = NULL;
+ HANDLE himage = NULL;
+ LPWSTR tmp;
+ UINT r;
+
+ TRACE("%p %s %u %u %08x\n", db, debugstr_w(name), cx, cy, flags);
+
+ tmp = msi_create_tmp_path();
+ if( !tmp )
+ return himage;
+
+ rec = msi_get_binary_record( db, name );
+ if( rec )
+ {
+ r = MSI_RecordStreamToFile( rec, 2, tmp );
+ if( r == ERROR_SUCCESS )
+ {
+ himage = LoadImageW( 0, tmp, type, cx, cy, flags );
+ DeleteFileW( tmp );
+ }
+ msiobj_release( &rec->hdr );
+ }
+
+ HeapFree( GetProcessHeap(), 0, tmp );
+ return himage;
+}
+
+static HICON msi_load_icon( MSIDATABASE *db, LPCWSTR text, UINT attributes )
+{
+ DWORD cx = 0, cy = 0, flags;
+
+ flags = LR_LOADFROMFILE | LR_DEFAULTSIZE;
+ if( attributes & msidbControlAttributesFixedSize )
+ {
+ flags &= ~LR_DEFAULTSIZE;
+ if( attributes & msidbControlAttributesIconSize16 )
+ {
+ cx += 16;
+ cy += 16;
+ }
+ if( attributes & msidbControlAttributesIconSize32 )
+ {
+ cx += 32;
+ cy += 32;
+ }
+ /* msidbControlAttributesIconSize48 handled by above logic */
+ }
+ return msi_load_image( db, text, IMAGE_ICON, cx, cy, flags );
+}
+
+
/* called from the Control Event subscription code */
void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
LPCWSTR attribute, MSIRECORD *rec )
static UINT msi_dialog_button_control( msi_dialog *dialog, MSIRECORD *rec )
{
msi_control *control;
+ UINT attributes, style;
+ LPCWSTR text;
TRACE("%p %p\n", dialog, rec);
- control = msi_dialog_add_control( dialog, rec, szButton, WS_TABSTOP );
+ style = WS_TABSTOP;
+ attributes = MSI_RecordGetInteger( rec, 8 );
+ if( attributes & msidbControlAttributesIcon )
+ style |= BS_ICON;
+
+ control = msi_dialog_add_control( dialog, rec, szButton, style );
+ if( !control )
+ return ERROR_FUNCTION_FAILED;
+
control->handler = msi_dialog_button_handler;
+ /* set the icon */
+ text = MSI_RecordGetString( rec, 10 );
+ control->hIcon = msi_load_icon( dialog->package->db, text, attributes );
+ if( attributes & msidbControlAttributesIcon )
+ SendMessageW( control->hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM) control->hIcon );
+
return ERROR_SUCCESS;
}
return ERROR_SUCCESS;
}
-static MSIRECORD *msi_get_binary_record( MSIDATABASE *db, LPCWSTR name )
-{
- const static WCHAR query[] = {
- 's','e','l','e','c','t',' ','*',' ',
- 'f','r','o','m',' ','B','i','n','a','r','y',' ',
- 'w','h','e','r','e',' ',
- '`','N','a','m','e','`',' ','=',' ','\'','%','s','\'',0
- };
-
- return MSI_QueryGetRecord( db, query, name );
-}
-
-static UINT msi_load_bitmap( MSIDATABASE *db, LPCWSTR name, IPicture **pic )
-{
- MSIRECORD *rec = NULL;
- IStream *stm = NULL;
- UINT r;
-
- rec = msi_get_binary_record( db, name );
- if( !rec )
- return ERROR_FUNCTION_FAILED;
-
- r = MSI_RecordGetIStream( rec, 2, &stm );
- msiobj_release( &rec->hdr );
- if( r != ERROR_SUCCESS )
- return r;
-
- r = OleLoadPicture( stm, 0, TRUE, &IID_IPicture, (LPVOID*) pic );
- IStream_Release( stm );
- if( FAILED( r ) )
- return ERROR_FUNCTION_FAILED;
-
- return ERROR_SUCCESS;
-}
-
static UINT msi_dialog_bitmap_control( msi_dialog *dialog, MSIRECORD *rec )
{
- IPicture *pic = NULL;
+ UINT cx, cy, flags, style, attributes;
msi_control *control;
- OLE_HANDLE hBitmap = 0;
LPCWSTR text;
- UINT r;
- control = msi_dialog_add_control( dialog, rec, szStatic,
- SS_BITMAP | SS_LEFT | SS_CENTERIMAGE );
- text = MSI_RecordGetString( rec, 10 );
- r = msi_load_bitmap( dialog->package->db, text, &pic );
- if( r == ERROR_SUCCESS )
- {
- r = IPicture_get_Handle( pic, &hBitmap );
- if( SUCCEEDED( r ) )
- SendMessageW( control->hwnd, STM_SETIMAGE, IMAGE_BITMAP, hBitmap );
- control->pic = pic;
- }
-
- return ERROR_SUCCESS;
-}
-
-static LPWSTR msi_create_tmp_path(void)
-{
- WCHAR tmp[MAX_PATH];
- LPWSTR path = NULL;
- static const WCHAR prefix[] = { 'm','s','i',0 };
- DWORD len, r;
+ flags = LR_LOADFROMFILE;
+ style = SS_BITMAP | SS_LEFT | WS_GROUP;
- r = GetTempPathW( MAX_PATH, tmp );
- if( !r )
- return path;
- len = lstrlenW( tmp ) + 20;
- path = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
- if( path )
- {
- r = GetTempFileNameW( tmp, prefix, 0, path );
- if (!r)
- {
- HeapFree( GetProcessHeap(), 0, path );
- path = NULL;
- }
- }
- return path;
-}
-
-static UINT
-msi_load_icon( MSIDATABASE *db, LPCWSTR name, DWORD attributes, HICON *picon )
-{
- UINT r = ERROR_FUNCTION_FAILED;
- LPWSTR tmp;
- MSIRECORD *rec;
- HICON hicon = 0;
-
- TRACE("loading %s\n", debugstr_w( name ) );
-
- tmp = msi_create_tmp_path();
- if( !tmp )
- return r;
-
- rec = msi_get_binary_record( db, name );
- if( rec )
+ attributes = MSI_RecordGetInteger( rec, 8 );
+ if( attributes & msidbControlAttributesFixedSize )
{
- r = MSI_RecordStreamToFile( rec, 2, tmp );
- if( r == ERROR_SUCCESS )
- {
- DWORD cx = 0, cy = 0, flags = LR_LOADFROMFILE | LR_DEFAULTSIZE;
-
- if( attributes & msidbControlAttributesFixedSize )
- {
- flags &= ~LR_DEFAULTSIZE;
- if( attributes & msidbControlAttributesIconSize16 )
- {
- cx += 16;
- cy += 16;
- }
- if( attributes & msidbControlAttributesIconSize32 )
- {
- cx += 32;
- cy += 32;
- }
- /* msidbControlAttributesIconSize48 handled by above logic */
- }
-
- hicon = LoadImageW( 0, tmp, IMAGE_ICON, cx, cy, flags );
- if( hicon )
- *picon = hicon;
- else
- ERR("failed to load icon from %s\n", debugstr_w( tmp ));
- DeleteFileW( tmp );
- }
- msiobj_release( &rec->hdr );
+ flags |= LR_DEFAULTSIZE;
+ style |= SS_CENTERIMAGE;
}
- HeapFree( GetProcessHeap(), 0, tmp );
-
- return r;
+ control = msi_dialog_add_control( dialog, rec, szStatic, style );
+ text = MSI_RecordGetString( rec, 10 );
+ cx = MSI_RecordGetInteger( rec, 6 );
+ cy = MSI_RecordGetInteger( rec, 7 );
+ cx = msi_dialog_scale_unit( dialog, cx );
+ cy = msi_dialog_scale_unit( dialog, cy );
+
+ control->hBitmap = msi_load_image( dialog->package->db, text,
+ IMAGE_BITMAP, cx, cy, flags );
+ if( control->hBitmap )
+ SendMessageW( control->hwnd, STM_SETIMAGE,
+ IMAGE_BITMAP, (LPARAM) control->hBitmap );
+ else
+ ERR("Failed to load bitmap %s\n", debugstr_w(text));
+
+ return ERROR_SUCCESS;
}
static UINT msi_dialog_icon_control( msi_dialog *dialog, MSIRECORD *rec )
{
msi_control *control;
DWORD attributes;
- HICON hIcon = 0;
LPCWSTR text;
- UINT r;
TRACE("\n");
control = msi_dialog_add_control( dialog, rec, szStatic,
SS_ICON | SS_CENTERIMAGE | WS_GROUP );
- text = MSI_RecordGetString( rec, 10 );
+
attributes = MSI_RecordGetInteger( rec, 8 );
- r = msi_load_icon( dialog->package->db, text, attributes, &hIcon );
- if( r == ERROR_SUCCESS )
- {
- r = SendMessageW( control->hwnd, STM_SETICON, (WPARAM) hIcon, 0 );
- control->hIcon = hIcon;
- }
+ text = MSI_RecordGetString( rec, 10 );
+ control->hIcon = msi_load_icon( dialog->package->db, text, attributes );
+ if( control->hIcon )
+ SendMessageW( control->hwnd, STM_SETICON, (WPARAM) control->hIcon, 0 );
else
ERR("Failed to load bitmap %s\n", debugstr_w(text));
return ERROR_SUCCESS;
HeapFree( GetProcessHeap(), 0, val );
}
+/* now move to the next control if necessary */
+static VOID msi_mask_next_control( struct msi_maskedit_info *info, HWND hWnd )
+{
+ HWND hWndNext;
+ UINT len, i;
+
+ for( i=0; i<info->num_groups; i++ )
+ if( info->group[i].hwnd == hWnd )
+ break;
+
+ /* don't move from the last control */
+ if( i >= (info->num_groups-1) )
+ return;
+
+ len = SendMessageW( hWnd, WM_GETTEXTLENGTH, 0, 0 );
+ if( len < info->group[i].len )
+ return;
+
+ hWndNext = GetNextDlgTabItem( GetParent( hWnd ), hWnd, FALSE );
+ SetFocus( hWndNext );
+}
+
static LRESULT WINAPI
MSIMaskedEdit_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
{
case WM_COMMAND:
if (HIWORD(wParam) == EN_CHANGE)
+ {
msi_mask_control_change( info );
+ msi_mask_next_control( info, (HWND) lParam );
+ }
break;
case WM_NCDESTROY:
HeapFree( GetProcessHeap(), 0, info->prop );
sz->cy = rect.bottom - rect.top;
}
+static BOOL msi_control_set_next( msi_control *control, msi_control *next )
+{
+ return SetWindowPos( next->hwnd, control->hwnd, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREDRAW |
+ SWP_NOREPOSITION | SWP_NOSENDCHANGING | SWP_NOSIZE );
+}
+
+static UINT msi_dialog_set_tab_order( msi_dialog *dialog )
+{
+ msi_control *control, *tab_next;
+
+ for( control = dialog->control_list; control; control = control->next )
+ {
+ tab_next = msi_dialog_find_control( dialog, control->tabnext );
+ if( !tab_next )
+ continue;
+ msi_control_set_next( control, tab_next );
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static void msi_dialog_set_first_control( msi_dialog* dialog, LPCWSTR name )
+{
+ msi_control *control;
+
+ control = msi_dialog_find_control( dialog, name );
+ if( control )
+ dialog->hWndFocus = control->hwnd;
+ else
+ dialog->hWndFocus = NULL;
+}
+
static LRESULT msi_dialog_oncreate( HWND hwnd, LPCREATESTRUCTW cs )
{
static const WCHAR df[] = {
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW );
HeapFree( GetProcessHeap(), 0, title );
- msiobj_release( &rec->hdr );
msi_dialog_build_font_list( dialog );
msi_dialog_fill_controls( dialog );
msi_dialog_evaluate_control_conditions( dialog );
+ msi_dialog_set_tab_order( dialog );
+ msi_dialog_set_first_control( dialog, MSI_RecordGetString( rec, 8 ) );
+ msiobj_release( &rec->hdr );
return 0;
}
return 0;
}
+static void msi_dialog_setfocus( msi_dialog *dialog )
+{
+ HWND hwnd = dialog->hWndFocus;
+
+ hwnd = GetNextDlgTabItem( dialog->hwnd, hwnd, TRUE);
+ hwnd = GetNextDlgTabItem( dialog->hwnd, hwnd, FALSE);
+ SetFocus( hwnd );
+ dialog->hWndFocus = hwnd;
+}
+
static LRESULT WINAPI MSIDialog_WndProc( HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam )
{
case WM_COMMAND:
return msi_dialog_oncommand( dialog, wParam, (HWND)lParam );
+ case WM_ACTIVATE:
+ if( LOWORD(wParam) == WA_INACTIVE )
+ dialog->hWndFocus = GetFocus();
+ else
+ msi_dialog_setfocus( dialog );
+ return 0;
+
+ case WM_SETFOCUS:
+ msi_dialog_setfocus( dialog );
+ return 0;
+
/* bounce back to our subclassed static control */
case WM_CTLCOLORSTATIC:
return SendMessageW( (HWND) lParam, WM_CTLCOLORSTATIC, wParam, lParam );
/* leave dialog->hwnd - destroying parent destroys child windows */
HeapFree( GetProcessHeap(), 0, t->property );
HeapFree( GetProcessHeap(), 0, t->value );
- if( t->pic )
- IPicture_Release( t->pic );
+ if( t->hBitmap )
+ DeleteObject( t->hBitmap );
if( t->hIcon )
DestroyIcon( t->hIcon );
+ HeapFree( GetProcessHeap(), 0, t->tabnext );
HeapFree( GetProcessHeap(), 0, t );
}
/*
* Create a dialog box and run it if it's modal
*/
-static UINT event_do_dialog( MSIPACKAGE *package, LPCWSTR name )
+static UINT event_do_dialog( MSIPACKAGE *package, LPCWSTR name, BOOL destroy_modeless )
{
msi_dialog *dialog;
UINT r;
- /* kill the current modeless dialog */
- if( package->dialog )
- msi_dialog_destroy( package->dialog );
- package->dialog = NULL;
-
/* create a new dialog */
dialog = msi_dialog_create( package, name,
ControlEvent_HandleControlEvent );
if( dialog )
{
+ /* kill the current modeless dialog */
+ if( destroy_modeless && package->dialog )
+ {
+ msi_dialog_destroy( package->dialog );
+ package->dialog = NULL;
+ }
+
/* modeless dialogs return an error message */
r = msi_dialog_run_message_loop( dialog );
if( r == ERROR_SUCCESS )
static UINT ControlEvent_SpawnDialog(MSIPACKAGE* package, LPCWSTR argument,
msi_dialog *dialog)
{
- event_do_dialog( package, argument );
+ /* don't destroy a modeless dialogs that might be our parent */
+ event_do_dialog( package, argument, FALSE );
if( package->CurrentInstallState != ERROR_SUCCESS )
msi_dialog_end_dialog( dialog );
return ERROR_SUCCESS;
* dialog, as it returns ERROR_IO_PENDING when we try to run
* its message loop.
*/
- r = event_do_dialog( package, szDialogName );
+ r = event_do_dialog( package, szDialogName, TRUE );
while( r == ERROR_SUCCESS && package->next_dialog )
{
LPWSTR name = package->next_dialog;
package->next_dialog = NULL;
- r = event_do_dialog( package, name );
+ r = event_do_dialog( package, name, TRUE );
HeapFree( GetProcessHeap(), 0, name );
}
#include "winerror.h"
#include "wine/debug.h"
#include "fdi.h"
+#include "msi.h"
#include "msidefs.h"
#include "msvcrt/fcntl.h"
#include "msipriv.h"
file->SourcePath = build_directory_name(2, path, file->File);
}
-static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
+static BOOL check_volume(LPCWSTR path, LPCWSTR want_volume, LPWSTR volume,
+ UINT *intype)
+{
+ WCHAR drive[4];
+ WCHAR name[MAX_PATH];
+ UINT type;
+
+ if (!(path[0] && path[1] == ':'))
+ return TRUE;
+
+ drive[0] = path[0];
+ drive[1] = path[1];
+ drive[2] = '\\';
+ drive[3] = 0;
+ TRACE("Checking volume %s .. (%s)\n",debugstr_w(drive), debugstr_w(want_volume));
+ type = GetDriveTypeW(drive);
+ TRACE("drive is of type %x\n",type);
+
+ if (type == DRIVE_UNKNOWN || type == DRIVE_NO_ROOT_DIR ||
+ type == DRIVE_FIXED || type == DRIVE_RAMDISK)
+ return TRUE;
+
+ GetVolumeInformationW(drive, name, MAX_PATH, NULL, NULL, NULL, NULL, 0);
+ TRACE("Drive contains %s\n", debugstr_w(name));
+ volume = strdupW(name);
+ if (*intype)
+ *intype=type;
+ return (strcmpiW(want_volume,name)==0);
+}
+
+static BOOL check_for_sourcefile(LPCWSTR source)
+{
+ DWORD attrib = GetFileAttributesW(source);
+ return (!(attrib == INVALID_FILE_ATTRIBUTES));
+}
+
+static UINT ready_volume(MSIPACKAGE* package, LPCWSTR path, LPWSTR last_volume,
+ MSIRECORD *row,UINT *type )
+{
+ LPWSTR volume = NULL;
+ LPCWSTR want_volume = MSI_RecordGetString(row, 5);
+ BOOL ok = check_volume(path, want_volume, volume, type);
+
+ TRACE("Readying Volume for %s (%s, %s)\n",debugstr_w(path), debugstr_w(want_volume), debugstr_w(last_volume));
+
+ if (check_for_sourcefile(path) && !ok)
+ {
+ FIXME("Found the Sourcefile but not on the correct volume.(%s,%s,%s)\n",
+ debugstr_w(path),debugstr_w(want_volume), debugstr_w(volume));
+ return ERROR_SUCCESS;
+ }
+
+ while (!ok)
+ {
+ INT rc;
+ LPCWSTR prompt;
+ LPWSTR msg;
+
+ prompt = MSI_RecordGetString(row,3);
+ msg = generate_error_string(package, 1302, 1, prompt);
+ rc = MessageBoxW(NULL,msg,NULL,MB_OKCANCEL);
+ HeapFree(GetProcessHeap(),0,volume);
+ HeapFree(GetProcessHeap(),0,msg);
+ if (rc == IDOK)
+ ok = check_for_sourcefile(path);
+ else
+ return ERROR_INSTALL_USEREXIT;
+ }
+
+ HeapFree(GetProcessHeap(),0,last_volume);
+ last_volume = strdupW(volume);
+ return ERROR_SUCCESS;
+}
+
+static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
MSICOMPONENT* comp)
{
UINT rc = ERROR_SUCCESS;
'`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ','>','=',
' ','%', 'i',' ','O','R','D','E','R',' ','B','Y',' ',
'`','L','a','s','t','S','e','q','u','e','n','c','e','`',0};
- LPCWSTR cab;
+ LPCWSTR cab, volume;
DWORD sz;
INT seq;
static UINT last_sequence = 0;
+ static LPWSTR last_volume = NULL;
static LPWSTR last_path = NULL;
MSIFILE* file = NULL;
+ UINT type;
+ LPCWSTR prompt;
+ static DWORD count = 0;
/* cleanup signal */
if (!package)
{
HeapFree(GetProcessHeap(),0,last_path);
+ HeapFree(GetProcessHeap(),0,last_volume);
+ last_sequence = 0;
+ last_path = NULL;
+ last_volume = NULL;
+ count = 0;
+ memset(source,0,sizeof(source));
return ERROR_SUCCESS;
}
return ERROR_SUCCESS;
}
+ count ++;
row = MSI_QueryGetRecord(package->db, ExecSeqQuery, file->Sequence);
if (!row)
{
seq = MSI_RecordGetInteger(row,2);
last_sequence = seq;
+ volume = MSI_RecordGetString(row, 5);
+ prompt = MSI_RecordGetString(row, 3);
+
HeapFree(GetProcessHeap(),0,last_path);
last_path = NULL;
{
last_path = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL);
set_file_source(package,file,comp,last_path);
+ rc = ready_volume(package, file->SourcePath, last_volume, row,&type);
+
+ MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, count, volume,
+ prompt);
+
+ if (type == DRIVE_REMOVABLE || type == DRIVE_CDROM ||
+ type == DRIVE_RAMDISK)
+ MsiSourceListSetInfoW(package->ProductCode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT|MSISOURCETYPE_MEDIA,
+ INSTALLPROPERTY_LASTUSEDSOURCEW, last_path);
+ else
+ MsiSourceListSetInfoW(package->ProductCode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT|MSISOURCETYPE_NETWORK,
+ INSTALLPROPERTY_LASTUSEDSOURCEW, last_path);
msiobj_release(&row->hdr);
return rc;
}
/* the stream does not contain the # character */
if (cab[0]=='#')
{
+ LPWSTR path;
+
writeout_cabinet_stream(package,&cab[1],source);
last_path = strdupW(source);
*(strrchrW(last_path,'\\')+1)=0;
+
+ path = load_dynamic_property(package,cszSourceDir,NULL);
+
+ MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, count,
+ volume, prompt);
+
+ MsiSourceListSetInfoW(package->ProductCode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT|MSISOURCETYPE_NETWORK,
+ INSTALLPROPERTY_LASTUSEDSOURCEW, path);
+
+ HeapFree(GetProcessHeap(),0,path);
}
else
{
{
strcpyW(last_path,source);
strcatW(source,cab);
+
+ rc = ready_volume(package, source, last_volume, row, &type);
+ if (type == DRIVE_REMOVABLE || type == DRIVE_CDROM ||
+ type == DRIVE_RAMDISK)
+ MsiSourceListSetInfoW(package->ProductCode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT|MSISOURCETYPE_MEDIA,
+ INSTALLPROPERTY_LASTUSEDSOURCEW, last_path);
+ else
+ MsiSourceListSetInfoW(package->ProductCode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT|MSISOURCETYPE_NETWORK,
+ INSTALLPROPERTY_LASTUSEDSOURCEW, last_path);
+
/* extract the cab file into a folder in the temp folder */
sz = MAX_PATH;
if (MSI_GetPropertyW(package, cszTempFolder,last_path, &sz)
last_path = HeapAlloc(GetProcessHeap(),0,MAX_PATH*sizeof(WCHAR));
MSI_GetPropertyW(package,cszSourceDir,source,&sz);
strcpyW(last_path,source);
+ rc = ready_volume(package, last_path, last_volume, row, &type);
+
+ if (type == DRIVE_REMOVABLE || type == DRIVE_CDROM ||
+ type == DRIVE_RAMDISK)
+ MsiSourceListSetInfoW(package->ProductCode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT|MSISOURCETYPE_MEDIA,
+ INSTALLPROPERTY_LASTUSEDSOURCEW, last_path);
+ else
+ MsiSourceListSetInfoW(package->ProductCode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT|MSISOURCETYPE_NETWORK,
+ INSTALLPROPERTY_LASTUSEDSOURCEW, last_path);
}
set_file_source(package, file, comp, last_path);
+
+ MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, count, volume,
+ prompt);
+
msiobj_release(&row->hdr);
return rc;
{
UINT rc = ERROR_SUCCESS;
DWORD index;
+ LPWSTR ptr;
if (!package)
return ERROR_INVALID_HANDLE;
/* increment progress bar each time action data is sent */
ui_progress(package,1,1,0,0);
+ /* handle the keys for the SouceList */
+ ptr = strrchrW(package->PackagePath,'\\');
+ if (ptr)
+ {
+ ptr ++;
+ MsiSourceListSetInfoW(package->ProductCode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT,
+ INSTALLPROPERTY_PACKAGENAMEW, ptr);
+ }
+ FIXME("Write DiskPrompt\n");
+
/* Pass 1 */
for (index = 0; index < package->loaded_files; index++)
{
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};
UINT build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name,
LPWSTR *FilePath)
{
- LPWSTR ProductCode;
LPWSTR SystemFolder;
LPWSTR dest;
- UINT rc;
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);
- 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);
HeapFree(GetProcessHeap(),0,SystemFolder);
- HeapFree(GetProcessHeap(),0,ProductCode);
HeapFree(GetProcessHeap(),0,dest);
return ERROR_SUCCESS;
}
HeapFree(GetProcessHeap(),0,package->script->Actions[i]);
}
+
+ for (i = 0; i < package->script->UniqueActionsCount; i++)
+ HeapFree(GetProcessHeap(),0,package->script->UniqueActions[i]);
+
+ HeapFree(GetProcessHeap(),0,package->script->UniqueActions);
HeapFree(GetProcessHeap(),0,package->script);
}
HeapFree(GetProcessHeap(),0,package->PackagePath);
+ HeapFree(GetProcessHeap(),0,package->msiFilePath);
+ HeapFree(GetProcessHeap(),0,package->ProductCode);
/* cleanup control event subscriptions */
ControlEvent_CleanupSubscriptions(package);
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);
sprintfW(output,fmt2,productid_85,feature,component_85);
else
sprintfW(output,fmt1,productid_85,feature);
-
- HeapFree(GetProcessHeap(),0,productid);
return output;
}
component->Action, component->ActionRequest);
}
}
+
+UINT register_unique_action(MSIPACKAGE *package, LPCWSTR action)
+{
+ UINT count;
+ LPWSTR *newbuf = NULL;
+
+ if (!package || !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 = HeapReAlloc(GetProcessHeap(),0,
+ package->script->UniqueActions,
+ package->script->UniqueActionsCount* sizeof(LPWSTR));
+ else
+ newbuf = HeapAlloc(GetProcessHeap(),0, 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 || !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 = HeapAlloc(GetProcessHeap(),0,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;
+}
msiobj_release( &package->hdr );
return ret;
}
+
+/***********************************************************************
+ * MsiGetLanguage (MSI.@)
+ */
+LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall)
+{
+ MSIPACKAGE* package;
+ LANGID langid;
+ LPWSTR buffer;
+ static const WCHAR szProductLanguage[] =
+ {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
+
+ package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
+ if (!package)
+ return ERROR_INVALID_HANDLE;
+
+ buffer = load_dynamic_property(package,szProductLanguage,NULL);
+ langid = atoiW(buffer);
+
+ HeapFree(GetProcessHeap(),0,buffer);
+ msiobj_release (&package->hdr);
+ return langid;
+}
UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
{
- static const WCHAR szLocalPackage[] = {
- 'L','o','c','a','l','P','a','c','k','a','g','e', 0
- };
LPWSTR path = NULL;
UINT r;
HKEY hKeyProduct = NULL;
/* find the size of the path */
type = count = 0;
- r = RegQueryValueExW( hKeyProduct, szLocalPackage,
+ r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
NULL, &type, NULL, &count );
if( r != ERROR_SUCCESS )
{
if( !path )
goto end;
- r = RegQueryValueExW( hKeyProduct, szLocalPackage,
+ r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
NULL, &type, (LPBYTE) path, &count );
if( r != ERROR_SUCCESS )
{
MSIPACKAGE *package = NULL;
UINT r;
MSIHANDLE handle;
+ WCHAR path[MAX_PATH];
+ WCHAR filename[MAX_PATH];
+ static const WCHAR szMSI[] = {'M','S','I',0};
FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
if (r != ERROR_SUCCESS)
return r;
- r = MSI_OpenPackageW(szPackagePath,&package);
+ /* copy the msi file to a temp file to pervent locking a CD
+ * with a multi disc install
+ */
+ GetTempPathW(MAX_PATH, path);
+ GetTempFileNameW(path, szMSI, 0, filename);
+
+ CopyFileW(szPackagePath, filename, FALSE);
+
+ TRACE("Opening relocated package %s\n",debugstr_w(filename));
+ r = MSI_OpenPackageW(filename, &package);
if (r != ERROR_SUCCESS)
+ {
+ DeleteFileW(filename);
return r;
+ }
handle = alloc_msihandle( &package->hdr );
- r = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine);
+ r = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine,
+ filename);
MsiCloseHandle(handle);
msiobj_release( &package->hdr );
+
+ DeleteFileW(filename);
return r;
}
MSIHANDLE handle = -1;
MSIPACKAGE* package;
UINT rc;
- HKEY hkey=0,hkey1=0;
DWORD sz;
- static const WCHAR szSouceList[] = {
- 'S','o','u','r','c','e','L','i','s','t',0};
- static const WCHAR szLUS[] = {
- 'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
- WCHAR sourcepath[0x200];
+ WCHAR sourcepath[MAX_PATH];
+ WCHAR filename[MAX_PATH];
static const WCHAR szInstalled[] = {
' ','I','n','s','t','a','l','l','e','d','=','1',0};
LPWSTR commandline;
return ERROR_CALL_NOT_IMPLEMENTED;
}
- rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
- if (rc != ERROR_SUCCESS)
- goto end;
+ sz = sizeof(sourcepath);
+ MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
+ &sz);
- rc = RegOpenKeyW(hkey,szSouceList,&hkey1);
- if (rc != ERROR_SUCCESS)
- goto end;
+ sz = sizeof(filename);
+ MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
- sz = sizeof(sourcepath);
- rc = RegQueryValueExW(hkey1, szLUS, NULL, NULL,(LPBYTE)sourcepath, &sz);
- if (rc != ERROR_SUCCESS)
- goto end;
+ strcatW(sourcepath,filename);
- RegCloseKey(hkey1);
/*
* ok 1, we need to find the msi file for this product.
* 2, find the source dir for the files
if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
lstrcatW(commandline,szInstalled);
- rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline);
+ rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline, sourcepath);
msiobj_release( &package->hdr );
HeapFree(GetProcessHeap(),0,commandline);
end:
- RegCloseKey(hkey);
if (handle != -1)
MsiCloseHandle(handle);
{
MSIHANDLE hProduct;
UINT r;
- static const WCHAR szPackageCode[] =
- {'P','a','c','k','a','g','e','C','o','d','e',0};
- static const WCHAR szVersionString[] =
- {'V','e','r','s','i','o','n','S','t','r','i','n','g',0};
static const WCHAR szProductVersion[] =
{'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
- static const WCHAR szAssignmentType[] =
- {'A','s','s','i','g','n','m','e','n','t','T','y','p','e',0};
- static const WCHAR szLanguage[] =
- {'L','a','n','g','u','a','g','e',0};
static const WCHAR szProductLanguage[] =
{'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
return ERROR_INVALID_PARAMETER;
/* check for special properties */
- if (strcmpW(szAttribute, szPackageCode)==0)
+ if (strcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW)==0)
{
HKEY hkey;
WCHAR squished[GUID_SIZE];
if (r != ERROR_SUCCESS)
return ERROR_UNKNOWN_PRODUCT;
- r = RegQueryValueExW(hkey, szPackageCode, NULL, NULL,
+ r = RegQueryValueExW(hkey, INSTALLPROPERTY_PACKAGECODEW, NULL, NULL,
(LPBYTE)squished, &sz);
if (r != ERROR_SUCCESS)
{
RegCloseKey(hkey);
r = ERROR_SUCCESS;
}
- else if (strcmpW(szAttribute, szVersionString)==0)
+ else if (strcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW)==0)
{
r = MsiOpenProductW(szProduct, &hProduct);
if (ERROR_SUCCESS != r)
r = MsiGetPropertyW(hProduct, szProductVersion, szBuffer, pcchValueBuf);
MsiCloseHandle(hProduct);
}
- else if (strcmpW(szAttribute, szAssignmentType)==0)
+ else if (strcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW)==0)
{
FIXME("0 (zero) if advertised or per user , 1(one) if per machine.\n");
if (szBuffer)
*pcchValueBuf = 1;
r = ERROR_SUCCESS;
}
- else if (strcmpW(szAttribute, szLanguage)==0)
+ else if (strcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW)==0)
{
r = MsiOpenProductW(szProduct, &hProduct);
if (ERROR_SUCCESS != r)
INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
DWORD *pcchBuf)
{
- FIXME("%s %p %08lx\n", debugstr_a(szComponent), lpPathBuf, *pcchBuf);
+ FIXME("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
return INSTALLSTATE_UNKNOWN;
}
INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
DWORD *pcchBuf)
{
- FIXME("%s %p %08lx\n", debugstr_w(szComponent), lpPathBuf, *pcchBuf);
+ FIXME("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
return INSTALLSTATE_UNKNOWN;
}
HKEY hkey;
DWORD sz;
UINT rc = ERROR_SUCCESS,rc2 = ERROR_SUCCESS;
- static const WCHAR szOwner[] = {'R','e','g','O','w','n','e','r',0};
- static const WCHAR szCompany[] = {'R','e','g','C','o','m','p','a','n','y',0};
- static const WCHAR szSerial[] = {'P','r','o','d','u','c','t','I','D',0};
TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
if (lpUserNameBuf)
{
sz = *lpUserNameBuf * sizeof(WCHAR);
- rc = RegQueryValueExW( hkey, szOwner, NULL, NULL, (LPBYTE)lpUserNameBuf,
+ rc = RegQueryValueExW( hkey, INSTALLPROPERTY_REGOWNERW, NULL,
+ NULL, (LPBYTE)lpUserNameBuf,
&sz);
}
if (!lpUserNameBuf && pcchUserNameBuf)
{
sz = 0;
- rc = RegQueryValueExW( hkey, szOwner, NULL, NULL, NULL, &sz);
+ rc = RegQueryValueExW( hkey, INSTALLPROPERTY_REGOWNERW, NULL,
+ NULL, NULL, &sz);
}
if (pcchUserNameBuf)
if (lpOrgNameBuf)
{
sz = *pcchOrgNameBuf * sizeof(WCHAR);
- rc2 = RegQueryValueExW( hkey, szCompany, NULL, NULL,
- (LPBYTE)lpOrgNameBuf, &sz);
+ rc2 = RegQueryValueExW( hkey, INSTALLPROPERTY_REGCOMPANYW, NULL,
+ NULL, (LPBYTE)lpOrgNameBuf, &sz);
}
if (!lpOrgNameBuf && pcchOrgNameBuf)
{
sz = 0;
- rc2 = RegQueryValueExW( hkey, szCompany, NULL, NULL, NULL, &sz);
+ rc2 = RegQueryValueExW( hkey, INSTALLPROPERTY_REGCOMPANYW, NULL,
+ NULL, NULL, &sz);
}
if (pcchOrgNameBuf)
if (lpSerialBuf)
{
sz = *pcchSerialBuf * sizeof(WCHAR);
- RegQueryValueExW( hkey, szSerial, NULL, NULL, (LPBYTE)lpSerialBuf,
- &sz);
+ RegQueryValueExW( hkey, INSTALLPROPERTY_PRODUCTIDW, NULL, NULL,
+ (LPBYTE)lpSerialBuf, &sz);
}
if (!lpSerialBuf && pcchSerialBuf)
{
sz = 0;
- rc = RegQueryValueExW( hkey, szSerial, NULL, NULL, NULL, &sz);
+ rc = RegQueryValueExW( hkey, INSTALLPROPERTY_PRODUCTIDW, NULL,
+ NULL, NULL, &sz);
}
if (pcchSerialBuf)
*pcchSerialBuf = sz / sizeof(WCHAR);
60 stdcall MsiGetFeatureUsageW(wstr wstr ptr ptr)\r
61 stub MsiGetFeatureValidStatesA\r
62 stub MsiGetFeatureValidStatesW\r
-63 stub MsiGetLanguage\r
+63 stdcall MsiGetLanguage(long)\r
64 stdcall MsiGetMode(long long)\r
65 stdcall MsiGetProductCodeA(str str)\r
66 stdcall MsiGetProductCodeW(wstr wstr)\r
<file>registry.c</file>
<file>regsvr.c</file>
<file>select.c</file>
+ <file>source.c</file>
<file>sql.tab.c</file>
<file>string.c</file>
<file>suminfo.c</file>
{
UINT magic;
UINT type;
- DWORD refcount;
+ LONG refcount;
msihandledestructor destructor;
struct tagMSIOBJECTHDR *next;
struct tagMSIOBJECTHDR *prev;
UINT RunningActionCount;
LPWSTR PackagePath;
+ LPWSTR msiFilePath;
+ LPWSTR ProductCode;
UINT CurrentInstallState;
msi_dialog *dialog;
/* string table functions */
-extern BOOL msi_addstring( string_table *st, int string_no, const CHAR *data, int len, UINT refcount );
-extern BOOL msi_addstringW( string_table *st, int string_no, const WCHAR *data, int len, UINT refcount );
+extern BOOL msi_addstring( string_table *st, UINT string_no, const CHAR *data, int len, UINT refcount );
+extern BOOL msi_addstringW( string_table *st, UINT string_no, const WCHAR *data, int len, UINT refcount );
extern UINT msi_id2stringW( string_table *st, UINT string_no, LPWSTR buffer, UINT *sz );
extern UINT msi_id2stringA( string_table *st, UINT string_no, LPSTR buffer, UINT *sz );
USHORT **pdata, UINT *psz );
/* action internals */
-extern UINT ACTION_DoTopLevelINSTALL( MSIPACKAGE *, LPCWSTR, LPCWSTR );
+extern UINT ACTION_DoTopLevelINSTALL( MSIPACKAGE *, LPCWSTR, LPCWSTR, LPCWSTR );
extern void ACTION_free_package_structures( MSIPACKAGE* );
extern UINT ACTION_DialogBox( MSIPACKAGE*, LPCWSTR);
MSIDATABASE *db = NULL;
MSIPACKAGE *package;
MSIHANDLE handle;
+ DWORD size;
+ static const WCHAR szProductCode[]= {'P','r','o','d','u','c','t','C','o','d','e',0};
TRACE("%s %p\n", debugstr_w(szPackage), pPackage);
MSI_SetPropertyW( package, Database, szPackage );
}
+ /* this property must exist */
+ size = 0;
+ MSI_GetPropertyW(package,szProductCode,NULL,&size);
+ size ++;
+ package->ProductCode = HeapAlloc(GetProcessHeap(),0,size * sizeof(WCHAR));
+ MSI_GetPropertyW(package,szProductCode,package->ProductCode, &size);
+
*pPackage = package;
return ERROR_SUCCESS;
{
MSIPACKAGE *package = NULL;
UINT ret;
+ WCHAR path[MAX_PATH];
+ WCHAR filename[MAX_PATH];
+ static const WCHAR szMSI[] = {'M','S','I',0};
TRACE("%s %08lx %p\n",debugstr_w(szPackage), dwOptions, phPackage);
+ /* copy the msi file to a temp file to pervent locking a CD
+ * with a multi disc install
+ */
+ if( szPackage[0] == '#' )
+ strcpyW(filename,szPackage);
+ else
+ {
+ GetTempPathW(MAX_PATH, path);
+ GetTempFileNameW(path, szMSI, 0, filename);
+
+ CopyFileW(szPackage, filename, FALSE);
+
+ TRACE("Opening relocated package %s\n",debugstr_w(filename));
+ }
+
if( dwOptions )
FIXME("dwOptions %08lx not supported\n", dwOptions);
- ret = MSI_OpenPackageW( szPackage, &package);
+ ret = MSI_OpenPackageW( filename, &package);
if( ret == ERROR_SUCCESS )
{
*phPackage = alloc_msihandle( &package->hdr );
msiobj_release( &package->hdr );
}
+
+ if( szPackage[0] != '#' )
+ DeleteFileW(filename);
+
return ret;
}
if (NULL != szValueBuf && NULL == pchValueBuf)
return ERROR_INVALID_PARAMETER;
+ /* This was tested against native msi */
+ if (NULL == szValueBuf && NULL != pchValueBuf)
+ *pchValueBuf = 0;
+
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
if (!package)
return ERROR_INVALID_HANDLE;
if (NULL != szValueBuf && NULL == pchValueBuf)
return ERROR_INVALID_PARAMETER;
+ /* This was tested against native msi */
+ if (NULL == szValueBuf && NULL != pchValueBuf)
+ *pchValueBuf = 0;
+
package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
if (!package)
return ERROR_INVALID_HANDLE;
rc = RegEnumValueW(key, iIndex, lpQualifierBuf, pcchQualifierBuf, NULL,
NULL, (LPBYTE)full_buffer, &full_buffer_size);
+ if (rc == ERROR_MORE_DATA)
+ {
+ HeapFree(GetProcessHeap(),0,full_buffer);
+ full_buffer_size+=sizeof(WCHAR);
+ full_buffer = HeapAlloc(GetProcessHeap(),0,full_buffer_size);
+ rc = RegEnumValueW(key, iIndex, lpQualifierBuf, pcchQualifierBuf, NULL,
+ NULL, (LPBYTE)full_buffer, &full_buffer_size);
+ }
+
RegCloseKey(key);
- if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA)
+ if (rc == ERROR_SUCCESS)
{
if (lpApplicationDataBuf && pcchApplicationDataBuf)
{
debugstr_w(lpApplicationDataBuf));
}
+ HeapFree(GetProcessHeap(),0,full_buffer);
+
return rc;
}
--- /dev/null
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2005 Aric Stewart for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winnls.h"
+#include "shlwapi.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+#include "wincrypt.h"
+#include "winver.h"
+#include "winuser.h"
+#include "wine/unicode.h"
+#include "action.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+/*
+ * These apis are defined in MSI 3.0
+ */
+
+typedef struct tagMediaInfo
+{
+ LPWSTR path;
+ WCHAR szIndex[10];
+ WCHAR type;
+} media_info;
+
+static UINT OpenSourceKey(LPCWSTR szProduct, HKEY* key, BOOL user, BOOL create)
+{
+ HKEY rootkey = 0;
+ UINT rc;
+ static const WCHAR szSourceList[] = {'S','o','u','r','c','e','L','i','s','t',0};
+
+ if (user)
+ rc = MSIREG_OpenUserProductsKey(szProduct, &rootkey, create);
+ else
+ rc = MSIREG_OpenProductsKey(szProduct, &rootkey, create);
+
+ if (rc)
+ return rc;
+
+ if (create)
+ rc = RegCreateKeyW(rootkey, szSourceList, key);
+ else
+ rc = RegOpenKeyW(rootkey,szSourceList, key);
+
+ return rc;
+}
+
+static UINT OpenMediaSubkey(HKEY rootkey, HKEY *key, BOOL create)
+{
+ UINT rc;
+ static const WCHAR media[] = {'M','e','d','i','a',0};
+
+ if (create)
+ rc = RegCreateKeyW(rootkey, media, key);
+ else
+ rc = RegOpenKeyW(rootkey,media, key);
+
+ return rc;
+}
+
+static UINT OpenNetworkSubkey(HKEY rootkey, HKEY *key, BOOL create)
+{
+ UINT rc;
+ static const WCHAR net[] = {'N','e','t',0};
+
+ if (create)
+ rc = RegCreateKeyW(rootkey, net, key);
+ else
+ rc = RegOpenKeyW(rootkey, net, key);
+
+ return rc;
+}
+
+static UINT OpenURLSubkey(HKEY rootkey, HKEY *key, BOOL create)
+{
+ UINT rc;
+ static const WCHAR URL[] = {'U','R','L',0};
+
+ if (create)
+ rc = RegCreateKeyW(rootkey, URL, key);
+ else
+ rc = RegOpenKeyW(rootkey, URL, key);
+
+ return rc;
+}
+
+
+static UINT find_given_source(HKEY key, LPCWSTR szSource, media_info *ss)
+{
+ DWORD index = 0;
+ WCHAR szIndex[10];
+ DWORD size;
+ DWORD val_size;
+ LPWSTR val;
+ UINT rc = ERROR_SUCCESS;
+
+ while (rc == ERROR_SUCCESS)
+ {
+ val = NULL;
+ val_size = 0;
+ rc = RegEnumValueW(key, index, szIndex, &size, NULL, NULL, NULL, &val_size);
+ if (rc != ERROR_NO_MORE_ITEMS)
+ {
+ val = HeapAlloc(GetProcessHeap(),0,val_size);
+ RegEnumValueW(key, index, szIndex, &size, NULL, NULL, (LPBYTE)val,
+ &val_size);
+ if (lstrcmpiW(szSource,val)==0)
+ {
+ ss->path = val;
+ strcpyW(ss->szIndex,szIndex);
+ break;
+ }
+ else
+ strcpyW(ss->szIndex,szIndex);
+
+ HeapFree(GetProcessHeap(),0,val);
+ index ++;
+ }
+ }
+ return rc;
+}
+
+/******************************************************************
+ * MsiSourceListGetInfoW (MSI.@)
+ */
+UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
+ MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
+ LPCWSTR szProperty, LPWSTR szValue,
+ LPDWORD pcchValue)
+{
+ HKEY sourcekey;
+ UINT rc;
+
+ TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szProperty));
+
+ if (!szProduct || lstrlenW(szProduct) > 39)
+ return ERROR_INVALID_PARAMETER;
+
+ if (szValue && !pcchValue)
+ return ERROR_INVALID_PARAMETER;
+
+ if (dwOptions == MSICODE_PATCH)
+ {
+ FIXME("Unhandled options MSICODE_PATCH\n");
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ if (szUserSid)
+ FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
+
+ if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
+ FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
+
+ if (dwContext == MSIINSTALLCONTEXT_MACHINE)
+ rc = OpenSourceKey(szProduct, &sourcekey, FALSE, FALSE);
+ else
+ rc = OpenSourceKey(szProduct, &sourcekey, TRUE, FALSE);
+
+ if (rc != ERROR_SUCCESS)
+ return ERROR_UNKNOWN_PRODUCT;
+
+ if (strcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) == 0)
+ {
+ HKEY key;
+ rc = OpenMediaSubkey(sourcekey, &key, FALSE);
+ if (rc == ERROR_SUCCESS)
+ rc = RegQueryValueExW(key, INSTALLPROPERTY_MEDIAPACKAGEPATHW,
+ 0, 0, (LPBYTE)szValue, pcchValue);
+ if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
+ rc = ERROR_UNKNOWN_PROPERTY;
+ RegCloseKey(key);
+ }
+ else if (strcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW) ==0)
+ {
+ HKEY key;
+ rc = OpenMediaSubkey(sourcekey, &key, FALSE);
+ if (rc == ERROR_SUCCESS)
+ rc = RegQueryValueExW(key, INSTALLPROPERTY_DISKPROMPTW, 0, 0,
+ (LPBYTE)szValue, pcchValue);
+ if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
+ rc = ERROR_UNKNOWN_PROPERTY;
+ RegCloseKey(key);
+ }
+ else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)==0)
+ {
+ LPWSTR buffer;
+ DWORD size = 0;
+
+ RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 0,
+ NULL, &size);
+ if (size == 0)
+ rc = ERROR_UNKNOWN_PROPERTY;
+ else
+ {
+ LPWSTR ptr;
+ buffer = HeapAlloc(GetProcessHeap(),0,size);
+ rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
+ 0, 0, (LPBYTE)buffer,&size);
+ ptr = strchrW(buffer,';');
+ if (ptr) ptr = strchrW(ptr+1,';');
+ if (!ptr)
+ rc = ERROR_UNKNOWN_PROPERTY;
+ else
+ {
+ ptr ++;
+ lstrcpynW(szValue, ptr, *pcchValue);
+ if (lstrlenW(ptr) > *pcchValue)
+ {
+ *pcchValue = lstrlenW(ptr)+1;
+ rc = ERROR_MORE_DATA;
+ }
+ else
+ rc = ERROR_SUCCESS;
+ }
+ HeapFree(GetProcessHeap(),0,buffer);
+ }
+ }
+ else if (strcmpW(INSTALLPROPERTY_LASTUSEDTYPEW, szProperty)==0)
+ {
+ LPWSTR buffer;
+ DWORD size = 0;
+
+ RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0, 0,
+ NULL, &size);
+ if (size == 0)
+ rc = ERROR_UNKNOWN_PROPERTY;
+ else
+ {
+ buffer = HeapAlloc(GetProcessHeap(),0,size);
+ rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW,
+ 0, 0, (LPBYTE)buffer,&size);
+ if (*pcchValue < 1)
+ {
+ rc = ERROR_MORE_DATA;
+ *pcchValue = 1;
+ }
+ else
+ {
+ szValue[0] = buffer[0];
+ rc = ERROR_SUCCESS;
+ }
+ HeapFree(GetProcessHeap(),0,buffer);
+ }
+ }
+ else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
+ {
+ rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0, 0,
+ (LPBYTE)szValue, pcchValue);
+ if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
+ rc = ERROR_UNKNOWN_PROPERTY;
+ }
+ else
+ {
+ FIXME("Unknown property %s\n",debugstr_w(szProperty));
+ rc = ERROR_UNKNOWN_PROPERTY;
+ }
+
+ RegCloseKey(sourcekey);
+ return rc;
+}
+
+/******************************************************************
+ * MsiSourceListSetInfoW (MSI.@)
+ */
+UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
+ MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
+ LPCWSTR szProperty, LPCWSTR szValue)
+{
+ HKEY sourcekey;
+ UINT rc;
+
+ TRACE("%s %s %x %lx %s %s\n", debugstr_w(szProduct), debugstr_w(szUserSid),
+ dwContext, dwOptions, debugstr_w(szProperty), debugstr_w(szValue));
+
+ if (!szProduct || lstrlenW(szProduct) > 39)
+ return ERROR_INVALID_PARAMETER;
+
+ if (dwOptions & MSICODE_PATCH)
+ {
+ FIXME("Unhandled options MSICODE_PATCH\n");
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ if (szUserSid)
+ FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
+
+ if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
+ FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
+
+ if (dwContext == MSIINSTALLCONTEXT_MACHINE)
+ rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
+ else
+ rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);
+
+ if (rc != ERROR_SUCCESS)
+ return ERROR_UNKNOWN_PRODUCT;
+
+
+ if (strcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATHW) == 0)
+ {
+ HKEY key;
+ DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
+ rc = OpenMediaSubkey(sourcekey, &key, FALSE);
+ if (rc == ERROR_SUCCESS)
+ rc = RegSetValueExW(key, INSTALLPROPERTY_MEDIAPACKAGEPATHW, 0,
+ REG_SZ, (LPBYTE)szValue, size);
+ if (rc != ERROR_SUCCESS)
+ rc = ERROR_UNKNOWN_PROPERTY;
+ RegCloseKey(key);
+ }
+ else if (strcmpW(szProperty, INSTALLPROPERTY_DISKPROMPTW) == 0)
+ {
+ HKEY key;
+ DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
+ rc = OpenMediaSubkey(sourcekey, &key, FALSE);
+ if (rc == ERROR_SUCCESS)
+ rc = RegSetValueExW(key, INSTALLPROPERTY_DISKPROMPTW, 0,
+ REG_SZ, (LPBYTE)szValue, size);
+ if (rc != ERROR_SUCCESS)
+ rc = ERROR_UNKNOWN_PROPERTY;
+ RegCloseKey(key);
+ }
+ else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCEW)==0)
+ {
+ LPWSTR buffer = NULL;
+ DWORD size;
+ WCHAR typechar = 'n';
+ static const WCHAR LastUsedSource_Fmt[] = {'%','c',';','%','i',';','%','s',0};
+
+ /* make sure the source is registered */
+ MsiSourceListAddSourceExW(szProduct, szUserSid, dwContext,
+ dwOptions, szValue, 0);
+
+ if (dwOptions & MSISOURCETYPE_NETWORK)
+ typechar = 'n';
+ else if (dwOptions & MSISOURCETYPE_URL)
+ typechar = 'u';
+ else if (dwOptions & MSISOURCETYPE_MEDIA)
+ typechar = 'm';
+ else
+ ERR("Unknown source type! 0x%lx\n",dwOptions);
+
+ size = (lstrlenW(szValue)+5)*sizeof(WCHAR);
+ buffer = HeapAlloc(GetProcessHeap(),0,size);
+ sprintfW(buffer, LastUsedSource_Fmt, typechar, 1, szValue);
+ rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCEW, 0,
+ REG_EXPAND_SZ, (LPBYTE)buffer, size);
+ if (rc != ERROR_SUCCESS)
+ rc = ERROR_UNKNOWN_PROPERTY;
+ HeapFree( GetProcessHeap(), 0, buffer );
+ }
+ else if (strcmpW(INSTALLPROPERTY_PACKAGENAMEW, szProperty)==0)
+ {
+ DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
+ rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAMEW, 0,
+ REG_SZ, (LPBYTE)szValue, size);
+ if (rc != ERROR_SUCCESS)
+ rc = ERROR_UNKNOWN_PROPERTY;
+ }
+ else
+ {
+ FIXME("Unknown property %s\n",debugstr_w(szProperty));
+ rc = ERROR_UNKNOWN_PROPERTY;
+ }
+
+ RegCloseKey(sourcekey);
+ return rc;
+
+}
+
+/******************************************************************
+ * MsiSourceListAddSourceExW (MSI.@)
+ */
+UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid,
+ MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCWSTR szSource,
+ DWORD dwIndex)
+{
+ HKEY sourcekey;
+ HKEY typekey;
+ UINT rc;
+ media_info source_struct;
+
+ TRACE("%s, %s, %x, %lx, %s, %li\n", debugstr_w(szProduct),
+ debugstr_w(szUserSid), dwContext, dwOptions, debugstr_w(szSource),
+ dwIndex);
+
+ if (!szProduct)
+ return ERROR_INVALID_PARAMETER;
+
+ if (!szSource)
+ return ERROR_INVALID_PARAMETER;
+
+ if (dwOptions & MSICODE_PATCH)
+ {
+ FIXME("Unhandled options MSICODE_PATCH\n");
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ if (szUserSid)
+ FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
+
+ if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
+ FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
+
+ if (dwContext == MSIINSTALLCONTEXT_MACHINE)
+ rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
+ else
+ rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);
+
+ if (rc != ERROR_SUCCESS)
+ return ERROR_UNKNOWN_PRODUCT;
+
+ if (dwOptions & MSISOURCETYPE_NETWORK)
+ rc = OpenNetworkSubkey(sourcekey, &typekey, TRUE);
+ else if (dwOptions & MSISOURCETYPE_URL)
+ rc = OpenURLSubkey(sourcekey, &typekey, TRUE);
+ else
+ {
+ ERR("Unknown media type!\n");
+ RegCloseKey(sourcekey);
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ source_struct.szIndex[0] = 0;
+ if (find_given_source(typekey, szSource, &source_struct)==ERROR_SUCCESS)
+ {
+ DWORD current_index = atoiW(source_struct.szIndex);
+ /* found the source */
+ if (dwIndex > 0 && current_index != dwIndex)
+ FIXME("Need to reorder the souces! UNHANDLED\n");
+ }
+ else
+ {
+ DWORD current_index = 0;
+ static const WCHAR fmt[] = {'%','i',0};
+ DWORD size = lstrlenW(szSource)*sizeof(WCHAR);
+
+ if (source_struct.szIndex[0])
+ current_index = atoiW(source_struct.szIndex);
+ /* new source */
+ if (dwIndex > 0 && dwIndex < current_index)
+ FIXME("Need to reorder the souces! UNHANDLED\n");
+
+ current_index ++;
+ sprintfW(source_struct.szIndex,fmt,current_index);
+ rc = RegSetValueExW(typekey, source_struct.szIndex, 0, REG_EXPAND_SZ,
+ (LPBYTE)szSource, size);
+ }
+
+ RegCloseKey(typekey);
+ RegCloseKey(sourcekey);
+ return rc;
+}
+
+/******************************************************************
+ * MsiSourceListAddMediaDisk(MSI.@)
+ */
+UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR szProduct, LPCWSTR szUserSid,
+ MSIINSTALLCONTEXT dwContext, DWORD dwOptions, DWORD dwDiskId,
+ LPCWSTR szVolumeLabel, LPCWSTR szDiskPrompt)
+{
+ HKEY sourcekey;
+ HKEY mediakey;
+ UINT rc;
+ WCHAR szIndex[10];
+ static const WCHAR fmt[] = {'%','i',0};
+ static const WCHAR disk_fmt[] = {'%','s',';','%','s',0};
+ static const WCHAR empty[1] = {0};
+ LPCWSTR pt1,pt2;
+ LPWSTR buffer;
+ DWORD size;
+
+ TRACE("%s %s %x %lx %li %s %s\n", debugstr_w(szProduct),
+ debugstr_w(szUserSid), dwContext, dwOptions, dwDiskId,
+ debugstr_w(szVolumeLabel), debugstr_w(szDiskPrompt));
+
+ if (!szProduct || lstrlenW(szProduct) > 39)
+ return ERROR_INVALID_PARAMETER;
+
+ if (dwOptions & MSICODE_PATCH)
+ {
+ FIXME("Unhandled options MSICODE_PATCH\n");
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ if (szUserSid)
+ FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
+
+ if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
+ FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
+
+ if (dwContext == MSIINSTALLCONTEXT_MACHINE)
+ rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
+ else
+ rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);
+
+ if (rc != ERROR_SUCCESS)
+ return ERROR_UNKNOWN_PRODUCT;
+
+ OpenMediaSubkey(sourcekey,&mediakey,TRUE);
+
+ sprintfW(szIndex,fmt,dwDiskId);
+
+ size = 2;
+ if (szVolumeLabel)
+ {
+ size +=lstrlenW(szVolumeLabel);
+ pt1 = szVolumeLabel;
+ }
+ else
+ pt1 = empty;
+ if (szDiskPrompt)
+ {
+ size +=lstrlenW(szDiskPrompt);
+ pt2 = szDiskPrompt;
+ }
+ else
+ pt2 = empty;
+
+ size *=sizeof(WCHAR);
+
+ buffer = HeapAlloc(GetProcessHeap(),0,size);
+ sprintfW(buffer,disk_fmt,pt1,pt2);
+
+ RegSetValueExW(mediakey, szIndex, 0, REG_SZ, (LPBYTE)buffer, size);
+ HeapFree( GetProcessHeap(), 0, buffer );
+
+ RegCloseKey(sourcekey);
+ RegCloseKey(mediakey);
+
+ return ERROR_SUCCESS;
+}
st->freeslot = n + 1;
}
-int msi_addstring( string_table *st, int n, const CHAR *data, int len, UINT refcount )
+int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, UINT refcount )
{
int sz;
return n;
}
-int msi_addstringW( string_table *st, int n, const WCHAR *data, int len, UINT refcount )
+int msi_addstringW( string_table *st, UINT n, const WCHAR *data, int len, UINT refcount )
{
/* TRACE("[%2d] = %s\n", string_no, debugstr_an(data,len) ); */
DWORD len = lstrlenA( str ) + 1;
write_dword( data, ofs, len );
if( data )
- lstrcpyA( &data[ofs + 4], str );
+ memcpy( &data[ofs + 4], str, len );
return (7 + len) & ~3;
}
DWORD sz = 0x100;
HKEY hukey;
INT r;
- static const WCHAR szVersion[] =
- {'V','e','r','s','i','o','n',0};
- static const WCHAR szLanguage[] =
- {'L','a','n','g','u','a','g','e',0};
unsquash_guid(product,productid);
rc = MSIREG_OpenUserProductsKey(productid, &hukey, FALSE);
}
sz = sizeof(DWORD);
- RegQueryValueExW(hukey, szVersion, NULL, NULL, (LPBYTE)&check,
- &sz);
+ RegQueryValueExW(hukey, INSTALLPROPERTY_VERSIONW, NULL, NULL,
+ (LPBYTE)&check, &sz);
/* check min */
ver = MSI_RecordGetString(rec,2);
comp_ver = build_version_dword(ver);
/* check language*/
sz = sizeof(DWORD);
- RegQueryValueExW(hukey, szLanguage, NULL, NULL, (LPBYTE)&check,
- &sz);
+ RegQueryValueExW(hukey, INSTALLPROPERTY_LANGUAGEW, NULL, NULL,
+ (LPBYTE)&check, &sz);
RegCloseKey(hukey);
language = MSI_RecordGetString(rec,4);
TRACE("Checking languages 0x%lx and %s\n", check,
UINT rc = ERROR_SUCCESS;
MSIQUERY *view;
- if (package->script && package->script->FindRelatedProductsRun)
+ if (check_unique_action(package,szFindRelatedProducts))
+ {
+ TRACE("Skipping FindRelatedProducts action: already done on client side\n");
return ERROR_SUCCESS;
+ }
+ else
+ register_unique_action(package,szFindRelatedProducts);
- if (package->script)
- package->script->FindRelatedProductsRun = TRUE;
-
rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
INSTALLTYPE_NETWORK_IMAGE = 1
} INSTALLTYPE;
+typedef enum tagMSIINSTALLCONTEXT
+{
+ MSIINSTALLCONTEXT_FIRSTVISIBLE = 0,
+ MSIINSTALLCONTEXT_NONE = 0,
+ MSIINSTALLCONTEXT_USERMANAGED = 1,
+ MSIINSTALLCONTEXT_USERUNMANAGED = 2,
+ MSIINSTALLCONTEXT_MACHINE = 4,
+ MSIINSTALLCONTEXT_ALL = (MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED | MSIINSTALLCONTEXT_MACHINE),
+ MSIINSTALLCONTEXT_ALLUSERMANAGED= 8,
+} MSIINSTALLCONTEXT;
+
+typedef enum tagMSISOURCETYPE
+{
+ MSISOURCETYPE_UNKNOWN = 0x00000000L,
+ MSISOURCETYPE_NETWORK = 0x00000001L,
+ MSISOURCETYPE_URL = 0x00000002L,
+ MSISOURCETYPE_MEDIA = 0x00000004
+} MSISOURCETYPE;
+
+typedef enum tagMSICODE
+{
+ MSICODE_PRODUCT = 0x00000000L,
+ MSICODE_PATCH = 0x40000000L
+} MSICODE;
+
#define MAX_FEATURE_CHARS 38
+/* Strings defined in msi.h */
+/* Advertised Information */
+
+#define INSTALLPROPERTY_PACKAGENAMEA "PackageName"
+static const WCHAR INSTALLPROPERTY_PACKAGENAMEW[] = {'P','a','c','k','a','g','e','N','a','m','e',0};
+#define INSTALLPROPERTY_PACKAGENAME WINELIB_NAME_AW(INSTALLPROPERTY_PACKAGENAME)
+
+#define INSTALLPROPERTY_TRANSFORMSA "Transforms"
+static const WCHAR INSTALLPROPERTY_TRANSFORMSW[] = {'T','r','a','n','s','f','o','r','m','s',0};
+#define INSTALLPROPERTY_TRANSFORMS WINELIB_NAME_AW(INSTALLPROPERTY_TRANSFORMS)
+
+#define INSTALLPROPERTY_LANGUAGEA "Language"
+static const WCHAR INSTALLPROPERTY_LANGUAGEW[] = {'L','a','n','g','u','a','g','e',0};
+#define INSTALLPROPERTY_LANGUAGE WINELIB_NAME_AW(INSTALLPROPERTY_LANGUAGE)
+
+#define INSTALLPROPERTY_PRODUCTNAMEA "ProductName"
+static const WCHAR INSTALLPROPERTY_PRODUCTNAMEW[] = {'P','r','o','d','u','c','t','N','a','m','e',0};
+#define INSTALLPROPERTY_PRODUCTNAME WINELIB_NAME_AW(INSTALLPROPERTY_PRODUCTNAME)
+
+#define INSTALLPROPERTY_ASSIGNMENTTYPEA "AssignmentType"
+static const WCHAR INSTALLPROPERTY_ASSIGNMENTTYPEW[] = {'A','s','s','i','g','n','m','e','n','t','T','y','p','e',0};
+#define INSTALLPROPERTY_ASSIGNMENTTYPE WINELIB_NAME_AW(INSTALLPROPERTY_ASSIGNMENTTYPE)
+
+#define INSTALLPROPERTY_PACKAGECODEA "PackageCode"
+static const WCHAR INSTALLPROPERTY_PACKAGECODEW[] = {'P','a','c','k','a','g','e','C','o','d','e',0};
+#define INSTALLPROPERTY_PACKAGECODE WINELIB_NAME_AW(INSTALLPROPERTY_PACKAGECODE)
+
+#define INSTALLPROPERTY_VERSIONA "Version"
+static const WCHAR INSTALLPROPERTY_VERSIONW[]= {'V','e','r','s','i','o','n',0};
+#define INSTALLPROPERTY_VERSION WINELIB_NAME_AW(INSTALLPROPERTY_VERSION)
+
+/* MSI version 1.1 and above */
+
+#define INSTALLPROPERTY_PRODUCTICONA "ProductIcon"
+static const WCHAR INSTALLPROPERTY_PRODUCTICONW[] = {'P','r','o','d','u','c','t','I','c','o','n',0};
+#define INSTALLPROPERTY_PRODUCTICON WINELIB_NAME_AW(INSTALLPROPERTY_PRODUCTICON)
+
+/* MSI version 1.5 and above */
+#define INSTALLPROPERTY_INSTANCETYPEA "InstanceType"
+static const WCHAR INSTALLPROPERTY_INSTANCETYPEW[] = {'I','n','s','t','a','n','c','e','T','y','p','e',0};
+#define INSTALLPROPERTY_INSTANCETYPE WINELIB_NAME_AW(INSTALLPROPERTY_INSTANCETYPE)
+
+/* MSI version 3 and above */
+#define INSTALLPROPERTY_AUTHORIZED_LUA_APPA "AuthorizedLUAApp"
+static const WCHAR INSTALLPROPERTY_AUTHORIZED_LUA_APPW[] = {'A','u','t','h','o','r','i','z','e','d','L','U','A','A','p','p',0};
+#define INSTALLPROPERTY_AUTHORIZED_LUA_APP WINELIB_NAME_AW(INSTALLPROPERTY_AUTHORIZED_LUA_APP)
+
+
+/* Installed Information */
+#define INSTALLPROPERTY_INSTALLEDPRODUCTNAMEA "InstalledProductName"
+static const WCHAR INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW[] = {'I','n','s','t','a','l','l','e','d','P','r','o','d','u','c','t','N','a','m','e',0};
+#define INSTALLPROPERTY_INSTALLEDPRODUCTNAME WINELIB_NAME_AW(INSTALLPROPERTY_INSTALLEDPRODUCTNAME)
+
+#define INSTALLPROPERTY_VERSIONSTRINGA "VersionString"
+static const WCHAR INSTALLPROPERTY_VERSIONSTRINGW[] = {'V','e','r','s','i','o','n','S','t','r','i','n','g',0};
+#define INSTALLPROPERTY_VERSIONSTRING WINELIB_NAME_AW(INSTALLPROPERTY_VERSIONSTRING)
+
+#define INSTALLPROPERTY_HELPLINKA "HelpLink"
+static const WCHAR INSTALLPROPERTY_HELPLINKW[] = {'H','e','l','p','L','i','n','k',0};
+#define INSTALLPROPERTY_HELPLINK WINELIB_NAME_AW(INSTALLPROPERTY_HELPLINK)
+
+#define INSTALLPROPERTY_HELPTELEPHONEA "HelpTelephone"
+static const WCHAR INSTALLPROPERTY_HELPTELEPHONEW[] = {'H','e','l','p','T','e','l','e','p','h','o','n','e',0};
+#define INSTALLPROPERTY_HELPTELEPHONE WINELIB_NAME_AW(INSTALLPROPERTY_HELPTELEPHONE)
+
+#define INSTALLPROPERTY_INSTALLLOCATIONA "InstallLocation"
+static const WCHAR INSTALLPROPERTY_INSTALLLOCATIONW[] = {'I','n','s','t','a','l','l','L','o','c','a','t','i','o','n',0};
+#define INSTALLPROPERTY_INSTALLLOCATION WINELIB_NAME_AW(INSTALLPROPERTY_INSTALLLOCATION)
+
+#define INSTALLPROPERTY_INSTALLSOURCEA "InstallSource"
+static const WCHAR INSTALLPROPERTY_INSTALLSOURCEW[] = {'I','n','s','t','a','l','l','S','o','u','r','c','e',0};
+#define INSTALLPROPERTY_INSTALLSOURCE WINELIB_NAME_AW(INSTALLPROPERTY_INSTALLSOURCE)
+
+#define INSTALLPROPERTY_INSTALLDATEA "InstallDate"
+static const WCHAR INSTALLPROPERTY_INSTALLDATEW[] = {'I','n','s','t','a','l','l','D','a','t','e',0};
+#define INSTALLPROPERTY_INSTALLDATE WINELIB_NAME_AW(INSTALLPROPERTY_INSTALLDATE)
+
+#define INSTALLPROPERTY_PUBLISHERA "Publisher"
+static const WCHAR INSTALLPROPERTY_PUBLISHERW[] ={'P','u','b','l','i','s','h','e','r',0};
+#define INSTALLPROPERTY_PUBLISHER WINELIB_NAME_AW(INSTALLPROPERTY_PUBLISHER)
+
+#define INSTALLPROPERTY_LOCALPACKAGEA "LocalPackage"
+static const WCHAR INSTALLPROPERTY_LOCALPACKAGEW[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
+#define INSTALLPROPERTY_LOCALPACKAGE WINELIB_NAME_AW(INSTALLPROPERTY_LOCALPACKAGE)
+
+#define INSTALLPROPERTY_URLINFOABOUTA "URLInfoAbout"
+static const WCHAR INSTALLPROPERTY_URLINFOABOUTW[] = {'U','R','L','I','n','f','o','A','b','o','u','t',0};
+#define INSTALLPROPERTY_URLINFOABOUT WINELIB_NAME_AW(INSTALLPROPERTY_URLINFOABOUT)
+
+#define INSTALLPROPERTY_URLUPDATEINFOA "URLUpdateInfo"
+static const WCHAR INSTALLPROPERTY_URLUPDATEINFOW[] = {'U','R','L','U','p','d','a','t','e','I','n','f','o',0};
+#define INSTALLPROPERTY_URLUPDATEINFO WINELIB_NAME_AW(INSTALLPROPERTY_URLUPDATEINFO)
+
+#define INSTALLPROPERTY_VERSIONMINORA "VersionMinor"
+static const WCHAR INSTALLPROPERTY_VERSIONMINORW[] = {'V','e','r','s','i','o','n','M','i','n','o','r',0};
+#define INSTALLPROPERTY_VERSIONMINOR WINELIB_NAME_AW(INSTALLPROPERTY_VERSIONMINOR)
+
+#define INSTALLPROPERTY_VERSIONMAJORA "VersionMajor"
+static const WCHAR INSTALLPROPERTY_VERSIONMAJORW[] = {'V','e','r','s','i','o','n','M','a','j','o','r',0};
+#define INSTALLPROPERTY_VERSIONMAJOR WINELIB_NAME_AW(INSTALLPROPERTY_VERSIONMAJOR)
+
+#define INSTALLPROPERTY_PRODUCTIDA "ProductID"
+static const WCHAR INSTALLPROPERTY_PRODUCTIDW[] = {'P','r','o','d','u','c','t','I','D',0};
+#define INSTALLPROPERTY_PRODUCTID WINELIB_NAME_AW(INSTALLPROPERTY_PRODUCTID)
+
+#define INSTALLPROPERTY_REGCOMPANYA "RegCompany"
+static const WCHAR INSTALLPROPERTY_REGCOMPANYW[] = {'R','e','g','C','o','m','p','a','n','y',0};
+#define INSTALLPROPERTY_REGCOMPANY WINELIB_NAME_AW(INSTALLPROPERTY_REGCOMPANY)
+
+#define INSTALLPROPERTY_REGOWNERA "RegOwner"
+static const WCHAR INSTALLPROPERTY_REGOWNERW[] = {'R','e','g','O','w','n','e','r',0};
+#define INSTALLPROPERTY_REGOWNER WINELIB_NAME_AW(INSTALLPROPERTY_REGOWNER)
+
+/* MSI Version 3.0 and greater */
+#define INSTALLPROPERTY_UNINSTALLABLEA "Uninstallable"
+static const WCHAR INSTALLPROPERTY_UNINSTALLABLEW[] = {'U','n','i','n','s','t','a','l','l','a','b','l','e',0};
+#define INSTALLPROPERTY_UNINSTALLABLE WINELIB_NAME_AW(INSTALLPROPERTY_UNINSTALLABLE)
+
+#define INSTALLPROPERTY_PRODUCTSTATEA "State"
+static const WCHAR INSTALLPROPERTY_PRODUCTSTATEW[] = {'S','t','a','t','e',0};
+#define INSTALLPROPERTY_PRODUCTSTATE WINELIB_NAME_AW(INSTALLPROPERTY_PRODUCTSTATE)
+
+#define INSTALLPROPERTY_PATCHSTATEA "State"
+static const WCHAR INSTALLPROPERTY_PATCHSTATEW[] ={'S','t','a','t','e',0};
+#define INSTALLPROPERTY_PATCHSTATE WINELIB_NAME_AW(INSTALLPROPERTY_PATCHSTATE)
+
+#define INSTALLPROPERTY_PATCHTYPEA "PatchType"
+static const WCHAR INSTALLPROPERTY_PATCHTYPEW[] = {'P','a','t','c','h','T','y','p','e',0};
+#define INSTALLPROPERTY_PATCHTYPE WINELIB_NAME_AW(INSTALLPROPERTY_PATCHTYPE)
+
+#define INSTALLPROPERTY_LUAENABLEDA "LUAEnabled"
+static const WCHAR INSTALLPROPERTY_LUAENABLEDW[] = {'L','U','A','E','n','a','b','l','e','d',0};
+#define INSTALLPROPERTY_LUAENABLED WINELIB_NAME_AW(INSTALLPROPERTY_LUAENABLED)
+
+#define INSTALLPROPERTY_DISPLAYNAMEA "DisplayName"
+static const WCHAR INSTALLPROPERTY_DISPLAYNAMEW[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
+#define INSTALLPROPERTY_DISPLAYNAME WINELIB_NAME_AW(INSTALLPROPERTY_DISPLAYNAME)
+
+#define INSTALLPROPERTY_MOREINFOURLA "MoreInfoURL"
+static const WCHAR INSTALLPROPERTY_MOREINFOURLW[] = {'M','o','r','e','I','n','f','o','U','R','L',0};
+#define INSTALLPROPERTY_MOREINFOURL WINELIB_NAME_AW(INSTALLPROPERTY_MOREINFOURL)
+
+/* Source List Info */
+#define INSTALLPROPERTY_LASTUSEDSOURCEA "LastUsedSource"
+static const WCHAR INSTALLPROPERTY_LASTUSEDSOURCEW[] = {'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
+#define INSTALLPROPERTY_LASTUSEDSOURCE WINELIB_NAME_AW(INSTALLPROPERTY_LASTUSEDSOURCEW)
+
+#define INSTALLPROPERTY_LASTUSEDTYPEA "LastUsedType"
+static const WCHAR INSTALLPROPERTY_LASTUSEDTYPEW[] = {'L','a','s','t','U','s','e','d','T','y','p','e',0};
+#define INSTALLPROPERTY_LASTUSEDTYPE WINELIB_NAME_AW(INSTALLPROPERTY_LASTUSEDTYPE)
+
+#define INSTALLPROPERTY_MEDIAPACKAGEPATHA "MediaPackagePath"
+static const WCHAR INSTALLPROPERTY_MEDIAPACKAGEPATHW[] = {'M','e','d','i','a','P','a','c','k','a','g','e','P','a','t','h',0};
+#define INSTALLPROPERTY_MEDIAPACKAGEPATH WINELIB_NAME_AW(INSTALLPROPERTY_MEDIAPACKAGEPATH)
+
+#define INSTALLPROPERTY_DISKPROMPTA "DiskPrompt"
+static const WCHAR INSTALLPROPERTY_DISKPROMPTW[] = {'D','i','s','k','P','r','o','m','p','t',0};
+#define INSTALLPROPERTY_DISKPROMPT WINELIB_NAME_AW(INSTALLPROPERTY_DISKPROMPT)
+
typedef INT (CALLBACK *INSTALLUI_HANDLERA)(LPVOID, UINT, LPCSTR);
typedef INT (CALLBACK *INSTALLUI_HANDLERW)(LPVOID, UINT, LPCWSTR);
UINT WINAPI MsiEnumClientsW(LPCWSTR, DWORD, LPWSTR);
#define MsiEnumClients WINELIB_NAME_AW(MsiEnumClients)
-UINT WINAPI MsiOpenDatabaseA(LPCSTR, LPCSTR, MSIHANDLE *);
-UINT WINAPI MsiOpenDatabaseW(LPCWSTR, LPCWSTR, MSIHANDLE *);
-#define MsiOpenDatabase WINELIB_NAME_AW(MsiOpenDatabase)
-
UINT WINAPI MsiOpenPackageA(LPCSTR, MSIHANDLE*);
UINT WINAPI MsiOpenPackageW(LPCWSTR, MSIHANDLE*);
#define MsiOpenPackage WINELIB_NAME_AW(MsiOpenPackage)
UINT WINAPI MsiGetProductPropertyW(MSIHANDLE,LPCWSTR,LPWSTR,DWORD*);
#define MsiGetProductProperty WINELIB_NAME_AW(MsiGetProductProperty)
-UINT WINAPI MsiGetPropertyA(MSIHANDLE, LPCSTR, LPSTR, DWORD*);
-UINT WINAPI MsiGetPropertyW(MSIHANDLE, LPCWSTR, LPWSTR, DWORD*);
-#define MsiGetProperty WINELIB_NAME_AW(MsiGetProperty)
-
UINT WINAPI MsiVerifyPackageA(LPCSTR);
UINT WINAPI MsiVerifyPackageW(LPCWSTR);
#define MsiVerifyPackage WINELIB_NAME_AW(MsiVerifyPackage)
INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR, LPWSTR, DWORD *);
#define MsiLocateComponent WINELIB_NAME_AW(MsiLocateComponent)
+UINT WINAPI MsiSourceListGetInfoA(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
+UINT WINAPI MsiSourceListGetInfoW(LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, DWORD, LPCWSTR, LPWSTR, LPDWORD);
+#define MsiSourceListGetInfo WINELIB_NAME_AW(MsiSourceListGetInfo)
+
+UINT WINAPI MsiSourceListSetInfoA(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPCSTR);
+UINT WINAPI MsiSourceListSetInfoW(LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, DWORD, LPCWSTR, LPCWSTR);
+#define MsiSourceListSetInfo WINELIB_NAME_AW(MsiSourceListSetInfo)
+
+UINT WINAPI MsiSourceListAddSourceExA(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, DWORD);
+UINT WINAPI MsiSourceListAddSourceExW(LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, DWORD, LPCWSTR, DWORD);
+#define MsiSourceListAddSourceEx WINELIB_NAME_AW(MsiSourceListAddSourceEx)
+
+UINT WINAPI MsiSourceListAddMediaDiskA(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPCSTR, LPCSTR);
+UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPCWSTR, LPCWSTR);
+#define MsiSourceListAddMediaDisk WINELIB_NAME_AW(MsiSourceListAddMediaDisk)
+
/* Non Unicode */
UINT WINAPI MsiCloseHandle(MSIHANDLE);
UINT WINAPI MsiCloseAllHandles(void);