Sync to Wine-0_9_5:
Francois Gouget <fgouget@free.fr>
- Small documentation tweaks to avoid winapi_check warnings.
Mike McCormack <mike@codeweavers.com>
- msi: Change some FIXME messages to comments.
- msi: Add stub actions for CCPSearch and RMCCPSearch.
- msi: Fixes for the MaskedEdit control.
  Allow MaskedEdit masks that aren't enclosed with <>.
  Allow the MaskedEdit's edit controls to scroll a bit in case things
  don't line up.
- msi: Subclass the Richedit control.
  Send a "DoAction" control event when the user scrolls the text.
- msi: Implement the Reset control event.
- MSI: Improve the MsiGetMode stub a little.
- msi: Add a stub for MsiGetLastErrorRecord.
- msi: Define the property "Intel" if we're running on an Intel processor.
- msi: Apply any MSI transforms specified by the TRANSFORMS property.
Marcus Meissner <marcus@jet.franken.de>
- msi: Report the commandline that failed to start in ERR()s.
Modified: trunk/reactos/lib/msi/action.c
Modified: trunk/reactos/lib/msi/custom.c
Modified: trunk/reactos/lib/msi/dialog.c
Modified: trunk/reactos/lib/msi/events.c
Modified: trunk/reactos/lib/msi/install.c
Modified: trunk/reactos/lib/msi/msi.c
Modified: trunk/reactos/lib/msi/msi.spec
Modified: trunk/reactos/lib/msi/msipriv.h
Modified: trunk/reactos/lib/msi/msiquery.c
Modified: trunk/reactos/lib/msi/package.c

Modified: trunk/reactos/lib/msi/action.c
--- trunk/reactos/lib/msi/action.c	2006-01-06 19:59:46 UTC (rev 20619)
+++ trunk/reactos/lib/msi/action.c	2006-01-06 20:14:15 UTC (rev 20620)
@@ -569,6 +569,30 @@
     return r;
 }
 
+static UINT msi_apply_transforms( MSIPACKAGE *package )
+{
+    static const WCHAR szTransforms[] = {
+        'T','R','A','N','S','F','O','R','M','S',0 };
+    LPWSTR xform_list, *xforms;
+    UINT i, r = ERROR_SUCCESS;
+
+    xform_list = msi_dup_property( package, szTransforms );
+    xforms = msi_split_string( xform_list, ';' );
+
+    for( i=0; xforms && xforms[i] && r == ERROR_SUCCESS; i++ )
+    {
+        if (xforms[i][0] == ':')
+            r = msi_apply_substorage_transform( package, package->db, &xforms[i][1] );
+        else
+            r = MSI_DatabaseApplyTransformW( package->db, xforms[i], 0 );
+    }
+
+    msi_free( xforms );
+    msi_free( xform_list );
+
+    return r;
+}
+
 /****************************************************
  * TOP level entry points 
  *****************************************************/
@@ -618,6 +642,7 @@
 
     msi_parse_command_line( package, szCommandLine );
 
+    msi_apply_transforms( package );
     msi_apply_patches( package );
 
     if ( msi_get_property_int(package, szUILevel, 0) >= INSTALLUILEVEL_REDUCED )
@@ -3096,7 +3121,7 @@
     }
     msi_free(buffer);
     
-    FIXME("Need to write more keys to the user registry\n");
+    /* FIXME: Need to write more keys to the user registry */
   
     hDb= alloc_msihandle( &package->db->hdr );
     rc = MsiGetSummaryInformationW(hDb, NULL, 0, &hSumInfo); 
@@ -3540,7 +3565,7 @@
         return rc;
 
     /* dump all the info i can grab */
-    FIXME("Flesh out more information\n");
+    /* FIXME: Flesh out more information */
 
     msi_write_uninstall_property_vals( package, hkey );
 
@@ -3554,7 +3579,7 @@
     RegSetValueExW(hkey,szUninstallString,0,REG_EXPAND_SZ,(LPBYTE)buffer,size);
     msi_free(buffer);
 
-    FIXME("Write real Estimated Size when we have it\n");
+    /* FIXME: Write real Estimated Size when we have it */
     msi_reg_set_val_dword( hkey, szEstimatedSize, 0 );
    
     GetLocalTime(&systime);
