Hib Eris : msi: Add support for importing binary OBJECTS.

Alexandre Julliard julliard at winehq.org
Wed May 27 09:26:54 CDT 2009


Module: wine
Branch: master
Commit: cad837c99992e27146ab3831ad601726709f609b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=cad837c99992e27146ab3831ad601726709f609b

Author: Hib Eris <hib at hiberis.nl>
Date:   Tue May 26 22:31:45 2009 +0200

msi: Add support for importing binary OBJECTS.

---

 dlls/msi/database.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++---
 dlls/msi/msipriv.h  |    1 +
 dlls/msi/record.c   |    2 +-
 dlls/msi/tests/db.c |   12 +++++-----
 4 files changed, 57 insertions(+), 11 deletions(-)

diff --git a/dlls/msi/database.c b/dlls/msi/database.c
index 70bcd90..ec944be 100644
--- a/dlls/msi/database.c
+++ b/dlls/msi/database.c
@@ -377,6 +377,7 @@ static LPWSTR msi_build_createsql_columns(LPWSTR *columns_data, LPWSTR *types, D
     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_object[] = {'O','B','J','E','C','T',0};
     static const WCHAR type_notnull[] = {' ','N','O','T',' ','N','U','L','L',0};
     static const WCHAR localizable[] = {' ','L','O','C','A','L','I','Z','A','B','L','E',0};
 
@@ -421,6 +422,11 @@ static LPWSTR msi_build_createsql_columns(LPWSTR *columns_data, LPWSTR *types, D
                 else
                     type = type_long;
                 break;
+            case 'v':
+                lstrcpyW(extra, type_notnull);
+            case 'V':
+                type = type_object;
+                break;
             default:
                 ERR("Unknown type: %c\n", types[i][0]);
                 msi_free(columns);
@@ -522,8 +528,32 @@ static UINT msi_add_table_to_db(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types,
     return r;
 }
 
+static LPWSTR msi_import_stream_filename(LPCWSTR path, LPCWSTR name)
+{
+    DWORD len;
+    LPWSTR fullname, ptr;
+
+    len = lstrlenW(path) + lstrlenW(name) + 1;
+    fullname = msi_alloc(len*sizeof(WCHAR));
+    if (!fullname)
+       return NULL;
+
+    lstrcpyW( fullname, path );
+
+    /* chop off extension from path */
+    ptr = strrchrW(fullname, '.');
+    if (!ptr)
+    {
+        msi_free (fullname);
+        return NULL;
+    }
+    *ptr++ = '\\';
+    lstrcpyW( ptr, name );
+    return fullname;
+}
+
 static UINT construct_record(DWORD num_columns, LPWSTR *types,
-                             LPWSTR *data, MSIRECORD **rec)
+                             LPWSTR *data, LPWSTR path, MSIRECORD **rec)
 {
     UINT i;
 
@@ -542,6 +572,20 @@ static UINT construct_record(DWORD num_columns, LPWSTR *types,
                 if (*data[i])
                     MSI_RecordSetInteger(*rec, i + 1, atoiW(data[i]));
                 break;
+            case 'V': case 'v':
+                if (*data[i])
+                {
+                    UINT r;
+                    LPWSTR file = msi_import_stream_filename(path, data[i]);
+                    if (!file)
+                        return ERROR_FUNCTION_FAILED;
+
+                    r = MSI_RecordSetStreamFromFileW(*rec, i + 1, file);
+                    msi_free (file);
+                    if (r != ERROR_SUCCESS)
+                        return ERROR_FUNCTION_FAILED;
+                }
+                break;
             default:
                 ERR("Unhandled column type: %c\n", types[i][0]);
                 msiobj_release(&(*rec)->hdr);
@@ -554,7 +598,8 @@ static UINT construct_record(DWORD num_columns, LPWSTR *types,
 
 static UINT msi_add_records_to_table(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types,
                                      LPWSTR *labels, LPWSTR **records,
-                                     int num_columns, int num_records)
+                                     int num_columns, int num_records,
+                                     LPWSTR path)
 {
     UINT r;
     int i;
@@ -579,7 +624,7 @@ static UINT msi_add_records_to_table(MSIDATABASE *db, LPWSTR *columns, LPWSTR *t
 
     for (i = 0; i < num_records; i++)
     {
-        r = construct_record(num_columns, types, records[i], &rec);
+        r = construct_record(num_columns, types, records[i], path, &rec);
         if (r != ERROR_SUCCESS)
             goto done;
 
@@ -683,7 +728,7 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
             }
         }
 
-        r = msi_add_records_to_table( db, columns, types, labels, records, num_columns, num_records );
+        r = msi_add_records_to_table( db, columns, types, labels, records, num_columns, num_records, path );
     }
 
 done:
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 408c968..8c4bd3a 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -704,6 +704,7 @@ extern UINT MSI_RecordReadStream( MSIRECORD *, UINT, char *, LPDWORD);
 extern UINT MSI_RecordSetStream(MSIRECORD *, UINT, IStream *);
 extern UINT MSI_RecordGetFieldCount( const MSIRECORD *rec );
 extern UINT MSI_RecordStreamToFile( MSIRECORD *, UINT, LPCWSTR );
+extern UINT MSI_RecordSetStreamFromFileW( MSIRECORD *, UINT, LPCWSTR );
 extern UINT MSI_RecordCopyField( MSIRECORD *, UINT, MSIRECORD *, UINT );
 extern MSIRECORD *MSI_CloneRecord( MSIRECORD * );
 extern BOOL MSI_RecordsAreEqual( MSIRECORD *, MSIRECORD * );
diff --git a/dlls/msi/record.c b/dlls/msi/record.c
index 9211e1c..68eab69 100644
--- a/dlls/msi/record.c
+++ b/dlls/msi/record.c
@@ -673,7 +673,7 @@ UINT MSI_RecordSetStream(MSIRECORD *rec, UINT iField, IStream *stream)
     return ERROR_SUCCESS;
 }
 
-static UINT MSI_RecordSetStreamFromFileW(MSIRECORD *rec, UINT iField, LPCWSTR szFilename)
+UINT MSI_RecordSetStreamFromFileW(MSIRECORD *rec, UINT iField, LPCWSTR szFilename)
 {
     IStream *stm = NULL;
     HRESULT r;
diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c
index d408c49..ec0bf30 100644
--- a/dlls/msi/tests/db.c
+++ b/dlls/msi/tests/db.c
@@ -1966,23 +1966,23 @@ static void test_binary_import(void)
 
     GetCurrentDirectory(MAX_PATH, path);
     r = MsiDatabaseImport(hdb, path, "bin_import.idt");
-    todo_wine ok(r == ERROR_SUCCESS , "Failed to import Binary table\n");
+    ok(r == ERROR_SUCCESS , "Failed to import Binary table\n");
 
     /* read file from the Binary table */
     query = "SELECT * FROM `Binary`";
     r = do_query(hdb, query, &rec);
-    todo_wine ok(r == ERROR_SUCCESS, "SELECT query failed: %d\n", r);
+    ok(r == ERROR_SUCCESS, "SELECT query failed: %d\n", r);
 
     size = MAX_PATH;
     r = MsiRecordGetString(rec, 1, file, &size);
-    todo_wine ok(r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
-    todo_wine ok(!lstrcmp(file, "filename1"), "Expected 'filename1', got %s\n", file);
+    ok(r == ERROR_SUCCESS, "Failed to get string: %d\n", r);
+    ok(!lstrcmp(file, "filename1"), "Expected 'filename1', got %s\n", file);
 
     size = MAX_PATH;
     memset(buf, 0, MAX_PATH);
     r = MsiRecordReadStream(rec, 2, buf, &size);
-    todo_wine ok(r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
-    todo_wine ok(!lstrcmp(buf, "just some words"),
+    ok(r == ERROR_SUCCESS, "Failed to get stream: %d\n", r);
+    ok(!lstrcmp(buf, "just some words"),
         "Expected 'just some words', got %s\n", buf);
 
     r = MsiCloseHandle(rec);




More information about the wine-cvs mailing list