[MSI_WINETEST]: Sync with Wine 1.5.19.
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 9 Dec 2012 19:52:12 +0000 (19:52 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 9 Dec 2012 19:52:12 +0000 (19:52 +0000)
svn path=/trunk/; revision=57852

rostests/winetests/msi/action.c
rostests/winetests/msi/format.c
rostests/winetests/msi/package.c

index 1fcb82d..5de3155 100644 (file)
@@ -490,7 +490,14 @@ static const char wrv_registry_dat[] =
     "regdata1\t2\tSOFTWARE\\Wine\\msitest\t*\t\taugustus\n"
     "regdata2\t2\tSOFTWARE\\Wine\\msitest\t*\t#%\taugustus\n"
     "regdata3\t2\tSOFTWARE\\Wine\\msitest\t*\t#x\taugustus\n"
-    "regdata4\t2\tSOFTWARE\\Wine\\msitest\\VisualStudio\\10.0\\AD7Metrics\\Exception\\{049EC4CC-30D2-4032-9256-EE18EB41B62B}\\Common Language Runtime Exceptions\\System.Workflow.ComponentModel.Serialization\\System.Workflow.ComponentModel.Serialization.WorkflowMarkupSerializationException\tlong\tkey\taugustus\n";
+    "regdata4\t2\tSOFTWARE\\Wine\\msitest\\VisualStudio\\10.0\\AD7Metrics\\Exception\\{049EC4CC-30D2-4032-9256-EE18EB41B62B}\\Common Language Runtime Exceptions\\System.Workflow.ComponentModel.Serialization\\System.Workflow.ComponentModel.Serialization.WorkflowMarkupSerializationException\tlong\tkey\taugustus\n"
+    "regdata5\t2\tSOFTWARE\\Wine\\msitest\tValue1\t[~]one[~]\taugustus\n"
+    "regdata6\t2\tSOFTWARE\\Wine\\msitest\tValue2\t[~]two\taugustus\n"
+    "regdata7\t2\tSOFTWARE\\Wine\\msitest\tValue3\tone[~]\taugustus\n"
+    "regdata8\t2\tSOFTWARE\\Wine\\msitest\tValue4\tone[~]two\taugustus\n"
+    "regdata9\t2\tSOFTWARE\\Wine\\msitest\tValue5\t[~]one[~]two[~]three\taugustus\n"
+    "regdata10\t2\tSOFTWARE\\Wine\\msitest\tValue6\t[~]\taugustus\n"
+    "regdata11\t2\tSOFTWARE\\Wine\\msitest\tValue7\t[~]two\taugustus\n";
 
 static const char cf_directory_dat[] =
     "Directory\tDirectory_Parent\tDefaultDir\n"
@@ -2610,36 +2617,46 @@ static void check_reg_dword5(HKEY prodkey, LPCSTR name, DWORD expected1, DWORD e
     check_reg_str(prodkey, name, expected, TRUE, __LINE__);
 
 #define CHECK_DEL_REG_STR(prodkey, name, expected) \
-    check_reg_str(prodkey, name, expected, TRUE, __LINE__); \
-    RegDeleteValueA(prodkey, name);
+    do { \
+        check_reg_str(prodkey, name, expected, TRUE, __LINE__); \
+        RegDeleteValueA(prodkey, name); \
+    } while(0)
 
 #define CHECK_REG_ISTR(prodkey, name, expected) \
     check_reg_str(prodkey, name, expected, FALSE, __LINE__);
 
 #define CHECK_DEL_REG_ISTR(prodkey, name, expected) \
-    check_reg_str(prodkey, name, expected, FALSE, __LINE__); \
-    RegDeleteValueA(prodkey, name);
+    do { \
+        check_reg_str(prodkey, name, expected, FALSE, __LINE__); \
+        RegDeleteValueA(prodkey, name); \
+    } while(0)
 
 #define CHECK_REG_DWORD(prodkey, name, expected) \
     check_reg_dword(prodkey, name, expected, __LINE__);
 
 #define CHECK_DEL_REG_DWORD(prodkey, name, expected) \
-    check_reg_dword(prodkey, name, expected, __LINE__); \
-    RegDeleteValueA(prodkey, name);
+    do { \
+        check_reg_dword(prodkey, name, expected, __LINE__); \
+        RegDeleteValueA(prodkey, name); \
+    } while(0)
 
 #define CHECK_REG_DWORD2(prodkey, name, expected1, expected2) \
     check_reg_dword2(prodkey, name, expected1, expected2, __LINE__);
 
 #define CHECK_DEL_REG_DWORD2(prodkey, name, expected1, expected2) \
-    check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); \
-    RegDeleteValueA(prodkey, name);
+    do { \
+        check_reg_dword2(prodkey, name, expected1, expected2, __LINE__); \
+        RegDeleteValueA(prodkey, name); \
+    } while(0)
 
 #define CHECK_REG_DWORD4(prodkey, name, expected1, expected2, expected3, expected4) \
     check_reg_dword4(prodkey, name, expected1, expected2, expected3, expected4, __LINE__);
 
 #define CHECK_DEL_REG_DWORD5(prodkey, name, expected1, expected2, expected3, expected4 ,expected5) \
-    check_reg_dword5(prodkey, name, expected1, expected2, expected3, expected4, expected5, __LINE__); \
-    RegDeleteValueA(prodkey, name);
+    do { \
+        check_reg_dword5(prodkey, name, expected1, expected2, expected3, expected4, expected5, __LINE__); \
+        RegDeleteValueA(prodkey, name); \
+    } while(0)
 
 static void get_date_str(LPSTR date)
 {
@@ -4709,6 +4726,30 @@ static void test_write_registry_values(void)
 
     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
 
+    if (is_64bit)
+        res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Wine\\msitest", 0, NULL, 0,
+                              KEY_ALL_ACCESS, NULL, &hkey, NULL);
+    else
+        res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", 0, NULL, 0, KEY_ALL_ACCESS,
+                              NULL, &hkey, NULL);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+
+    res = RegSetValueExA(hkey, "Value1", 0, REG_MULTI_SZ, (const BYTE *)"two\0", 5);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    res = RegSetValueExA(hkey, "Value2", 0, REG_MULTI_SZ, (const BYTE *)"one\0", 5);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    res = RegSetValueExA(hkey, "Value3", 0, REG_MULTI_SZ, (const BYTE *)"two\0", 5);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    res = RegSetValueExA(hkey, "Value4", 0, REG_MULTI_SZ, (const BYTE *)"one\0", 5);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    res = RegSetValueExA(hkey, "Value5", 0, REG_MULTI_SZ, (const BYTE *)"one\0two\0", 9);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    res = RegSetValueExA(hkey, "Value6", 0, REG_MULTI_SZ, (const BYTE *)"one\0", 5);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    res = RegSetValueExA(hkey, "Value7", 0, REG_SZ, (const BYTE *)"one", 4);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    RegCloseKey(hkey);
+
     r = MsiInstallProductA(msifile, NULL);
     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
     {
@@ -4740,7 +4781,77 @@ static void test_write_registry_values(void)
     res = action_RegDeleteTreeA(hkey, "VisualStudio", KEY_ALL_ACCESS);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
+    size = MAX_PATH;
+    type = 0xdeadbeef;
+    memset(path, 'a', MAX_PATH);
+    res = RegQueryValueExA(hkey, "Value1", NULL, &type, (LPBYTE)path, &size);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    ok(!memcmp(path, "one\0", size), "Wrong multi-sz data\n");
+    ok(size == 5, "Expected 5, got %d\n", size);
+    ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
+
+    size = MAX_PATH;
+    type = 0xdeadbeef;
+    memset(path, 'a', MAX_PATH);
+    res = RegQueryValueExA(hkey, "Value2", NULL, &type, (LPBYTE)path, &size);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    ok(!memcmp(path, "one\0two\0", size), "Wrong multi-sz data\n");
+    ok(size == 9, "Expected 9, got %d\n", size);
+    ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
+
+    size = MAX_PATH;
+    type = 0xdeadbeef;
+    memset(path, 'a', MAX_PATH);
+    res = RegQueryValueExA(hkey, "Value3", NULL, &type, (LPBYTE)path, &size);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    ok(!memcmp(path, "one\0two\0", size), "Wrong multi-sz data\n");
+    ok(size == 9, "Expected 9, got %d\n", size);
+    ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
+
+    size = MAX_PATH;
+    type = 0xdeadbeef;
+    memset(path, 'a', MAX_PATH);
+    res = RegQueryValueExA(hkey, "Value4", NULL, &type, (LPBYTE)path, &size);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    ok(!memcmp(path, "one\0two\0", size), "Wrong multi-sz data\n");
+    ok(size == 9, "Expected 9, got %d\n", size);
+    ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
+
+    size = MAX_PATH;
+    type = 0xdeadbeef;
+    memset(path, 'a', MAX_PATH);
+    res = RegQueryValueExA(hkey, "Value5", NULL, &type, (LPBYTE)path, &size);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    ok(!memcmp(path, "one\0two\0three\0", size), "Wrong multi-sz data\n");
+    ok(size == 15, "Expected 15, got %d\n", size);
+    ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
+
+    size = MAX_PATH;
+    type = 0xdeadbeef;
+    memset(path, 'a', MAX_PATH);
+    res = RegQueryValueExA(hkey, "Value6", NULL, &type, (LPBYTE)path, &size);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    ok(!memcmp(path, "", size), "Wrong multi-sz data\n");
+    ok(size == 1, "Expected 1, got %d\n", size);
+    ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
+
+    size = MAX_PATH;
+    type = 0xdeadbeef;
+    memset(path, 'a', MAX_PATH);
+    res = RegQueryValueExA(hkey, "Value7", NULL, &type, (LPBYTE)path, &size);
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    ok(!memcmp(path, "two\0", size), "Wrong multi-sz data\n");
+    ok(size == 5, "Expected 5, got %d\n", size);
+    ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type);
+
     RegDeleteValueA(hkey, "Value");