@@ -4210,11 +4235,23 @@
     return msi_unimplemented_action_stub( package, "UnregisterFonts", table );
 }
 
+static UINT ACTION_CCPSearch( MSIPACKAGE *package )
+{
+    static const WCHAR table[] = { 'C','C','P','S','e','a','r','c','h',0 };
+    return msi_unimplemented_action_stub( package, "CCPSearch", table );
+}
+
+static UINT ACTION_RMCCPSearch( MSIPACKAGE *package )
+{
+    static const WCHAR table[] = { 'C','C','P','S','e','a','r','c','h',0 };
+    return msi_unimplemented_action_stub( package, "RMCCPSearch", table );
+}
+
 static struct _actions StandardActions[] = {
     { szAllocateRegistrySpace, ACTION_AllocateRegistrySpace },
     { szAppSearch, ACTION_AppSearch },
     { szBindImage, ACTION_BindImage },
-    { szCCPSearch, NULL},
+    { szCCPSearch, ACTION_CCPSearch},
     { szCostFinalize, ACTION_CostFinalize },
     { szCostInitialize, ACTION_CostInitialize },
     { szCreateFolders, ACTION_CreateFolders },
@@ -4266,7 +4303,7 @@
     { szRemoveRegistryValues, NULL},
     { szRemoveShortcuts, NULL},
     { szResolveSource, ACTION_ResolveSource},
-    { szRMCCPSearch, NULL},
+    { szRMCCPSearch, ACTION_RMCCPSearch},
     { szScheduleReboot, NULL},
     { szSelfRegModules, ACTION_SelfRegModules },
     { szSelfUnregModules, ACTION_SelfUnregModules },

Modified: trunk/reactos/lib/msi/custom.c
--- trunk/reactos/lib/msi/custom.c	2006-01-06 19:59:46 UTC (rev 20619)
+++ trunk/reactos/lib/msi/custom.c	2006-01-06 20:14:15 UTC (rev 20620)
@@ -548,13 +548,14 @@
     rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL,
                   c_collen, &si, &info);
 
-    msi_free(cmd);
 
     if ( !rc )
     {
-        ERR("Unable to execute command\n");
+        ERR("Unable to execute command %s\n", debugstr_w(cmd));
+        msi_free(cmd);
         return ERROR_SUCCESS;
     }
+    msi_free(cmd);
 
     prc = process_handle(package, type, info.hThread, info.hProcess, action, 
                           &finished);
@@ -609,13 +610,14 @@
     rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL,
                   c_collen, &si, &info);
 
-    msi_free(cmd);
     
     if ( !rc )
     {
-        ERR("Unable to execute command\n");
+        ERR("Unable to execute command %s\n", debugstr_w(cmd));
+        msi_free(cmd);
         return ERROR_SUCCESS;
     }
+    msi_free(cmd);
 
     prc = process_handle(package, type, info.hThread, info.hProcess, action, 
                          NULL);
@@ -694,13 +696,14 @@
     rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL,
                   c_collen, &si, &info);
 
-    msi_free(cmd);
     
     if ( !rc )
     {
-        ERR("Unable to execute command\n");
+        ERR("Unable to execute command %s\n", debugstr_w(cmd));
+        msi_free(cmd);
         return ERROR_SUCCESS;
     }
+    msi_free(cmd);
 
     return process_handle(package, type, info.hThread, info.hProcess, action, NULL);
 }
@@ -733,13 +736,14 @@
 
     rc = CreateProcessW(NULL, deformated, NULL, NULL, FALSE, 0, NULL,
                   c_collen, &si, &info);
-    msi_free(deformated);
 
     if ( !rc )
     {
-        ERR("Unable to execute command\n");
+        ERR("Unable to execute command %s\n", debugstr_w(deformated));
+        msi_free(deformated);
         return ERROR_SUCCESS;
     }
+    msi_free(deformated);
 
     prc = process_handle(package, type, info.hThread, info.hProcess, action,
                          NULL);

