-/* $Id: scm.c,v 1.7 2001/06/25 14:19:56 ekohl Exp $
+/* $Id: scm.c,v 1.8 2001/10/21 19:06:42 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
STDCALL
CreateServiceA(
SC_HANDLE hSCManager,
- LPCTSTR lpServiceName,
- LPCTSTR lpDisplayName,
+ LPCSTR lpServiceName,
+ LPCSTR lpDisplayName,
DWORD dwDesiredAccess,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
- LPCTSTR lpBinaryPathName,
- LPCTSTR lpLoadOrderGroup,
+ LPCSTR lpBinaryPathName,
+ LPCSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
- LPCTSTR lpDependencies,
- LPCTSTR lpServiceStartName,
- LPCTSTR lpPassword
+ LPCSTR lpDependencies,
+ LPCSTR lpServiceStartName,
+ LPCSTR lpPassword
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
LPCWSTR lpDatabaseName,
DWORD dwDesiredAccess)
{
- HANDLE h;
-
- if (lpMachineName == NULL ||
- wcslen(lpMachineName) == 0)
- {
- if (lpDatabaseName != NULL &&
- wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0)
- {
- return(NULL);
- }
-
- h = CreateFileW(L"\\\\.\\pipe\\ntsrvctrl",
- dwDesiredAccess,
- 0,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
- if (h == INVALID_HANDLE_VALUE)
- {
- return(NULL);
- }
+ HANDLE hPipe;
+ DWORD dwMode;
+ BOOL fSuccess;
+ LPWSTR lpszPipeName = L"\\\\.\\pipe\\Ntsvcs";
+
+ if (lpMachineName == NULL || wcslen(lpMachineName) == 0)
+ {
+ if (lpDatabaseName != NULL && wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0)
+ {
+ return(NULL);
+ }
- return(h);
- }
- else
- {
- return(NULL);
- }
+ // Try to open a named pipe; wait for it, if necessary
+ while (1)
+ {
+ hPipe = CreateFileW(
+ lpszPipeName, // pipe name
+ dwDesiredAccess,
+ 0, // no sharing
+ NULL, // no security attributes
+ OPEN_EXISTING, // opens existing pipe
+ 0, // default attributes
+ NULL); // no template file
+
+ // Break if the pipe handle is valid
+
+ if (hPipe != INVALID_HANDLE_VALUE)
+ break;
+
+ // Exit if an error other than ERROR_PIPE_BUSY occurs
+
+ if (GetLastError() != ERROR_PIPE_BUSY)
+ {
+ return(NULL);
+ }
+
+ // All pipe instances are busy, so wait for 20 seconds
+
+ if (!WaitNamedPipeW(lpszPipeName, 20000))
+ {
+ return(NULL);
+ }
+ }
+
+ // The pipe connected; change to message-read mode
+
+ dwMode = PIPE_READMODE_MESSAGE;
+ fSuccess = SetNamedPipeHandleState(
+ hPipe, // pipe handle
+ &dwMode, // new pipe mode
+ NULL, // don't set maximum bytes
+ NULL); // don't set maximum time
+ if (!fSuccess)
+ {
+ CloseHandle(hPipe);
+ return(NULL);
+ }
+#if 0
+ // Send a message to the pipe server
+
+ lpvMessage = (argc > 1) ? argv[1] : "default message";
+
+ fSuccess = WriteFile(
+ hPipe, // pipe handle
+ lpvMessage, // message
+ strlen(lpvMessage) + 1, // message length
+ &cbWritten, // bytes written
+ NULL); // not overlapped
+ if (!fSuccess)
+ {
+ CloseHandle(hPipe);
+ return(NULL);
+ }
+
+ do
+ {
+ // Read from the pipe
+
+ fSuccess = ReadFile(
+ hPipe, // pipe handle
+ chBuf, // buffer to receive reply
+ 512, // size of buffer
+ &cbRead, // number of bytes read
+ NULL); // not overlapped
+
+ if (! fSuccess && GetLastError() != ERROR_MORE_DATA)
+ break;
+
+ // Reply from the pipe is written to STDOUT.
+
+ if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
+ chBuf, cbRead, &cbWritten, NULL))
+ {
+ break;
+ }
+
+ } while (!fSuccess); // repeat loop if ERROR_MORE_DATA
+ //CloseHandle(hPipe);
+#endif
+ return(hPipe);
+ }
+ else
+ {
+ /* FIXME: Connect to remote SCM */
+ return(NULL);
+ }
}
-/* $Id: sctrl.c,v 1.2 2001/06/25 14:19:56 ekohl Exp $
+/* $Id: sctrl.c,v 1.3 2001/10/21 19:06:42 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
typedef struct
{
- DWORD ThreadId;
+ DWORD ThreadId;
+ UNICODE_STRING ServiceName;
+ SERVICE_STATUS ServiceStatus;
+ LPHANDLER_FUNCTION Handler;
} ACTIVE_SERVICE, *PACTIVE_SERVICE;
/* GLOBALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
+PACTIVE_SERVICE
+ScLookupServiceByThreadId(
+ DWORD ThreadId)
+{
+ DWORD i;
+
+ for (i = 0; i < ActiveServiceCount; i++)
+ {
+ if (ActiveServices[i].ThreadId == ThreadId)
+ {
+ return &ActiveServices[i];
+ }
+ }
+
+ return NULL;
+}
+
+
+DWORD
+WINAPI
+ScServiceMainStub(
+ LPVOID Context)
+{
+ LPSERVICE_MAIN_FUNCTION lpServiceProc = (LPSERVICE_MAIN_FUNCTION)Context;
+
+ /* FIXME: Send argc and argv (from command line) as arguments */
+
+ (lpServiceProc)(0, NULL);
+
+ return ERROR_SUCCESS;
+}
+
+
/**********************************************************************
* RegisterServiceCtrlHandlerA
*/
SERVICE_STATUS_HANDLE SHandle;
RtlInitAnsiString(&ServiceNameA, (LPSTR)lpServiceName);
- RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE);
-
+ if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ServiceNameU, &ServiceNameA, TRUE)))
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return (SERVICE_STATUS_HANDLE)0;
+ }
+
SHandle = RegisterServiceCtrlHandlerW(ServiceNameU.Buffer,
lpHandlerProc);
-
- RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceNameU.Buffer);
+
+ RtlFreeUnicodeString(&ServiceNameU);
return(SHandle);
}
LPCWSTR lpServiceName,
LPHANDLER_FUNCTION lpHandlerProc)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ PACTIVE_SERVICE Service;
+
+ /* FIXME: Locate active service entry from name */
+
+ Service = &ActiveServices[0];
+
+ Service->Handler = lpHandlerProc;
+
+ return (SERVICE_STATUS_HANDLE)Service->ThreadId;
}
STDCALL
SetServiceStatus(
SERVICE_STATUS_HANDLE hServiceStatus,
- LPSERVICE_STATUS lpServiceStatus
- )
+ LPSERVICE_STATUS lpServiceStatus)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ PACTIVE_SERVICE Service;
+
+ Service = ScLookupServiceByThreadId((DWORD)hServiceStatus);
+ if (!Service)
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ RtlCopyMemory(
+ &Service->ServiceStatus,
+ lpServiceStatus,
+ sizeof(SERVICE_STATUS));
+
+ return TRUE;
}
/**********************************************************************
* StartServiceCtrlDispatcherA
*/
BOOL STDCALL StartServiceCtrlDispatcherA(
- LPSERVICE_TABLE_ENTRYA lpServiceStartTable)
+ LPSERVICE_TABLE_ENTRYA lpServiceStartTable)
{
- LPSERVICE_TABLE_ENTRYW ServiceStartTableW;
- ANSI_STRING ServiceNameA;
- UNICODE_STRING ServiceNameW;
- ULONG i;
- ULONG Count;
- BOOL b;
-
- i = 0;
- while (lpServiceStartTable[i].lpServiceProc != NULL)
- {
- i++;
- }
- Count = i;
-
- ServiceStartTableW = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_ZERO_MEMORY,
- sizeof(SERVICE_TABLE_ENTRYW) * Count);
- for (i = 0; i < Count; i++)
- {
- RtlInitAnsiString(&ServiceNameA,
- lpServiceStartTable[i].lpServiceName);
- RtlAnsiStringToUnicodeString(&ServiceNameW,
- &ServiceNameA,
- TRUE);
- ServiceStartTableW[i].lpServiceName = ServiceNameW.Buffer;
- ServiceStartTableW[i].lpServiceProc =
- lpServiceStartTable[i].lpServiceProc;
- }
-
- b = StartServiceCtrlDispatcherW(ServiceStartTableW);
-
- for (i = 0; i < Count; i++)
- {
- RtlFreeHeap(RtlGetProcessHeap(),
- 0,
- ServiceStartTableW[i].lpServiceName);
- }
- RtlFreeHeap(RtlGetProcessHeap(),
- 0,
- ServiceStartTableW);
-
- return(b);
+ LPSERVICE_TABLE_ENTRYW ServiceStartTableW;
+ ANSI_STRING ServiceNameA;
+ UNICODE_STRING ServiceNameW;
+ ULONG i, j;
+ ULONG Count;
+ BOOL b;
+
+ i = 0;
+ while (lpServiceStartTable[i].lpServiceProc != NULL)
+ {
+ i++;
+ }
+ Count = i;
+
+ ServiceStartTableW = RtlAllocateHeap(
+ RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(SERVICE_TABLE_ENTRYW) * Count);
+ for (i = 0; i < Count; i++)
+ {
+ RtlInitAnsiString(
+ &ServiceNameA,
+ lpServiceStartTable[i].lpServiceName);
+ if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(
+ &ServiceNameW,
+ &ServiceNameA,
+ TRUE)))
+ {
+ for (j = 0; j < i; j++)
+ {
+ RtlInitUnicodeString(
+ &ServiceNameW,
+ ServiceStartTableW[j].lpServiceName);
+ RtlFreeUnicodeString(&ServiceNameW);
+ }
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceStartTableW);
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+ ServiceStartTableW[i].lpServiceName = ServiceNameW.Buffer;
+ ServiceStartTableW[i].lpServiceProc =
+ lpServiceStartTable[i].lpServiceProc;
+ }
+
+ b = StartServiceCtrlDispatcherW(ServiceStartTableW);
+
+ for (i = 0; i < Count; i++)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceStartTableW[i].lpServiceName);
+ }
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ServiceStartTableW);
+
+ return b;
}
BOOL STDCALL StartServiceCtrlDispatcherW(
LPSERVICE_TABLE_ENTRYW lpServiceStartTable)
{
- ULONG i;
- HANDLE h;
- DWORD Tid;
- DWORD r;
-
- i = 0;
- while (lpServiceStartTable[i].lpServiceProc != NULL)
- {
- i++;
- }
-
- ActiveServiceCount = i;
- ActiveServices = RtlAllocateHeap(GetProcessHeap(),
- HEAP_ZERO_MEMORY,
- ActiveServiceCount *
- sizeof(ACTIVE_SERVICE));
- ActiveServicesThreadHandles = RtlAllocateHeap(GetProcessHeap(),
- HEAP_ZERO_MEMORY,
- (ActiveServiceCount + 1) *
- sizeof(HANDLE));
-
- for (i = 0; i<ActiveServiceCount; i++)
- {
- h = CreateThread(NULL,
- 0,
- (LPTHREAD_START_ROUTINE)lpServiceStartTable[i].lpServiceProc,
- NULL,
- 0,
- &Tid);
- if (h == INVALID_HANDLE_VALUE)
- {
- return(FALSE);
- }
- ActiveServicesThreadHandles[i + 1] = h;
- ActiveServices[i].ThreadId = Tid;
- }
-
- while (ActiveServiceCount > 0)
- {
- r = WaitForMultipleObjects(ActiveServiceCount + 1,
- ActiveServicesThreadHandles,
- FALSE,
- INFINITE);
- if (r == WAIT_OBJECT_0)
- {
- /* Received message from the scm */
- }
- else if (r > WAIT_OBJECT_0 &&
- r < (WAIT_OBJECT_0 + ActiveServiceCount))
- {
- /* A service died */
-
- ActiveServiceCount--;
- ActiveServicesThreadHandles[r - WAIT_OBJECT_0 - 1] =
- ActiveServicesThreadHandles[ActiveServiceCount + 1];
- memcpy(&ActiveServices[r - WAIT_OBJECT_0 - 2],
- &ActiveServices[ActiveServiceCount],
- sizeof(ACTIVE_SERVICE));
- }
- else
- {
- /* Bail */
- }
- }
- return(TRUE);
+ ULONG i;
+ HANDLE h;
+ DWORD Tid;
+ DWORD r;
+
+ i = 0;
+ while (lpServiceStartTable[i].lpServiceProc != NULL)
+ {
+ i++;
+ }
+
+ ActiveServiceCount = i;
+ ActiveServices = RtlAllocateHeap(
+ RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ ActiveServiceCount *
+ sizeof(ACTIVE_SERVICE));
+ if (!ActiveServices)
+ {
+ return FALSE;
+ }
+
+ ActiveServicesThreadHandles = RtlAllocateHeap(
+ RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ (ActiveServiceCount + 1) *
+ sizeof(HANDLE));
+ if (!ActiveServicesThreadHandles)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServices);
+ ActiveServices = NULL;
+ return FALSE;
+ }
+
+ for (i = 0; i<ActiveServiceCount; i++)
+ {
+ h = CreateThread(
+ NULL,
+ 0,
+ ScServiceMainStub,
+ lpServiceStartTable[i].lpServiceProc,
+ 0,
+ &Tid);
+ if (h == INVALID_HANDLE_VALUE)
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServicesThreadHandles);
+ ActiveServicesThreadHandles = NULL;
+ RtlFreeHeap(RtlGetProcessHeap(), 0, ActiveServices);
+ ActiveServices = NULL;
+ return(FALSE);
+ }
+ ActiveServicesThreadHandles[i + 1] = h;
+ ActiveServices[i].ThreadId = Tid;
+ }
+
+ while (ActiveServiceCount > 0)
+ {
+ r = WaitForMultipleObjects(
+ ActiveServiceCount + 1,
+ ActiveServicesThreadHandles,
+ FALSE,
+ INFINITE);
+ if (r == WAIT_OBJECT_0)
+ {
+ /* Received message from the scm */
+ }
+ else if (r > WAIT_OBJECT_0 && r < (WAIT_OBJECT_0 + ActiveServiceCount))
+ {
+ /* A service died */
+
+ ActiveServiceCount--;
+ ActiveServicesThreadHandles[r - WAIT_OBJECT_0 - 1] =
+ ActiveServicesThreadHandles[ActiveServiceCount + 1];
+ RtlCopyMemory(
+ &ActiveServices[r - WAIT_OBJECT_0 - 2],
+ &ActiveServices[ActiveServiceCount],
+ sizeof(ACTIVE_SERVICE));
+ }
+ else
+ {
+ /* Bail */
+ }
+ }
+ return TRUE;
}