MSI: allow return codes for Control Events

Aric Stewart aric at codeweavers.com
Fri Jun 17 12:18:15 CDT 2005


Allow control events to return codes to halt the processing of event. 
Needed for the SetTargetPath Event.
-------------- next part --------------
Index: dlls/msi/events.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/events.c,v
retrieving revision 1.4
diff -u -r1.4 events.c
--- dlls/msi/events.c	6 Jun 2005 15:40:15 -0000	1.4
+++ dlls/msi/events.c	17 Jun 2005 17:16:46 -0000
@@ -38,7 +38,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(msi);
 
-typedef void (*EVENTHANDLER)(MSIPACKAGE*,LPCWSTR,msi_dialog *);
+typedef UINT (*EVENTHANDLER)(MSIPACKAGE*,LPCWSTR,msi_dialog *);
 
 struct _events {
     LPCSTR event;
@@ -52,7 +52,7 @@
     LPWSTR attribute;
 };
 
-VOID ControlEvent_HandleControlEvent(MSIPACKAGE *, LPCWSTR, LPCWSTR, msi_dialog*);
+UINT ControlEvent_HandleControlEvent(MSIPACKAGE *, LPCWSTR, LPCWSTR, msi_dialog*);
 
 /*
  * Create a dialog box and run it if it's modal
@@ -89,7 +89,7 @@
 /*
  * End a modal dialog box
  */
