static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
+static UINT msi_locate_product(LPCWSTR szProduct, MSIINSTALLCONTEXT *context)
+{
+ HKEY hkey = NULL;
+
+ *context = MSIINSTALLCONTEXT_NONE;
+
+ if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
+ &hkey, FALSE) == ERROR_SUCCESS)
+ *context = MSIINSTALLCONTEXT_USERMANAGED;
+ else if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
+ &hkey, FALSE) == ERROR_SUCCESS)
+ *context = MSIINSTALLCONTEXT_MACHINE;
+ else if (MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ &hkey, FALSE) == ERROR_SUCCESS)
+ *context = MSIINSTALLCONTEXT_USERUNMANAGED;
+
+ RegCloseKey(hkey);
+
+ if (*context == MSIINSTALLCONTEXT_NONE)
+ return ERROR_UNKNOWN_PRODUCT;
+
+ return ERROR_SUCCESS;
+}
+
UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
{
UINT r;
return r;
}
-static UINT MSI_OpenProductW( LPCWSTR szProduct, MSIPACKAGE **ppackage )
+static UINT MSI_OpenProductW(LPCWSTR szProduct, MSIPACKAGE **package)
{
- LPWSTR path = NULL;
UINT r;
- HKEY hKeyProduct = NULL;
- DWORD count, type;
+ HKEY props;
+ LPWSTR path;
+ MSIINSTALLCONTEXT context;
- TRACE("%s %p\n", debugstr_w(szProduct), ppackage );
+ static const WCHAR managed[] = {
+ 'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0};
+ static const WCHAR local[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
- r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
- if( r != ERROR_SUCCESS )
- {
- r = ERROR_UNKNOWN_PRODUCT;
- goto end;
- }
+ TRACE("%s %p\n", debugstr_w(szProduct), package);
- /* find the size of the path */
- type = count = 0;
- r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
- NULL, &type, NULL, &count );
- if( r != ERROR_SUCCESS )
- {
- r = ERROR_UNKNOWN_PRODUCT;
- goto end;
- }
+ r = msi_locate_product(szProduct, &context);
+ if (r != ERROR_SUCCESS)
+ return r;
- /* now alloc and fetch the path of the database to open */
- path = msi_alloc( count );
- if( !path )
- goto end;
+ r = MSIREG_OpenInstallProps(szProduct, context, NULL, &props, FALSE);
+ if (r != ERROR_SUCCESS)
+ return ERROR_UNKNOWN_PRODUCT;
+
+ if (context == MSIINSTALLCONTEXT_USERMANAGED)
+ path = msi_reg_get_val_str(props, managed);
+ else
+ path = msi_reg_get_val_str(props, local);
- r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
- NULL, &type, (LPBYTE) path, &count );
- if( r != ERROR_SUCCESS )
+ r = ERROR_UNKNOWN_PRODUCT;
+
+ if (!path || GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
+ goto done;
+
+ if (PathIsRelativeW(path))
{
- r = ERROR_UNKNOWN_PRODUCT;
- goto end;
+ r = ERROR_INSTALL_PACKAGE_OPEN_FAILED;
+ goto done;
}
- r = MSI_OpenPackageW( path, ppackage );
-
-end:
- msi_free( path );
- if( hKeyProduct )
- RegCloseKey( hKeyProduct );
+ r = MSI_OpenPackageW(path, package);
+done:
+ RegCloseKey(props);
+ msi_free(path);
return r;
}
-UINT WINAPI MsiOpenProductW( LPCWSTR szProduct, MSIHANDLE *phProduct )
+UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
{
- MSIPACKAGE *package = NULL;
- UINT r;
+ MSIPACKAGE *package = NULL;
+ WCHAR squished_pc[GUID_SIZE];
+ UINT r;
- r = MSI_OpenProductW( szProduct, &package );
- if( r == ERROR_SUCCESS )
- {
- *phProduct = alloc_msihandle( &package->hdr );
- if (! *phProduct)
- r = ERROR_NOT_ENOUGH_MEMORY;
- msiobj_release( &package->hdr );
- }
- return r;
+ if (!szProduct || !squash_guid(szProduct, squished_pc))
+ return ERROR_INVALID_PARAMETER;
+
+ if (!phProduct)
+ return ERROR_INVALID_PARAMETER;
+
+ r = MSI_OpenProductW(szProduct, &package);
+ if (r != ERROR_SUCCESS)
+ return r;
+
+ *phProduct = alloc_msihandle(&package->hdr);
+ if (!*phProduct)
+ r = ERROR_NOT_ENOUGH_MEMORY;
+
+ msiobj_release(&package->hdr);
+ return r;
}
UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
+ if (!szPackagePath)
+ return ERROR_INVALID_PARAMETER;
+
+ if (!*szPackagePath)
+ return ERROR_PATH_NOT_FOUND;
+
r = MSI_OpenPackageW( szPackagePath, &package );
if (r == ERROR_SUCCESS)
{
UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
{
- FIXME("%s %08x\n", debugstr_a(szProduct), dwReinstallMode);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ LPWSTR wszProduct;
+ UINT rc;
+
+ TRACE("%s %08x\n", debugstr_a(szProduct), dwReinstallMode);
+
+ wszProduct = strdupAtoW(szProduct);
+
+ rc = MsiReinstallProductW(wszProduct, dwReinstallMode);
+
+ msi_free(wszProduct);
+ return rc;
}
UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
{
- FIXME("%s %08x\n", debugstr_w(szProduct), dwReinstallMode);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ TRACE("%s %08x\n", debugstr_w(szProduct), dwReinstallMode);
+
+ return MsiReinstallFeatureW(szProduct, szAll, dwReinstallMode);
}
UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
return r;
}
-UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
- INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
+static UINT get_patch_product_codes( LPCWSTR szPatchPackage, WCHAR **product_codes )
{
- MSIHANDLE patch, info;
+ MSIHANDLE patch, info = 0;
UINT r, type;
- DWORD size = 0;
- LPCWSTR cmd_ptr = szCommandLine;
- LPWSTR beg, end;
- LPWSTR cmd = NULL, codes = NULL;
-
- static const WCHAR space[] = {' ',0};
- static const WCHAR patcheq[] = {'P','A','T','C','H','=',0};
+ DWORD size;
static WCHAR empty[] = {0};
+ WCHAR *codes;
- TRACE("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
- eInstallType, debugstr_w(szCommandLine));
-
- if (szInstallPackage || eInstallType == INSTALLTYPE_NETWORK_IMAGE ||
- eInstallType == INSTALLTYPE_SINGLE_INSTANCE)
- {
- FIXME("Only reading target products from patch\n");
- return ERROR_CALL_NOT_IMPLEMENTED;
- }
-
- r = MsiOpenDatabaseW(szPatchPackage, MSIDBOPEN_READONLY, &patch);
+ r = MsiOpenDatabaseW( szPatchPackage, MSIDBOPEN_READONLY, &patch );
if (r != ERROR_SUCCESS)
return r;
- r = MsiGetSummaryInformationW(patch, NULL, 0, &info);
+ r = MsiGetSummaryInformationW( patch, NULL, 0, &info );
if (r != ERROR_SUCCESS)
goto done;
- r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, empty, &size);
+ size = 0;
+ r = MsiSummaryInfoGetPropertyW( info, PID_TEMPLATE, &type, NULL, NULL, empty, &size );
if (r != ERROR_MORE_DATA || !size || type != VT_LPSTR)
{
ERR("Failed to read product codes from patch\n");
+ r = ERROR_FUNCTION_FAILED;
goto done;
}
- codes = msi_alloc(++size * sizeof(WCHAR));
+ codes = msi_alloc( ++size * sizeof(WCHAR) );
if (!codes)
{
r = ERROR_OUTOFMEMORY;
goto done;
}
- r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, codes, &size);
+ r = MsiSummaryInfoGetPropertyW( info, PID_TEMPLATE, &type, NULL, NULL, codes, &size );
if (r != ERROR_SUCCESS)
- goto done;
+ msi_free( codes );
+ else
+ *product_codes = codes;
+
+done:
+ MsiCloseHandle( info );
+ MsiCloseHandle( patch );
+ return r;
+}
+
+static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWSTR szCommandLine)
+{
+ UINT r;
+ DWORD size;
+ LPCWSTR cmd_ptr = szCommandLine;
+ LPWSTR beg, end, cmd, codes = NULL;
+ BOOL succeeded = FALSE;
+
+ static const WCHAR patcheq[] = {'P','A','T','C','H','=',0};
+ static WCHAR empty[] = {0};
+
+ if (!szPatchPackage || !szPatchPackage[0])
+ return ERROR_INVALID_PARAMETER;
+
+ if (!szProductCode && (r = get_patch_product_codes( szPatchPackage, &codes )))
+ return r;
if (!szCommandLine)
cmd_ptr = empty;
cmd = msi_alloc(size * sizeof(WCHAR));
if (!cmd)
{
- r = ERROR_OUTOFMEMORY;
- goto done;
+ msi_free(codes);
+ return ERROR_OUTOFMEMORY;
}
lstrcpyW(cmd, cmd_ptr);
- if (szCommandLine) lstrcatW(cmd, space);
+ if (szCommandLine) lstrcatW(cmd, szSpace);
lstrcatW(cmd, patcheq);
lstrcatW(cmd, szPatchPackage);
- beg = codes;
- while ((end = strchrW(beg, '}')))
+ if (szProductCode)
+ r = MsiConfigureProductExW(szProductCode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd);
+ else
{
- *(end + 1) = '\0';
-
- r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd);
- if (r != ERROR_SUCCESS)
- goto done;
+ beg = codes;
+ while ((end = strchrW(beg, '}')))
+ {
+ *(end + 1) = '\0';
+ r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd);
+ if (r == ERROR_SUCCESS)
+ {
+ TRACE("patch applied\n");
+ succeeded = TRUE;
+ }
+ beg = end + 2;
+ }
- beg = end + 2;
+ if (succeeded)
+ r = ERROR_SUCCESS;
}
-done:
msi_free(cmd);
msi_free(codes);
+ return r;
+}
+
+UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
+ INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
+{
+ TRACE("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
+ eInstallType, debugstr_w(szCommandLine));
+
+ if (szInstallPackage || eInstallType == INSTALLTYPE_NETWORK_IMAGE ||
+ eInstallType == INSTALLTYPE_SINGLE_INSTANCE)
+ {
+ FIXME("Only reading target products from patch\n");
+ return ERROR_CALL_NOT_IMPLEMENTED;
+ }
+
+ return MSI_ApplyPatchW(szPatchPackage, NULL, szCommandLine);
+}
+
+UINT WINAPI MsiApplyMultiplePatchesA(LPCSTR szPatchPackages,
+ LPCSTR szProductCode, LPCSTR szPropertiesList)
+{
+ LPWSTR patch_packages = NULL;
+ LPWSTR product_code = NULL;
+ LPWSTR properties_list = NULL;
+ UINT r = ERROR_OUTOFMEMORY;
+
+ TRACE("%s %s %s\n", debugstr_a(szPatchPackages), debugstr_a(szProductCode),
+ debugstr_a(szPropertiesList));
+
+ if (!szPatchPackages || !szPatchPackages[0])
+ return ERROR_INVALID_PARAMETER;
+
+ if (!(patch_packages = strdupAtoW(szPatchPackages)))
+ return ERROR_OUTOFMEMORY;
+
+ if (szProductCode && !(product_code = strdupAtoW(szProductCode)))
+ goto done;
+
+ if (szPropertiesList && !(properties_list = strdupAtoW(szPropertiesList)))
+ goto done;
- MsiCloseHandle(info);
- MsiCloseHandle(patch);
+ r = MsiApplyMultiplePatchesW(patch_packages, product_code, properties_list);
+
+done:
+ msi_free(patch_packages);
+ msi_free(product_code);
+ msi_free(properties_list);
return r;
}
+UINT WINAPI MsiApplyMultiplePatchesW(LPCWSTR szPatchPackages,
+ LPCWSTR szProductCode, LPCWSTR szPropertiesList)
+{
+ UINT r = ERROR_SUCCESS;
+ LPCWSTR beg, end;
+
+ TRACE("%s %s %s\n", debugstr_w(szPatchPackages), debugstr_w(szProductCode),
+ debugstr_w(szPropertiesList));
+
+ if (!szPatchPackages || !szPatchPackages[0])
+ return ERROR_INVALID_PARAMETER;
+
+ beg = end = szPatchPackages;
+ while (*beg)
+ {
+ DWORD len;
+ LPWSTR patch;
+
+ while (*beg == ' ') beg++;
+ while (*end && *end != ';') end++;
+
+ len = end - beg;
+ while (len && beg[len - 1] == ' ') len--;
+
+ if (!len) return ERROR_INVALID_NAME;
+
+ patch = msi_alloc((len + 1) * sizeof(WCHAR));
+ if (!patch)
+ return ERROR_OUTOFMEMORY;
+
+ memcpy(patch, beg, len * sizeof(WCHAR));
+ patch[len] = '\0';
+
+ r = MSI_ApplyPatchW(patch, szProductCode, szPropertiesList);
+ msi_free(patch);
+
+ if (r != ERROR_SUCCESS)
+ break;
+
+ beg = ++end;
+ }
+ return r;
+}
+
+UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
+ DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
+{
+ UINT i, r;
+ WCHAR *package_path = NULL;
+ MSIPATCHSEQUENCEINFOW *psi;
+
+ TRACE("(%s, %d, %p)\n", debugstr_a(szProductPackagePath), cPatchInfo, pPatchInfo);
+
+ if (szProductPackagePath && !(package_path = strdupAtoW( szProductPackagePath )))
+ return ERROR_OUTOFMEMORY;
+
+ psi = msi_alloc( cPatchInfo * sizeof(*psi) );
+ if (!psi)
+ {
+ msi_free( package_path );
+ return ERROR_OUTOFMEMORY;
+ }
+
+ for (i = 0; i < cPatchInfo; i++)
+ {
+ psi[i].szPatchData = strdupAtoW( pPatchInfo[i].szPatchData );
+ psi[i].ePatchDataType = pPatchInfo[i].ePatchDataType;
+ }
+
+ r = MsiDetermineApplicablePatchesW( package_path, cPatchInfo, psi );
+ if (r == ERROR_SUCCESS)
+ {
+ for (i = 0; i < cPatchInfo; i++)
+ {
+ pPatchInfo[i].dwOrder = psi[i].dwOrder;
+ pPatchInfo[i].uStatus = psi[i].uStatus;
+ }
+ }
+
+ msi_free( package_path );
+ for (i = 0; i < cPatchInfo; i++)
+ msi_free( (WCHAR *)psi[i].szPatchData );
+ msi_free( psi );
+ return r;
+}
+
+static UINT MSI_ApplicablePatchW( MSIPACKAGE *package, LPCWSTR patch )
+{
+ MSISUMMARYINFO *si;
+ MSIDATABASE *patch_db;
+ UINT r = ERROR_SUCCESS;
+
+ r = MSI_OpenDatabaseW( patch, MSIDBOPEN_READONLY, &patch_db );
+ if (r != ERROR_SUCCESS)
+ {
+ WARN("failed to open patch file %s\n", debugstr_w(patch));
+ return r;
+ }
+
+ si = MSI_GetSummaryInformationW( patch_db->storage, 0 );
+ if (!si)
+ {
+ msiobj_release( &patch_db->hdr );
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ r = msi_check_patch_applicable( package, si );
+ if (r != ERROR_SUCCESS)
+ TRACE("patch not applicable\n");
+
+ msiobj_release( &patch_db->hdr );
+ msiobj_release( &si->hdr );
+ return r;
+}
+
+UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
+ DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
+{
+ UINT i, r, ret = ERROR_FUNCTION_FAILED;
+ MSIPACKAGE *package;
+
+ TRACE("(%s, %d, %p)\n", debugstr_w(szProductPackagePath), cPatchInfo, pPatchInfo);
+
+ r = MSI_OpenPackageW( szProductPackagePath, &package );
+ if (r != ERROR_SUCCESS)
+ {
+ ERR("failed to open package %u\n", r);
+ return r;
+ }
+
+ for (i = 0; i < cPatchInfo; i++)
+ {
+ switch (pPatchInfo[i].ePatchDataType)
+ {
+ case MSIPATCH_DATATYPE_PATCHFILE:
+ {
+ FIXME("patch ordering not supported\n");
+ r = MSI_ApplicablePatchW( package, pPatchInfo[i].szPatchData );
+ if (r != ERROR_SUCCESS)
+ {
+ pPatchInfo[i].dwOrder = ~0u;
+ pPatchInfo[i].uStatus = ERROR_PATCH_TARGET_NOT_FOUND;
+ }
+ else
+ {
+ pPatchInfo[i].dwOrder = i;
+ pPatchInfo[i].uStatus = ret = ERROR_SUCCESS;
+ }
+ break;
+ }
+ default:
+ {
+ FIXME("patch data type %u not supported\n", pPatchInfo[i].ePatchDataType);
+ pPatchInfo[i].dwOrder = ~0u;
+ pPatchInfo[i].uStatus = ERROR_PATCH_TARGET_NOT_FOUND;
+ break;
+ }
+ }
+
+ TRACE(" szPatchData: %s\n", debugstr_w(pPatchInfo[i].szPatchData));
+ TRACE("ePatchDataType: %u\n", pPatchInfo[i].ePatchDataType);
+ TRACE(" dwOrder: %u\n", pPatchInfo[i].dwOrder);
+ TRACE(" uStatus: %u\n", pPatchInfo[i].uStatus);
+ }
+ return ret;
+}
+
+UINT WINAPI MsiDeterminePatchSequenceA(LPCSTR szProductCode, LPCSTR szUserSid,
+ MSIINSTALLCONTEXT dwContext, DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
+{
+ FIXME("(%s, %s, %d, %d, %p): stub!\n", debugstr_a(szProductCode),
+ debugstr_a(szUserSid), dwContext, cPatchInfo, pPatchInfo);
+
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDeterminePatchSequenceW(LPCWSTR szProductCode, LPCWSTR szUserSid,
+ MSIINSTALLCONTEXT dwContext, DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
+{
+ FIXME("(%s, %s, %d, %d, %p): stub!\n", debugstr_w(szProductCode),
+ debugstr_w(szUserSid), dwContext, cPatchInfo, pPatchInfo);
+
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+static UINT msi_open_package(LPCWSTR product, MSIINSTALLCONTEXT context,
+ MSIPACKAGE **package)
+{
+ UINT r;
+ DWORD sz;
+ HKEY props;
+ LPWSTR localpack;
+ WCHAR sourcepath[MAX_PATH];
+ WCHAR filename[MAX_PATH];
+
+ r = MSIREG_OpenInstallProps(product, context, NULL, &props, FALSE);
+ if (r != ERROR_SUCCESS)
+ return ERROR_BAD_CONFIGURATION;
+
+ localpack = msi_reg_get_val_str(props, szLocalPackage);
+ if (localpack)
+ {
+ lstrcpyW(sourcepath, localpack);
+ msi_free(localpack);
+ }
+
+ if (!localpack || GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
+ {
+ sz = sizeof(sourcepath);
+ MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
+ INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
+
+ sz = sizeof(filename);
+ MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
+ INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
+
+ lstrcatW(sourcepath, filename);
+ }
+
+ if (GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
+ return ERROR_INSTALL_SOURCE_ABSENT;
+
+ return MSI_OpenPackageW(sourcepath, package);
+}
+
UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
{
MSIPACKAGE* package = NULL;
+ MSIINSTALLCONTEXT context;
UINT r;
DWORD sz;
- WCHAR sourcepath[MAX_PATH];
- WCHAR filename[MAX_PATH];
+ WCHAR sourcepath[MAX_PATH], filename[MAX_PATH];
+ LPWSTR commandline;
+
static const WCHAR szInstalled[] = {
' ','I','n','s','t','a','l','l','e','d','=','1',0};
- LPWSTR commandline;
+ static const WCHAR szRemoveAll[] = {
+ ' ','R','E','M','O','V','E','=','A','L','L',0};
+ static const WCHAR szMachine[] = {
+ ' ','A','L','L','U','S','E','R','S','=','1',0};
TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
debugstr_w(szCommandLine));
- if (eInstallState != INSTALLSTATE_LOCAL &&
- eInstallState != INSTALLSTATE_DEFAULT)
+ if (!szProduct || lstrlenW(szProduct) != GUID_SIZE - 1)
+ return ERROR_INVALID_PARAMETER;
+
+ if (eInstallState == INSTALLSTATE_ADVERTISED ||
+ eInstallState == INSTALLSTATE_SOURCE)
{
- FIXME("Not implemented for anything other than local installs\n");
+ FIXME("State %d not implemented\n", eInstallState);
return ERROR_CALL_NOT_IMPLEMENTED;
}
- sz = sizeof(sourcepath);
- MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
- &sz);
-
- sz = sizeof(filename);
- MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
-
- lstrcatW(sourcepath,filename);
-
- /*
- * ok 1, we need to find the msi file for this product.
- * 2, find the source dir for the files
- * 3, do the configure/install.
- * 4, cleanupany runonce entry.
- */
+ r = msi_locate_product(szProduct, &context);
+ if (r != ERROR_SUCCESS)
+ return r;
- r = MSI_OpenProductW( szProduct, &package );
+ r = msi_open_package(szProduct, context, &package);
if (r != ERROR_SUCCESS)
return r;
if (szCommandLine)
sz += lstrlenW(szCommandLine);
+ if (eInstallState == INSTALLSTATE_ABSENT)
+ sz += lstrlenW(szRemoveAll);
+
+ if (context == MSIINSTALLCONTEXT_MACHINE)
+ sz += lstrlenW(szMachine);
+
commandline = msi_alloc(sz * sizeof(WCHAR));
- if (!commandline )
+ if (!commandline)
{
r = ERROR_OUTOFMEMORY;
goto end;
if (szCommandLine)
lstrcpyW(commandline,szCommandLine);
- if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
- lstrcatW(commandline,szInstalled);
+ if (eInstallState == INSTALLSTATE_ABSENT)
+ lstrcatW(commandline, szRemoveAll);
+
+ if (context == MSIINSTALLCONTEXT_MACHINE)
+ lstrcatW(commandline, szMachine);
+
+ sz = sizeof(sourcepath);
+ MsiSourceListGetInfoW(szProduct, NULL, context, MSICODE_PRODUCT,
+ INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
+
+ sz = sizeof(filename);
+ MsiSourceListGetInfoW(szProduct, NULL, context, MSICODE_PRODUCT,
+ INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
+
+ strcatW(sourcepath, filename);
r = MSI_InstallPackage( package, sourcepath, commandline );
UINT r;
WCHAR szwBuffer[GUID_SIZE];
- TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
+ TRACE("%s %p\n", debugstr_a(szComponent), szBuffer);
if( szComponent )
{
if (!squash_guid(szComponent, squished_comp))
return ERROR_INVALID_PARAMETER;
- if (MSIREG_OpenUserDataComponentKey(szComponent, &compkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenLocalSystemComponentKey(szComponent, &compkey, FALSE) != ERROR_SUCCESS)
+ if (MSIREG_OpenUserDataComponentKey(szComponent, NULL, &compkey, FALSE) != ERROR_SUCCESS &&
+ MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &compkey, FALSE) != ERROR_SUCCESS)
{
return ERROR_UNKNOWN_COMPONENT;
}
sz = GUID_SIZE;
unsquash_guid(squished_prod, szBuffer);
- if (MSIREG_OpenLocalManagedProductKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenUserProductsKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenLocalClassesProductKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS)
+ if (MSIREG_OpenProductKey(szBuffer, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ &prodkey, FALSE) == ERROR_SUCCESS ||
+ MSIREG_OpenProductKey(szBuffer, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ &prodkey, FALSE) == ERROR_SUCCESS ||
+ MSIREG_OpenProductKey(szBuffer, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ &prodkey, FALSE) == ERROR_SUCCESS)
{
RegCloseKey(prodkey);
rc = ERROR_SUCCESS;
return strdupW(temp);
}
-static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
- awstring *szValue, LPDWORD pcchValueBuf)
+static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
+ awstring *szValue, LPDWORD pcchValueBuf)
{
+ MSIINSTALLCONTEXT context = MSIINSTALLCONTEXT_USERUNMANAGED;
UINT r = ERROR_UNKNOWN_PROPERTY;
HKEY prodkey, userdata, source;
LPWSTR val = NULL;
WCHAR squished_pc[GUID_SIZE];
WCHAR packagecode[GUID_SIZE];
- BOOL classes = FALSE;
BOOL badconfig = FALSE;
LONG res;
- DWORD save, type = REG_NONE;
+ DWORD type = REG_NONE;
static WCHAR empty[] = {0};
static const WCHAR sourcelist[] = {
if (!squash_guid(szProduct, squished_pc))
return ERROR_INVALID_PARAMETER;
- r = MSIREG_OpenLocalManagedProductKey(szProduct, &prodkey, FALSE);
- if (r != ERROR_SUCCESS)
+ if ((r = MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ &prodkey, FALSE)) != ERROR_SUCCESS &&
+ (r = MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ &prodkey, FALSE)) != ERROR_SUCCESS &&
+ (r = MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_MACHINE,
+ &prodkey, FALSE)) == ERROR_SUCCESS)
{
- r = MSIREG_OpenUserProductsKey(szProduct, &prodkey, FALSE);
- if (r != ERROR_SUCCESS)
- {
- r = MSIREG_OpenLocalClassesProductKey(szProduct, &prodkey, FALSE);
- if (r == ERROR_SUCCESS)
- classes = TRUE;
- }
+ context = MSIINSTALLCONTEXT_MACHINE;
}
- if (classes)
- MSIREG_OpenLocalSystemProductKey(szProduct, &userdata, FALSE);
- else
- MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
+ MSIREG_OpenInstallProps(szProduct, context, NULL, &userdata, FALSE);
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) ||
!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) ||
if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW))
{
res = RegOpenKeyW(prodkey, sourcelist, &source);
- if (res == ERROR_SUCCESS)
- val = msi_reg_get_value(source, szAttribute, &type);
+ if (res != ERROR_SUCCESS)
+ {
+ r = ERROR_UNKNOWN_PRODUCT;
+ goto done;
+ }
+
+ val = msi_reg_get_value(source, szAttribute, &type);
+ if (!val)
+ val = empty;
RegCloseKey(source);
}
if (pcchValueBuf)
{
- save = *pcchValueBuf;
-
- if (lstrlenW(val) < *pcchValueBuf)
- r = msi_strcpy_to_awstring(val, szValue, pcchValueBuf);
- else if (szValue->str.a || szValue->str.w)
- r = ERROR_MORE_DATA;
+ /* If szBuffer (szValue->str) is NULL, there's no need to copy the value
+ * out. Also, *pcchValueBuf may be uninitialized in this case, so we
+ * can't rely on its value.
+ */
+ if (szValue->str.a || szValue->str.w)
+ {
+ DWORD size = *pcchValueBuf;
+ if (strlenW(val) < size)
+ r = msi_strcpy_to_awstring(val, szValue, &size);
+ else
+ {
+ r = ERROR_MORE_DATA;
+ }
+ }
if (!badconfig)
*pcchValueBuf = lstrlenW(val);
- else if (r == ERROR_SUCCESS)
- {
- *pcchValueBuf = save;
- r = ERROR_BAD_CONFIGURATION;
- }
}
- else if (badconfig)
+
+ if (badconfig)
r = ERROR_BAD_CONFIGURATION;
if (val != empty)
static UINT msi_copy_outval(LPWSTR val, LPWSTR out, LPDWORD size)
{
- UINT r;
+ UINT r = ERROR_SUCCESS;
if (!val)
return ERROR_UNKNOWN_PROPERTY;
if (out)
{
- if (lstrlenW(val) >= *size)
+ if (strlenW(val) >= *size)
{
r = ERROR_MORE_DATA;
if (*size > 0)
if (size)
*size = lstrlenW(val);
- return ERROR_SUCCESS;
+ return r;
}
UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
DWORD type;
UINT r = ERROR_UNKNOWN_PRODUCT;
- static const WCHAR one[] = {'1',0};
static const WCHAR five[] = {'5',0};
- static const WCHAR empty[] = {0};
static const WCHAR displayname[] = {
'D','i','s','p','l','a','y','N','a','m','e',0};
static const WCHAR displayversion[] = {
if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
return ERROR_INVALID_PARAMETER;
- MSIREG_OpenLocalManagedProductKey(szProductCode, &managed, FALSE);
- MSIREG_OpenUserProductsKey(szProductCode, &prod, FALSE);
+ /* FIXME: dwContext is provided, no need to search for it */
+ MSIREG_OpenProductKey(szProductCode, NULL,MSIINSTALLCONTEXT_USERMANAGED,
+ &managed, FALSE);
+ MSIREG_OpenProductKey(szProductCode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ &prod, FALSE);
+
+ MSIREG_OpenInstallProps(szProductCode, dwContext, NULL, &props, FALSE);
if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
{
package = INSTALLPROPERTY_LOCALPACKAGEW;
- MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
if (!props && !prod)
goto done;
else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
{
package = managed_local_package;
- MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
if (!props && !managed)
goto done;
else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
{
package = INSTALLPROPERTY_LOCALPACKAGEW;
- MSIREG_OpenLocalSystemProductKey(szProductCode, &props, FALSE);
- MSIREG_OpenLocalClassesProductKey(szProductCode, &classes, FALSE);
+ MSIREG_OpenProductKey(szProductCode, NULL, dwContext, &classes, FALSE);
if (!props && !classes)
goto done;
val = msi_reg_get_value(props, szProperty, &type);
if (!val)
- val = strdupW(empty);
+ val = strdupW(szEmpty);
r = msi_copy_outval(val, szValue, pcchValue);
}
val = msi_reg_get_value(hkey, szProperty, &type);
if (!val)
- val = strdupW(empty);
+ val = strdupW(szEmpty);
r = msi_copy_outval(val, szValue, pcchValue);
}
val = strdupW(five);
}
else
- val = strdupW(one);
+ val = strdupW(szOne);
r = msi_copy_outval(val, szValue, pcchValue);
goto done;
}
- else if (props && (val = msi_reg_get_value(props, package, &type)))
+ else if (props && (val = msi_reg_get_value(props, package, &type)))
+ {
+ msi_free(val);
+ val = strdupW(five);
+ r = msi_copy_outval(val, szValue, pcchValue);
+ goto done;
+ }
+
+ if (prod || managed)
+ val = strdupW(szOne);
+ else
+ goto done;
+
+ r = msi_copy_outval(val, szValue, pcchValue);
+ }
+ else if (!lstrcmpW(szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW))
+ {
+ if (!prod && !classes)
+ goto done;
+
+ /* FIXME */
+ val = strdupW(szEmpty);
+ r = msi_copy_outval(val, szValue, pcchValue);
+ }
+ else
+ r = ERROR_UNKNOWN_PROPERTY;
+
+done:
+ RegCloseKey(props);
+ RegCloseKey(prod);
+ RegCloseKey(managed);
+ RegCloseKey(classes);
+ msi_free(val);
+
+ return r;
+}
+
+UINT WINAPI MsiGetPatchInfoExA(LPCSTR szPatchCode, LPCSTR szProductCode,
+ LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext,
+ LPCSTR szProperty, LPSTR lpValue, DWORD *pcchValue)
+{
+ LPWSTR patch = NULL, product = NULL, usersid = NULL;
+ LPWSTR property = NULL, val = NULL;
+ DWORD len;
+ UINT r;
+
+ TRACE("(%s, %s, %s, %d, %s, %p, %p)\n", debugstr_a(szPatchCode),
+ debugstr_a(szProductCode), debugstr_a(szUserSid), dwContext,
+ debugstr_a(szProperty), lpValue, pcchValue);
+
+ if (lpValue && !pcchValue)
+ return ERROR_INVALID_PARAMETER;
+
+ if (szPatchCode) patch = strdupAtoW(szPatchCode);
+ if (szProductCode) product = strdupAtoW(szProductCode);
+ if (szUserSid) usersid = strdupAtoW(szUserSid);
+ if (szProperty) property = strdupAtoW(szProperty);
+
+ len = 0;
+ r = MsiGetPatchInfoExW(patch, product, usersid, dwContext, property,
+ NULL, &len);
+ if (r != ERROR_SUCCESS)
+ goto done;
+
+ val = msi_alloc(++len * sizeof(WCHAR));
+ if (!val)
+ {
+ r = ERROR_OUTOFMEMORY;
+ goto done;
+ }
+
+ r = MsiGetPatchInfoExW(patch, product, usersid, dwContext, property,
+ val, &len);
+ if (r != ERROR_SUCCESS || !pcchValue)
+ goto done;
+
+ if (lpValue)
+ WideCharToMultiByte(CP_ACP, 0, val, -1, lpValue,
+ *pcchValue - 1, NULL, NULL);
+
+ len = lstrlenW(val);
+ if ((*val && *pcchValue < len + 1) || !lpValue)
+ {
+ if (lpValue)
+ {
+ r = ERROR_MORE_DATA;
+ lpValue[*pcchValue - 1] = '\0';
+ }
+
+ *pcchValue = len * sizeof(WCHAR);
+ }
+ else
+ *pcchValue = len;
+
+done:
+ msi_free(val);
+ msi_free(patch);
+ msi_free(product);
+ msi_free(usersid);
+ msi_free(property);
+
+ return r;
+}
+
+UINT WINAPI MsiGetPatchInfoExW(LPCWSTR szPatchCode, LPCWSTR szProductCode,
+ LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
+ LPCWSTR szProperty, LPWSTR lpValue, DWORD *pcchValue)
+{
+ WCHAR squished_pc[GUID_SIZE];
+ WCHAR squished_patch[GUID_SIZE];
+ HKEY udprod = 0, prod = 0, props = 0;
+ HKEY patch = 0, patches = 0;
+ HKEY udpatch = 0, datakey = 0;
+ HKEY prodpatches = 0;
+ LPWSTR val = NULL;
+ UINT r = ERROR_UNKNOWN_PRODUCT;
+ DWORD len;
+ LONG res;
+
+ static const WCHAR szManagedPackage[] = {'M','a','n','a','g','e','d',
+ 'L','o','c','a','l','P','a','c','k','a','g','e',0};
+
+ TRACE("(%s, %s, %s, %d, %s, %p, %p)\n", debugstr_w(szPatchCode),
+ debugstr_w(szProductCode), debugstr_w(szUserSid), dwContext,
+ debugstr_w(szProperty), lpValue, pcchValue);
+
+ if (!szProductCode || !squash_guid(szProductCode, squished_pc))
+ return ERROR_INVALID_PARAMETER;
+
+ if (!szPatchCode || !squash_guid(szPatchCode, squished_patch))
+ return ERROR_INVALID_PARAMETER;
+
+ if (!szProperty)
+ return ERROR_INVALID_PARAMETER;
+
+ if (lpValue && !pcchValue)
+ return ERROR_INVALID_PARAMETER;
+
+ if (dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
+ dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
+ dwContext != MSIINSTALLCONTEXT_MACHINE)
+ return ERROR_INVALID_PARAMETER;
+
+ if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
+ return ERROR_INVALID_PARAMETER;
+
+ if (!lstrcmpW(szUserSid, szLocalSid))
+ return ERROR_INVALID_PARAMETER;
+
+ if (MSIREG_OpenUserDataProductKey(szProductCode, dwContext, NULL,
+ &udprod, FALSE) != ERROR_SUCCESS)
+ goto done;
+
+ if (MSIREG_OpenInstallProps(szProductCode, dwContext, NULL,
+ &props, FALSE) != ERROR_SUCCESS)
+ goto done;
+
+ r = ERROR_UNKNOWN_PATCH;
+
+ res = RegOpenKeyExW(udprod, szPatches, 0, KEY_READ, &patches);
+ if (res != ERROR_SUCCESS)
+ goto done;
+
+ res = RegOpenKeyExW(patches, squished_patch, 0, KEY_READ, &patch);
+ if (res != ERROR_SUCCESS)
+ goto done;
+
+ if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW))
+ {
+ if (MSIREG_OpenProductKey(szProductCode, NULL, dwContext,
+ &prod, FALSE) != ERROR_SUCCESS)
+ goto done;
+
+ res = RegOpenKeyExW(prod, szPatches, 0, KEY_ALL_ACCESS, &prodpatches);
+ if (res != ERROR_SUCCESS)
+ goto done;
+
+ datakey = prodpatches;
+ szProperty = squished_patch;
+ }
+ else
+ {
+ if (MSIREG_OpenUserDataPatchKey(szPatchCode, dwContext,
+ &udpatch, FALSE) != ERROR_SUCCESS)
+ goto done;
+
+ if (!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW))
+ {
+ if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
+ szProperty = szManagedPackage;
+ datakey = udpatch;
+ }
+ else if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW))
{
- msi_free(val);
- val = strdupW(five);
- r = msi_copy_outval(val, szValue, pcchValue);
- goto done;
+ datakey = patch;
+ szProperty = szInstalled;
+ }
+ else if (!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW))
+ {
+ datakey = udpatch;
+ }
+ else if (!lstrcmpW(szProperty, INSTALLPROPERTY_UNINSTALLABLEW) ||
+ !lstrcmpW(szProperty, INSTALLPROPERTY_PATCHSTATEW) ||
+ !lstrcmpW(szProperty, INSTALLPROPERTY_DISPLAYNAMEW) ||
+ !lstrcmpW(szProperty, INSTALLPROPERTY_MOREINFOURLW))
+ {
+ datakey = patch;
}
-
- if (prod || managed)
- val = strdupW(one);
else
+ {
+ r = ERROR_UNKNOWN_PROPERTY;
goto done;
-
- r = msi_copy_outval(val, szValue, pcchValue);
+ }
}
- else if (!lstrcmpW(szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW))
+
+ val = msi_reg_get_val_str(datakey, szProperty);
+ if (!val)
+ val = strdupW(szEmpty);
+
+ r = ERROR_SUCCESS;
+
+ if (!pcchValue)
+ goto done;
+
+ if (lpValue)
+ lstrcpynW(lpValue, val, *pcchValue);
+
+ len = lstrlenW(val);
+ if ((*val && *pcchValue < len + 1) || !lpValue)
{
- if (!prod && !classes)
- goto done;
+ if (lpValue)
+ r = ERROR_MORE_DATA;
- /* FIXME */
- val = strdupW(empty);
- r = msi_copy_outval(val, szValue, pcchValue);
+ *pcchValue = len * sizeof(WCHAR);
}
- else
- r = ERROR_UNKNOWN_PROPERTY;
+
+ *pcchValue = len;
done:
- RegCloseKey(props);
- RegCloseKey(prod);
- RegCloseKey(managed);
- RegCloseKey(classes);
msi_free(val);
+ RegCloseKey(prodpatches);
+ RegCloseKey(prod);
+ RegCloseKey(patch);
+ RegCloseKey(patches);
+ RegCloseKey(udpatch);
+ RegCloseKey(props);
+ RegCloseKey(udprod);
+
+ 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)
{
LPWSTR szwLogFile = NULL;
LPWSTR lpDriveBuf, DWORD *pcchDriveBuf,
int *piCost, int *pTempCost)
{
- FIXME("(%ld, %s, %d, %d, %p, %p, %p %p): stub!\n", hInstall,
+ FIXME("(%d, %s, %d, %d, %p, %p, %p %p): stub!\n", hInstall,
debugstr_w(szComponent), dwIndex, iState, lpDriveBuf,
pcchDriveBuf, piCost, pTempCost);
UINT r;
HKEY hkey;
- if (context == MSIINSTALLCONTEXT_MACHINE)
- r = MSIREG_OpenLocalClassesProductKey(prodcode, &hkey, FALSE);
- else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
- r = MSIREG_OpenUserProductsKey(prodcode, &hkey, FALSE);
- else
- r = MSIREG_OpenLocalManagedProductKey(prodcode, &hkey, FALSE);
-
+ r = MSIREG_OpenProductKey(prodcode, NULL, context, &hkey, FALSE);
RegCloseKey(hkey);
return (r == ERROR_SUCCESS);
}
'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0
};
- if (context == MSIINSTALLCONTEXT_MACHINE)
- r = MSIREG_OpenLocalSystemProductKey(prodcode, &hkey, FALSE);
- else
- r = MSIREG_OpenCurrentUserInstallProps(prodcode, &hkey, FALSE);
-
+ r = MSIREG_OpenInstallProps(prodcode, context, NULL, &hkey, FALSE);
if (r != ERROR_SUCCESS)
return FALSE;
static BOOL msi_comp_find_prodcode(LPWSTR squished_pc,
MSIINSTALLCONTEXT context,
- LPCWSTR comp, DWORD *sz)
+ LPCWSTR comp, LPWSTR val, DWORD *sz)
{
HKEY hkey;
LONG res;
UINT r;
if (context == MSIINSTALLCONTEXT_MACHINE)
- r = MSIREG_OpenLocalSystemComponentKey(comp, &hkey, FALSE);
+ r = MSIREG_OpenUserDataComponentKey(comp, szLocalSid, &hkey, FALSE);
else
- r = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
+ r = MSIREG_OpenUserDataComponentKey(comp, NULL, &hkey, FALSE);
if (r != ERROR_SUCCESS)
return FALSE;
- *sz = 0;
- res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, NULL, sz);
+ res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, (BYTE *)val, sz);
if (res != ERROR_SUCCESS)
return FALSE;
LPCWSTR szComponent, INSTALLSTATE *pdwState)
{
WCHAR squished_pc[GUID_SIZE];
+ WCHAR val[MAX_PATH];
BOOL found;
DWORD sz;
TRACE("(%s, %s, %d, %s, %p)\n", debugstr_w(szProductCode),
debugstr_w(szUserSid), dwContext, debugstr_w(szComponent), pdwState);
- if (!pdwState)
+ if (!pdwState || !szComponent)
return ERROR_INVALID_PARAMETER;
if (!szProductCode || !*szProductCode || lstrlenW(szProductCode) != GUID_SIZE - 1)
*pdwState = INSTALLSTATE_UNKNOWN;
- if (!msi_comp_find_prodcode(squished_pc, dwContext, szComponent, &sz))
+ sz = MAX_PATH;
+ if (!msi_comp_find_prodcode(squished_pc, dwContext, szComponent, val, &sz))
return ERROR_UNKNOWN_COMPONENT;
if (sz == 0)
*pdwState = INSTALLSTATE_NOTUSED;
else
- *pdwState = INSTALLSTATE_LOCAL;
+ {
+ if (lstrlenW(val) > 2 &&
+ val[0] >= '0' && val[0] <= '9' && val[1] >= '0' && val[1] <= '9')
+ {
+ *pdwState = INSTALLSTATE_SOURCE;
+ }
+ else
+ *pdwState = INSTALLSTATE_LOCAL;
+ }
return ERROR_SUCCESS;
}
INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
{
+ MSIINSTALLCONTEXT context = MSIINSTALLCONTEXT_USERUNMANAGED;
INSTALLSTATE state = INSTALLSTATE_ADVERTISED;
HKEY prodkey = 0, userdata = 0;
- BOOL user = TRUE;
DWORD val;
UINT r;
if (lstrlenW(szProduct) != GUID_SIZE - 1)
return INSTALLSTATE_INVALIDARG;
- r = MSIREG_OpenLocalManagedProductKey(szProduct, &prodkey, FALSE);
- if (r != ERROR_SUCCESS)
+ if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
+ &prodkey, FALSE) != ERROR_SUCCESS &&
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ &prodkey, FALSE) != ERROR_SUCCESS &&
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
+ &prodkey, FALSE) == ERROR_SUCCESS)
{
- r = MSIREG_OpenUserProductsKey(szProduct, &prodkey, FALSE);
- if (r != ERROR_SUCCESS)
- {
- r = MSIREG_OpenLocalClassesProductKey(szProduct, &prodkey, FALSE);
- if (r == ERROR_SUCCESS)
- user = FALSE;
- }
+ context = MSIINSTALLCONTEXT_MACHINE;
}
- if (user)
- {
- r = MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
- if (r != ERROR_SUCCESS)
- goto done;
- }
- else
- {
- r = MSIREG_OpenLocalSystemInstallProps(szProduct, &userdata, FALSE);
- if (r != ERROR_SUCCESS)
- goto done;
- }
+ r = MSIREG_OpenInstallProps(szProduct, context, NULL, &userdata, FALSE);
+ if (r != ERROR_SUCCESS)
+ goto done;
if (!msi_reg_get_val_dword(userdata, szWindowsInstaller, &val))
goto done;
{
INSTALLUI_HANDLERA prev = gUIHandlerA;
- TRACE("%p %x %p\n",puiHandler, dwMessageFilter,pvContext);
+ TRACE("%p %08x %p\n", puiHandler, dwMessageFilter, pvContext);
+
gUIHandlerA = puiHandler;
- gUIFilter = dwMessageFilter;
- gUIContext = pvContext;
+ gUIHandlerW = NULL;
+ gUIFilter = dwMessageFilter;
+ gUIContext = pvContext;
return prev;
}
{
INSTALLUI_HANDLERW prev = gUIHandlerW;
- TRACE("%p %x %p\n",puiHandler,dwMessageFilter,pvContext);
+ TRACE("%p %08x %p\n", puiHandler, dwMessageFilter, pvContext);
+
+ gUIHandlerA = NULL;
gUIHandlerW = puiHandler;
- gUIFilter = dwMessageFilter;
- gUIContext = pvContext;
+ gUIFilter = dwMessageFilter;
+ gUIContext = pvContext;
return prev;
}
LPWSTR p;
DWORD i, len;
- TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
+ TRACE("%d %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
if( handle != -1 )
- FIXME("don't know how to deal with handle = %08lx\n", handle);
+ FIXME("don't know how to deal with handle = %08x\n", handle);
if( !lang )
lang = GetUserDefaultLangID();
{
LPWSTR bufW;
LANGID r;
- DWORD len;
+ INT len;
bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
+ if (!szComponent || !pcchBuf)
+ return INSTALLSTATE_INVALIDARG;
+
if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
return INSTALLSTATE_UNKNOWN;
TRACE("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
+ if (!szComponent || !pcchBuf)
+ return INSTALLSTATE_INVALIDARG;
+
if (MsiGetProductCodeW( szComponent, szProduct ) != ERROR_SUCCESS)
return INSTALLSTATE_UNKNOWN;
return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId);
}
+UINT WINAPI MsiMessageBoxExA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
+ DWORD unknown, WORD wLanguageId, DWORD f)
+{
+ FIXME("(%p, %s, %s, %u, 0x%08x, 0x%08x, 0x%08x): semi-stub\n", hWnd, debugstr_a(lpText),
+ debugstr_a(lpCaption), uType, unknown, wLanguageId, f);
+ return MessageBoxExA(hWnd, lpText, lpCaption, uType, wLanguageId);
+}
+
+UINT WINAPI MsiMessageBoxExW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
+ DWORD unknown, WORD wLanguageId, DWORD f)
+{
+ FIXME("(%p, %s, %s, %u, 0x%08x, 0x%08x, 0x%08x): semi-stub\n", hWnd, debugstr_w(lpText),
+ debugstr_w(lpCaption), uType, unknown, wLanguageId, f);
+ return MessageBoxExW(hWnd, lpText, lpCaption, uType, wLanguageId);
+}
+
UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
LPDWORD pcchPathBuf )
return ERROR_CALL_NOT_IMPLEMENTED;
}
-UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
- LPSTR szValue, LPDWORD pccbValue )
+/******************************************************************
+ * MsiGetProductPropertyA [MSI.@]
+ */
+UINT WINAPI MsiGetProductPropertyA(MSIHANDLE hProduct, LPCSTR szProperty,
+ LPSTR szValue, LPDWORD pccbValue)
{
- FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ LPWSTR prop = NULL, val = NULL;
+ DWORD len;
+ UINT r;
+
+ TRACE("(%d, %s, %p, %p)\n", hProduct, debugstr_a(szProperty),
+ szValue, pccbValue);
+
+ if (szValue && !pccbValue)
+ return ERROR_INVALID_PARAMETER;
+
+ if (szProperty) prop = strdupAtoW(szProperty);
+
+ len = 0;
+ r = MsiGetProductPropertyW(hProduct, prop, NULL, &len);
+ if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
+ goto done;
+
+ if (r == ERROR_SUCCESS)
+ {
+ if (szValue) *szValue = '\0';
+ if (pccbValue) *pccbValue = 0;
+ goto done;
+ }
+
+ val = msi_alloc(++len * sizeof(WCHAR));
+ if (!val)
+ {
+ r = ERROR_OUTOFMEMORY;
+ goto done;
+ }
+
+ r = MsiGetProductPropertyW(hProduct, prop, val, &len);
+ if (r != ERROR_SUCCESS)
+ goto done;
+
+ len = WideCharToMultiByte(CP_ACP, 0, val, -1, NULL, 0, NULL, NULL);
+
+ if (szValue)
+ WideCharToMultiByte(CP_ACP, 0, val, -1, szValue,
+ *pccbValue, NULL, NULL);
+
+ if (pccbValue)
+ {
+ if (len > *pccbValue)
+ r = ERROR_MORE_DATA;
+
+ *pccbValue = len - 1;
+ }
+
+done:
+ msi_free(prop);
+ msi_free(val);
+
+ return r;
}
-UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
- LPWSTR szValue, LPDWORD pccbValue )
+/******************************************************************
+ * MsiGetProductPropertyW [MSI.@]
+ */
+UINT WINAPI MsiGetProductPropertyW(MSIHANDLE hProduct, LPCWSTR szProperty,
+ LPWSTR szValue, LPDWORD pccbValue)
{
- FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
- return ERROR_CALL_NOT_IMPLEMENTED;
+ MSIPACKAGE *package;
+ MSIQUERY *view = NULL;
+ MSIRECORD *rec = NULL;
+ LPCWSTR val;
+ UINT r;
+
+ static const WCHAR query[] = {
+ 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+ '`','P','r','o','p','e','r','t','y','`',' ','W','H','E','R','E',' ',
+ '`','P','r','o','p','e','r','t','y','`','=','\'','%','s','\'',0};
+
+ TRACE("(%d, %s, %p, %p)\n", hProduct, debugstr_w(szProperty),
+ szValue, pccbValue);
+
+ if (!szProperty)
+ return ERROR_INVALID_PARAMETER;
+
+ if (szValue && !pccbValue)
+ return ERROR_INVALID_PARAMETER;
+
+ package = msihandle2msiinfo(hProduct, MSIHANDLETYPE_PACKAGE);
+ if (!package)
+ return ERROR_INVALID_HANDLE;
+
+ r = MSI_OpenQuery(package->db, &view, query, szProperty);
+ if (r != ERROR_SUCCESS)
+ goto done;
+
+ r = MSI_ViewExecute(view, 0);
+ if (r != ERROR_SUCCESS)
+ goto done;
+
+ r = MSI_ViewFetch(view, &rec);
+ if (r != ERROR_SUCCESS)
+ goto done;
+
+ val = MSI_RecordGetString(rec, 2);
+ if (!val)
+ goto done;
+
+ if (lstrlenW(val) >= *pccbValue)
+ {
+ lstrcpynW(szValue, val, *pccbValue);
+ *pccbValue = lstrlenW(val);
+ r = ERROR_MORE_DATA;
+ }
+ else
+ {
+ lstrcpyW(szValue, val);
+ *pccbValue = lstrlenW(val);
+ r = ERROR_SUCCESS;
+ }
+
+done:
+ if (view)
+ {
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ if (rec) msiobj_release(&rec->hdr);
+ }
+
+ if (!rec)
+ {
+ if (szValue) *szValue = '\0';
+ if (pccbValue) *pccbValue = 0;
+ r = ERROR_SUCCESS;
+ }
+
+ msiobj_release(&package->hdr);
+ return r;
}
UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
return r;
}
-static INSTALLSTATE WINAPI MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
- awstring* lpPathBuf, LPDWORD pcchBuf)
+static INSTALLSTATE MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
+ awstring* lpPathBuf, LPDWORD pcchBuf)
{
WCHAR squished_pc[GUID_SIZE];
WCHAR squished_comp[GUID_SIZE];
state = INSTALLSTATE_UNKNOWN;
- if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
+ if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS ||
+ MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
{
path = msi_reg_get_val_str(hkey, squished_pc);
RegCloseKey(hkey);
state = INSTALLSTATE_ABSENT;
- if ((MSIREG_OpenLocalSystemProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenUserDataProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS) &&
+ if ((MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE, NULL,
+ &hkey, FALSE) == ERROR_SUCCESS ||
+ MSIREG_OpenUserDataProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+ NULL, &hkey, FALSE) == ERROR_SUCCESS) &&
msi_reg_get_val_dword(hkey, wininstaller, &version) &&
GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
{
}
if (state != INSTALLSTATE_LOCAL &&
- (MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenLocalClassesProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS))
+ (MSIREG_OpenProductKey(szProduct, NULL,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ &hkey, FALSE) == ERROR_SUCCESS ||
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
+ &hkey, FALSE) == ERROR_SUCCESS))
{
RegCloseKey(hkey);
- if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
+ if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS ||
+ MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
{
msi_free(path);
path = msi_reg_get_val_str(hkey, squished_pc);
INSTALLSTATE r;
BOOL missing = FALSE;
BOOL machine = FALSE;
+ BOOL source = FALSE;
TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
if (!squash_guid( szProduct, squishProduct ))
return INSTALLSTATE_INVALIDARG;
- if (MSIREG_OpenManagedFeaturesKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenUserFeaturesKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS)
+ if (MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
+ &hkey, FALSE) != ERROR_SUCCESS &&
+ MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+ &hkey, FALSE) != ERROR_SUCCESS)
{
- rc = MSIREG_OpenLocalClassesFeaturesKey(szProduct, &hkey, FALSE);
+ rc = MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
+ &hkey, FALSE);
if (rc != ERROR_SUCCESS)
return INSTALLSTATE_UNKNOWN;
return r;
if (machine)
- rc = MSIREG_OpenLocalUserDataFeaturesKey(szProduct, &hkey, FALSE);
+ rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
+ MSIINSTALLCONTEXT_MACHINE,
+ &hkey, FALSE);
else
- rc = MSIREG_OpenUserDataFeaturesKey(szProduct, &hkey, FALSE);
+ rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
+ MSIINSTALLCONTEXT_USERUNMANAGED,
+ &hkey, FALSE);
if (rc != ERROR_SUCCESS)
return INSTALLSTATE_ADVERTISED;
StringFromGUID2(&guid, comp, GUID_SIZE);
if (machine)
- rc = MSIREG_OpenLocalUserDataComponentKey(comp, &hkey, FALSE);
+ rc = MSIREG_OpenUserDataComponentKey(comp, szLocalSid, &hkey, FALSE);
else
- rc = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
+ rc = MSIREG_OpenUserDataComponentKey(comp, NULL, &hkey, FALSE);
if (rc != ERROR_SUCCESS)
{
path = msi_reg_get_val_str(hkey, squishProduct);
if (!path)
missing = TRUE;
+ else if (lstrlenW(path) > 2 &&
+ path[0] >= '0' && path[0] <= '9' &&
+ path[1] >= '0' && path[1] <= '9')
+ {
+ source = TRUE;
+ }
msi_free(path);
}
if (missing)
return INSTALLSTATE_ADVERTISED;
+ if (source)
+ return INSTALLSTATE_SOURCE;
+
return INSTALLSTATE_LOCAL;
}
HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
if (lpVersionBuf) lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
- if (lstrlenW(tmp) >= *pcchVersionBuf)
+ if (strlenW(tmp) >= *pcchVersionBuf)
ret = ERROR_MORE_DATA;
*pcchVersionBuf = lstrlenW(tmp);
wsprintfW(tmp, szLangFormat, *lang);
if (lpLangBuf) lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
- if (lstrlenW(tmp) >= *pcchLangBuf)
+ if (strlenW(tmp) >= *pcchLangBuf)
ret = ERROR_MORE_DATA;
*pcchLangBuf = lstrlenW(tmp);
/***********************************************************************
* MSI_ProvideQualifiedComponentEx [internal]
*/
-static UINT WINAPI MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
+static UINT MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
LPDWORD pcchPathBuf)
/***********************************************************************
* MSI_GetUserInfo [internal]
*/
-static USERINFOSTATE WINAPI MSI_GetUserInfo(LPCWSTR szProduct,
+static USERINFOSTATE MSI_GetUserInfo(LPCWSTR szProduct,
awstring *lpUserNameBuf, LPDWORD pcchUserNameBuf,
awstring *lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
awstring *lpSerialBuf, LPDWORD pcchSerialBuf)
LPCWSTR orgptr;
UINT r;
- static const WCHAR szEmpty[] = {0};
-
TRACE("%s %p %p %p %p %p %p\n", debugstr_w(szProduct), lpUserNameBuf,
pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
pcchSerialBuf);
if (!szProduct || !squash_guid(szProduct, squished_pc))
return USERINFOSTATE_INVALIDARG;
- if (MSIREG_OpenLocalManagedProductKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenLocalClassesProductKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS)
+ if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
+ &hkey, FALSE) != ERROR_SUCCESS &&
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
+ &hkey, FALSE) != ERROR_SUCCESS &&
+ MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
+ &hkey, FALSE) != ERROR_SUCCESS)
{
return USERINFOSTATE_UNKNOWN;
}
- if (MSIREG_OpenCurrentUserInstallProps(szProduct, &props, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenLocalSystemInstallProps(szProduct, &props, FALSE) != ERROR_SUCCESS)
+ if (MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
+ NULL, &props, FALSE) != ERROR_SUCCESS &&
+ MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE,
+ NULL, &props, FALSE) != ERROR_SUCCESS)
{
RegCloseKey(hkey);
return USERINFOSTATE_ABSENT;
if (rc != ERROR_SUCCESS)
return ERROR_INVALID_PARAMETER;
+ /* MsiCollectUserInfo cannot be called from a custom action. */
package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
+ if (!package)
+ return ERROR_CALL_NOT_IMPLEMENTED;
+
rc = ACTION_PerformUIAction(package, szFirstRun, -1);
msiobj_release( &package->hdr );
if (rc != ERROR_SUCCESS)
return ERROR_INVALID_PARAMETER;
+ /* MsiCollectUserInfo cannot be called from a custom action. */
package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
+ if (!package)
+ return ERROR_CALL_NOT_IMPLEMENTED;
+
rc = ACTION_PerformUIAction(package, szFirstRun, -1);
msiobj_release( &package->hdr );
WCHAR filename[MAX_PATH];
static const WCHAR szLogVerbose[] = {
' ','L','O','G','V','E','R','B','O','S','E',0 };
- static const WCHAR szInstalled[] = { 'I','n','s','t','a','l','l','e','d',0};
- static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
- static const WCHAR szReinstallMode[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
- static const WCHAR szOne[] = {'1',0};
WCHAR reinstallmode[11];
LPWSTR ptr;
DWORD sz;
if (r != ERROR_SUCCESS)
return r;
- MSI_SetPropertyW( package, szReinstallMode, reinstallmode );
- MSI_SetPropertyW( package, szInstalled, szOne );
- MSI_SetPropertyW( package, szLogVerbose, szOne );
- MSI_SetPropertyW( package, szReinstall, szFeature );
+ msi_set_property( package->db, szReinstallMode, reinstallmode );
+ msi_set_property( package->db, szInstalled, szOne );
+ msi_set_property( package->db, szLogVerbose, szOne );
+ msi_set_property( package->db, szReinstall, szFeature );
r = MSI_InstallPackage( package, sourcepath, NULL );
*pfElevated = TRUE;
return ERROR_SUCCESS;
}
+
+/***********************************************************************
+ * MsiSetExternalUIRecord [MSI.@]
+ */
+UINT WINAPI MsiSetExternalUIRecord( INSTALLUI_HANDLER_RECORD handler,
+ DWORD filter, LPVOID context,
+ PINSTALLUI_HANDLER_RECORD prev )
+{
+ TRACE("%p %08x %p %p\n", handler, filter, context, prev);
+
+ if (prev)
+ *prev = gUIHandlerRecord;
+
+ gUIHandlerRecord = handler;
+ gUIFilter = filter;
+ gUIContext = context;
+
+ return ERROR_SUCCESS;
+}
+
+/***********************************************************************
+ * MsiInstallMissingComponentW [MSI.@]
+ */
+UINT WINAPI MsiInstallMissingComponentW(LPCWSTR szProduct, LPCWSTR szComponent, INSTALLSTATE eInstallState)
+{
+ FIXME("(%s %s %d\n", debugstr_w(szProduct), debugstr_w(szComponent), eInstallState);
+ return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiBeginTransactionW( LPCWSTR name, DWORD attrs, MSIHANDLE *id, HANDLE *event );
+/***********************************************************************
+ * MsiBeginTransactionA [MSI.@]
+ */
+UINT WINAPI MsiBeginTransactionA( LPCSTR name, DWORD attrs, MSIHANDLE *id, HANDLE *event )
+{
+ WCHAR *nameW;
+ UINT r;
+
+ FIXME("%s %u %p %p\n", debugstr_a(name), attrs, id, event);
+
+ nameW = strdupAtoW( name );
+ if (name && !nameW)
+ return ERROR_OUTOFMEMORY;
+
+ r = MsiBeginTransactionW( nameW, attrs, id, event );
+ msi_free( nameW );
+ return r;
+}
+
+/***********************************************************************
+ * MsiBeginTransactionW [MSI.@]
+ */
+UINT WINAPI MsiBeginTransactionW( LPCWSTR name, DWORD attrs, MSIHANDLE *id, HANDLE *event )
+{
+ FIXME("%s %u %p %p\n", debugstr_w(name), attrs, id, event);
+
+ *id = (MSIHANDLE)0xdeadbeef;
+ *event = (HANDLE)0xdeadbeef;
+
+ return ERROR_SUCCESS;
+}
+
+/***********************************************************************
+ * MsiEndTransaction [MSI.@]
+ */
+UINT WINAPI MsiEndTransaction( DWORD state )
+{
+ FIXME("%u\n", state);
+ return ERROR_SUCCESS;
+}