示例#1
0
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;
}
示例#2
0
文件: mailslot.c 项目: mingpen/OpenNT
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;
}