Modified: trunk/reactos/lib/msi/dialog.c
--- trunk/reactos/lib/msi/dialog.c	2006-01-06 19:59:46 UTC (rev 20619)
+++ trunk/reactos/lib/msi/dialog.c	2006-01-06 20:14:15 UTC (rev 20620)
@@ -59,7 +59,6 @@
     HBITMAP hBitmap;
     HICON hIcon;
     LPWSTR tabnext;
-    HMODULE hDll;
     WCHAR name[1];
 };
 
@@ -329,7 +328,6 @@
     control->value = NULL;
     control->hBitmap = NULL;
     control->hIcon = NULL;
-    control->hDll = NULL;
     control->tabnext = strdupW( MSI_RecordGetString( rec, 11) );
 
     x = MSI_RecordGetInteger( rec, 4 );
@@ -695,6 +693,42 @@
     return ERROR_SUCCESS;
 }
 
+/******************** Scroll Text ********************************************/
+
+struct msi_scrolltext_info
+{
+    msi_dialog *dialog;
+    msi_control *control;
+    WNDPROC oldproc;
+    HMODULE hRichedit;
+};
+
+static LRESULT WINAPI
+MSIScrollText_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    struct msi_scrolltext_info *info;
+    HRESULT r;
+
+    TRACE("%p %04x %08x %08lx\n", hWnd, msg, wParam, lParam);
+
+    info = GetPropW( hWnd, szButtonData );
+
+    r = CallWindowProcW( info->oldproc, hWnd, msg, wParam, lParam );
+
+    switch( msg )
+    {
+    case WM_NCDESTROY:
+        FreeLibrary( info->hRichedit );
+        msi_free( info );
+        RemovePropW( hWnd, szButtonData );
+        break;
+    case WM_VSCROLL:
+        msi_dialog_button_handler( info->dialog, info->control, BN_CLICKED );
+        break;
+    }
+    return r;
+}
+
 struct msi_streamin_info
 {
     LPSTR string;
@@ -718,41 +752,60 @@
     return 0;
 }
 
+static void msi_scrolltext_add_text( msi_control *control, LPCWSTR text )
+{
+    struct msi_streamin_info info;
+    EDITSTREAM es;
+
+    info.string = strdupWtoA( text );
+    info.offset = 0;
+    info.length = lstrlenA( info.string ) + 1;
+
+    es.dwCookie = (DWORD_PTR) &info;
+    es.dwError = 0;
+    es.pfnCallback = msi_richedit_stream_in;
+
+    SendMessageW( control->hwnd, EM_STREAMIN, SF_RTF, (LPARAM) &es );
+
+    msi_free( info.string );
+}
+
 static UINT msi_dialog_scrolltext_control( msi_dialog *dialog, MSIRECORD *rec )
 {
     static const WCHAR szRichEdit20W[] = {
     	'R','i','c','h','E','d','i','t','2','0','W',0
     };
-    struct msi_streamin_info info;
+    struct msi_scrolltext_info *info;
     msi_control *control;
-    LPCWSTR text;
-    EDITSTREAM es;
     DWORD style;
-    HMODULE hRichedit;
 
-    hRichedit = LoadLibraryA("riched20");
+    info = msi_alloc( sizeof *info );
+    if (!info)
+        return ERROR_FUNCTION_FAILED;
 
+    info->hRichedit = LoadLibraryA("riched20");
+
     style = WS_BORDER | ES_MULTILINE | WS_VSCROLL |
             ES_READONLY | ES_AUTOVSCROLL | WS_TABSTOP;
     control = msi_dialog_add_control( dialog, rec, szRichEdit20W, style );
     if (!control)
+    {
+        FreeLibrary( info->hRichedit );
+        msi_free( info );
         return ERROR_FUNCTION_FAILED;
+    }
 
-    control->hDll = hRichedit;
+    info->dialog = dialog;
+    info->control = control;
 
-    text = MSI_RecordGetString( rec, 10 );
-    info.string = strdupWtoA( text );
-    info.offset = 0;
-    info.length = lstrlenA( info.string ) + 1;
+    /* subclass the static control */
+    info->oldproc = (WNDPROC) SetWindowLongPtrW( control->hwnd, GWLP_WNDPROC,
+                                          (LONG_PTR)MSIScrollText_WndProc );
+    SetPropW( control->hwnd, szButtonData, info );
 
-    es.dwCookie = (DWORD_PTR) &info;
-    es.dwError = 0;
-    es.pfnCallback = msi_richedit_stream_in;
+    /* add the text into the richedit */
+    msi_scrolltext_add_text( control, MSI_RecordGetString( rec, 10 ) );
 
-    SendMessageW( control->hwnd, EM_STREAMIN, SF_RTF, (LPARAM) &es );
-
-    msi_free( info.string );
-
     return ERROR_SUCCESS;
 }
 
