⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 create.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * COPYRIGHT:       See COPYING in the top level directory
 * PROJECT:         ReactOS system libraries
 * FILE:            lib/kernel32/process/create.c
 * PURPOSE:         Process functions
 * PROGRAMMER:      Alex Ionescu (alex@relsoft.net)
 *                  Ariadne ( ariadne@xs4all.nl)
 */

/* INCLUDES ****************************************************************/

#include <k32.h>

#define NDEBUG
#include "../include/debug.h"

#define CMD_STRING L"cmd /c "

extern __declspec(noreturn)
VOID
CALLBACK 
ConsoleControlDispatcher(DWORD CodeAndFlag);

/* INTERNAL FUNCTIONS *******************************************************/

_SEH_FILTER(BaseExceptionFilter)
{
    EXCEPTION_POINTERS *ExceptionInfo = _SEH_GetExceptionPointers();
    LONG ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;

    if (GlobalTopLevelExceptionFilter != NULL)
    {
        _SEH_TRY
        {
            ExceptionDisposition = GlobalTopLevelExceptionFilter(ExceptionInfo);
        }
        _SEH_HANDLE
        {
        }
        _SEH_END;
    }
    if ((ExceptionDisposition == EXCEPTION_CONTINUE_SEARCH || ExceptionDisposition == EXCEPTION_EXECUTE_HANDLER) &&
        GlobalTopLevelExceptionFilter != UnhandledExceptionFilter)
    {
       ExceptionDisposition = UnhandledExceptionFilter(ExceptionInfo);
    }

    return ExceptionDisposition;
}

VOID
STDCALL
BaseProcessStartup(PPROCESS_START_ROUTINE lpStartAddress)
{
    UINT uExitCode = 0;

    DPRINT("BaseProcessStartup(..) - setting up exception frame.\n");

    _SEH_TRY
    {
        /* Set our Start Address */
        NtSetInformationThread(NtCurrentThread(),
                               ThreadQuerySetWin32StartAddress,
                               &lpStartAddress,
                               sizeof(PPROCESS_START_ROUTINE));
        
        /* Call the Start Routine */
        uExitCode = (lpStartAddress)();
    }
    _SEH_EXCEPT(BaseExceptionFilter)
    {
        /* Get the SEH Error */
        uExitCode = _SEH_GetExceptionCode();
    }
    _SEH_END;

    /* Exit the Process with our error */
    ExitProcess(uExitCode);
}

/*
 * Tells CSR that a new process was created
 */
NTSTATUS
STDCALL
BasepNotifyCsrOfCreation(ULONG dwCreationFlags,
                         IN HANDLE ProcessId,
                         IN BOOL InheritHandles)
{
    ULONG Request = CREATE_PROCESS;
    CSR_API_MESSAGE CsrRequest;
    NTSTATUS Status;
    
    DPRINT("BasepNotifyCsrOfCreation: Process: %lx, Flags %lx\n", 
            ProcessId, dwCreationFlags);
         
    /* Fill out the request */
    CsrRequest.Data.CreateProcessRequest.NewProcessId = ProcessId;
    CsrRequest.Data.CreateProcessRequest.Flags = dwCreationFlags;
    CsrRequest.Data.CreateProcessRequest.bInheritHandles = InheritHandles;
    
    /* Call CSR */
    Status = CsrClientCallServer(&CsrRequest,
                                 NULL,
                                 MAKE_CSR_API(Request, CSR_NATIVE),
                                 sizeof(CSR_API_MESSAGE));
    if (!NT_SUCCESS(Status) || !NT_SUCCESS(CsrRequest.Status))
    {
        DPRINT1("Failed to tell csrss about new process\n");
        return CsrRequest.Status;
    }
    
    /* REturn Success */
    return STATUS_SUCCESS;
}

/*
 * Creates the first Thread in a Proces
 */
