Commit 438ad93b authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msi: Implement and test MsiGetPatchInfoA/W.

parent 38933b1a
......@@ -1613,6 +1613,93 @@ done:
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;
......
......@@ -171,8 +171,8 @@
175 stdcall MsiApplyPatchW(wstr wstr long wstr)
176 stdcall MsiAdvertiseScriptA(str long ptr long)
177 stdcall MsiAdvertiseScriptW(wstr long ptr long)
178 stub MsiGetPatchInfoA
179 stub MsiGetPatchInfoW
178 stdcall MsiGetPatchInfoA(str str ptr ptr)
179 stdcall MsiGetPatchInfoW(wstr wstr ptr ptr)
180 stdcall MsiEnumPatchesA(str long ptr ptr ptr)
181 stdcall MsiEnumPatchesW(str long ptr ptr ptr)
182 stdcall -private DllGetVersion(ptr)
......
......@@ -10888,6 +10888,183 @@ static void test_MsiGetPatchInfoEx(void)
LocalFree(usersid);
}
static void test_MsiGetPatchInfo(void)
{
UINT r;
char prod_code[MAX_PATH], prod_squashed[MAX_PATH], val[MAX_PATH];
char patch_code[MAX_PATH], patch_squashed[MAX_PATH], keypath[MAX_PATH];
WCHAR valW[MAX_PATH], patch_codeW[MAX_PATH];
HKEY hkey_product, hkey_patch, hkey_patches, hkey_udprops, hkey_udproduct;
HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
DWORD size;
LONG res;
create_test_guid(patch_code, patch_squashed);
create_test_guid(prod_code, prod_squashed);
MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
r = MsiGetPatchInfoA(patch_code, NULL, NULL, NULL);
ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, NULL, NULL);
ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
size = 0;
r = MsiGetPatchInfoA(patch_code, NULL, NULL, &size);
ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
r = MsiGetPatchInfoA(patch_code, "", NULL, &size);
ok(r == ERROR_UNKNOWN_PROPERTY, "expected ERROR_UNKNOWN_PROPERTY, got %u\n", r);
lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
lstrcatA(keypath, prod_squashed);
res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_product);
ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
/* product key exists */
size = MAX_PATH;
lstrcpyA(val, "apple");
r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
res = RegCreateKeyA(hkey_product, "Patches", &hkey_patches);
ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
/* patches key exists */
size = MAX_PATH;
lstrcpyA(val, "apple");
r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
res = RegCreateKeyA(hkey_patches, patch_squashed, &hkey_patch);
ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
/* patch key exists */
size = MAX_PATH;
lstrcpyA(val, "apple");
r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
lstrcatA(keypath, prod_squashed);
res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_udproduct);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
/* UserData product key exists */
size = MAX_PATH;
lstrcpyA(val, "apple");
r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
res = RegCreateKeyA(hkey_udproduct, "InstallProperties", &hkey_udprops);
ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
/* InstallProperties key exists */
size = MAX_PATH;
lstrcpyA(val, "apple");
r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
res = RegCreateKeyA(hkey_udproduct, "Patches", &hkey_udpatches);
ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
/* UserData Patches key exists */
size = MAX_PATH;
lstrcpyA(val, "apple");
r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
res = RegCreateKeyA(hkey_udproduct, "Patches", &hkey_udproductpatches);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
res = RegCreateKeyA(hkey_udproductpatches, patch_squashed, &hkey_udproductpatch);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
/* UserData product patch key exists */
size = MAX_PATH;
lstrcpyA(val, "apple");
r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT got %u\n", r);
ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer");
lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
lstrcatA(keypath, patch_squashed);
res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_udpatch);
ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
/* UserData Patch key exists */
size = 0;
lstrcpyA(val, "apple");
r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
ok(!lstrcmpA(val, "apple"), "expected \"apple\", got \"%s\"\n", val);
ok(size == 11, "expected 11 got %u\n", size);
size = MAX_PATH;
lstrcpyA(val, "apple");
r = MsiGetPatchInfoA(patch_code, INSTALLPROPERTY_LOCALPACKAGEA, val, &size);
ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
ok(!lstrcmpA(val, "c:\\test.msp"), "expected \"c:\\test.msp\", got \"%s\"\n", val);
ok(size == 11, "expected 11 got %u\n", size);
size = 0;
valW[0] = 0;
r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
ok(r == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", r);
ok(!valW[0], "expected 0 got %u\n", valW[0]);
ok(size == 11, "expected 11 got %u\n", size);
size = MAX_PATH;
valW[0] = 0;
r = MsiGetPatchInfoW(patch_codeW, INSTALLPROPERTY_LOCALPACKAGEW, valW, &size);
ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS got %u\n", r);
ok(valW[0], "expected > 0 got %u\n", valW[0]);
ok(size == 11, "expected 11 got %u\n", size);
RegDeleteKeyA(hkey_udproductpatch, "");
RegCloseKey(hkey_udproductpatch);
RegDeleteKeyA(hkey_udproductpatches, "");
RegCloseKey(hkey_udproductpatches);
RegDeleteKeyA(hkey_udpatch, "");
RegCloseKey(hkey_udpatch);
RegDeleteKeyA(hkey_patches, "");
RegCloseKey(hkey_patches);
RegDeleteKeyA(hkey_product, "");
RegCloseKey(hkey_product);
RegDeleteKeyA(hkey_patch, "");
RegCloseKey(hkey_patch);
RegDeleteKeyA(hkey_udpatches, "");
RegCloseKey(hkey_udpatches);
RegDeleteKeyA(hkey_udprops, "");
RegCloseKey(hkey_udprops);
RegDeleteKeyA(hkey_udproduct, "");
RegCloseKey(hkey_udproduct);
}
static void test_MsiEnumProducts(void)
{
UINT r;
......@@ -10985,6 +11162,7 @@ START_TEST(msi)
test_MsiEnumPatchesEx();
test_MsiEnumPatches();
test_MsiGetPatchInfoEx();
test_MsiGetPatchInfo();
test_MsiEnumProducts();
}
......
......@@ -503,6 +503,10 @@ UINT WINAPI MsiGetPatchInfoExA(LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR
UINT WINAPI MsiGetPatchInfoExW(LPCWSTR, LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, LPCWSTR, LPWSTR, LPDWORD);
#define MsiGetPatchInfoEx WINELIB_NAME_AW(MsiGetPatchInfoEx)
UINT WINAPI MsiGetPatchInfoA(LPCSTR, LPCSTR, LPSTR, LPDWORD);
UINT WINAPI MsiGetPatchInfoW(LPCWSTR, LPCWSTR, LPWSTR, LPDWORD);
#define MsiGetPatchInfo WINELIB_NAME_AW(MsiGetPatchInfo)
UINT WINAPI MsiEnableLogA(DWORD, LPCSTR, DWORD);
UINT WINAPI MsiEnableLogW(DWORD, LPCWSTR, DWORD);
#define MsiEnableLog WINELIB_NAME_AW(MsiEnableLog)
......
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