msi 3: Implement the MSIINSTALLCONTEXT_MACHINE context for MsiQueryComponentState

James Hawkins truiken at gmail.com
Mon Aug 6 22:48:34 CDT 2007


Hi,

Changelog:
* Implement the MSIINSTALLCONTEXT_MACHINE context for MsiQueryComponentState.

 dlls/msi/msi.c       |   45 ++++++++++++++++++++++++++--
 dlls/msi/msipriv.h   |    2 +
 dlls/msi/registry.c  |   60 ++++++++++++++++++++++++++++++++++++++
 dlls/msi/tests/msi.c |   80 ++++++++++++++++----------------------------------
 4 files changed, 129 insertions(+), 58 deletions(-)

-- 
James Hawkins
-------------- next part --------------
diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c
index 9b311d7..115f71b 100644
--- a/dlls/msi/msi.c
+++ b/dlls/msi/msi.c
@@ -764,14 +764,53 @@ UINT WINAPI MsiQueryComponentStateW(LPCW
                                     LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
                                     LPCWSTR szComponent, INSTALLSTATE *pdwState)
 {
-    FIXME("(%s, %s, %d, %s, %p): stub!\n", debugstr_w(szProductCode),
+    WCHAR squished_pc[GUID_SIZE];
+    HKEY hkey;
+    LONG res;
+    DWORD sz;
+    UINT r;
+
+    TRACE("(%s, %s, %d, %s, %p)\n", debugstr_w(szProductCode),
           debugstr_w(szUserSid), dwContext, debugstr_w(szComponent), pdwState);
 
     if (!pdwState)
         return ERROR_INVALID_PARAMETER;
 
-    *pdwState = INSTALLSTATE_UNKNOWN;
-    return ERROR_UNKNOWN_PRODUCT;
+    if (!szProductCode || !*szProductCode || lstrlenW(szProductCode) != GUID_SIZE - 1)
+        return ERROR_INVALID_PARAMETER;
+
+    if (!squash_guid(szProductCode, squished_pc))
+        return ERROR_INVALID_PARAMETER;
+
+    if (dwContext == MSIINSTALLCONTEXT_MACHINE)
+    {
+        r = MSIREG_OpenLocalSystemProductKey(szProductCode, &hkey, FALSE);
+        if (r != ERROR_SUCCESS)
+            return ERROR_UNKNOWN_PRODUCT;
+
+        RegCloseKey(hkey);
+        *pdwState = INSTALLSTATE_UNKNOWN;
+
+        r = MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE);
+        if (r != ERROR_SUCCESS)
+            return ERROR_UNKNOWN_COMPONENT;
+
+        sz = 0;
+        res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, NULL, &sz);
+        if (res != ERROR_SUCCESS)
+            return ERROR_UNKNOWN_COMPONENT;
+
+        RegCloseKey(hkey);
+
+        if (sz == 0)
+            *pdwState = INSTALLSTATE_NOTUSED;
+        else
+            *pdwState = INSTALLSTATE_LOCAL;
+
+        return ERROR_SUCCESS;
+    }
+
+    return ERROR_UNKNOWN_COMPONENT;
 }
 
 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index d4ccd80..799e90a 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -747,6 +747,8 @@ extern UINT MSIREG_OpenUserUpgradeCodesK
 extern UINT MSIREG_DeleteProductKey(LPCWSTR szProduct);
 extern UINT MSIREG_DeleteUserProductKey(LPCWSTR szProduct);
 extern UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct);
+extern UINT MSIREG_OpenLocalSystemProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create);
+extern UINT MSIREG_OpenLocalSystemComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create);
 
 extern LPWSTR msi_reg_get_val_str( HKEY hkey, LPCWSTR name );
 extern BOOL msi_reg_get_val_dword( HKEY hkey, LPCWSTR name, DWORD *val);
diff --git a/dlls/msi/registry.c b/dlls/msi/registry.c
index 6aedc71..67eae4b 100644
--- a/dlls/msi/registry.c
+++ b/dlls/msi/registry.c
@@ -195,6 +195,26 @@ static const WCHAR szInstallProperties_f
 '%','s','\\','P','r','o','d','u','c','t','s','\\','%','s','\\',
 'I','n','s','t','a','l','l','P','r','o','p','e','r','t','i','e','s',0};
 
+static const WCHAR szInstaller_LocalSystemProductCodes_fmt[] = {
+'S','o','f','t','w','a','r','e','\\',
+'M','i','c','r','o','s','o','f','t','\\',
+'W','i','n','d','o','w','s','\\',
+'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+'I','n','s','t','a','l','l','e','r','\\',
+'U','s','e','r','D','a','t','a','\\',
+'S','-','1','-','5','-','1','8','\\','P','r','o','d','u','c','t','s','\\',
+'%','s','\\','I','n','s','t','a','l','l','P','r','o','p','e','r','t','i','e','s',0};
+
+static const WCHAR szInstaller_LocalSystemComponent_fmt[] = {
+'S','o','f','t','w','a','r','e','\\',
+'M','i','c','r','o','s','o','f','t','\\',
+'W','i','n','d','o','w','s','\\',
+'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+'I','n','s','t','a','l','l','e','r','\\',
+'U','s','e','r','D','a','t','a','\\',
+'S','-','1','-','5','-','1','8','\\',
+'C','o','m','p','o','n','e','n','t','s','\\','%','s',0};
+
 
 #define SQUISH_GUID_SIZE 33
 
