#define TOOLS_CORE_SIG_SHUTDOWN "tcs_shutdown"
#if defined(G_PLATFORM_WIN32)
-/**
- * Signal sent when there's a change in the state of a user's session.
- *
- * @param[in] src The source object.
- * @param[in] ctx ToolsAppCtx *: The application context.
- * @param[in] code DWORD: Session state change code.
- * @param[in] id DWORD: Session ID.
- * @param[in] data Client data.
- */
-#define TOOLS_CORE_SIG_SESSION_CHANGE "tcs_session_change"
/**
- * Signal sent when the pre shutdown event is received in the service.
+ * Signal sent when the service receives a control message. For a list
+ * of control messages, see the documentation on MSDN:
+ *
+ * http://msdn.microsoft.com/en-us/library/ms683241%28VS.85%29.aspx
+ *
+ * The signal is only available on Win32. Receiving this signal doesn't
+ * mean the service is running through the Windows SCM: plugins may detect
+ * equivalent notifications through other means and send this signal with
+ * the appropriate parameters so others can react to them.
*
* @param[in] src The source object.
* @param[in] ctx ToolsAppCtx *: The application context.
- * @param[in] handle SERVICE_STATUS_HANDLE: Service status handle.
+ * @param[in] handle SERVICE_STATUS_HANDLE: Service status handle. May be
+ * NULL if process is not under SCM control.
+ * @param[in] control guint: The control code.
+ * @param[in] evtType guint: The event type.
+ * @param[in] evtData gpointer: Event data.
* @param[in] data Client data.
+ *
+ * @return See MSDN documentation. NO_ERROR has precedence over
+ * ERROR_CALL_NOT_IMPLEMENTED; if any handler returns any value other than
+ * those two, then that value will be used as the return value, unless the
+ * Tools service itself also handles the control message, or the MSDN
+ * documentation specifies a return value.
*/
-#define TOOLS_CORE_SIG_PRESHUTDOWN "tcs_preshutdown"
+#define TOOLS_CORE_SIG_SERVICE_CONTROL "tcs_service_control"
#endif
}
+#if defined(_WIN32)
+/**
+ * Accumulator function for the "service control" signal. Updates the return
+ * value according to the signal's documentation.
+ *
+ * @param[in] ihint Unused.
+ * @param[out] retval Return value of the signal.
+ * @param[in] handlerRet Return value from the current handler.
+ * @param[in] data Unused.
+ *
+ * @return TRUE.
+ */
+
+static gboolean
+ToolsCoreServiceControlAccumulator(GSignalInvocationHint *ihint,
+ GValue *retval,
+ const GValue *handlerRet,
+ gpointer data)
+{
+ guint ret = g_value_get_uint(retval);
+ guint handlerVal = g_value_get_uint(handlerRet);
+ switch (ret) {
+ case ERROR_CALL_NOT_IMPLEMENTED:
+ ret = handlerVal;
+ break;
+
+ case NO_ERROR:
+ if (handlerVal != ERROR_CALL_NOT_IMPLEMENTED) {
+ ret = handlerVal;
+ }
+ break;
+
+ default:
+ break;
+ }
+ g_value_set_uint(retval, ret);
+ return TRUE;
+}
+#endif
+
/**
* Initializes the ToolsCoreService class. Sets up the signals that are sent
* by the vmtoolsd service.
1,
G_TYPE_POINTER);
#if defined(G_PLATFORM_WIN32)
- g_signal_new(TOOLS_CORE_SIG_SESSION_CHANGE,
+ g_signal_new(TOOLS_CORE_SIG_SERVICE_CONTROL,
G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_LAST,
0,
NULL,
NULL,
- g_cclosure_user_marshal_VOID__POINTER_UINT_UINT,
- G_TYPE_NONE,
- 3,
- G_TYPE_POINTER,
+ g_cclosure_user_marshal_UINT__POINTER_POINTER_UINT_UINT_POINTER,
G_TYPE_UINT,
- G_TYPE_UINT);
-
- g_signal_new(TOOLS_CORE_SIG_PRESHUTDOWN,
- G_OBJECT_CLASS_TYPE(klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL,
- NULL,
- g_cclosure_user_marshal_VOID__POINTER_POINTER,
- G_TYPE_NONE,
- 2,
+ 5,
+ G_TYPE_POINTER,
G_TYPE_POINTER,
+ G_TYPE_UINT,
+ G_TYPE_UINT,
G_TYPE_POINTER);
#endif
}
# The "set option" signal.
BOOLEAN:POINTER,STRING,STRING
-# The "session change" signal.
+# The "service control" signal.
# Used on Win32 only.
-VOID:POINTER,UINT,UINT
-
-# The "pre shutdown" signal.
-# Used on Win32 only.
-VOID:POINTER,POINTER
+UINT:POINTER,POINTER,UINT,UINT,POINTER
#if defined(G_PLATFORM_WIN32)
/**
- * Handles a session state change callback; this is only called on Windows,
- * from both the "vmsvc" instance (handled by SCM notifications) and from
- * "vmusr" with the "fast user switch" plugin.
+ * Handles a service control signal; this is only called on Windows.
*
- * @param[in] src The source object.
- * @param[in] ctx The application context.
- * @param[in] code Session state change code.
- * @param[in] id Session ID.
- * @param[in] data Client data.
- */
-
-static void
-TestPluginSessionChange(gpointer src,
- ToolsAppCtx *ctx,
- DWORD code,
- DWORD sessionId,
- ToolsPluginData *plugin)
-{
- g_debug("Got session state change signal, code = %u, id = %u\n", code, sessionId);
-}
-
-
-/**
- * Handles the preshutdown callback; this is only called on Windows Vista & up,
- * from the "vmsvc" instance. This is called only "upgrade at powercycle" flag is
- * set in the UI. If the upgrader is launched, the service waits for upgrader
- * to terminate before shutting down.
+ * @param[in] src The source object.
+ * @param[in] ctx The application context.
+ * @param[in] serviceStatusHandle Handle of type SERVICE_STATUS_HANDLE.
+ * @param[in] controlCode Control code.
+ * @param[in] eventType Unused.
+ * @param[in] eventData Unused.
+ * @param[in] data Unused.
*
- * @param[in] src The source object.
- * @param[in] ctx ToolsAppCtx *: The application context.
- * @param[in] serviceStatusHandle A handle of type SERVICE_STATUS_HANDLE
- * @param[in] data Client data.
+ * @retval ERROR_CALL_NOT_IMPLEMENTED
*/
-static void
-TestPluginPreShutdownChange(gpointer src,
- ToolsAppCtx *ctx,
- gpointer serviceStatusHandle,
- gpointer data)
+static DWORD
+TestPluginServiceControl(gpointer src,
+ ToolsAppCtx *ctx,
+ gpointer serviceStatusHandle,
+ guint controlCode,
+ guint eventType,
+ gpointer eventData,
+ gpointer data)
{
- g_debug("%s: Got preshutdown signal for app %s\n", __FUNCTION__, ctx->name);
+ g_debug("Got service control signal, code = %u, event = %u\n",
+ controlCode, eventType);
+ return ERROR_CALL_NOT_IMPLEMENTED;
}
#endif
{ TOOLS_CORE_SIG_CAPABILITIES, TestPluginCapabilities, ®Data },
{ TOOLS_CORE_SIG_SET_OPTION, TestPluginSetOption, ®Data },
#if defined(G_PLATFORM_WIN32)
- { TOOLS_CORE_SIG_SESSION_CHANGE, TestPluginSessionChange, ®Data },
- { TOOLS_CORE_SIG_PRESHUTDOWN, TestPluginPreShutdownChange, ®Data },
+ { TOOLS_CORE_SIG_SERVICE_CONTROL, TestPluginServiceControl, ®Data },
#endif
};
TestApp tapp[] = {