diff --git a/reactos/lib/advapi32/makefile b/reactos/lib/advapi32/makefile index 65fd5580721..726079c898b 100644 --- a/reactos/lib/advapi32/makefile +++ b/reactos/lib/advapi32/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.19 2001/08/21 20:13:05 chorns Exp $ +# $Id: makefile,v 1.20 2001/10/21 19:06:42 chorns Exp $ PATH_TO_TOP = ../.. @@ -8,6 +8,8 @@ TARGET_NAME = advapi32 TARGET_SDKLIBS = ntdll.a kernel32.a +# TARGET_CFLAGS = -DUNICODE + TARGET_BASE = 0x77dc0000 MISC_OBJECTS=\ diff --git a/reactos/lib/advapi32/service/scm.c b/reactos/lib/advapi32/service/scm.c index b4f9653dbdf..01d17c104f1 100644 --- a/reactos/lib/advapi32/service/scm.c +++ b/reactos/lib/advapi32/service/scm.c @@ -1,4 +1,4 @@ -/* $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 @@ -100,18 +100,18 @@ SC_HANDLE 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); @@ -410,35 +410,112 @@ SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess) { - HANDLE h; - - if (lpMachineName == NULL || - wcslen(lpMachineName) == 0) - { - if (lpDatabaseName != NULL && - wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0) - { - 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); + } - h = CreateFileW(L"\\\\.\\pipe\\ntsrvctrl", - dwDesiredAccess, - 0, - NULL, - OPEN_EXISTING, - 0, - NULL); - if (h == INVALID_HANDLE_VALUE) - { - 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); + } } diff --git a/reactos/lib/advapi32/service/sctrl.c b/reactos/lib/advapi32/service/sctrl.c index ddf2dae94bf..e5abf826914 100644 --- a/reactos/lib/advapi32/service/sctrl.c +++ b/reactos/lib/advapi32/service/sctrl.c @@ -1,4 +1,4 @@ -/* $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 @@ -19,7 +19,10 @@ typedef struct { - DWORD ThreadId; + DWORD ThreadId; + UNICODE_STRING ServiceName; + SERVICE_STATUS ServiceStatus; + LPHANDLER_FUNCTION Handler; } ACTIVE_SERVICE, *PACTIVE_SERVICE; /* GLOBALS *******************************************************************/ @@ -30,6 +33,39 @@ static PHANDLE ActiveServicesThreadHandles; /* 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 */ @@ -43,12 +79,16 @@ SERVICE_STATUS_HANDLE STDCALL 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); } @@ -61,8 +101,15 @@ SERVICE_STATUS_HANDLE STDCALL RegisterServiceCtrlHandlerW( 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; } @@ -102,61 +149,85 @@ BOOL 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; } @@ -166,71 +237,90 @@ BOOL STDCALL StartServiceCtrlDispatcherA( 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 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 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; } diff --git a/reactos/lib/kernel32/file/npipe.c b/reactos/lib/kernel32/file/npipe.c index 72a19dde78f..24249e526bc 100644 --- a/reactos/lib/kernel32/file/npipe.c +++ b/reactos/lib/kernel32/file/npipe.c @@ -1,4 +1,4 @@ -/* $Id: npipe.c,v 1.7 2001/10/20 15:28:03 ekohl Exp $ +/* $Id: npipe.c,v 1.8 2001/10/21 19:06:42 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -345,25 +345,29 @@ SetNamedPipeHandleState(HANDLE hNamedPipe, NPFS_SET_STATE SetState; IO_STATUS_BLOCK Iosb; NTSTATUS Status; - -#if 0 + Status = NtFsControlFile(hNamedPipe, NULL, NULL, NULL, &Iosb, - FSCTL_GET_STATE, + FSCTL_PIPE_GET_STATE, NULL, 0, &GetState, - sizeof(GetState)); - if (!NT_SUCCESS(Status)) + sizeof(NPFS_GET_STATE)); + if (Status == STATUS_PENDING) { - SetLastErrorByStatus (Status); - return(FALSE); + Status = NtWaitForSingleObject(hNamedPipe, + FALSE, + NULL); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } } -#endif - + if (lpMode != NULL) { if ((*lpMode) & PIPE_READMODE_MESSAGE) @@ -410,25 +414,30 @@ SetNamedPipeHandleState(HANDLE hNamedPipe, { SetState.Timeout = GetState.Timeout; } - -#if 0 + Status = NtFsControlFile(hNamedPipe, NULL, NULL, NULL, &Iosb, - FSCTL_SET_STATE, + FSCTL_PIPE_SET_STATE, &SetState, - sizeof(SetState), + sizeof(NPFS_SET_STATE), NULL, 0); - if (!NT_SUCCESS(Status)) + if (Status == STATUS_PENDING) { - SetLastErrorByStatus (Status); - return(FALSE); + Status = NtWaitForSingleObject(hNamedPipe, + FALSE, + NULL); + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return(FALSE); + } } -#endif - return(TRUE); + + return(TRUE); }