@@ -869,6 +889,46 @@ UINT MSIREG_OpenUserUpgradeCodesKey(LPCW
     return rc;
 }
 
+UINT MSIREG_OpenLocalSystemProductKey(LPCWSTR szProductCode, HKEY *key, BOOL create)
+{
+    WCHAR squished_pc[GUID_SIZE];
+    WCHAR keypath[0x200];
+
+    TRACE("%s\n", debugstr_w(szProductCode));
+
+    if (!squash_guid(szProductCode, squished_pc))
+        return ERROR_FUNCTION_FAILED;
+
+    TRACE("squished (%s)\n", debugstr_w(squished_pc));
+
+    sprintfW(keypath, szInstaller_LocalSystemProductCodes_fmt, squished_pc);
+
+    if (create)
+        return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+
+    return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+}
+
+UINT MSIREG_OpenLocalSystemComponentKey(LPCWSTR szComponent, HKEY *key, BOOL create)
+{
+    WCHAR squished_pc[GUID_SIZE];
+    WCHAR keypath[0x200];
+
+    TRACE("%s\n", debugstr_w(szComponent));
+
+    if (!squash_guid(szComponent, squished_pc))
+        return ERROR_FUNCTION_FAILED;
+
+    TRACE("squished (%s)\n", debugstr_w(squished_pc));
+
+    sprintfW(keypath, szInstaller_LocalSystemComponent_fmt, squished_pc);
+
+    if (create)
+        return RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+
+    return RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+}
+
 
 /*************************************************************************
  *  MsiDecomposeDescriptorW   [MSI.@]
diff --git a/dlls/msi/tests/msi.c b/dlls/msi/tests/msi.c
index 99be877..5a95ade 100644
--- a/dlls/msi/tests/msi.c
+++ b/dlls/msi/tests/msi.c
@@ -665,56 +665,38 @@ static void test_MsiQueryComponentState(
     /* NULL szProductCode */
     state = 0xdeadbeef;
     r = MsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
-    todo_wine
-    {
-        ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
-        ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
-    }
+    ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+    ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
 
     /* empty szProductCode */
     state = 0xdeadbeef;
     r = MsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);\
-    todo_wine
-    {
-        ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
-        ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
-    }
+    ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+    ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
 
     /* random szProductCode */
     state = 0xdeadbeef;
     r = MsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
-    todo_wine
-    {
-        ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
-        ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
-    }
+    ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+    ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
 
     /* GUID-length szProductCode */
     state = 0xdeadbeef;
     r = MsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
-    todo_wine
-    {
-        ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
-        ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
-    }
+    ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+    ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
 
     /* GUID-length with brackets */
     state = 0xdeadbeef;
     r = MsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
-    todo_wine
-    {
-        ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
-        ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
-    }
+    ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
+    ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
 
     /* actual GUID */
     state = 0xdeadbeef;
     r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
-    todo_wine
-    {
-        ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
-    }
+    ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
 
     /* create local system product key */
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
@@ -730,10 +712,7 @@ static void test_MsiQueryComponentState(
     /* local system product key exists */
     state = 0xdeadbeef;
     r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
-    todo_wine
-    {
-        ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
-    }
+    ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
@@ -745,10 +724,7 @@ static void test_MsiQueryComponentState(
     /* component key exists */
     state = 0xdeadbeef;
     r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
-    todo_wine
-    {
-        ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
-    }
+    ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
 
     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
@@ -757,22 +733,16 @@ static void test_MsiQueryComponentState(
     /* component\product exists */
     state = 0xdeadbeef;
     r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
-    todo_wine
-    {
-        ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
-        ok(state == INSTALLSTATE_NOTUSED, "Expected INSTALLSTATE_NOTUSED, got %d\n", state);
-    }
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(state == INSTALLSTATE_NOTUSED, "Expected INSTALLSTATE_NOTUSED, got %d\n", state);
 
     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     state = 0xdeadbeef;
     r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
-    todo_wine
-    {
-        ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
-        ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
-    }
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
 
     RegDeleteValueA(prodkey, "LocalPackage");
     RegDeleteKeyA(prodkey, "");
@@ -785,11 +755,11 @@ static void test_MsiQueryComponentState(
 
     state = 0xdeadbeef;
     r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
-    ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
     todo_wine
     {
-        ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
+        ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
     }
+    ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
     lstrcatA(keypath, usersid);
@@ -805,11 +775,11 @@ static void test_MsiQueryComponentState(
 
     state = 0xdeadbeef;
     r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
+    ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
     todo_wine
     {
-        ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
+        ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
     }
-    ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
     lstrcatA(keypath, usersid);
@@ -822,11 +792,11 @@ static void test_MsiQueryComponentState(
     /* component key exists */
     state = 0xdeadbeef;
     r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, component, &state);
+    ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
     todo_wine
     {
-        ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
+        ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
     }
-    ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
 
     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
@@ -855,11 +825,11 @@ static void test_MsiQueryComponentState(
 
     state = 0xdeadbeef;
     r = MsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_USERMANAGED, component, &state);
-    ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
     todo_wine
     {
-        ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
+        ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
     }
+    ok(state == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", state);
 
     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
-- 
1.4.1


More information about the wine-patches mailing list