msi: Implement MsiDatabaseImport [try3]

James Hawkins truiken at gmail.com
Thu Sep 28 14:58:16 CDT 2006


Hi,

This version fixes leaks.

Changelog:
* Implement MsiDatabaseImport.

 dlls/msi/database.c      |  413 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/msi/tests/db.c      |   87 +++-------
 dlls/msi/tests/install.c |   68 ++------
 3 files changed, 462 insertions(+), 106 deletions(-)

-- 
James Hawkins
-------------- next part --------------
diff --git a/dlls/msi/database.c b/dlls/msi/database.c
index fa40c08..5634ebf 100644
--- a/dlls/msi/database.c
+++ b/dlls/msi/database.c
@@ -262,14 +262,419 @@ end:
     return r;
 }
 
-UINT MSI_DatabaseImport( MSIDATABASE *db, LPCWSTR folder, LPCWSTR file )
+static LPWSTR msi_read_text_archive(LPCWSTR path)
 {
-    FIXME("%p %s %s\n", db, debugstr_w(folder), debugstr_w(file) );
+    HANDLE file;
+    LPSTR data = NULL;
+    LPWSTR wdata = NULL;
+    DWORD read, size = 0;
+
+    file = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
+    if (file == INVALID_HANDLE_VALUE)
+        return NULL;
+
+    size = GetFileSize( file, NULL );
+    data = msi_alloc( size + 1 );
+    if (!data)
+        goto done;
+
+    if (!ReadFile( file, data, size, &read, NULL ))
+        goto done;
+
+    data[size] = '\0';
+    wdata = strdupAtoW( data );
+
+done:
+    CloseHandle( file );
+    msi_free( data );
+    return wdata;
+}
+
+static void msi_parse_line(LPWSTR *line, LPWSTR **entries, DWORD *num_entries)
+{
+    LPWSTR ptr = *line, save;
+    DWORD i, count = 1;
+
+    *entries = NULL;
+
+    /* stay on this line */
+    while (*ptr && *ptr != '\n')
+    {
+        /* entries are separated by tabs */
+        if (*ptr == '\t')
+            count++;
+
+        ptr++;
+    }
+
+    *entries = msi_alloc(count * sizeof(LPWSTR));
+    if (!*entries)
+        return;
+
+    /* store pointers into the data */
+    for (i = 0, ptr = *line; i < count; i++)
+    {
+        save = ptr;
+
+        while (*ptr && *ptr != '\t' && *ptr != '\n') ptr++;
+
+        /* NULL-separate the data */
+        if (*ptr)
+            *ptr++ = '\0';
+
+        (*entries)[i] = save;
+    }
+
+    /* move to the next line if there's more, else EOF */
+    *line = ptr;
+
+    if (num_entries)
+        *num_entries = count;
+}
+
+static LPWSTR msi_build_createsql_prelude(LPWSTR table)
+{
+    LPWSTR prelude;
+    DWORD size;
+
+    static const WCHAR create_fmt[] = {'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','%','s','`',' ','(',' ',0};
+
+    size = sizeof(create_fmt) + lstrlenW(table) - 2;
+    prelude = msi_alloc(size * sizeof(WCHAR));
+    if (!prelude)
+        return NULL;
+
+    sprintfW(prelude, create_fmt, table);
+    return prelude;
+}
+
+static LPWSTR msi_build_createsql_columns(LPWSTR *columns_data, LPWSTR *types, DWORD num_columns)
+{
+    LPWSTR columns;
+    LPCWSTR type;
+    DWORD sql_size = 1, i, len;
+    WCHAR expanded[128], *ptr;
+    WCHAR size[10], comma[2], extra[10];
+
+    static const WCHAR column_fmt[] = {'`','%','s','`',' ','%','s','%','s','%','s','%','s',' ',0};
+    static const WCHAR size_fmt[] = {'(','%','s',')',0};
+    static const WCHAR type_char[] = {'C','H','A','R',0};
+    static const WCHAR type_int[] = {'I','N','T',0};
+    static const WCHAR type_long[] = {'L','O','N','G',0};
+    static const WCHAR type_notnull[] = {' ','N','O','T',' ','N','U','L','L',0};
+
+    columns = msi_alloc_zero(sql_size * sizeof(WCHAR));
+    if (!columns)
+        return NULL;
+
+    for (i = 0; i < num_columns; i++)
+    {
+        type = NULL;
+        comma[1] = size[0] = extra[0] = '\0';
+
+        if (i == num_columns - 1)
+            comma[0] = '\0';
+        else
+            comma[0] = ',';
+
+        ptr = &types[i][1];
+        len = atolW(ptr);
+
+        switch (types[i][0])
+        {
+            case 'l': case 's':
+                lstrcpyW(extra, type_notnull);
+            case 'L': case 'S':
+                type = type_char;
+                sprintfW(size, size_fmt, ptr);
+                break;
+            case 'I': case 'i':
+                if (len == 2)
+                    type = type_int;
+                else
+                    type = type_long;
+                break;
+        }
+
+        sprintfW(expanded, column_fmt, columns_data[i], type, size, extra, comma);
+        sql_size += lstrlenW(expanded);
+
+        columns = msi_realloc(columns, sql_size * sizeof(WCHAR));
+        if (!columns)
+            return NULL;
+
+        lstrcatW(columns, expanded);
+    }
+
+    return columns;
+}
+
+static LPWSTR msi_build_createsql_postlude(LPWSTR primary_key)
+{
+    LPWSTR postlude;
+    DWORD size;
+
+    static const WCHAR postlude_fmt[] = {'P','R','I','M','A','R','Y',' ','K','E','Y',' ','`','%','s','`',')',' ','H','O','L','D',0};
+
+    size = sizeof(postlude_fmt) + lstrlenW(primary_key) - 2;
+    postlude = msi_alloc(size * sizeof(WCHAR));
+    if (!postlude)
+        return NULL;
+
+    sprintfW(postlude, postlude_fmt, primary_key);
+    return postlude;
+}
+
+static UINT msi_add_table_to_db(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types, LPWSTR *labels, DWORD num_columns)
+{
+    UINT r;
+    DWORD size;
+    MSIQUERY *view;
+    LPWSTR create_sql;
+    LPWSTR prelude, columns_sql, postlude;
+
+    prelude = msi_build_createsql_prelude(labels[0]);
+    columns_sql = msi_build_createsql_columns(columns, types, num_columns);
+    postlude = msi_build_createsql_postlude(labels[1]);
+
+    if (!prelude || !columns_sql || !postlude)
+        return ERROR_OUTOFMEMORY;
+
+    size = lstrlenW(prelude) + lstrlenW(columns_sql) + lstrlenW(postlude) + 1;
+    create_sql = msi_alloc(size * sizeof(WCHAR));
+    if (!create_sql)
+        return ERROR_OUTOFMEMORY;
+
+    lstrcpyW(create_sql, prelude);
+    lstrcatW(create_sql, columns_sql);
+    lstrcatW(create_sql, postlude);
+
+    msi_free(prelude);
+    msi_free(columns_sql);
+    msi_free(postlude);
+
+    r = MSI_DatabaseOpenViewW( db, create_sql, &view );
+    msi_free(create_sql);
+
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    r = MSI_ViewExecute(view, NULL);
+    MSI_ViewClose(view);
+    msiobj_release(&view->hdr);
+
+    return r;
+}
+
+static LPWSTR msi_build_insertsql_prelude(LPWSTR table)
+{
+    LPWSTR prelude;
+    DWORD size;
+
+    static const WCHAR insert_fmt[] = {'I','N','S','E','R','T',' ','I','N','T','O',' ','`','%','s','`',' ','(',' ',0};
+
+    size = sizeof(insert_fmt) + lstrlenW(table) - 2;
+    prelude = msi_alloc(size * sizeof(WCHAR));
+    if (!prelude)
+        return NULL;
+
+    sprintfW(prelude, insert_fmt, table);
+    return prelude;
+}
+
+static LPWSTR msi_build_insertsql_columns(LPWSTR *columns_data, LPWSTR *types, DWORD num_columns)
+{
+    LPWSTR columns;
+    DWORD sql_size = 1, i;
+    WCHAR expanded[128];
+
+    static const WCHAR column_fmt[] =  {'`','%','s','`',',',' ',0};
+
+    columns = msi_alloc_zero(sql_size * sizeof(WCHAR));
+    if (!columns)
+        return NULL;
+
+    for (i = 0; i < num_columns; i++)
+    {
+        sprintfW(expanded, column_fmt, columns_data[i]);
+        sql_size += lstrlenW(expanded);
+
+        if (i == num_columns - 1)
+        {
+            sql_size -= 2;
+            expanded[lstrlenW(expanded) - 2] = '\0';
+        }
+
+        columns = msi_realloc(columns, sql_size * sizeof(WCHAR));
+        if (!columns)
+            return NULL;
+
+        lstrcatW(columns, expanded);
+    }
+
+    return columns;
+}
+
+static LPWSTR msi_build_insertsql_data(LPWSTR **records, LPWSTR *types, DWORD num_columns, DWORD irec)
+{
+    LPWSTR columns;
+    DWORD sql_size = 1, i;
+    WCHAR expanded[128];
+
+    static const WCHAR str_fmt[] = {'\'','%','s','\'',',',' ',0};
+    static const WCHAR int_fmt[] = {'%','s',',',' ',0};
+    static const WCHAR empty[] = {'\'','\'',',',' ',0};
+
+    columns = msi_alloc_zero(sql_size * sizeof(WCHAR));
+    if (!columns)
+        return NULL;
+
+    for (i = 0; i < num_columns; i++)
+    {
+        switch (types[i][0])
+        {
+            case 'L': case 'l': case 'S': case 's':
+                sprintfW(expanded, str_fmt, records[irec][i]);
+                break;
+            case 'I': case 'i':
+            	if (*records[0][i])
+                	sprintfW(expanded, int_fmt, records[irec][i]);
+               	else
+               		lstrcpyW(expanded, empty);
+                break;
+            default:
+                return NULL;
+        }
+
+        if (i == num_columns - 1)
+            expanded[lstrlenW(expanded) - 2] = '\0';
+
+        sql_size += lstrlenW(expanded);
+        columns = msi_realloc(columns, sql_size * sizeof(WCHAR));
+        if (!columns)
+            return NULL;
+
+        lstrcatW(columns, expanded);
+    }
+
+    return columns;
+}
+
+static UINT msi_add_records_to_table(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types,
+                                     LPWSTR *labels, LPWSTR **records,
+                                     int num_columns, int num_records)
+{
+    MSIQUERY *view;
+    LPWSTR insert_sql;
+    DWORD size, i;
+    UINT r = ERROR_SUCCESS;
+
+	static const WCHAR mid[] = {' ',')',' ','V','A','L','U','E','S',' ','(',' ',0};
+	static const WCHAR end[] = {' ',')',0};
+
+    LPWSTR prelude = msi_build_insertsql_prelude(labels[0]);
+    LPWSTR columns_sql = msi_build_insertsql_columns(columns, types, num_columns);
+    
+    for (i = 0; i < num_records; i++)
+    {
+        LPWSTR data = msi_build_insertsql_data(records, types, num_columns, i);
+
+        size = lstrlenW(prelude) + lstrlenW(columns_sql) + sizeof(mid) + lstrlenW(data) + sizeof(end) - 1; 
+        insert_sql = msi_alloc(size * sizeof(WCHAR));
+        if (!insert_sql)
+            return ERROR_OUTOFMEMORY;
+    
+        lstrcpyW(insert_sql, prelude);
+        lstrcatW(insert_sql, columns_sql);
+        lstrcatW(insert_sql, mid);
+        lstrcatW(insert_sql, data);
+        lstrcatW(insert_sql, end);
+
+        msi_free(data);
+
+        r = MSI_DatabaseOpenViewW( db, insert_sql, &view );
+        msi_free(insert_sql);
+
+        if (r != ERROR_SUCCESS)
+            goto done;
+
+        r = MSI_ViewExecute(view, NULL);
+        MSI_ViewClose(view);
+        msiobj_release(&view->hdr);
+    }
+
+done:
+    msi_free(prelude);
+    msi_free(columns_sql);
+
+    return r;
+}
+
+UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
+{
+    UINT r;
+    DWORD len, i;
+    DWORD num_columns, num_records = 0;
+    LPWSTR *columns, *types, *labels;
+    LPWSTR path, ptr, data;
+    LPWSTR **records;
+
+    static const WCHAR backslash[] = {'\\',0};
+
+    TRACE("%p %s %s\n", db, debugstr_w(folder), debugstr_w(file) );
 
     if( folder == NULL || file == NULL )
         return ERROR_INVALID_PARAMETER;
-   
-    return ERROR_CALL_NOT_IMPLEMENTED;
+
+    len = lstrlenW(folder) + lstrlenW(backslash) + lstrlenW(file) + 1;
+    path = msi_alloc( len * sizeof(WCHAR) );
+    if (!path)
+        return ERROR_OUTOFMEMORY;
+
+    lstrcpyW( path, folder );
+    lstrcatW( path, backslash );
+    lstrcatW( path, file );
+
+    data = msi_read_text_archive( path );
+
+    ptr = data;
+    msi_parse_line( &ptr, &columns, &num_columns );
+    msi_parse_line( &ptr, &types, NULL );
+    msi_parse_line( &ptr, &labels, NULL );
+
+    records = msi_alloc(sizeof(LPWSTR *));
+    if (!records)
+        return ERROR_OUTOFMEMORY;
+
+    /* read in the table records */
+    while (*ptr)
+    {
+        msi_parse_line( &ptr, &records[num_records], NULL );
+
+        num_records++;
+        records = msi_realloc(records, (num_records + 1) * sizeof(LPWSTR *));
+        if (!records)
+            return ERROR_OUTOFMEMORY;
+    }
+
+    r = msi_add_table_to_db( db, columns, types, labels, num_columns );
+    if (r != ERROR_SUCCESS)
+        goto done;
+
+    r = msi_add_records_to_table( db, columns, types, labels, records, num_columns, num_records );
+
+done:
+    msi_free(path);
+    msi_free(data);
+    msi_free(columns);
+    msi_free(types);
+
+    for (i = 0; i < num_records; i++)
+        msi_free(records[i]);
+
+    msi_free(records);
+
+    return r;
 }
 
 UINT WINAPI MsiDatabaseImportW(MSIHANDLE handle, LPCWSTR szFolder, LPCWSTR szFilename)
diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c
index 5ccd731..318d167 100644
--- a/dlls/msi/tests/db.c
+++ b/dlls/msi/tests/db.c
@@ -1396,91 +1396,66 @@ static void test_msiimport(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     r = add_table_to_db(hdb, test_data);
-    todo_wine
-    {
-        ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
-    }
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     query = "SELECT * FROM `TestTable`";
     r = MsiDatabaseOpenView(hdb, query, &view);
-    todo_wine
-    {
-        ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
-    }
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     r = MsiViewGetColumnInfo(view, MSICOLINFO_NAMES, &rec);
     count = MsiRecordGetFieldCount(rec);
-    todo_wine
-    {
-        ok(count == 9, "Expected 9, got %d\n", count);
-        ok(check_record(rec, 1, "FirstPrimaryColumn"), "Expected FirstPrimaryColumn\n");
-        ok(check_record(rec, 2, "SecondPrimaryColumn"), "Expected SecondPrimaryColumn\n");
-        ok(check_record(rec, 3, "ShortInt"), "Expected ShortInt\n");
-        ok(check_record(rec, 4, "ShortIntNullable"), "Expected ShortIntNullalble\n");
-        ok(check_record(rec, 5, "LongInt"), "Expected LongInt\n");
-        ok(check_record(rec, 6, "LongIntNullable"), "Expected LongIntNullalble\n");
-        ok(check_record(rec, 7, "String"), "Expected String\n");
-        ok(check_record(rec, 8, "LocalizableString"), "Expected LocalizableString\n");
-        ok(check_record(rec, 9, "LocalizableStringNullable"), "Expected LocalizableStringNullable\n");
-    }
+    ok(count == 9, "Expected 9, got %d\n", count);
+    ok(check_record(rec, 1, "FirstPrimaryColumn"), "Expected FirstPrimaryColumn\n");
+    ok(check_record(rec, 2, "SecondPrimaryColumn"), "Expected SecondPrimaryColumn\n");
+    ok(check_record(rec, 3, "ShortInt"), "Expected ShortInt\n");
+    ok(check_record(rec, 4, "ShortIntNullable"), "Expected ShortIntNullalble\n");
+    ok(check_record(rec, 5, "LongInt"), "Expected LongInt\n");
+    ok(check_record(rec, 6, "LongIntNullable"), "Expected LongIntNullalble\n");
+    ok(check_record(rec, 7, "String"), "Expected String\n");
+    ok(check_record(rec, 8, "LocalizableString"), "Expected LocalizableString\n");
+    ok(check_record(rec, 9, "LocalizableStringNullable"), "Expected LocalizableStringNullable\n");
 
     r = MsiViewGetColumnInfo(view, MSICOLINFO_TYPES, &rec);
     count = MsiRecordGetFieldCount(rec);
+    ok(count == 9, "Expected 9, got %d\n", count);
+    ok(check_record(rec, 1, "s255"), "Expected s255\n");
+    ok(check_record(rec, 4, "I2"), "Expected I2\n");
+    ok(check_record(rec, 6, "I4"), "Expected I4\n");
+    ok(check_record(rec, 7, "S255"), "Expected S255\n");
+    ok(check_record(rec, 8, "S0"), "Expected S0\n");
+    ok(check_record(rec, 9, "s0"), "Expected s0\n");
     todo_wine
     {
-        ok(count == 9, "Expected 9, got %d\n", count);
-        ok(check_record(rec, 1, "s255"), "Expected s255\n");
         ok(check_record(rec, 2, "i2"), "Expected i2\n");
         ok(check_record(rec, 3, "i2"), "Expected i2\n");
-        ok(check_record(rec, 4, "I2"), "Expected I2\n");
         ok(check_record(rec, 5, "i4"), "Expected i4\n");
-        ok(check_record(rec, 6, "I4"), "Expected I4\n");
-        ok(check_record(rec, 7, "S255"), "Expected S255\n");
-        ok(check_record(rec, 8, "S0"), "Expected S0\n");
-        ok(check_record(rec, 9, "s0"), "Expected s0\n");
     }
 
     query = "SELECT * FROM `TestTable`";
     r = do_query(hdb, query, &rec);
-    todo_wine
-    {
-        ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
-    }
-
-    todo_wine
-    {
-        ok(check_record(rec, 1, "stringage"), "Expected 'stringage'\n");
-        ok(check_record(rec, 7, "another string"), "Expected 'another string'\n");
-        ok(check_record(rec, 8, "localizable"), "Expected 'localizable'\n");
-        ok(check_record(rec, 9, "duh"), "Expected 'duh'\n");
-    }
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(check_record(rec, 1, "stringage"), "Expected 'stringage'\n");
+    ok(check_record(rec, 7, "another string"), "Expected 'another string'\n");
+    ok(check_record(rec, 8, "localizable"), "Expected 'localizable'\n");
+    ok(check_record(rec, 9, "duh"), "Expected 'duh'\n");
 
     i = MsiRecordGetInteger(rec, 2);
-    todo_wine
-    {
-        ok(i == 5, "Expected 5, got %d\n", i);
-    }
+    ok(i == 5, "Expected 5, got %d\n", i);
 
     i = MsiRecordGetInteger(rec, 3);
-    todo_wine
-    {
-        ok(i == 2, "Expected 2, got %d\n", i);
-    }
+    ok(i == 2, "Expected 2, got %d\n", i);
 
     i = MsiRecordGetInteger(rec, 4);
-    ok(i == 0x80000000, "Expected 0x80000000, got %d\n", i);
-
-    i = MsiRecordGetInteger(rec, 5);
     todo_wine
     {
-        ok(i == 2147483640, "Expected 2147483640, got %d\n", i);
+        ok(i == 0x80000000, "Expected 0x80000000, got %d\n", i);
     }
 
+    i = MsiRecordGetInteger(rec, 5);
+    ok(i == 2147483640, "Expected 2147483640, got %d\n", i);
+
     i = MsiRecordGetInteger(rec, 6);
-    todo_wine
-    {
-        ok(i == -2147483640, "Expected -2147483640, got %d\n", i);
-    }
+    ok(i == -2147483640, "Expected -2147483640, got %d\n", i);
 
     MsiCloseHandle(rec);
     MsiCloseHandle(view);
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index 33f34b3..4e611da 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -579,10 +579,7 @@ static void create_database(const CHAR *
         write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
 
         r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
-        todo_wine
-        {
-            ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
-        }
+        ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
 
         DeleteFileA(table->filename);
     }
@@ -604,10 +601,7 @@ static void test_MsiInstallProduct(void)
     DWORD num, size, type;
 
     r = MsiInstallProductA(msifile, NULL);
-    todo_wine
-    {
-        ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
-    }
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
 
     todo_wine
     {
@@ -624,19 +618,13 @@ static void test_MsiInstallProduct(void)
     }
 
     res = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest", &hkey);
-    todo_wine
-    {
-        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
-    }
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
 
     size = MAX_PATH;
     type = REG_SZ;
     res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
-    todo_wine
-    {
-        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
-        ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
-    }
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
+    ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
 
     size = MAX_PATH;
     type = REG_SZ;
@@ -649,11 +637,8 @@ static void test_MsiInstallProduct(void)
     size = sizeof(num);
     type = REG_DWORD;
     res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
-    todo_wine
-    {
-        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
-        ok(num == 314, "Expected 314, got %ld\n", num);
-    }
+    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
+    ok(num == 314, "Expected 314, got %ld\n", num);
 
     RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");
 }
@@ -683,10 +668,7 @@ static void test_MsiSetComponentState(vo
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
 
     r = MsiSetComponentState(package, "dangler", INSTALLSTATE_SOURCE);
-    todo_wine
-    {
-        ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
-    }
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
 
     MsiCloseHandle(package);
     CoUninitialize();
@@ -710,37 +692,31 @@ static void test_packagecoltypes(void)
 
     query = "SELECT * FROM `Media`";
     r = MsiDatabaseOpenView( hdb, query, &view );
-    todo_wine
-    {
-        ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
-    }
+    ok(r == ERROR_SUCCESS, "MsiDatabaseOpenView failed\n");
 
     r = MsiViewGetColumnInfo( view, MSICOLINFO_NAMES, &rec );
     count = MsiRecordGetFieldCount( rec );
-    todo_wine
-    {
-        ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
-        ok(count == 6, "Expected 6, got %d\n", count);
-        ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
-        ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
-        ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
-        ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
-        ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
-        ok(check_record(rec, 6, "Source"), "wrong column label\n");
-    }
+    ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
+    ok(count == 6, "Expected 6, got %d\n", count);
+    ok(check_record(rec, 1, "DiskId"), "wrong column label\n");
+    ok(check_record(rec, 2, "LastSequence"), "wrong column label\n");
+    ok(check_record(rec, 3, "DiskPrompt"), "wrong column label\n");
+    ok(check_record(rec, 4, "Cabinet"), "wrong column label\n");
+    ok(check_record(rec, 5, "VolumeLabel"), "wrong column label\n");
+    ok(check_record(rec, 6, "Source"), "wrong column label\n");
 
     r = MsiViewGetColumnInfo( view, MSICOLINFO_TYPES, &rec );
     count = MsiRecordGetFieldCount( rec );
+    ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
+    ok(count == 6, "Expected 6, got %d\n", count);
+    ok(check_record(rec, 4, "S255"), "wrong column label\n");
+    ok(check_record(rec, 5, "S32"), "wrong column label\n");
+    ok(check_record(rec, 6, "S72"), "wrong column label\n");
     todo_wine
     {
-        ok(r == ERROR_SUCCESS, "MsiViewGetColumnInfo failed\n");
-        ok(count == 6, "Expected 6, got %d\n", count);
         ok(check_record(rec, 1, "i2"), "wrong column label\n");
         ok(check_record(rec, 2, "i4"), "wrong column label\n");
         ok(check_record(rec, 3, "L64"), "wrong column label\n");
-        ok(check_record(rec, 4, "S255"), "wrong column label\n");
-        ok(check_record(rec, 5, "S32"), "wrong column label\n");
-        ok(check_record(rec, 6, "S72"), "wrong column label\n");
     }
 
     MsiCloseHandle(hdb);
-- 
1.4.2.1


More information about the wine-patches mailing list