HANDLE
STDCALL
BasepCreateFirstThread(HANDLE ProcessHandle,
                       LPSECURITY_ATTRIBUTES lpThreadAttributes,
                       PSECTION_IMAGE_INFORMATION SectionImageInfo,
                       PCLIENT_ID ClientId)
{
    OBJECT_ATTRIBUTES LocalObjectAttributes;
    POBJECT_ATTRIBUTES ObjectAttributes;
    CONTEXT Context;
    INITIAL_TEB InitialTeb;
    NTSTATUS Status;
    HANDLE hThread;
    
    DPRINT("BasepCreateFirstThread. hProcess: %lx\n", ProcessHandle);

    /* Create the Thread's Stack */
    BasepCreateStack(ProcessHandle,
                     SectionImageInfo->MaximumStackSize,
                     SectionImageInfo->CommittedStackSize,
                     &InitialTeb);
                     
    /* Create the Thread's Context */
    BasepInitializeContext(&Context,
                           NtCurrentPeb(),
                           SectionImageInfo->TransferAddress,
                           InitialTeb.StackBase,
                           0);
    
    /* Convert the thread attributes */
    ObjectAttributes = BasepConvertObjectAttributes(&LocalObjectAttributes,
                                                    lpThreadAttributes,
                                                    NULL);
    
    /* Create the Kernel Thread Object */
    Status = NtCreateThread(&hThread,
                            THREAD_ALL_ACCESS,
                            ObjectAttributes,
                            ProcessHandle,
                            ClientId,
                            &Context,
                            &InitialTeb,
                            TRUE);
    if (!NT_SUCCESS(Status))
    {
        return NULL;
    }

    /* Success */
    return hThread;
}

/*
 * Converts ANSI to Unicode Environment
 */
PVOID
STDCALL
BasepConvertUnicodeEnvironment(OUT SIZE_T* EnvSize,
                               IN PVOID lpEnvironment)
{
    PCHAR pcScan;
    ANSI_STRING AnsiEnv;
    UNICODE_STRING UnicodeEnv;
    NTSTATUS Status;
    
    DPRINT("BasepConvertUnicodeEnvironment\n");

    /* Scan the environment to calculate its Unicode size */
    AnsiEnv.Buffer = pcScan = (PCHAR)lpEnvironment;
    while (*pcScan) 
    {
        pcScan += strlen(pcScan) + 1;
    }

    /* Create our ANSI String */
    if (pcScan == (PCHAR)lpEnvironment)
    {
        AnsiEnv.Length = 2 * sizeof(CHAR);
    }
    else
    {

        AnsiEnv.Length = (ULONG_PTR)pcScan - (ULONG_PTR)lpEnvironment + sizeof(CHAR);
    }
    AnsiEnv.MaximumLength = AnsiEnv.Length + 1;
    
    /* Allocate memory for the Unicode Environment */
    UnicodeEnv.Buffer = NULL;
    *EnvSize = AnsiEnv.MaximumLength * sizeof(WCHAR);
    Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                     (PVOID)&UnicodeEnv.Buffer,
                                     0,
                                     EnvSize,
                                     MEM_COMMIT,
                                     PAGE_READWRITE);
    /* Failure */
    if (!NT_SUCCESS(Status))
    {
        SetLastError(Status);
        *EnvSize = 0;
        return NULL;
    }
        
    /* Use the allocated size */
    UnicodeEnv.MaximumLength = *EnvSize;
    
    /* Convert */
    RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE);
    return UnicodeEnv.Buffer;
}

/*
 * Converts a Win32 Priority Class to NT
 */
ULONG
STDCALL
BasepConvertPriorityClass(IN ULONG dwCreationFlags)
{
    ULONG ReturnClass;
    
    if(dwCreationFlags & IDLE_PRIORITY_CLASS)
    {    
        ReturnClass = PROCESS_PRIORITY_CLASS_IDLE;
    }
    else if(dwCreationFlags & BELOW_NORMAL_PRIORITY_CLASS)
    {
        ReturnClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
    }
    else if(dwCreationFlags & NORMAL_PRIORITY_CLASS)
    {
        ReturnClass = PROCESS_PRIORITY_CLASS_NORMAL;
    }
    else if(dwCreationFlags & ABOVE_NORMAL_PRIORITY_CLASS)
    {
        ReturnClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
    }
    else if(dwCreationFlags & HIGH_PRIORITY_CLASS)
    {
        ReturnClass = PROCESS_PRIORITY_CLASS_HIGH;
    }
    else if(dwCreationFlags & REALTIME_PRIORITY_CLASS)
    {
        /* Check for Privilege First */
        if (BasepCheckRealTimePrivilege())
        {
            ReturnClass = PROCESS_PRIORITY_CLASS_REALTIME;
        }
        else
        {
            ReturnClass = PROCESS_PRIORITY_CLASS_HIGH;
        }
    }
    else
    {
        ReturnClass = PROCESS_PRIORITY_CLASS_INVALID;
    }
    
    return ReturnClass;
}

