Commit b4b8bc83 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msi: Implement MsiApplyMultiplePatchesA/W.

parent dd16b91a
...@@ -301,13 +301,13 @@ done: ...@@ -301,13 +301,13 @@ done:
return r; return r;
} }
UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage, static UINT MSI_ApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szProductCode, LPCWSTR szCommandLine)
INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
{ {
MSIHANDLE patch, info; MSIHANDLE patch, info;
UINT r, type; UINT r, type;
DWORD size = 0; DWORD size = 0;
LPCWSTR cmd_ptr = szCommandLine; LPCWSTR cmd_ptr = szCommandLine;
LPCWSTR product_code = szProductCode;
LPWSTR beg, end; LPWSTR beg, end;
LPWSTR cmd = NULL, codes = NULL; LPWSTR cmd = NULL, codes = NULL;
...@@ -315,16 +315,8 @@ UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage, ...@@ -315,16 +315,8 @@ UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
static const WCHAR patcheq[] = {'P','A','T','C','H','=',0}; static const WCHAR patcheq[] = {'P','A','T','C','H','=',0};
static WCHAR empty[] = {0}; static WCHAR empty[] = {0};
TRACE("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage), if (!szProductCode)
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) if (r != ERROR_SUCCESS)
return r; return r;
...@@ -351,6 +343,9 @@ UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage, ...@@ -351,6 +343,9 @@ UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
goto done; goto done;
product_code = codes;
}
if (!szCommandLine) if (!szCommandLine)
cmd_ptr = empty; cmd_ptr = empty;
...@@ -389,6 +384,99 @@ done: ...@@ -389,6 +384,99 @@ done:
return r; 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;
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, UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo) DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
{ {
......
...@@ -232,8 +232,8 @@ ...@@ -232,8 +232,8 @@
236 stub Migrate10CachedPackagesW 236 stub Migrate10CachedPackagesW
237 stub MsiRemovePatchesA 237 stub MsiRemovePatchesA
238 stub MsiRemovePatchesW 238 stub MsiRemovePatchesW
239 stub MsiApplyMultiplePatchesA 239 stdcall MsiApplyMultiplePatchesA(str str str)
240 stub MsiApplyMultiplePatchesW 240 stdcall MsiApplyMultiplePatchesW(wstr wstr wstr)
241 stub MsiExtractPatchXMLDataA 241 stub MsiExtractPatchXMLDataA
242 stub MsiExtractPatchXMLDataW 242 stub MsiExtractPatchXMLDataW
243 stdcall MsiGetPatchInfoExA(str str str long str ptr ptr) 243 stdcall MsiGetPatchInfoExA(str str str long str ptr ptr)
......
...@@ -11533,6 +11533,38 @@ static void test_MsiSetProperty(void) ...@@ -11533,6 +11533,38 @@ static void test_MsiSetProperty(void)
DeleteFileA(msifile); DeleteFileA(msifile);
} }
static void test_MsiApplyMultiplePatches(void)
{
UINT r;
r = MsiApplyMultiplePatchesA(NULL, NULL, NULL);
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
r = MsiApplyMultiplePatchesA("", NULL, NULL);
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u\n", r);
r = MsiApplyMultiplePatchesA(";", NULL, NULL);
ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
r = MsiApplyMultiplePatchesA(" ;", NULL, NULL);
ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
r = MsiApplyMultiplePatchesA(";;", NULL, NULL);
ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
r = MsiApplyMultiplePatchesA("nosuchpatchpackage;", NULL, NULL);
todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
r = MsiApplyMultiplePatchesA(";nosuchpatchpackage", NULL, NULL);
ok(r == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %u\n", r);
r = MsiApplyMultiplePatchesA("nosuchpatchpackage;nosuchpatchpackage", NULL, NULL);
todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
r = MsiApplyMultiplePatchesA(" nosuchpatchpackage ; nosuchpatchpackage ", NULL, NULL);
todo_wine ok(r == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %u\n", r);
}
START_TEST(package) START_TEST(package)
{ {
GetCurrentDirectoryA(MAX_PATH, CURR_DIR); GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
...@@ -11566,4 +11598,5 @@ START_TEST(package) ...@@ -11566,4 +11598,5 @@ START_TEST(package)
test_emptypackage(); test_emptypackage();
test_MsiGetProductProperty(); test_MsiGetProductProperty();
test_MsiSetProperty(); test_MsiSetProperty();
test_MsiApplyMultiplePatches();
} }
...@@ -649,6 +649,10 @@ UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR, DWORD, PMSIPATCHSEQUENCEINFOA ...@@ -649,6 +649,10 @@ UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR, DWORD, PMSIPATCHSEQUENCEINFOA
UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR, DWORD, PMSIPATCHSEQUENCEINFOW); UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR, DWORD, PMSIPATCHSEQUENCEINFOW);
#define MsiDetermineApplicablePatches WINELIB_NAME_AW(MsiDetermineApplicablePatches) #define MsiDetermineApplicablePatches WINELIB_NAME_AW(MsiDetermineApplicablePatches)
UINT WINAPI MsiApplyMultiplePatchesA(LPCSTR, LPCSTR, LPCSTR);
UINT WINAPI MsiApplyMultiplePatchesW(LPCWSTR, LPCWSTR, LPCWSTR);
#define MsiApplyMultiplePatches WINELIB_NAME_AW(MsiApplyMultiplePatches)
/* Non Unicode */ /* Non Unicode */
UINT WINAPI MsiCloseHandle(MSIHANDLE); UINT WINAPI MsiCloseHandle(MSIHANDLE);
UINT WINAPI MsiCloseAllHandles(void); UINT WINAPI MsiCloseAllHandles(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment