James Hawkins : msi: Load the AdminProperties stream if the package is an Admin package.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Jul 17 07:36:49 CDT 2007


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

Author: James Hawkins <truiken at gmail.com>
Date:   Mon Jul 16 14:45:29 2007 -0700

msi: Load the AdminProperties stream if the package is an Admin package.

---

 dlls/msi/action.c        |    2 +-
 dlls/msi/msipriv.h       |    3 +-
 dlls/msi/package.c       |   20 +++++++++++++
 dlls/msi/string.c        |    4 +-
 dlls/msi/table.c         |    8 ++--
 dlls/msi/tests/install.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 100 insertions(+), 8 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 10443c6..953ecb5 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -293,7 +293,7 @@ static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start,
     msiobj_release(&row->hdr);
 }
 
-static UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine )
+UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine )
 {
     LPCWSTR ptr,ptr2;
     BOOL quote;
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 3253a5d..a94866a 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -605,7 +605,7 @@ extern MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR tabl
 
 extern UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname,
                                   USHORT **pdata, UINT *psz );
-extern UINT read_stream_data( IStorage *stg, LPCWSTR stname,
+extern UINT read_stream_data( IStorage *stg, LPCWSTR stname, BOOL table,
                               BYTE **pdata, UINT *psz );
 extern UINT write_stream_data( IStorage *stg, LPCWSTR stname,
                                LPCVOID data, UINT sz, BOOL bTable );
@@ -623,6 +623,7 @@ extern UINT ACTION_DialogBox( MSIPACKAGE*, LPCWSTR);
 extern UINT ACTION_ForceReboot(MSIPACKAGE *package);
 extern UINT MSI_Sequence( MSIPACKAGE *package, LPCWSTR szTable, INT iSequenceMode );
 extern UINT MSI_SetFeatureStates( MSIPACKAGE *package );
+extern UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine );
 
 /* record internals */
 extern UINT MSI_RecordSetIStream( MSIRECORD *, unsigned int, IStream *);
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index 2fb7fbe..0309dc3 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -720,6 +720,23 @@ static MSIPACKAGE *msi_alloc_package( void )
     return package;
 }
 
+static UINT msi_load_admin_properties(MSIPACKAGE *package)
+{
+    BYTE *data;
+    UINT r, sz;
+
+    static const WCHAR stmname[] = {'A','d','m','i','n','P','r','o','p','e','r','t','i','e','s',0};
+
+    r = read_stream_data(package->db->storage, stmname, FALSE, &data, &sz);
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    r = msi_parse_command_line(package, (WCHAR *)data);
+
+    msi_free(data);
+    return r;
+}
+
 MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
 {
     static const WCHAR szLevel[] = { 'U','I','L','e','v','e','l',0 };
@@ -750,6 +767,9 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
         package->ProductCode = msi_dup_property( package, szProductCode );
         set_installed_prop( package );
         msi_load_summary_properties( package );
+
+        if (package->WordCount & MSIWORDCOUNT_ADMINISTRATIVE)
+            msi_load_admin_properties( package );
     }
 
     return package;
diff --git a/dlls/msi/string.c b/dlls/msi/string.c
index fe1f5cc..0cacf1e 100644
--- a/dlls/msi/string.c
+++ b/dlls/msi/string.c
@@ -521,10 +521,10 @@ string_table *msi_load_string_table( IStorage *stg, UINT *bytes_per_strref )
     UINT r, datasize = 0, poolsize = 0, codepage;
     DWORD i, count, offset, len, n, refs;
 
-    r = read_stream_data( stg, szStringPool, (BYTE **)&pool, &poolsize );
+    r = read_stream_data( stg, szStringPool, TRUE, (BYTE **)&pool, &poolsize );
     if( r != ERROR_SUCCESS)
         goto end;
-    r = read_stream_data( stg, szStringData, (BYTE **)&data, &datasize );
+    r = read_stream_data( stg, szStringData, TRUE, (BYTE **)&data, &datasize );
     if( r != ERROR_SUCCESS)
         goto end;
 
diff --git a/dlls/msi/table.c b/dlls/msi/table.c
index fb414a2..69a033c 100644
--- a/dlls/msi/table.c
+++ b/dlls/msi/table.c
@@ -262,7 +262,7 @@ void enum_stream_names( IStorage *stg )
     IEnumSTATSTG_Release( stgenum );
 }
 
-UINT read_stream_data( IStorage *stg, LPCWSTR stname,
+UINT read_stream_data( IStorage *stg, LPCWSTR stname, BOOL table,
                        BYTE **pdata, UINT *psz )
 {
     HRESULT r;
@@ -273,7 +273,7 @@ UINT read_stream_data( IStorage *stg, LPCWSTR stname,
     STATSTG stat;
     LPWSTR encname;
 
-    encname = encode_streamname(TRUE, stname);
+    encname = encode_streamname(table, stname);
 
     TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname));
 
@@ -506,7 +506,7 @@ static UINT read_table_from_storage( MSITABLE *t, IStorage *stg )
     row_size = msi_table_get_row_size( t->colinfo, t->col_count );
 
     /* if we can't read the table, just assume that it's empty */
-    read_stream_data( stg, t->name, &rawdata, &rawsize );
+    read_stream_data( stg, t->name, TRUE, &rawdata, &rawsize );
     if( !rawdata )
         return ERROR_SUCCESS;
 
@@ -1992,7 +1992,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
     TRACE("%p %p %p %s\n", db, stg, st, debugstr_w(name) );
 
     /* read the transform data */
-    read_stream_data( stg, name, &rawdata, &rawsize );
+    read_stream_data( stg, name, TRUE, &rawdata, &rawsize );
     if ( !rawdata )
     {
         TRACE("table %s empty\n", debugstr_w(name) );
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index 0d9d703..164040f 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -443,6 +443,11 @@ static const CHAR adm_admin_exec_seq_dat[] = "Action\tCondition\tSequence\n"
                                              "InstallValidate\t\t1400\n"
                                              "LaunchConditions\t\t100";
 
+static const CHAR amp_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
+                                        "s72\tS38\ts72\ti2\tS255\tS72\n"
+                                        "Component\tComponent\n"
+                                        "augustus\t\tMSITESTDIR\t0\tMYPROP=2718\taugustus\n";
+
 typedef struct _msi_table
 {
     const CHAR *filename;
@@ -667,6 +672,18 @@ static const msi_table adm_tables[] =
     ADD_TABLE(adm_admin_exec_seq),
 };
 
+static const msi_table amp_tables[] =
+{
+    ADD_TABLE(amp_component),
+    ADD_TABLE(directory),
+    ADD_TABLE(rof_feature),
+    ADD_TABLE(ci2_feature_comp),
+    ADD_TABLE(ci2_file),
+    ADD_TABLE(install_exec_seq),
+    ADD_TABLE(rof_media),
+    ADD_TABLE(property),
+};
+
 /* cabinet definitions */
 
 /* make the max size large so there is only one cab file */
@@ -2635,6 +2652,59 @@ static void test_admin(void)
     RemoveDirectory("msitest");
 }
 
+static void set_admin_property_stream(LPCSTR file)
+{
+    IStorage *stg;
+    IStream *stm;
+    WCHAR fileW[MAX_PATH];
+    HRESULT hr;
+    DWORD count;
+    const DWORD mode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
+
+    /* AdminProperties */
+    static const WCHAR stmname[] = {0x41ca,0x4330,0x3e71,0x44b5,0x4233,0x45f5,0x422c,0x4836,0};
+    static const WCHAR data[] = {'M','Y','P','R','O','P','=','2','7','1','8',0};
+
+    MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH);
+
+    hr = StgOpenStorage(fileW, NULL, mode, NULL, 0, &stg);
+    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
+    if (!stg)
+        return;
+
+    hr = IStorage_CreateStream(stg, stmname, STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
+    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
+
+    hr = IStream_Write(stm, data, sizeof(data) - 1, &count);
+    ok(hr == S_OK, "Expected S_OK, got %d\n", hr);
+
+    IStream_Release(stm);
+    IStorage_Release(stg);
+}
+
+static void test_adminprops(void)
+{
+    UINT r;
+
+    CreateDirectoryA("msitest", NULL);
+    create_file("msitest\\augustus", 500);
+
+    create_database(msifile, amp_tables, sizeof(amp_tables) / sizeof(msi_table));
+    set_admin_summary_info(msifile);
+    set_admin_property_stream(msifile);
+
+    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
+
+    r = MsiInstallProductA(msifile, NULL);
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+    ok(delete_pf("msitest\\augustus", TRUE), "File installed\n");
+    ok(delete_pf("msitest", FALSE), "File installed\n");
+
+    DeleteFile(msifile);
+    DeleteFile("msitest\\augustus");
+    RemoveDirectory("msitest");
+}
+
 START_TEST(install)
 {
     DWORD len;
@@ -2670,6 +2740,7 @@ START_TEST(install)
     test_transformprop();
     test_currentworkingdir();
     test_admin();
+    test_adminprops();
 
     SetCurrentDirectoryA(prev_path);
 }




More information about the wine-cvs mailing list