+static DWORD
+ScmWaitForServiceConnect(PSERVICE Service)
+{
+ DWORD dwRead = 0;
+ DWORD dwProcessId = 0;
+ DWORD dwError = ERROR_SUCCESS;
+ BOOL bResult;
+#ifdef USE_ASYNCHRONOUS_IO
+ OVERLAPPED Overlapped = {0, 0, 0, 0, 0};
+#endif
+
+ DPRINT1("ScmWaitForServiceConnect()\n");
+
+#ifdef USE_ASYNCHRONOUS_IO
+ Overlapped.hEvent = (HANDLE)NULL;
+
+ bResult = ConnectNamedPipe(Service->lpImage->hControlPipe,
+ &Overlapped);
+ if (bResult == FALSE)
+ {
+ DPRINT1("ConnectNamedPipe() returned FALSE\n");
+
+ dwError = GetLastError();
+ if (dwError == ERROR_IO_PENDING)
+ {
+ DPRINT1("dwError: ERROR_IO_PENDING\n");
+
+ dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
+ dwPipeTimeout);
+ DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
+
+ if (dwError == WAIT_TIMEOUT)
+ {
+ bResult = CancelIo(Service->lpImage->hControlPipe);
+ if (bResult == FALSE)
+ {
+ DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
+ }
+
+ return ERROR_SERVICE_REQUEST_TIMEOUT;
+ }
+ else if (dwError == ERROR_SUCCESS)
+ {
+ bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
+ &Overlapped,
+ &dwRead,
+ TRUE);
+ if (bResult == FALSE)
+ {
+ dwError = GetLastError();
+ DPRINT1("GetOverlappedResult failed (Error %lu)\n", dwError);
+
+ return dwError;
+ }
+ }
+ }
+ else if (dwError != ERROR_PIPE_CONNECTED)
+ {
+ DPRINT1("ConnectNamedPipe failed (Error %lu)\n", dwError);
+ return dwError;
+ }
+ }
+
+ DPRINT1("Control pipe connected!\n");
+
+ Overlapped.hEvent = (HANDLE) NULL;
+
+ /* Read the process id from pipe */
+ bResult = ReadFile(Service->lpImage->hControlPipe,
+ (LPVOID)&dwProcessId,
+ sizeof(DWORD),
+ &dwRead,
+ &Overlapped);
+ if (bResult == FALSE)
+ {
+ DPRINT1("ReadFile() returned FALSE\n");
+
+ dwError = GetLastError();
+ if (dwError == ERROR_IO_PENDING)
+ {
+ DPRINT1("dwError: ERROR_IO_PENDING\n");
+
+ dwError = WaitForSingleObject(Service->lpImage->hControlPipe,
+ dwPipeTimeout);
+ if (dwError == WAIT_TIMEOUT)
+ {
+ DPRINT1("WaitForSingleObject() returned WAIT_TIMEOUT\n");
+
+ bResult = CancelIo(Service->lpImage->hControlPipe);
+ if (bResult == FALSE)
+ {
+ DPRINT1("CancelIo() failed (Error: %lu)\n", GetLastError());
+ }
+
+ return ERROR_SERVICE_REQUEST_TIMEOUT;
+ }
+ else if (dwError == ERROR_SUCCESS)
+ {
+ DPRINT1("WaitForSingleObject() returned ERROR_SUCCESS\n");
+
+ DPRINT1("Process Id: %lu\n", dwProcessId);
+
+ bResult = GetOverlappedResult(Service->lpImage->hControlPipe,
+ &Overlapped,
+ &dwRead,
+ TRUE);
+ if (bResult == FALSE)
+ {
+ dwError = GetLastError();
+ DPRINT1("GetOverlappedResult() failed (Error %lu)\n", dwError);
+
+ return dwError;
+ }
+ }
+ else
+ {
+ DPRINT1("WaitForSingleObject() returned %lu\n", dwError);
+ }
+ }
+ else
+ {
+ DPRINT1("ReadFile() failed (Error %lu)\n", dwError);
+ return dwError;
+ }
+ }
+
+ DPRINT1("ScmWaitForServiceConnect() done\n");
+
+ return ERROR_SUCCESS;
+#else
+
+ /* Connect control pipe */
+ if (ConnectNamedPipe(Service->lpImage->hControlPipe, NULL) ?
+ TRUE : (dwError = GetLastError()) == ERROR_PIPE_CONNECTED)
+ {
+ DPRINT("Control pipe connected!\n");
+
+ /* Read SERVICE_STATUS_HANDLE from pipe */
+ bResult = ReadFile(Service->lpImage->hControlPipe,
+ (LPVOID)&dwProcessId,
+ sizeof(DWORD),
+ &dwRead,
+ NULL);
+ if (bResult == FALSE)
+ {
+ dwError = GetLastError();
+ DPRINT1("Reading the service control pipe failed (Error %lu)\n",
+ dwError);
+ }
+ }
+ else
+ {
+ DPRINT1("Connecting control pipe failed! (Error %lu)\n", dwError);
+ }
+
+ return dwError;
+#endif
+}
+
+