* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * ---- rpcss_main.c:
- * Initialize and start serving requests. Bail if rpcss already is
- * running.
- *
- * ---- RPCSS.EXE:
- *
- * Wine needs a server whose role is somewhat like that
- * of rpcss.exe in windows. This is not a clone of
- * windows rpcss at all. It has been given the same name, however,
- * to provide for the possibility that at some point in the future,
- * it may become interface compatible with the "real" rpcss.exe on
- * Windows.
- *
- * ---- KNOWN BUGS / TODO:
- *
- * o Service hooks are unimplemented (if you bother to implement
- * these, also implement net.exe, at least for "net start" and
- * "net stop" (should be pretty easy I guess, assuming the rest
- * of the services API infrastructure works.
- *
- * o There is a looming problem regarding listening on privileged
- * ports. We will need to be able to coexist with SAMBA, and be able
- * to function without running winelib code as root. This may
- * take some doing, including significant reconceptualization of the
- * role of rpcss.exe in wine.
*/
-#include "rpcss.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <assert.h>
-#include <wine/debug.h>
+#include "windef.h"
+#include "winbase.h"
+#include "winnt.h"
+#include "winsvc.h"
+#include "irot_s.h"
+#include "epm_s.h"
-WINE_DEFAULT_DEBUG_CHANNEL(ole);
+#include "wine/debug.h"
-HANDLE exit_event;
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
-//extern HANDLE __wine_make_process_system(void);
+static WCHAR rpcssW[] = {'R','p','c','S','s',0};
+static HANDLE exit_event;
+static SERVICE_STATUS_HANDLE service_handle;
-BOOL RPCSS_Initialize(void)
+static BOOL RPCSS_Initialize(void)
{
static unsigned short irot_protseq[] = IROT_PROTSEQ;
static unsigned short irot_endpoint[] = IROT_ENDPOINT;
if (status != RPC_S_OK)
goto fail;
-#ifndef __REACTOS__
- exit_event = __wine_make_process_system();
-#else
- exit_event = CreateEventW(NULL, FALSE, FALSE, NULL); // never fires
- {
- HANDLE hStartEvent = CreateEventW(NULL, TRUE, FALSE, L"ScmCreatedEvent");
- SetEvent(hStartEvent);
- }
-#endif
-
return TRUE;
fail:
return FALSE;
}
-/* returns false if we discover at the last moment that we
- aren't ready to terminate */
-BOOL RPCSS_Shutdown(void)
+static DWORD WINAPI service_handler( DWORD ctrl, DWORD event_type, LPVOID event_data, LPVOID context )
{
- RpcMgmtStopServerListening(NULL);
- RpcServerUnregisterIf(epm_v3_0_s_ifspec, NULL, TRUE);
- RpcServerUnregisterIf(Irot_v0_2_s_ifspec, NULL, TRUE);
+ SERVICE_STATUS status;
+
+ status.dwServiceType = SERVICE_WIN32;
+ status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+ status.dwWin32ExitCode = 0;
+ status.dwServiceSpecificExitCode = 0;
+ status.dwCheckPoint = 0;
+ status.dwWaitHint = 0;
+
+ switch (ctrl)
+ {
+ case SERVICE_CONTROL_STOP:
+ case SERVICE_CONTROL_SHUTDOWN:
+ TRACE( "shutting down\n" );
+ RpcMgmtStopServerListening( NULL );
+ RpcServerUnregisterIf( epm_v3_0_s_ifspec, NULL, TRUE );
+ RpcServerUnregisterIf( Irot_v0_2_s_ifspec, NULL, TRUE );
+ status.dwCurrentState = SERVICE_STOP_PENDING;
+ status.dwControlsAccepted = 0;
+ SetServiceStatus( service_handle, &status );
+ SetEvent( exit_event );
+ return NO_ERROR;
+ default:
+ FIXME( "got service ctrl %x\n", ctrl );
+ status.dwCurrentState = SERVICE_RUNNING;
+ SetServiceStatus( service_handle, &status );
+ return NO_ERROR;
+ }
+}
- CloseHandle(exit_event);
+static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv )
+{
+ SERVICE_STATUS status;
- return TRUE;
+ TRACE( "starting service\n" );
+
+ if (!RPCSS_Initialize()) return;
+
+ exit_event = CreateEventW( NULL, TRUE, FALSE, NULL );
+
+ service_handle = RegisterServiceCtrlHandlerExW( rpcssW, service_handler, NULL );
+ if (!service_handle) return;
+
+ status.dwServiceType = SERVICE_WIN32;
+ status.dwCurrentState = SERVICE_RUNNING;
+ status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+ status.dwWin32ExitCode = 0;
+ status.dwServiceSpecificExitCode = 0;
+ status.dwCheckPoint = 0;
+ status.dwWaitHint = 10000;
+ SetServiceStatus( service_handle, &status );
+
+ WaitForSingleObject( exit_event, INFINITE );
+
+ status.dwCurrentState = SERVICE_STOPPED;
+ status.dwControlsAccepted = 0;
+ SetServiceStatus( service_handle, &status );
+ TRACE( "service stopped\n" );
}
-#ifndef __REACTOS__
-int main( int argc, char **argv )
+int wmain( int argc, WCHAR *argv[] )
{
- /*
- * We are invoked as a standard executable; we act in a
- * "lazy" manner. We register our interfaces and endpoints, and hang around
- * until we all user processes exit, and then silently terminate.
- */
-
- if (RPCSS_Initialize()) {
- WaitForSingleObject(exit_event, INFINITE);
- RPCSS_Shutdown();
- }
-
- return 0;
+ static const SERVICE_TABLE_ENTRYW service_table[] =
+ {
+ { rpcssW, ServiceMain },
+ { NULL, NULL }
+ };
+
+ StartServiceCtrlDispatcherW( service_table );
+ return 0;
}
-#endif
+++ /dev/null
-/*
- * PROJECT: ReactOS Remote Procedure Call service
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: base/services/rpcss/service_main.c
- * PURPOSE: Service control code
- * COPYRIGHT: Copyright 2008 Ged Murphy <gedmurphy@reactos.org>
- *
- */
-
-#include "rpcss.h"
-
-#include <winsvc.h>
-
-#define NDEBUG
-#include <debug.h>
-
-extern BOOL RPCSS_Initialize(void);
-extern BOOL RPCSS_Shutdown(void);
-extern HANDLE exit_event;
-
-static VOID WINAPI ServiceMain(DWORD, LPWSTR *);
-static WCHAR ServiceName[] = L"RpcSs";
-SERVICE_TABLE_ENTRYW ServiceTable[] =
-{
- { ServiceName, ServiceMain },
- { NULL, NULL }
-};
-
-static SERVICE_STATUS ServiceStatus;
-static SERVICE_STATUS_HANDLE ServiceStatusHandle;
-
-DWORD WINAPI
-ServiceControlHandler(DWORD dwControl,
- DWORD dwEventType,
- LPVOID lpEventData,
- LPVOID lpContext)
-{
- switch (dwControl)
- {
- case SERVICE_CONTROL_SHUTDOWN:
- case SERVICE_CONTROL_STOP:
- SetEvent(exit_event);
- return NO_ERROR;
-
- case SERVICE_CONTROL_INTERROGATE:
- return NO_ERROR;
-
- default:
- return ERROR_CALL_NOT_IMPLEMENTED;
- }
-}
-
-VOID WINAPI
-ServiceMain(DWORD argc, LPWSTR argv[])
-{
- DWORD dwError;
-
- ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName,
- ServiceControlHandler,
- NULL);
- if (!ServiceStatusHandle)
- {
- dwError = GetLastError();
- DPRINT1("RegisterServiceCtrlHandlerW() failed! (Error %lu)\n", dwError);
- return;
- }
-
- ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
- ServiceStatus.dwControlsAccepted = 0;
- ServiceStatus.dwWin32ExitCode = NO_ERROR;
- ServiceStatus.dwServiceSpecificExitCode = 0;
- ServiceStatus.dwCheckPoint = 0;
- ServiceStatus.dwWaitHint = 1000;
- SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
-
- if (RPCSS_Initialize())
- {
- ServiceStatus.dwCurrentState = SERVICE_RUNNING;
- ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
- SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
-
- WaitForSingleObject(exit_event, INFINITE);
-
- RPCSS_Shutdown();
-
- ServiceStatus.dwCurrentState = SERVICE_STOPPED;
- SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
- }
-}
-
-int wmain(int argc, LPWSTR argv[])
-{
- if (!StartServiceCtrlDispatcherW(ServiceTable))
- {
- DPRINT1("StartServiceCtrlDispatcherW() failed\n");
- return 1;
- }
-
- return 0;
-}