Progress with opening and closing handles to SCM.

svn path=/trunk/; revision=3899
This commit is contained in:
Robert Dickenson 2002-12-27 14:40:03 +00:00
parent 70544cdae0
commit bb2e6e63b8

View file

@ -1,4 +1,4 @@
/* $Id: scm.c,v 1.14 2002/12/26 17:23:27 robd Exp $
/* $Id: scm.c,v 1.15 2002/12/27 14:40:03 robd Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -17,6 +17,9 @@
#include <windows.h>
#include <tchar.h>
#define DBG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
/**********************************************************************
@ -72,9 +75,16 @@ BOOL
STDCALL
CloseServiceHandle(SC_HANDLE hSCObject)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
HANDLE hPipe;
DPRINT("CloseServiceHandle() - called.\n");
// SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
if (!CloseHandle(hPipe)) {
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
return TRUE;
}
/**********************************************************************
@ -383,27 +393,20 @@ OpenSCManagerA(LPCSTR lpMachineName,
ANSI_STRING MachineNameA;
ANSI_STRING DatabaseNameA;
RtlInitAnsiString(&MachineNameA, (LPSTR)lpMachineName);
RtlAnsiStringToUnicodeString(&MachineNameW,
&MachineNameA,
TRUE);
RtlInitAnsiString(&DatabaseNameA, (LPSTR)lpDatabaseName);
RtlAnsiStringToUnicodeString(&DatabaseNameW,
&DatabaseNameA,
TRUE);
DPRINT("OpenSCManagerA(%x, %x, %d)\n", lpMachineName, lpDatabaseName, dwDesiredAccess);
Handle = OpenSCManagerW(MachineNameW.Buffer,
DatabaseNameW.Buffer,
RtlInitAnsiString(&MachineNameA, (LPSTR)lpMachineName);
RtlAnsiStringToUnicodeString(&MachineNameW, &MachineNameA, TRUE);
RtlInitAnsiString(&DatabaseNameA, (LPSTR)lpDatabaseName);
RtlAnsiStringToUnicodeString(&DatabaseNameW, &DatabaseNameA, TRUE);
Handle = OpenSCManagerW(lpMachineName ? MachineNameW.Buffer : NULL,
lpDatabaseName ? DatabaseNameW.Buffer : NULL,
dwDesiredAccess);
RtlFreeHeap(GetProcessHeap(),
0,
MachineNameW.Buffer);
RtlFreeHeap(GetProcessHeap(),
0,
DatabaseNameW.Buffer);
return(Handle);
RtlFreeHeap(GetProcessHeap(), 0, MachineNameW.Buffer);
RtlFreeHeap(GetProcessHeap(), 0, DatabaseNameW.Buffer);
return Handle;
}
@ -421,29 +424,65 @@ SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName,
HANDLE hStartEvent;
LPWSTR lpszPipeName = L"\\\\.\\pipe\\Ntsvcs";
if(lpMachineName == NULL || wcslen(lpMachineName) == 0)
{
if(lpDatabaseName != NULL && wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0)
{ return(NULL); }
DPRINT("OpenSCManagerW(%x, %x, %d)\n", lpMachineName, lpDatabaseName, dwDesiredAccess);
if (lpMachineName == NULL || wcslen(lpMachineName) == 0) {
if (lpDatabaseName != NULL && wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0) {
DPRINT("OpenSCManagerW() - Invalid parameters.\n");
return NULL;
}
DPRINT("OpenSCManagerW() - OpenEvent(\"SvcctrlStartEvent_A3725DX\")\n");
// Only connect to scm when event "SvcctrlStartEvent_A3725DX" is signaled
hStartEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("SvcctrlStartEvent_A3725DX"));
if(hStartEvent == NULL)
{
if (hStartEvent == NULL) {
SetLastError(ERROR_DATABASE_DOES_NOT_EXIST);
return (NULL);
DPRINT("OpenSCManagerW() - Failed to Open Event \"SvcctrlStartEvent_A3725DX\".\n");
return NULL;
}
DPRINT("OpenSCManagerW() - Waiting forever on event handle: %x\n", hStartEvent);
#if 1
dwWait = WaitForSingleObject(hStartEvent, INFINITE);
if (dwWait == WAIT_FAILED) {
DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n");
SetLastError(ERROR_ACCESS_DENIED);
return NULL;
}
#else
{
DWORD Count;
/* wait for event creation (by SCM) for max. 20 seconds */
for (Count = 0; Count < 20; Count++)
{
dwWait = WaitForSingleObject(hStartEvent, 1000);
if (dwWait == WAIT_FAILED) {
DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n");
Sleep(1000);
} else {
break;
}
}
if (dwWait == WAIT_FAILED)
{
SetLastError(ERROR_ACCESS_DENIED);
return (NULL);
DbgPrint("WL: Failed to wait on event \"SvcctrlStartEvent_A3725DX\"\n");
}
}
#endif
DPRINT("OpenSCManagerW() - Closing handle to event...\n");
CloseHandle(hStartEvent);
// Try to open a named pipe; wait for it, if necessary
while(1)
{
while (1) {
DWORD dwLastError;
DPRINT("OpenSCManagerW() - attempting to open named pipe to SCM.\n");
hPipe = CreateFileW(lpszPipeName, // pipe name
dwDesiredAccess,
0, // no sharing
@ -452,17 +491,24 @@ SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName,
0, // default attributes
NULL); // no template file
DPRINT("OpenSCManagerW() - handle to named pipe: %x\n", hPipe);
// Break if the pipe handle is valid
if(hPipe != INVALID_HANDLE_VALUE)
if (hPipe != INVALID_HANDLE_VALUE) {
break;
}
// Exit if an error other than ERROR_PIPE_BUSY occurs
if(GetLastError()!= ERROR_PIPE_BUSY)
{ return(NULL); }
dwLastError = GetLastError();
if (dwLastError != ERROR_PIPE_BUSY) {
DPRINT("OpenSCManagerW() - returning at 4, dwLastError %d\n", dwLastError);
return NULL;
}
// All pipe instances are busy, so wait for 20 seconds
if(!WaitNamedPipeW(lpszPipeName, 20000))
{ return(NULL); }
if (!WaitNamedPipeW(lpszPipeName, 20000)) {
DPRINT("OpenSCManagerW() - Failed on WaitNamedPipeW(...).\n");
return NULL;
}
}
// The pipe connected; change to message-read mode
@ -472,10 +518,10 @@ SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName,
&dwMode, // new pipe mode
NULL, // don't set maximum bytes
NULL); // don't set maximum time
if(!fSuccess)
{
if (!fSuccess) {
CloseHandle(hPipe);
return(NULL);
DPRINT("OpenSCManagerW() - Failed on SetNamedPipeHandleState(...).\n");
return NULL;
}
#if 0
// Send a message to the pipe server
@ -487,14 +533,14 @@ SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName,
strlen(lpvMessage) + 1, // message length
&cbWritten, // bytes written
NULL); // not overlapped
if(!fSuccess)
{
if (!fSuccess) {
CloseHandle(hPipe);
return(NULL);
DPRINT("OpenSCManagerW() - Failed to write to pipe.\n");
return NULL;
}
do
{
do {
DPRINT("OpenSCManagerW() - in I/O loop to SCM...\n");
// Read from the pipe
fSuccess = ReadFile(
hPipe, // pipe handle
@ -503,22 +549,25 @@ SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName,
&cbRead, // number of bytes read
NULL); // not overlapped
if(! fSuccess && GetLastError() != ERROR_MORE_DATA)
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))
if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), chBuf, cbRead, &cbWritten, NULL)) {
break;
}
} while(!fSuccess); // repeat loop if ERROR_MORE_DATA
DPRINT("OpenSCManagerW() - I/O loop completed.\n");
//CloseHandle(hPipe);
#endif
return(hPipe);
}
else
{
DPRINT("OpenSCManagerW() - success, returning handle to pipe %x\n", hPipe);
return hPipe;
} else {
/* FIXME: Connect to remote SCM */
return(NULL);
DPRINT("OpenSCManagerW() - FIXME: Connect to remote SCM not implemented.\n");
return NULL;
}
}
@ -532,7 +581,7 @@ OpenServiceA(SC_HANDLE hSCManager,
DWORD dwDesiredAccess)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return(NULL);
return NULL;
}