/// <summary> /// Callback used to register with thread pool to notify when a plugin operation shuts down. /// Conforms to: /// public delegate void WaitOrTimerCallback( Object state, bool timedOut ) /// </summary> /// <param name="operationContext">PVOID</param> /// <param name="timedOut">BOOLEAN</param> /// <returns></returns> public static void PSPluginOperationShutdownCallback( object operationContext, bool timedOut) { if (null == operationContext) { return; } WSManPluginOperationShutdownContext context = (WSManPluginOperationShutdownContext)operationContext; context.isShuttingDown = true; WSManPluginInstance.PerformCloseOperation(context); }
internal bool EnableTransportManagerSendDataToClient( WSManNativeApi.WSManPluginRequest requestDetails, WSManPluginOperationShutdownContext ctxtToReport) { _shutDownContext = ctxtToReport; bool isRegisterWaitForSingleObjectSucceeded = true; lock (_syncObject) { if (_isRequestPending) { // if a request is already pending..ignore this. WSManPluginInstance.ReportWSManOperationComplete( requestDetails, WSManPluginErrorCodes.NoError); return(false); } if (_isClosed) { WSManPluginInstance.ReportWSManOperationComplete(requestDetails, _lastErrorReported); return(false); } _isRequestPending = true; _requestDetails = requestDetails; if (Platform.IsWindows) { // Wrap the provided handle so it can be passed to the registration function SafeWaitHandle safeWaitHandle = new SafeWaitHandle(requestDetails.shutdownNotificationHandle, false); // Owned by WinRM EventWaitHandle eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset); eventWaitHandle.SafeWaitHandle = safeWaitHandle; _registeredShutDownWaitHandle = ThreadPool.RegisterWaitForSingleObject( eventWaitHandle, new WaitOrTimerCallback(WSManPluginManagedEntryWrapper.PSPluginOperationShutdownCallback), _shutDownContext, -1, // INFINITE true); // TODO: Do I need to worry not being able to set missing WT_TRANSFER_IMPERSONATION? if (_registeredShutDownWaitHandle == null) { isRegisterWaitForSingleObjectSucceeded = false; } } // release thread waiting to send data to the client. _waitHandle.Set(); } if (!isRegisterWaitForSingleObjectSucceeded) { WSManPluginInstance.PerformCloseOperation(ctxtToReport); WSManPluginInstance.ReportOperationComplete( requestDetails, WSManPluginErrorCodes.ShutdownRegistrationFailed, StringUtil.Format( RemotingErrorIdStrings.WSManPluginShutdownRegistrationFailed)); return(false); } return(true); }