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