@@ -1076,15 +1129,16 @@
     if( !mask )
         return info;
 
-    p = strchrW(mask, '<');
-    if( !p )
-        return info;
-
     info = msi_alloc_zero( sizeof *info );
     if( !info )
         return info;
 
-    p++;
+    p = strchrW(mask, '<');
+    if( p )
+        p++;
+    else
+        p = mask;
+
     for( i=0; i<MASK_MAX_GROUPS; i++ )
     {
         /* stop at the end of the string */
@@ -1124,7 +1178,7 @@
     HWND hwnd;
     UINT i;
 
-    style = WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP;
+    style = WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL;
 
     GetClientRect( info->hwnd, &rect );
 
@@ -1512,6 +1566,12 @@
     return r;
 }
 
+UINT msi_dialog_reset( msi_dialog *dialog )
+{
+    /* FIXME: should restore the original values of any properties we changed */
+    return msi_dialog_evaluate_control_conditions( dialog );
+}
+
 /* figure out the height of 10 point MS Sans Serif */
 static INT msi_dialog_get_sans_serif_height( HWND hwnd )
 {
@@ -2138,8 +2198,6 @@
             DestroyIcon( t->hIcon );
         msi_free( t->tabnext );
         msi_free( t );
-        if (t->hDll)
-            FreeLibrary( t->hDll );
     }
 
     /* destroy the list of fonts */

Modified: trunk/reactos/lib/msi/events.c
--- trunk/reactos/lib/msi/events.c	2006-01-06 19:59:46 UTC (rev 20619)
+++ trunk/reactos/lib/msi/events.c	2006-01-06 20:14:15 UTC (rev 20620)
@@ -243,6 +243,13 @@
     return r;
 }
 
+static UINT ControlEvent_Reset(MSIPACKAGE* package, LPCWSTR argument, 
+                                   msi_dialog* dialog)
+{
+    msi_dialog_reset(dialog);
+    return ERROR_SUCCESS;
+}
+
 /*
  * Subscribed events
  */
@@ -371,6 +378,7 @@
     { "Remove",ControlEvent_Remove },
     { "AddSource",ControlEvent_AddSource },
     { "SetTargetPath",ControlEvent_SetTargetPath },
+    { "Reset",ControlEvent_Reset },
     { NULL,NULL },
 };
 

Modified: trunk/reactos/lib/msi/install.c
--- trunk/reactos/lib/msi/install.c	2006-01-06 19:59:46 UTC (rev 20619)
+++ trunk/reactos/lib/msi/install.c	2006-01-06 20:14:15 UTC (rev 20620)
@@ -449,8 +449,31 @@
 
 BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
 {
-    FIXME("STUB (iRunMode=%i)\n",iRunMode);
-    return TRUE;
+    BOOL r = FALSE;
+
+    switch (iRunMode)
+    {
+    case MSIRUNMODE_WINDOWS9X:
+        if (GetVersion() & 0x80000000)
+            r = TRUE;
+        break;
+
+    case MSIRUNMODE_RESERVED11:
+    case MSIRUNMODE_RESERVED14:
+    case MSIRUNMODE_RESERVED15:
+        break;
+
+    case MSIRUNMODE_SCHEDULED:
+    case MSIRUNMODE_ROLLBACK:
+    case MSIRUNMODE_COMMIT:
+        break;
+
+    default:
+        FIXME("%ld %d\n", hInstall, iRunMode);
+        r = TRUE;
+    }
+
+    return r;
 }
 
 /***********************************************************************

Modified: trunk/reactos/lib/msi/msi.c
--- trunk/reactos/lib/msi/msi.c	2006-01-06 19:59:46 UTC (rev 20619)
+++ trunk/reactos/lib/msi/msi.c	2006-01-06 20:14:15 UTC (rev 20620)
@@ -57,7 +57,7 @@
 
 static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
 
-/**********************************************************************
+/*
  * Dll lifetime tracking declaration
  */
 static void LockModule(void)

