return r;
}
-static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWSTR szCommandLine)
+static UINT get_patch_product_codes( LPCWSTR szPatchPackage, WCHAR **product_codes )
{
- MSIHANDLE patch = 0, info = 0;
- UINT r = ERROR_SUCCESS, type;
- DWORD size = 0;
- LPCWSTR cmd_ptr = szCommandLine;
- LPCWSTR product_code = szProductCode;
- LPWSTR beg, end;
- LPWSTR cmd = NULL, codes = NULL;
-
- static const WCHAR patcheq[] = {'P','A','T','C','H','=',0};
+ MSIHANDLE patch, info = 0;
+ UINT r, type;
+ DWORD size;
static WCHAR empty[] = {0};
+ WCHAR *codes;
- if (!szPatchPackage || !szPatchPackage[0])
- return ERROR_INVALID_PARAMETER;
+ r = MsiOpenDatabaseW( szPatchPackage, MSIDBOPEN_READONLY, &patch );
+ if (r != ERROR_SUCCESS)
+ return r;
+
+ r = MsiGetSummaryInformationW( patch, NULL, 0, &info );
+ if (r != ERROR_SUCCESS)
+ goto done;
- if (!szProductCode)
+ size = 0;
+ r = MsiSummaryInfoGetPropertyW( info, PID_TEMPLATE, &type, NULL, NULL, empty, &size );
+ if (r != ERROR_MORE_DATA || !size || type != VT_LPSTR)
{
- r = MsiOpenDatabaseW(szPatchPackage, MSIDBOPEN_READONLY, &patch);
- if (r != ERROR_SUCCESS)
- return r;
+ ERR("Failed to read product codes from patch\n");
+ r = ERROR_FUNCTION_FAILED;
+ goto done;
+ }
- r = MsiGetSummaryInformationW(patch, NULL, 0, &info);
- if (r != ERROR_SUCCESS)
- goto done;
+ codes = msi_alloc( ++size * sizeof(WCHAR) );
+ if (!codes)
+ {
+ r = ERROR_OUTOFMEMORY;
+ goto done;
+ }
- 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");
- goto done;
- }
+ r = MsiSummaryInfoGetPropertyW( info, PID_TEMPLATE, &type, NULL, NULL, codes, &size );
+ if (r != ERROR_SUCCESS)
+ msi_free( codes );
+ else
+ *product_codes = codes;
- codes = msi_alloc(++size * sizeof(WCHAR));
- if (!codes)
- {
- r = ERROR_OUTOFMEMORY;
- goto done;
- }
+done:
+ MsiCloseHandle( info );
+ MsiCloseHandle( patch );
+ return r;
+}
- r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, codes, &size);
- if (r != ERROR_SUCCESS)
- goto done;
+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;
- product_code = codes;
- }
+ 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);
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);
-
- MsiCloseHandle(info);
- MsiCloseHandle(patch);
-
return r;
}
UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
{
- FIXME("(%s, %d, %p): stub!\n", debugstr_a(szProductPackagePath),
- cPatchInfo, pPatchInfo);
+ UINT i, r;
+ WCHAR *package_path = NULL;
+ MSIPATCHSEQUENCEINFOW *psi;
- return ERROR_CALL_NOT_IMPLEMENTED;
+ 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 )
si = MSI_GetSummaryInformationW( patch_db->storage, 0 );
if (!si)
{
- r = ERROR_FUNCTION_FAILED;
- goto done;
+ 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");
-done:
msiobj_release( &patch_db->hdr );
msiobj_release( &si->hdr );
return r;
WCHAR sourcepath[MAX_PATH];
WCHAR filename[MAX_PATH];
- static const WCHAR szLocalPackage[] = {
- 'L','o','c','a','l','P','a','c','k','a','g','e',0};
-
-
r = MSIREG_OpenInstallProps(product, context, NULL, &props, FALSE);
if (r != ERROR_SUCCESS)
return ERROR_BAD_CONFIGURATION;
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 )
{
static UINT msi_copy_outval(LPWSTR val, LPWSTR out, LPDWORD size)
{
- UINT r;
+ UINT r = ERROR_SUCCESS;
if (!val)
return ERROR_UNKNOWN_PROPERTY;
if (size)
*size = lstrlenW(val);
- return ERROR_SUCCESS;
+ return r;
}
UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
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;
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 )
r = ERROR_SUCCESS;
}
+ msiobj_release(&package->hdr);
return r;
}
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 );
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;
+}