+    RegDeleteValueA(hkey, "Value1");
+    RegDeleteValueA(hkey, "Value2");
+    RegDeleteValueA(hkey, "Value3");
+    RegDeleteValueA(hkey, "Value4");
+    RegDeleteValueA(hkey, "Value5");
+    RegDeleteValueA(hkey, "Value6");
+    RegDeleteValueA(hkey, "Value7");
     RegCloseKey(hkey);
     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
 
index 3ecfc66..c181037 100644 (file)
@@ -2530,6 +2530,9 @@ static void test_formatrecord_tables(void)
     r = add_custom_action_entry( hdb, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" );
     ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r);
 
+    r = add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop', '[~]np'" );
+    ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r);
+
     r = package_from_db( hdb, &hpkg );
     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
     {
@@ -2661,7 +2664,7 @@ static void test_formatrecord_tables(void)
 
     /* custom action 51, escaped text 1 */
     r = MsiDoAction( hpkg, "EscapeIt1" );
-    ok( r == ERROR_SUCCESS, "EscapeIt failed: %d\n", r);
+    ok( r == ERROR_SUCCESS, "EscapeIt1 failed: %d\n", r);
 
     size = MAX_PATH;
     r = MsiGetProperty( hpkg, "prop", buf, &size );
@@ -2670,7 +2673,7 @@ static void test_formatrecord_tables(void)
 
     /* custom action 51, escaped text 2 */
     r = MsiDoAction( hpkg, "EscapeIt2" );
-    ok( r == ERROR_SUCCESS, "EscapeIt failed: %d\n", r);
+    ok( r == ERROR_SUCCESS, "EscapeIt2 failed: %d\n", r);
 
     size = MAX_PATH;
     r = MsiGetProperty( hpkg, "prop", buf, &size );
@@ -2679,13 +2682,33 @@ static void test_formatrecord_tables(void)
 
     /* custom action 51, escaped text 3 */
     r = MsiDoAction( hpkg, "EscapeIt3" );
-    ok( r == ERROR_SUCCESS, "EscapeIt failed: %d\n", r);
+    ok( r == ERROR_SUCCESS, "EscapeIt3 failed: %d\n", r);
 
     size = MAX_PATH;
     r = MsiGetProperty( hpkg, "prop", buf, &size );
     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
     ok( !lstrcmp( buf, "" ), "Expected '', got %s\n", buf);
 
+    /* custom action 51, embedded null */
+    r = MsiDoAction( hpkg, "EmbedNull" );
+    ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
+
+    size = MAX_PATH;
+    memset( buf, 'a', sizeof(buf) );
+    r = MsiGetProperty( hpkg, "prop", buf, &size );
+    ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
+    ok( !memcmp( buf, "\0np", sizeof("\0np") ), "wrong value\n");
+    ok( size == sizeof("\0np") - 1, "got %u\n", size );
+
+    r = MsiSetProperty( hpkg, "prop", "[~]np" );
+    ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
+
+    size = MAX_PATH;
+    memset( buf, 'a', sizeof(buf) );
+    r = MsiGetProperty( hpkg, "prop", buf, &size );
+    ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
+    ok( !lstrcmp( buf, "[~]np" ), "Expected '[~]np', got %s\n", buf);
+
     sprintf( expected, "1: %sI am a really long directory\\ ", root);
 
     /* component with INSTALLSTATE_LOCAL */
index 92a0f9a..4bac512 100644 (file)
@@ -593,6 +593,17 @@ static UINT create_inilocator_table( MSIHANDLE hdb )
             "PRIMARY KEY `Signature_`)" );
 }
 
