[SERVICES] ScmControlService: Use TransactNamedPipe() instead of successive Write+Read (#7441)

This function combines those that write a message to and read
a message from the specified pipe into a single operation.

Its usage helps in simplifying the code further.
This commit is contained in:
Hermès Bélusca-Maïto 2024-10-10 15:58:43 +02:00
parent 0f7b021fe6
commit 84f423f030
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0

View file

@ -1430,7 +1430,6 @@ ScmControlServiceEx(
DWORD PacketSize; DWORD PacketSize;
DWORD i; DWORD i;
PWSTR Ptr; PWSTR Ptr;
DWORD dwWriteCount = 0;
DWORD dwReadCount = 0; DWORD dwReadCount = 0;
OVERLAPPED Overlapped = {0}; OVERLAPPED Overlapped = {0};
@ -1507,100 +1506,48 @@ ScmControlServiceEx(
/* Acquire the service control critical section, to synchronize requests */ /* Acquire the service control critical section, to synchronize requests */
EnterCriticalSection(&ControlServiceCriticalSection); EnterCriticalSection(&ControlServiceCriticalSection);
bResult = WriteFile(hControlPipe, bResult = TransactNamedPipe(hControlPipe,
ControlPacket, ControlPacket,
PacketSize, PacketSize,
&dwWriteCount, &ReplyPacket,
&Overlapped); sizeof(ReplyPacket),
&dwReadCount,
&Overlapped);
if (!bResult) if (!bResult)
{ {
/* Fail for any error other than pending IO */
dwError = GetLastError(); dwError = GetLastError();
if (dwError == ERROR_IO_PENDING) if (dwError != ERROR_IO_PENDING)
{ {
DPRINT("WriteFile(%S, %d) returned ERROR_IO_PENDING\n", pServiceName, dwControl); DPRINT1("TransactNamedPipe(%S, %d) failed (Error %lu)\n", pServiceName, dwControl, dwError);
dwError = WaitForSingleObject(hControlPipe,
PipeTimeout);
DPRINT("WaitForSingleObject(%S, %d) returned %lu\n", pServiceName, dwControl, dwError);
if (dwError == WAIT_TIMEOUT)
{
DPRINT1("WaitForSingleObject(%S, %d) timed out\n", pServiceName, dwControl);
bResult = CancelIo(hControlPipe);
if (!bResult)
DPRINT1("CancelIo(%S, %d) failed (Error %lu)\n", pServiceName, dwControl, GetLastError());
dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
goto Done;
}
else if (dwError == WAIT_OBJECT_0)
{
bResult = GetOverlappedResult(hControlPipe,
&Overlapped,
&dwWriteCount,
TRUE);
if (!bResult)
{
dwError = GetLastError();
DPRINT1("GetOverlappedResult(%S, %d) failed (Error %lu)\n", pServiceName, dwControl, dwError);
goto Done;
}
}
}
else
{
DPRINT1("WriteFile(%S, %d) failed (Error %lu)\n", pServiceName, dwControl, dwError);
goto Done; goto Done;
} }
}
/* Read the reply */ DPRINT("TransactNamedPipe(%S, %d) returned ERROR_IO_PENDING\n", pServiceName, dwControl);
Overlapped.hEvent = NULL;
bResult = ReadFile(hControlPipe, dwError = WaitForSingleObject(hControlPipe, PipeTimeout);
&ReplyPacket, DPRINT("WaitForSingleObject(%S, %d) returned %lu\n", pServiceName, dwControl, dwError);
sizeof(ReplyPacket),
&dwReadCount, if (dwError == WAIT_TIMEOUT)
&Overlapped);
if (!bResult)
{
dwError = GetLastError();
if (dwError == ERROR_IO_PENDING)
{ {
DPRINT("ReadFile(%S, %d) returned ERROR_IO_PENDING\n", pServiceName, dwControl); DPRINT1("WaitForSingleObject(%S, %d) timed out\n", pServiceName, dwControl);
bResult = CancelIo(hControlPipe);
if (!bResult)
DPRINT1("CancelIo(%S, %d) failed (Error %lu)\n", pServiceName, dwControl, GetLastError());
dwError = WaitForSingleObject(hControlPipe, dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
PipeTimeout);
DPRINT("WaitForSingleObject(%S, %d) returned %lu\n", pServiceName, dwControl, dwError);
if (dwError == WAIT_TIMEOUT)
{
DPRINT1("WaitForSingleObject(%S, %d) timed out\n", pServiceName, dwControl);
bResult = CancelIo(hControlPipe);
if (!bResult)
DPRINT1("CancelIo(%S, %d) failed (Error %lu)\n", pServiceName, dwControl, GetLastError());
dwError = ERROR_SERVICE_REQUEST_TIMEOUT;
goto Done;
}
else if (dwError == WAIT_OBJECT_0)
{
bResult = GetOverlappedResult(hControlPipe,
&Overlapped,
&dwReadCount,
TRUE);
if (!bResult)
{
dwError = GetLastError();
DPRINT1("GetOverlappedResult(%S, %d) failed (Error %lu)\n", pServiceName, dwControl, dwError);
goto Done;
}
}
} }
else else if (dwError == WAIT_OBJECT_0)
{ {
DPRINT1("ReadFile(%S, %d) failed (Error %lu)\n", pServiceName, dwControl, dwError); bResult = GetOverlappedResult(hControlPipe,
goto Done; &Overlapped,
&dwReadCount,
TRUE);
if (!bResult)
{
dwError = GetLastError();
DPRINT1("GetOverlappedResult(%S, %d) failed (Error %lu)\n", pServiceName, dwControl, dwError);
}
} }
} }