launcher: work around Win7 CreateProcess problem

This commit is contained in:
Bill Zissimopoulos 2017-12-11 21:23:38 -08:00
parent a2ec40008f
commit b2e474658d
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3

View File

@ -21,7 +21,9 @@
#define PROGNAME "WinFsp.Launcher" #define PROGNAME "WinFsp.Launcher"
BOOL CreateOverlappedPipe( BOOL CreateOverlappedPipe(
PHANDLE PReadPipe, PHANDLE PWritePipe, PSECURITY_ATTRIBUTES SecurityAttributes, DWORD Size, PHANDLE PReadPipe, PSECURITY_ATTRIBUTES ReadSecurityAttributes,
PHANDLE PWritePipe, PSECURITY_ATTRIBUTES WriteSecurityAttributes,
DWORD Size,
DWORD ReadMode, DWORD WriteMode) DWORD ReadMode, DWORD WriteMode)
{ {
RPC_STATUS RpcStatus; RPC_STATUS RpcStatus;
@ -46,13 +48,13 @@ BOOL CreateOverlappedPipe(
ReadPipe = CreateNamedPipeW(PipeNameBuf, ReadPipe = CreateNamedPipeW(PipeNameBuf,
PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | ReadMode, PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | ReadMode,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS,
1, Size, Size, 120 * 1000, SecurityAttributes); 1, Size, Size, 120 * 1000, ReadSecurityAttributes);
if (INVALID_HANDLE_VALUE == ReadPipe) if (INVALID_HANDLE_VALUE == ReadPipe)
return FALSE; return FALSE;
WritePipe = CreateFileW(PipeNameBuf, WritePipe = CreateFileW(PipeNameBuf,
GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
SecurityAttributes, OPEN_EXISTING, WriteMode, 0); WriteSecurityAttributes, OPEN_EXISTING, WriteMode, 0);
if (INVALID_HANDLE_VALUE == WritePipe) if (INVALID_HANDLE_VALUE == WritePipe)
{ {
LastError = GetLastError(); LastError = GetLastError();
@ -383,7 +385,7 @@ NTSTATUS SvcInstanceCreateProcess(PWSTR Executable, PWSTR CommandLine,
STARTUPINFOEXW StartupInfoEx; STARTUPINFOEXW StartupInfoEx;
HANDLE ChildHandles[3] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0/* DO NOT CLOSE!*/ }; HANDLE ChildHandles[3] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0/* DO NOT CLOSE!*/ };
HANDLE ParentHandles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; HANDLE ParentHandles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
SECURITY_ATTRIBUTES PipeAttributes = { sizeof(SECURITY_ATTRIBUTES), 0, TRUE }; SECURITY_ATTRIBUTES PipeAttributesInherit = { sizeof(SECURITY_ATTRIBUTES), 0, TRUE };
PPROC_THREAD_ATTRIBUTE_LIST AttrList = 0; PPROC_THREAD_ATTRIBUTE_LIST AttrList = 0;
SIZE_T Size; SIZE_T Size;
NTSTATUS Result; NTSTATUS Result;
@ -401,16 +403,20 @@ NTSTATUS SvcInstanceCreateProcess(PWSTR Executable, PWSTR CommandLine,
*/ */
/* create stdin read/write ends; make them inheritable */ /* create stdin read/write ends; make them inheritable */
if (!CreateOverlappedPipe(&ChildHandles[0], &ParentHandles[0], &PipeAttributes, 0, if (!CreateOverlappedPipe(
0, 0)) &ChildHandles[0], &PipeAttributesInherit,
&ParentHandles[0], 0,
0, 0, 0))
{ {
Result = FspNtStatusFromWin32(GetLastError()); Result = FspNtStatusFromWin32(GetLastError());
goto exit; goto exit;
} }
/* create stdout read/write ends; make them inheritable */ /* create stdout read/write ends; make them inheritable */
if (!CreateOverlappedPipe(&ParentHandles[1], &ChildHandles[1], &PipeAttributes, 0, if (!CreateOverlappedPipe(
FILE_FLAG_OVERLAPPED, 0)) &ParentHandles[1], 0,
&ChildHandles[1], &PipeAttributesInherit,
0, FILE_FLAG_OVERLAPPED, 0))
{ {
Result = FspNtStatusFromWin32(GetLastError()); Result = FspNtStatusFromWin32(GetLastError());
goto exit; goto exit;
@ -458,8 +464,28 @@ NTSTATUS SvcInstanceCreateProcess(PWSTR Executable, PWSTR CommandLine,
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP | EXTENDED_STARTUPINFO_PRESENT, 0, 0, CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP | EXTENDED_STARTUPINFO_PRESENT, 0, 0,
&StartupInfoEx.StartupInfo, ProcessInfo)) &StartupInfoEx.StartupInfo, ProcessInfo))
{ {
Result = FspNtStatusFromWin32(GetLastError()); if (ERROR_NO_SYSTEM_RESOURCES != GetLastError())
goto exit; {
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
/*
* On Win7 CreateProcessW with EXTENDED_STARTUPINFO_PRESENT
* may fail with ERROR_NO_SYSTEM_RESOURCES.
*
* In that case go ahead and retry with a CreateProcessW with
* bInheritHandles==TRUE, but without EXTENDED_STARTUPINFO_PRESENT.
* Not ideal, but...
*/
StartupInfoEx.StartupInfo.cb = sizeof StartupInfoEx.StartupInfo;
if (!CreateProcessW(Executable, CommandLine, 0, 0, TRUE,
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, 0, 0,
&StartupInfoEx.StartupInfo, ProcessInfo))
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
} }
} }
else else
@ -849,6 +875,10 @@ exit:
SvcInstanceRelease(SvcInstance); SvcInstanceRelease(SvcInstance);
if (STATUS_TIMEOUT == Result)
/* convert to an error! */
Result = 0x80070000 | ERROR_TIMEOUT;
return Result; return Result;
} }