+static UINT create_custom_action_table( MSIHANDLE hdb )
+{
+    return run_query( hdb,
+            "CREATE TABLE `CustomAction` ("
+            "`Action` CHAR(72) NOT NULL, "
+            "`Type` SHORT NOT NULL, "
+            "`Source` CHAR(75), "
+            "`Target` CHAR(255) "
+            "PRIMARY KEY `Action`)" );
+}
+
 #define make_add_entry(type, qtext) \
     static UINT add##_##type##_##entry( MSIHANDLE hdb, const char *values ) \
     { \
@@ -672,6 +683,10 @@ make_add_entry(inilocator,
                "(`Signature_`, `FileName`, `Section`, `Key`, `Field`, `Type`) "
                "VALUES( %s )")
 
+make_add_entry(custom_action,
+               "INSERT INTO `CustomAction`  "
+               "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )")
+
 static UINT add_reglocator_entry( MSIHANDLE hdb, const char *sig, UINT root, const char *path,
                                   const char *name, UINT type )
 {
@@ -2139,10 +2154,10 @@ static void test_props(void)
     DeleteFile(msifile);
 }
 
-static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val)
+static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val, int len)
 {
     MSIHANDLE hview, hrec;
-    BOOL found;
+    BOOL found = FALSE;
     CHAR buffer[MAX_PATH];
     DWORD sz;
     UINT r;
@@ -2152,7 +2167,8 @@ static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val)
     r = MsiViewExecute(hview, 0);
     ok(r == ERROR_SUCCESS, "MsiViewExecute failed\n");
 