/*
 * Duplicates a standard handle and writes it where requested.
 */
VOID
STDCALL
BasepDuplicateAndWriteHandle(IN HANDLE ProcessHandle,
                             IN HANDLE StandardHandle,
                             IN PHANDLE Address)
{
    NTSTATUS Status;
    HANDLE DuplicatedHandle;
    ULONG Dummy;
    
    DPRINT("BasepDuplicateAndWriteHandle. hProcess: %lx, Handle: %lx,"
           "Address: %p\n", ProcessHandle, StandardHandle, Address);
            
    /* Don't touch Console Handles */
    if (IsConsoleHandle(StandardHandle)) return;
    
    /* Duplicate the handle */
    Status = NtDuplicateObject(NtCurrentProcess(),
                               StandardHandle,
                               ProcessHandle,
                               &DuplicatedHandle,
                               DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES,
                               0,
                               0);
    if (NT_SUCCESS(Status))
    {
        /* Write it */
        NtWriteVirtualMemory(ProcessHandle,
                             Address,
                             &DuplicatedHandle,
                             sizeof(HANDLE),
                             &Dummy);
    }
}

LPWSTR
STDCALL
BasepGetDllPath(LPWSTR FullPath,
                PVOID Environment)
{
    /* FIXME: Not yet implemented */
    return NULL;
}

VOID
STDCALL
BasepCopyHandles(IN PRTL_USER_PROCESS_PARAMETERS Params,
                 IN PRTL_USER_PROCESS_PARAMETERS PebParams,
                 IN BOOL InheritHandles)
{
    DPRINT("BasepCopyHandles %p %p, %d\n", Params, PebParams, InheritHandles);

    /* Copy the handle if we are inheriting or if it's a console handle */
    if (InheritHandles || IsConsoleHandle(PebParams->StandardInput))
    {
        Params->StandardInput = PebParams->StandardInput;
    }
    if (InheritHandles || IsConsoleHandle(PebParams->StandardOutput))
    {
        Params->StandardOutput = PebParams->StandardOutput;
    }
    if (InheritHandles || IsConsoleHandle(PebParams->StandardError))
    {
        Params->StandardError = PebParams->StandardError;
    }
}

NTSTATUS
STDCALL
BasepInitializeEnvironment(HANDLE ProcessHandle,
                           PPEB Peb,
                           LPWSTR ApplicationPathName,
                           LPWSTR lpCurrentDirectory,
                           LPWSTR lpCommandLine,
                           LPVOID lpEnvironment,
                           SIZE_T EnvSize,
                           LPSTARTUPINFOW StartupInfo,
                           DWORD CreationFlags,
                           BOOL InheritHandles)
{
    WCHAR FullPath[MAX_PATH];
    LPWSTR Remaining;
    LPWSTR DllPathString;
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    PRTL_USER_PROCESS_PARAMETERS RemoteParameters = NULL;
    UNICODE_STRING DllPath, ImageName, CommandLine, CurrentDirectory;
    UINT RetVal;
    NTSTATUS Status;
    PWCHAR ScanChar;
    ULONG EnviroSize;
    SIZE_T Size;
    UNICODE_STRING Desktop, Shell, Runtime, Title;
    PPEB OurPeb = NtCurrentPeb();
    LPVOID Environment = lpEnvironment;
    
    DPRINT("BasepInitializeEnvironment\n");
    
    /* Get the full path name */
    RetVal = GetFullPathNameW(ApplicationPathName,
                              MAX_PATH,
                              FullPath,
                              &Remaining);
    DPRINT("ApplicationPathName: %S, FullPath: %S\n", ApplicationPathName, 
            FullPath);
                                  
    /* Get the DLL Path */
    DllPathString = BasepGetDllPath(FullPath, Environment);
    
    /* Initialize Strings */
    RtlInitUnicodeString(&DllPath, DllPathString);
    RtlInitUnicodeString(&ImageName, FullPath);
    RtlInitUnicodeString(&CommandLine, lpCommandLine);
    RtlInitUnicodeString(&CurrentDirectory, lpCurrentDirectory);
   
    /* Initialize more Strings from the Startup Info */
    if (StartupInfo->lpDesktop)
    {
        RtlInitUnicodeString(&Desktop, StartupInfo->lpDesktop);
    }
    else
    {
        RtlInitUnicodeString(&Desktop, L"");
    }
    if (StartupInfo->lpReserved)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -