NTSTATUS Nt_CreateProcess( LPCWSTR ApplicationName, LPWSTR CommandLine, ULONG CreationFlags, LPCWSTR CurrentDirectory, LPSTARTUPINFO StartupInfo, LPPROCESS_INFORMATION ProcessInformation ) { NTSTATUS Status; WCHAR FullPathBuffer[MAX_PATH *2], DllPathBuffer[0x3000]; UNICODE_STRING PathVariableName, DllPath, ImagePathName; UNICODE_STRING _CommandLine, _CurrentDirectory; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; RTL_USER_PROCESS_INFORMATION ProcessInfo; if (!RtlDosPathNameToNtPathName_U(ApplicationName, &ImagePathName, NULL, NULL)) return STATUS_OBJECT_PATH_NOT_FOUND; RTL_CONST_STRING(PathVariableName, L"Path"); DllPath.Length = 0; DllPath.MaximumLength = sizeof(DllPathBuffer); DllPath.Buffer = DllPathBuffer; RtlQueryEnvironmentVariable_U(NULL, &PathVariableName, &DllPath); if (CommandLine != NULL) RtlInitUnicodeString(&_CommandLine, CommandLine); if (CurrentDirectory != NULL) RtlInitUnicodeString(&_CurrentDirectory, CurrentDirectory); Status = RtlCreateProcessParameters( &ProcessParameters, &ImagePathName, &DllPath, CurrentDirectory == NULL ? NULL : &_CurrentDirectory, CommandLine == NULL ? NULL : &_CommandLine, NULL, NULL, NULL, NULL, NULL ); if (!NT_SUCCESS(Status)) { RtlFreeUnicodeString(&ImagePathName); return Status; } ProcessInfo.Size = sizeof(ProcessInfo); Status = RtlCreateUserProcess( &ImagePathName, OBJ_CASE_INSENSITIVE, ProcessParameters, NULL, NULL, NULL, FALSE, NULL, NULL, &ProcessInfo ); RtlDestroyProcessParameters(ProcessParameters); RtlFreeUnicodeString(&ImagePathName); if (!NT_SUCCESS(Status)) return Status; if (!FLAG_ON(CreationFlags, CREATE_SUSPENDED)) { NtResumeThread(ProcessInfo.ThreadHandle, NULL); } if (ProcessInformation == NULL) { NtClose(ProcessInfo.ProcessHandle); NtClose(ProcessInfo.ThreadHandle); return Status; } ProcessInformation->dwProcessId = (ULONG)ProcessInfo.ClientId.UniqueProcess; ProcessInformation->dwThreadId = (ULONG)ProcessInfo.ClientId.UniqueThread; ProcessInformation->hProcess = ProcessInfo.ProcessHandle; ProcessInformation->hThread = ProcessInfo.ThreadHandle; return Status; }
HANDLE APIENTRY CreateMailslotW( IN LPCWSTR lpName, IN DWORD nMaxMessageSize, IN DWORD lReadTimeout, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL ) /*++ Routine Description: The create mailslot API creates a local mailslot and return a server-side handle to the mailslot. Arguments: lpName - The name of the mailslot. This must be a local mailslot name. nMaxMessageSize - The size (in bytes) of the largest message that can be written to the mailslot. lReadTimeout - The initial read timeout, in milliseconds. This is the amount of time a read operation will block waiting for a message to be written to the mailslot. This value can be changed with the SetMailslotInfo API. lpSecurityAttributes - An optional pointer to security information for this mailslot. Return Value: Returns one of the following: 0xFFFFFFFF --An error occurred. Call GetLastError for more information. Anything else --Returns a handle for use in the server side of subsequent mailslot operations. --*/ { OBJECT_ATTRIBUTES objectAttributes; UNICODE_STRING fileName; LPWSTR filePart; RTL_RELATIVE_NAME relativeName; IO_STATUS_BLOCK ioStatusBlock; LARGE_INTEGER readTimeout; HANDLE handle; NTSTATUS status; PVOID freeBuffer; BOOLEAN TranslationStatus; RtlInitUnicodeString( &fileName, lpName ); TranslationStatus = RtlDosPathNameToNtPathName_U( lpName, &fileName, &filePart, &relativeName ); if ( !TranslationStatus ) { SetLastError(ERROR_PATH_NOT_FOUND); return INVALID_HANDLE_VALUE; } freeBuffer = fileName.Buffer; if ( relativeName.RelativeName.Length ) { fileName = *(PUNICODE_STRING)&relativeName.RelativeName; } else { relativeName.ContainingDirectory = NULL; } InitializeObjectAttributes( &objectAttributes, &fileName, OBJ_CASE_INSENSITIVE, relativeName.ContainingDirectory, NULL ); if ( ARGUMENT_PRESENT(lpSecurityAttributes) ) { objectAttributes.SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor; if ( lpSecurityAttributes->bInheritHandle ) { objectAttributes.Attributes |= OBJ_INHERIT; } } if (lReadTimeout == MAILSLOT_WAIT_FOREVER) { readTimeout.HighPart = 0x7FFFFFFF; readTimeout.LowPart = 0xFFFFFFFF; } else { readTimeout.QuadPart = - (LONGLONG)UInt32x32To64( lReadTimeout, 10 * 1000 ); } status = NtCreateMailslotFile ( &handle, GENERIC_READ | SYNCHRONIZE | WRITE_DAC, &objectAttributes, &ioStatusBlock, FILE_CREATE, 0, nMaxMessageSize, (PLARGE_INTEGER)&readTimeout ); if ( status == STATUS_NOT_SUPPORTED || status == STATUS_INVALID_DEVICE_REQUEST ) { // // The request must have been processed by some other device driver // (other than MSFS). Map the error to something reasonable. // status = STATUS_OBJECT_NAME_INVALID; } RtlFreeHeap( RtlProcessHeap(), 0, freeBuffer ); if (!NT_SUCCESS(status)) { BaseSetLastNTError( status ); return INVALID_HANDLE_VALUE; } return handle; }