-    found = FALSE;
+    if (len < 0) len = lstrlenA(val);
+
     while (r == ERROR_SUCCESS && !found)
     {
         r = MsiViewFetch(hview, &hrec);
@@ -2164,16 +2180,17 @@ static BOOL find_prop_in_property(MSIHANDLE hdb, LPCSTR prop, LPCSTR val)
         {
             sz = MAX_PATH;
             r = MsiRecordGetString(hrec, 2, buffer, &sz);
-            if (r == ERROR_SUCCESS && !lstrcmpA(buffer, val))
+            if (r == ERROR_SUCCESS && !memcmp(buffer, val, len) && !buffer[len])
+            {
+                ok(sz == len, "wrong size %u\n", sz);
                 found = TRUE;
+            }
         }
 
         MsiCloseHandle(hrec);
     }
-
     MsiViewClose(hview);
     MsiCloseHandle(hview);
-
     return found;
 }
 
@@ -2249,6 +2266,12 @@ static void test_property_table(void)
     r = add_property_entry(hdb, "'prop', 'val'");
     ok(r == ERROR_SUCCESS, "cannot add property: %d\n", r);
 
+    r = create_custom_action_table(hdb);
+    ok(r == ERROR_SUCCESS, "cannot create CustomAction table: %d\n", r);
+
+    r = add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop2', '[~]np'" );
+    ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r);
+
     r = package_from_db(hdb, &hpkg);
     ok(r == ERROR_SUCCESS, "failed to create package %u\n", r);
 
