Commit 44349af1 authored by James Hawkins's avatar James Hawkins Committed by Alexandre Julliard

msi: Reimplement MsiGetProductCode.

parent 2634d86a
......@@ -487,9 +487,10 @@ UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
return ERROR_OUTOFMEMORY;
}
*szwBuffer = '\0';
r = MsiGetProductCodeW( szwComponent, szwBuffer );
if( ERROR_SUCCESS == r )
if(*szwBuffer)
WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
msi_free( szwComponent );
......@@ -499,38 +500,65 @@ UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
{
UINT rc;
HKEY hkey;
WCHAR szSquished[GUID_SIZE];
UINT rc, index;
HKEY compkey, prodkey;
WCHAR squished_comp[GUID_SIZE];
WCHAR squished_prod[GUID_SIZE];
DWORD sz = GUID_SIZE;
static const WCHAR szPermKey[] =
{ '0','0','0','0','0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0',0};
TRACE("%s %p\n",debugstr_w(szComponent), szBuffer);
TRACE("%s %p\n", debugstr_w(szComponent), szBuffer);
if (NULL == szComponent)
if (!szComponent || !*szComponent)
return ERROR_INVALID_PARAMETER;
rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
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)
{
return ERROR_UNKNOWN_COMPONENT;
}
rc = RegEnumValueW(compkey, 0, squished_prod, &sz, NULL, NULL, NULL, NULL);
if (rc != ERROR_SUCCESS)
{
RegCloseKey(compkey);
return ERROR_UNKNOWN_COMPONENT;
}
rc = RegEnumValueW(hkey, 0, szSquished, &sz, NULL, NULL, NULL, NULL);
if (rc == ERROR_SUCCESS && strcmpW(szSquished,szPermKey)==0)
/* check simple case, only one product */
rc = RegEnumValueW(compkey, 1, squished_prod, &sz, NULL, NULL, NULL, NULL);
if (rc == ERROR_NO_MORE_ITEMS)
{
sz = GUID_SIZE;
rc = RegEnumValueW(hkey, 1, szSquished, &sz, NULL, NULL, NULL, NULL);
rc = ERROR_SUCCESS;
goto done;
}
RegCloseKey(hkey);
index = 0;
while ((rc = RegEnumValueW(compkey, index, squished_prod, &sz,
NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS)
{
index++;
sz = GUID_SIZE;
unsquash_guid(squished_prod, szBuffer);
if (rc != ERROR_SUCCESS)
return ERROR_INSTALL_FAILURE;
if (MSIREG_OpenLocalManagedProductKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS ||
MSIREG_OpenUserProductsKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS ||
MSIREG_OpenLocalClassesProductKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS)
{
RegCloseKey(prodkey);
rc = ERROR_SUCCESS;
goto done;
}
}
unsquash_guid(szSquished, szBuffer);
return ERROR_SUCCESS;
rc = ERROR_INSTALL_FAILURE;
done:
RegCloseKey(compkey);
unsquash_guid(squished_prod, szBuffer);
return rc;
}
static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
......
......@@ -1359,28 +1359,19 @@ static void test_MsiGetProductCode(void)
/* szComponent is empty */
lstrcpyA(product, "prod");
r = MsiGetProductCodeA("", product);
todo_wine
{
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
}
ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
/* garbage szComponent */
lstrcpyA(product, "prod");
r = MsiGetProductCodeA("garbage", product);
todo_wine
{
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
}
ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
/* guid without brackets */
lstrcpyA(product, "prod");
r = MsiGetProductCodeA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", product);
todo_wine
{
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
}
ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
/* guid with brackets */
......@@ -1392,10 +1383,7 @@ static void test_MsiGetProductCode(void)
/* same length as guid, but random */
lstrcpyA(product, "prod");
r = MsiGetProductCodeA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", product);
todo_wine
{
ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
}
ok(!lstrcmpA(product, "prod"), "Expected product to be unchanged, got %s\n", product);
/* all params correct, szComponent not published */
......@@ -1425,11 +1413,8 @@ static void test_MsiGetProductCode(void)
/* product value exists */
lstrcpyA(product, "prod");
r = MsiGetProductCodeA(component, product);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
}
res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
......@@ -1446,11 +1431,8 @@ static void test_MsiGetProductCode(void)
/* user managed product key of first product exists */
lstrcpyA(product, "prod");
r = MsiGetProductCodeA(component, product);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
}
RegDeleteKeyA(prodkey, "");
RegCloseKey(prodkey);
......@@ -1467,11 +1449,8 @@ static void test_MsiGetProductCode(void)
/* user unmanaged product key exists */
lstrcpyA(product, "prod");
r = MsiGetProductCodeA(component, product);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
}
RegDeleteKeyA(prodkey, "");
RegCloseKey(prodkey);
......@@ -1485,11 +1464,8 @@ static void test_MsiGetProductCode(void)
/* local classes product key exists */
lstrcpyA(product, "prod");
r = MsiGetProductCodeA(component, product);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
}
RegDeleteKeyA(prodkey, "");
RegCloseKey(prodkey);
......@@ -1506,11 +1482,8 @@ static void test_MsiGetProductCode(void)
/* user managed product key of second product exists */
lstrcpyA(product, "prod");
r = MsiGetProductCodeA(component, product);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
}
RegDeleteKeyA(prodkey, "");
RegCloseKey(prodkey);
......@@ -1538,11 +1511,8 @@ static void test_MsiGetProductCode(void)
/* product value exists */
lstrcpyA(product, "prod");
r = MsiGetProductCodeA(component, product);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
}
res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
......@@ -1559,11 +1529,8 @@ static void test_MsiGetProductCode(void)
/* user managed product key of first product exists */
lstrcpyA(product, "prod");
r = MsiGetProductCodeA(component, product);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
}
RegDeleteKeyA(prodkey, "");
RegCloseKey(prodkey);
......@@ -1577,11 +1544,8 @@ static void test_MsiGetProductCode(void)
/* user unmanaged product key exists */
lstrcpyA(product, "prod");
r = MsiGetProductCodeA(component, product);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
}
RegDeleteKeyA(prodkey, "");
RegCloseKey(prodkey);
......@@ -1595,11 +1559,8 @@ static void test_MsiGetProductCode(void)
/* local classes product key exists */
lstrcpyA(product, "prod");
r = MsiGetProductCodeA(component, product);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
}
RegDeleteKeyA(prodkey, "");
RegCloseKey(prodkey);
......@@ -1616,11 +1577,8 @@ static void test_MsiGetProductCode(void)
/* user managed product key of second product exists */
lstrcpyA(product, "prod");
r = MsiGetProductCodeA(component, product);
todo_wine
{
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
}
RegDeleteKeyA(prodkey, "");
RegCloseKey(prodkey);
......
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