Modified: trunk/reactos/lib/msi/msi.spec
--- trunk/reactos/lib/msi/msi.spec	2006-01-06 19:59:46 UTC (rev 20619)
+++ trunk/reactos/lib/msi/msi.spec	2006-01-06 20:14:15 UTC (rev 20620)
@@ -41,7 +41,7 @@
 45 stdcall MsiEnumProductsW(long ptr)
 46 stdcall MsiEvaluateConditionA(long str)
 47 stdcall MsiEvaluateConditionW(long wstr)
-48 stub MsiGetLastErrorRecord
+48 stdcall MsiGetLastErrorRecord()
 49 stdcall MsiGetActiveDatabase(long)
 50 stdcall MsiGetComponentStateA(long str ptr ptr)
 51 stdcall MsiGetComponentStateW(long wstr ptr ptr)

Modified: trunk/reactos/lib/msi/msipriv.h
--- trunk/reactos/lib/msi/msipriv.h	2006-01-06 19:59:46 UTC (rev 20619)
+++ trunk/reactos/lib/msi/msipriv.h	2006-01-06 20:14:15 UTC (rev 20620)
@@ -317,6 +317,8 @@
 
 /* transform functions */
 extern UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg );
+extern UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db, 
+                 LPCWSTR szTransformFile, int iErrorCond );
 
 /* action internals */
 extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR );
@@ -414,6 +416,7 @@
 extern BOOL msi_dialog_register_class( void );
 extern void msi_dialog_unregister_class( void );
 extern void msi_dialog_handle_event( msi_dialog*, LPCWSTR, LPCWSTR, MSIRECORD * );
+extern UINT msi_dialog_reset( msi_dialog *dialog );
 
 /* preview */
 extern MSIPREVIEW *MSI_EnableUIPreview( MSIDATABASE * );

Modified: trunk/reactos/lib/msi/msiquery.c
--- trunk/reactos/lib/msi/msiquery.c	2006-01-06 19:59:46 UTC (rev 20619)
+++ trunk/reactos/lib/msi/msiquery.c	2006-01-06 20:14:15 UTC (rev 20620)
@@ -639,9 +639,15 @@
     return r;
 }
 
+MSIHANDLE WINAPI MsiGetLastErrorRecord( void )
+{
+    FIXME("\n");
+    return 0;
+}
+
 DEFINE_GUID( CLSID_MsiTransform, 0x000c1082, 0x0000, 0x0000, 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
 
-static UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db, 
+UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db, 
                  LPCWSTR szTransformFile, int iErrorCond )
 {
     UINT r;

Modified: trunk/reactos/lib/msi/package.c
--- trunk/reactos/lib/msi/package.c	2006-01-06 19:59:46 UTC (rev 20619)
+++ trunk/reactos/lib/msi/package.c	2006-01-06 20:14:15 UTC (rev 20620)
@@ -228,6 +228,8 @@
     static const WCHAR szScreenY[] = {'S','c','r','e','e','n','Y',0};
     static const WCHAR szColorBits[] = {'C','o','l','o','r','B','i','t','s',0};
     static const WCHAR szScreenFormat[] = {'%','d',0};
+    static const WCHAR szIntel[] = { 'I','n','t','e','l',0 };
+    SYSTEM_INFO sys_info;
 
     /*
      * Other things that probably should be set:
@@ -353,6 +355,13 @@
     sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION);
     MSI_SetPropertyW( package, szVersionMsi, bufstr );
 
+    GetSystemInfo( &sys_info );
+    if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
+    {
+        sprintfW( bufstr, szScreenFormat, sys_info.wProcessorLevel );
+        MSI_SetPropertyW( package, szIntel, bufstr );
+    }
+
     /* Screen properties. */
     dc = GetDC(0);
     sprintfW( bufstr, szScreenFormat, GetDeviceCaps( dc, HORZRES ) );