-static VOID ControlEvent_EndDialog(MSIPACKAGE* package, LPCWSTR argument, 
+static UINT ControlEvent_EndDialog(MSIPACKAGE* package, LPCWSTR argument, 
                                    msi_dialog* dialog)
 {
     static const WCHAR szExit[] = {
@@ -117,48 +117,53 @@
 
     ControlEvent_CleanupSubscriptions(package);
     msi_dialog_end_dialog( dialog );
+    return ERROR_SUCCESS;
 }
 
 /*
  * transition from one modal dialog to another modal dialog
  */
-static VOID ControlEvent_NewDialog(MSIPACKAGE* package, LPCWSTR argument, 
+static UINT ControlEvent_NewDialog(MSIPACKAGE* package, LPCWSTR argument, 
                                    msi_dialog *dialog)
 {
     /* store the name of the next dialog, and signal this one to end */
     package->next_dialog = strdupW(argument);
     ControlEvent_CleanupSubscriptions(package);
     msi_dialog_end_dialog( dialog );
+    return ERROR_SUCCESS;
 }
 
 /*
  * Create a new child dialog of an existing modal dialog
  */
-static VOID ControlEvent_SpawnDialog(MSIPACKAGE* package, LPCWSTR argument, 
+static UINT ControlEvent_SpawnDialog(MSIPACKAGE* package, LPCWSTR argument, 
                               msi_dialog *dialog)
 {
     event_do_dialog( package, argument );
     if( package->CurrentInstallState != ERROR_SUCCESS )
         msi_dialog_end_dialog( dialog );
+    return ERROR_SUCCESS;
 }
 
 /*
  * Creates a dialog that remains up for a period of time
  * based on a condition
  */
-static VOID ControlEvent_SpawnWaitDialog(MSIPACKAGE* package, LPCWSTR argument, 
+static UINT ControlEvent_SpawnWaitDialog(MSIPACKAGE* package, LPCWSTR argument, 
                                   msi_dialog* dialog)
 {
     FIXME("Doing Nothing\n");
+    return ERROR_SUCCESS;
 }
 
-static VOID ControlEvent_DoAction(MSIPACKAGE* package, LPCWSTR argument, 
+static UINT ControlEvent_DoAction(MSIPACKAGE* package, LPCWSTR argument, 
                                   msi_dialog* dialog)
 {
     ACTION_PerformAction(package,argument,TRUE);
+    return ERROR_SUCCESS;
 }
 
-static VOID ControlEvent_AddLocal(MSIPACKAGE* package, LPCWSTR argument, 
+static UINT ControlEvent_AddLocal(MSIPACKAGE* package, LPCWSTR argument, 
                                   msi_dialog* dialog)
 {
     static const WCHAR szAll[] = {'A','L','L',0};
@@ -177,10 +182,10 @@
         }
         ACTION_UpdateComponentStates(package,argument);
     }
-
+    return ERROR_SUCCESS;
 }
 
-static VOID ControlEvent_Remove(MSIPACKAGE* package, LPCWSTR argument, 
+static UINT ControlEvent_Remove(MSIPACKAGE* package, LPCWSTR argument, 
                                 msi_dialog* dialog)
 {
     static const WCHAR szAll[] = {'A','L','L',0};
@@ -199,9 +204,10 @@
         }
         ACTION_UpdateComponentStates(package,argument);
     }
+    return ERROR_SUCCESS;
 }
 
-static VOID ControlEvent_AddSource(MSIPACKAGE* package, LPCWSTR argument, 
+static UINT ControlEvent_AddSource(MSIPACKAGE* package, LPCWSTR argument, 
                                    msi_dialog* dialog)
 {
     static const WCHAR szAll[] = {'A','L','L',0};
@@ -220,8 +226,16 @@
         }
         ACTION_UpdateComponentStates(package,argument);
     }
+    return ERROR_SUCCESS;
 }
 
+static UINT ControlEvent_SetTargetPath(MSIPACKAGE* package, LPCWSTR argument, 
+                                   msi_dialog* dialog)
+{
+    LPWSTR path = load_dynamic_property(package,argument, NULL);
+    /* failure to set the path halts the executing of control events */
+    return MSI_SetTargetPathW(package, argument, path);
+}
 
 /*
  * Subscribed events
@@ -350,17 +364,19 @@
     { "AddLocal",ControlEvent_AddLocal },
     { "Remove",ControlEvent_Remove },
     { "AddSource",ControlEvent_AddSource },
+    { "SetTargetPath",ControlEvent_SetTargetPath },
     { NULL,NULL },
 };
 
-VOID ControlEvent_HandleControlEvent(MSIPACKAGE *package, LPCWSTR event,
+UINT ControlEvent_HandleControlEvent(MSIPACKAGE *package, LPCWSTR event,
                                      LPCWSTR argument, msi_dialog* dialog)
 {
     int i = 0;
+    UINT rc = ERROR_SUCCESS;
 
     TRACE("Handling Control Event %s\n",debugstr_w(event));
     if (!event)
-        return;
+        return rc;
 
     while( Events[i].event != NULL)
     {
@@ -368,12 +384,13 @@
         if (lstrcmpW(wevent,event)==0)
         {
             HeapFree(GetProcessHeap(),0,wevent);
-            Events[i].handler(package,argument,dialog);
-            return;
+            rc = Events[i].handler(package,argument,dialog);
+            return rc;
         }
         HeapFree(GetProcessHeap(),0,wevent);
         i++;
     }
     FIXME("unhandled control event %s arg(%s)\n",
           debugstr_w(event), debugstr_w(argument));
+    return rc;
 }
Index: dlls/msi/msipriv.h
===================================================================
RCS file: /home/wine/wine/dlls/msi/msipriv.h,v
retrieving revision 1.66
diff -u -r1.66 msipriv.h
--- dlls/msi/msipriv.h	7 Jun 2005 20:29:51 -0000	1.66
+++ dlls/msi/msipriv.h	17 Jun 2005 17:16:46 -0000
@@ -387,7 +387,7 @@
 extern UINT MSIREG_OpenUserUpgradeCodesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
 
 /* msi dialog interface */
-typedef VOID (*msi_dialog_event_handler)( MSIPACKAGE*, LPCWSTR, LPCWSTR, msi_dialog* );
+typedef UINT (*msi_dialog_event_handler)( MSIPACKAGE*, LPCWSTR, LPCWSTR, msi_dialog* );
 extern msi_dialog *msi_dialog_create( MSIPACKAGE*, LPCWSTR, msi_dialog_event_handler );
 extern UINT msi_dialog_run_message_loop( msi_dialog* );
 extern void msi_dialog_end_dialog( msi_dialog* );


More information about the wine-patches mailing list