@@ -2261,7 +2284,7 @@ static void test_property_table(void)
 
     hdb = MsiGetActiveDatabase(hpkg);
 
-    found = find_prop_in_property(hdb, "prop", "val");
+    found = find_prop_in_property(hdb, "prop", "val", -1);
     ok(found, "prop should be in the _Property table\n");
 
     r = add_property_entry(hdb, "'dantes', 'mercedes'");
@@ -2271,7 +2294,7 @@ static void test_property_table(void)
     r = do_query(hdb, query, &hrec);
     ok(r == ERROR_BAD_QUERY_SYNTAX, "Expected ERROR_BAD_QUERY_SYNTAX, got %d\n", r);
 
-    found = find_prop_in_property(hdb, "dantes", "mercedes");
+    found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
     ok(found == FALSE, "dantes should not be in the _Property table\n");
 
     sz = MAX_PATH;
@@ -2283,9 +2306,22 @@ static void test_property_table(void)
     r = MsiSetProperty(hpkg, "dantes", "mercedes");
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
-    found = find_prop_in_property(hdb, "dantes", "mercedes");
+    found = find_prop_in_property(hdb, "dantes", "mercedes", -1);
     ok(found == TRUE, "dantes should be in the _Property table\n");
 
+    r = MsiDoAction( hpkg, "EmbedNull" );
+    ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
+
+    sz = MAX_PATH;
+    memset( buffer, 'a', sizeof(buffer) );
+    r = MsiGetProperty( hpkg, "prop2", buffer, &sz );
+    ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
+    ok( !memcmp( buffer, "\0np", sizeof("\0np") ), "wrong value\n");
+    ok( sz == sizeof("\0np") - 1, "got %u\n", sz );
+
+    found = find_prop_in_property(hdb, "prop2", "\0np", 3);
+    ok(found == TRUE, "prop2 should be in the _Property table\n");
+
     MsiCloseHandle(hdb);
     MsiCloseHandle(hpkg);
     DeleteFile(msifile);
@@ -4115,7 +4151,7 @@ static void test_appsearch_reglocator(void)
                          (const BYTE *)path, lstrlenA(path) + 1);
     ok( res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
 
-    space = (strchr(CURR_DIR, ' ')) ? TRUE : FALSE;
+    space = strchr(CURR_DIR, ' ') != NULL;
     sprintf(path, "%s\\FileName1 -option", CURR_DIR);
     res = RegSetValueExA(hklm, "value17", 0, REG_SZ,
                          (const BYTE *)path, lstrlenA(path) + 1);