#include "services.h"
+#include <winuser.h>
+
#define NDEBUG
#include <debug.h>
* Uncomment the line below to use asynchronous IO operations
* on the service control pipes.
*/
-// #define USE_ASYNCHRONOUS_IO
+#define USE_ASYNCHRONOUS_IO
/* GLOBALS *******************************************************************/
static RTL_RESOURCE DatabaseLock;
static DWORD ResumeCount = 1;
-/* The critical section synchronizes service controls commands */
+/* The critical section synchronizes service control requests */
static CRITICAL_SECTION ControlServiceCriticalSection;
static DWORD PipeTimeout = 30000; /* 30 Seconds */
}
/* Create '\\.\pipe\net\NtControlPipeXXX' instance */
- swprintf(szControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", ServiceCurrent);
+ swprintf(szControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%lu", ServiceCurrent);
DPRINT("PipeName: %S\n", szControlPipeName);
}
else // if (Service->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER)
{
+ ASSERT(Service->Status.dwServiceType == SERVICE_FILE_SYSTEM_DRIVER);
RtlInitUnicodeString(&DirName, L"\\FileSystem");
}
DWORD dwError = ERROR_SUCCESS;
BOOL bResult;
#ifdef USE_ASYNCHRONOUS_IO
- OVERLAPPED Overlapped = {0, 0, 0, 0, 0};
+ OVERLAPPED Overlapped = {0};
#endif
DPRINT("ScmControlService() called\n");
+ /* Acquire the service control critical section, to synchronize requests */
EnterCriticalSection(&ControlServiceCriticalSection);
/* Calculate the total length of the start command line */
&Overlapped);
if (bResult == FALSE)
{
- DPRINT1("WriteFile() returned FALSE\n");
+ DPRINT("WriteFile() returned FALSE\n");
dwError = GetLastError();
if (dwError == ERROR_IO_PENDING)
{
- DPRINT1("dwError: ERROR_IO_PENDING\n");
+ DPRINT("dwError: ERROR_IO_PENDING\n");
dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
PipeTimeout);
- DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
+ DPRINT("WaitForSingleObject() returned %lu\n", dwError);
if (dwError == WAIT_TIMEOUT)
{
dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
goto Done;
}
- else if (dwError == ERROR_SUCCESS)
+ else if (dwError == WAIT_OBJECT_0)
{
bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
&Overlapped,
&Overlapped);
if (bResult == FALSE)
{
- DPRINT1("ReadFile() returned FALSE\n");
+ DPRINT("ReadFile() returned FALSE\n");
dwError = GetLastError();
if (dwError == ERROR_IO_PENDING)
{
- DPRINT1("dwError: ERROR_IO_PENDING\n");
+ DPRINT("dwError: ERROR_IO_PENDING\n");
dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
PipeTimeout);
- DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
+ DPRINT("WaitForSingleObject() returned %lu\n", dwError);
if (dwError == WAIT_TIMEOUT)
{
dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
goto Done;
}
- else if (dwError == ERROR_SUCCESS)
+ else if (dwError == WAIT_OBJECT_0)
{
bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
&Overlapped,
PWSTR pArgPtr;
BOOL bResult;
#ifdef USE_ASYNCHRONOUS_IO
- OVERLAPPED Overlapped = {0, 0, 0, 0, 0};
+ OVERLAPPED Overlapped = {0};
#endif
DPRINT("ScmSendStartCommand() called\n");
&Overlapped);
if (bResult == FALSE)
{
- DPRINT1("WriteFile() returned FALSE\n");
+ DPRINT("WriteFile() returned FALSE\n");
dwError = GetLastError();
if (dwError == ERROR_IO_PENDING)
{
- DPRINT1("dwError: ERROR_IO_PENDING\n");
+ DPRINT("dwError: ERROR_IO_PENDING\n");
dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
PipeTimeout);
- DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
+ DPRINT("WaitForSingleObject() returned %lu\n", dwError);
if (dwError == WAIT_TIMEOUT)
{
dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
goto Done;
}
- else if (dwError == ERROR_SUCCESS)
+ else if (dwError == WAIT_OBJECT_0)
{
bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
&Overlapped,
&Overlapped);
if (bResult == FALSE)
{
- DPRINT1("ReadFile() returned FALSE\n");
+ DPRINT("ReadFile() returned FALSE\n");
dwError = GetLastError();
if (dwError == ERROR_IO_PENDING)
{
- DPRINT1("dwError: ERROR_IO_PENDING\n");
+ DPRINT("dwError: ERROR_IO_PENDING\n");
dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
PipeTimeout);
- DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
+ DPRINT("WaitForSingleObject() returned %lu\n", dwError);
if (dwError == WAIT_TIMEOUT)
{
dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
goto Done;
}
- else if (dwError == ERROR_SUCCESS)
+ else if (dwError == WAIT_OBJECT_0)
{
bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
&Overlapped,
DWORD dwError = ERROR_SUCCESS;
BOOL bResult;
#ifdef USE_ASYNCHRONOUS_IO
- OVERLAPPED Overlapped = {0, 0, 0, 0, 0};
+ OVERLAPPED Overlapped = {0};
+#endif
+#if 0
+ LPCWSTR lpErrorStrings[3];
+ WCHAR szBuffer1[20];
+ WCHAR szBuffer2[20];
#endif
DPRINT("ScmWaitForServiceConnect()\n");
DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
}
+#if 0
+ _ultow(PipeTimeout, szBuffer1, 10);
+ lpErrorStrings[0] = Service->lpDisplayName;
+ lpErrorStrings[1] = szBuffer1;
+
+ ScmLogEvent(EVENT_CONNECTION_TIMEOUT,
+ EVENTLOG_ERROR_TYPE,
+ 2,
+ lpErrorStrings);
+#endif
+ DPRINT1("Log EVENT_CONNECTION_TIMEOUT by %S\n", Service->lpDisplayName);
+
return ERROR_SERVICE_REQUEST_TIMEOUT;
}
else if (dwError == WAIT_OBJECT_0)
DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
}
+#if 0
+ _ultow(PipeTimeout, szBuffer1, 10);
+ lpErrorStrings[0] = szBuffer1;
+
+ ScmLogEvent(EVENT_READFILE_TIMEOUT,
+ EVENTLOG_ERROR_TYPE,
+ 1,
+ lpErrorStrings);
+#endif
+ DPRINT1("Log EVENT_READFILE_TIMEOUT by %S\n", Service->lpDisplayName);
+
return ERROR_SERVICE_REQUEST_TIMEOUT;
}
- else if (dwError == ERROR_SUCCESS)
+ else if (dwError == WAIT_OBJECT_0)
{
- DPRINT("WaitForSingleObject() returned ERROR_SUCCESS\n");
+ DPRINT("WaitForSingleObject() returned WAIT_OBJECT_0\n");
DPRINT("Process Id: %lu\n", dwProcessId);
}
}
- DPRINT1("ScmWaitForServiceConnect() done\n");
+ if (dwProcessId != Service->lpImage->dwProcessId)
+ {
+#if 0
+ _ultow(Service->lpImage->dwProcessId, szBuffer1, 10);
+ _ultow(dwProcessId, szBuffer2, 10);
+
+ lpErrorStrings[0] = Service->lpDisplayName;
+ lpErrorStrings[1] = szBuffer1;
+ lpErrorStrings[2] = szBuffer2;
+
+ ScmLogEvent(EVENT_SERVICE_DIFFERENT_PID_CONNECTED,
+ EVENTLOG_WARNING_TYPE,
+ 3,
+ lpErrorStrings);
+#endif
+
+ DPRINT1("Log EVENT_SERVICE_DIFFERENT_PID_CONNECTED by %S\n", Service->lpDisplayName);
+ }
+
+ DPRINT("ScmWaitForServiceConnect() done\n");
return ERROR_SUCCESS;
#else
{
PSERVICE_GROUP Group = Service->lpGroup;
DWORD dwError = ERROR_SUCCESS;
- LPCWSTR ErrorLogStrings[2];
+ LPCWSTR lpErrorStrings[2];
WCHAR szErrorBuffer[32];
DPRINT("ScmLoadService() called\n");
{
Group->ServicesRunning = TRUE;
}
+
+ /* Log a successful service start */
+ lpErrorStrings[0] = Service->lpDisplayName;
+ lpErrorStrings[1] = L"start";
+ ScmLogEvent(EVENT_SERVICE_CONTROL_SUCCESS,
+ EVENTLOG_INFORMATION_TYPE,
+ 2,
+ lpErrorStrings);
}
else
{
{
/* Log a failed service start */
swprintf(szErrorBuffer, L"%lu", dwError);
- ErrorLogStrings[0] = Service->lpServiceName;
- ErrorLogStrings[1] = szErrorBuffer;
- ScmLogError(EVENT_SERVICE_START_FAILED,
+ lpErrorStrings[0] = Service->lpServiceName;
+ lpErrorStrings[1] = szErrorBuffer;
+ ScmLogEvent(EVENT_SERVICE_START_FAILED,
+ EVENTLOG_ERROR_TYPE,
2,
- ErrorLogStrings);
+ lpErrorStrings);
}
#if 0
ScmAutoStartServices(VOID)
{
DWORD dwError = ERROR_SUCCESS;
- SC_RPC_LOCK Lock = NULL;
-
PLIST_ENTRY GroupEntry;
PLIST_ENTRY ServiceEntry;
PSERVICE_GROUP CurrentGroup;
HKEY hKey;
ULONG i;
- /* Acquire the service control critical section, to synchronize starts */
- EnterCriticalSection(&ControlServiceCriticalSection);
-
/*
- * Acquire the user service start lock while the service is starting, if
- * needed (i.e. if we are not starting it during the initialization phase).
- * If we don't success, bail out.
+ * This function MUST be called ONLY at initialization time.
+ * Therefore, no need to acquire the user service start lock.
*/
- if (!ScmInitialize)
- {
- /*
- * Actually this code is never executed since we are called
- * at initialization time, so that ScmInitialize == TRUE.
- * But keep the code here if someday we are called later on
- * for whatever reason...
- */
- dwError = ScmAcquireServiceStartLock(TRUE, &Lock);
- if (dwError != ERROR_SUCCESS) goto done;
- }
+ ASSERT(ScmInitialize);
+ /* Acquire the service control critical section, to synchronize starts */
+ EnterCriticalSection(&ControlServiceCriticalSection);
/* Clear 'ServiceVisited' flag (or set if not to start in Safe Mode) */
ServiceEntry = ServiceListHead.Flink;
ServiceEntry = ServiceEntry->Flink;
}
-
- /* Release the service start lock, if needed, and the critical section */
- if (Lock) ScmReleaseServiceStartLock(&Lock);
-
-done:
+ /* Release the critical section */
LeaveCriticalSection(&ControlServiceCriticalSection);
}