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

📄 create.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
                     FoundQuotes = TRUE;
                     break;
                 }

                 /* Keep looking */
                 ScanString++;
                 NullBuffer = ScanString;
             }
        }
        else
        {
            /* No quotes, so we'll be looking for white space */
        WhiteScan:   
            /* Reset the pointer */
            lpApplicationName = lpCommandLine;

            /* Find whitespace of Tab */
            while (*ScanString)
            {
                if (*ScanString == ' ' || *ScanString == '\t')
                {
                    /* Found it */
                    NullBuffer = ScanString;
                    break;
                }

                /* Keep looking */
                ScanString++;
                NullBuffer = ScanString;
            }
        }
                 
        /* Set the Null Buffer */
        SaveChar = *NullBuffer;
        *NullBuffer = UNICODE_NULL;
                
        /* Do a search for the file */
        DPRINT("Ready for SearchPathW: %S\n", lpApplicationName);
        RetVal = SearchPathW(NULL,
                             lpApplicationName,
                             L".exe",
                             MAX_PATH,
                             NameBuffer,
                             NULL) * sizeof(WCHAR);
               
        /* Did it find something? */
        if (RetVal)
        {
            /* Get file attributes */
            ULONG Attributes = GetFileAttributesW(NameBuffer);
            if (Attributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                /* Give it a length of 0 to fail, this was a directory. */
                RetVal = 0;
            }
            else
            {
                /* It's a file! */
                RetVal += sizeof(WCHAR);
            }
        }
                
        /* Now check if we have a file, and if the path size is OK */
        if (!RetVal || RetVal >= (MAX_PATH * sizeof(WCHAR)))
        {
            ULONG PathType;
            HANDLE hFile;
            
            /* We failed, try to get the Path Type */
            DPRINT("SearchPathW failed. Retval: %ld\n", RetVal);
            PathType = RtlDetermineDosPathNameType_U(lpApplicationName);
                    
            /* If it's not relative, try to get the error */
            if (PathType != RtlPathTypeRelative)
            {
                /* This should fail, and give us a detailed LastError */
                hFile = CreateFileW(lpApplicationName,
                                    GENERIC_READ,
                                    FILE_SHARE_READ | FILE_SHARE_WRITE,
                                    NULL,
                                    OPEN_EXISTING,
                                    FILE_ATTRIBUTE_NORMAL,
                                    NULL);
                                        
                /* Did it actually NOT fail? */
                if (hFile != INVALID_HANDLE_VALUE)
                {
                    /* Fake the error */
                    CloseHandle(hFile);
                    SetLastErrorByStatus(STATUS_OBJECT_NAME_NOT_FOUND);
                }
            }
            else
            {
                /* Immediately set the error */
                SetLastErrorByStatus(STATUS_OBJECT_NAME_NOT_FOUND);
            }
                    
            /* Did we already fail once? */
            if (Error)
            {
                SetLastError(Error);
            }
            else
            {
                /* Not yet, cache it */
                Error = GetLastError();
            }
                    
            /* Put back the command line */
            *NullBuffer = SaveChar;
            lpApplicationName = NameBuffer;
                    
            /* 
             * If the search isn't done and we still have cmdline
             * then start over. Ex: c:\ha ha ha\haha.exe
             */
            if (*ScanString && !SearchDone)
            {
                /* Move in the buffer */
                ScanString++;
                NullBuffer = ScanString;
                
                /* We will have to add a quote, since there is a space*/
                QuotesNeeded = TRUE;
                    
                /* And we will also fake the fact we found one */
                FoundQuotes = TRUE;
                    
                /* Start over */
                goto WhiteScan;
            }
                
            /* We totally failed */
            goto Cleanup;
        }
                
        /* Put back the command line */
        *NullBuffer = SaveChar;
        lpApplicationName = NameBuffer;
        DPRINT("SearchPathW suceeded (%ld): %S\n", RetVal, NameBuffer);
    }
    else if (!lpCommandLine || *lpCommandLine == UNICODE_NULL)
    {
        /* We have an app name (good!) but no command line */
        CmdLineIsAppName = TRUE;
        lpCommandLine = (LPWSTR)lpApplicationName;
    }
     
    /* At this point the name has been toyed with enough to be openable */
    Status = BasepMapFile(lpApplicationName, &hSection, &ApplicationName);
    
    /* Check for failure */
    if (!NT_SUCCESS(Status))
    {
        /* Could be a non-PE File */
        switch (Status)
        {
            /* Check if the Kernel tells us it's not even valid MZ */
            case STATUS_INVALID_IMAGE_NE_FORMAT:
            case STATUS_INVALID_IMAGE_PROTECT:
            case STATUS_INVALID_IMAGE_NOT_MZ:
            
#if 0
            /* If it's a DOS app, use VDM */
            if ((BasepCheckDosApp(&ApplicationName))) 
            {
                DPRINT1("Launching VDM...\n");
                RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
                RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer);
                return CreateProcessW(L"ntvdm.exe",
                                      (LPWSTR)lpApplicationName,
                                      lpProcessAttributes,
                                      lpThreadAttributes,
                                      bInheritHandles,
                                      dwCreationFlags,
                                      lpEnvironment,
                                      lpCurrentDirectory,
                                      &StartupInfo,
                                      lpProcessInformation);    
            } 
#endif            
            /* It's a batch file */
            Extension = &ApplicationName.Buffer[ApplicationName.Length / 
                                                sizeof(WCHAR) - 4];
            
            /* Make sure the extensions are correct */
            if (_wcsnicmp(Extension, L".bat", 4) && _wcsnicmp(Extension, L".cmd", 4))
            {
                SetLastError(ERROR_BAD_EXE_FORMAT);
                return FALSE;
            }
            
            /* Calculate the length of the command line */
            CmdLineLength = wcslen(CMD_STRING) + wcslen(lpCommandLine) + 1;
            
            /* If we found quotes, then add them into the length size */
            if (CmdLineIsAppName || FoundQuotes) CmdLineLength += 2;
            CmdLineLength *= sizeof(WCHAR);
            
            /* Allocate space for the new command line */
            BatchCommandLine = RtlAllocateHeap(RtlGetProcessHeap(),
                                               0,
                                               CmdLineLength);
            if (BatchCommandLine == NULL)
            {
                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
                goto Cleanup;
            }
                                              
            /* Build it */
            wcscpy(BatchCommandLine, CMD_STRING);
            if (CmdLineIsAppName || FoundQuotes)
            {
                wcscat(BatchCommandLine, L"\"");
            }
            wcscat(BatchCommandLine, lpCommandLine);
            if (CmdLineIsAppName || FoundQuotes)
            {
                wcscat(BatchCommandLine, L"\"");
            }
            
            /* Create it as a Unicode String */
            RtlInitUnicodeString(&CommandLineString, BatchCommandLine);
            
            /* Set the command line to this */
            lpCommandLine = CommandLineString.Buffer;
            lpApplicationName = NULL;
            
            /* Free memory */
            RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer);
            ApplicationName.Buffer = NULL;
            goto GetAppName;
            break;
            
            case STATUS_INVALID_IMAGE_WIN_16:
            
                /* It's a Win16 Image, use VDM */
                DPRINT1("Launching VDM...\n");
                RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
                RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer);
                return CreateProcessW(L"ntvdm.exe",
                                      (LPWSTR)lpApplicationName,
                                      lpProcessAttributes,
                                      lpThreadAttributes,
                                      bInheritHandles,
                                      dwCreationFlags,
                                      lpEnvironment,
                                      lpCurrentDirectory,
                                      &StartupInfo,
                                      lpProcessInformation);    

            default:
                /* Invalid Image Type */
                SetLastError(ERROR_BAD_EXE_FORMAT);
                goto Cleanup;
        }
    }
    
    /* Use our desktop if we didn't get any */
    if (!StartupInfo.lpDesktop)
    {
        StartupInfo.lpDesktop = OurPeb->ProcessParameters->DesktopInfo.Buffer;
    }
    
    /* FIXME: Check if Application is allowed to run */
    
    /* FIXME: Allow CREATE_SEPARATE only for WOW Apps, once we have that. */
    
    /* Get some information about the executable */
    Status = ZwQuerySection(hSection,
                            SectionImageInformation,
                            &SectionImageInfo,
                            sizeof(SectionImageInfo),
                            NULL);
    if(!NT_SUCCESS(Status))
    {
        DPRINT1("Unable to get SectionImageInformation, status 0x%x\n", Status);
        SetLastErrorByStatus(Status);
        goto Cleanup;
    }

    /* Don't execute DLLs */
    if (SectionImageInfo.ImageCharacteristics & IMAGE_FILE_DLL)
    {
        DPRINT1("Can't execute a DLL\n");
        SetLastError(ERROR_BAD_EXE_FORMAT);
        goto Cleanup;
    }
    
    /* FIXME: Check for Debugger */

    /* FIXME: Check if Machine Type and SubSys Version Match */

    /* We don't support POSIX or anything else for now */
    if (IMAGE_SUBSYSTEM_WINDOWS_GUI != SectionImageInfo.SubsystemType && 
        IMAGE_SUBSYSTEM_WINDOWS_CUI != SectionImageInfo.SubsystemType)
    {
        DPRINT1("Invalid subsystem %d\n", SectionImageInfo.SubsystemType);
        SetLastError(ERROR_BAD_EXE_FORMAT);
        goto Cleanup;
    }
    
    if (IMAGE_SUBSYSTEM_WINDOWS_GUI == SectionImageInfo.SubsystemType)
    {
        /* Do not create a console for GUI applications */
        dwCreationFlags &= ~CREATE_NEW_CONSOLE;
        dwCreationFlags |= DETACHED_PROCESS;
    }

    /* Initialize the process object attributes */
    ObjectAttributes = BasepConvertObjectAttributes(&LocalObjectAttributes, 
                                                    lpProcessAttributes,
                                                    NULL);

    /* Check if we're going to be debugged */
    if (dwCreationFlags & DEBUG_PROCESS)
    {
        /* FIXME: Set process flag */
    }

    /* Check if we're going to be debugged */
    if (dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
    {
        /* Connect to DbgUi */
        Status = DbgUiConnectToDbg();
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Failed to connect to DbgUI!\n");
            SetLastErrorByStatus(Status);
            goto Cleanup;
        }

        /* Get the debug object */
        hDebug = DbgUiGetThreadDebugObject();

        /* Check if only this process will be debugged */
        if (dwCreationFlags & DEBUG_ONLY_THIS_PROCESS)
        {
            /* FIXME: Set process flag */
        }
    }

    /* Create the Process */
    Status = NtCreateProcess(&hProcess,
                             PROCESS_ALL_ACCESS,
                             ObjectAttributes,
                             NtCurrentProcess(),
                             bInheritHandles,
                             hSection,
                             hDebug,
                             NULL);
    if(!NT_SUCCESS(Status))
    {
        DPRINT1("Unable to create process, status 0x%x\n", Status);
        SetLastErrorByStatus(Status);
        goto Cleanup;
    }
    
    /* Set new class */
    Status = NtSetInformationProcess(hProcess,
                                     ProcessPriorityClass,
                                     &PriorityClass,
                                     sizeof(PROCESS_PRIORITY_CLASS));
    if(!NT_SUCCESS(Status))
    {
        DPRINT1("Unable to set new process priority, status 0x%x\n", Status);
        SetLastErrorByStatus(Status);
        goto Cleanup;
    }
    
    /* Set Error Mode */
    if (dwCreationFlags & CREATE_DEFAULT_ERROR_MODE)
    {
        ULONG ErrorMode = SEM_FAILCRITICALERRORS;
        NtSetInformationProcess(hProcess,
                                ProcessDefaultHardErrorMode,
                                &ErrorMode,
                                sizeof(ULONG));
    }

    /* Convert the directory to a full path */
    if (lpCurrentDirectory)
    {
        /* Allocate a buffer */
        CurrentDirectory = RtlAllocateHeap(RtlGetProcessHeap(),
                                           0,
                                           (MAX_PATH + 1) * sizeof(WCHAR));
        if (CurrentDirectory == NULL)
        {
            DPRINT1("Cannot allocate memory for directory name\n");
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            goto Cleanup;
        }
                                           
        /* Get the length */
        if (GetFullPathNameW(lpCurrentDirectory,
                             MAX_PATH,
                             CurrentDirectory,
                             &CurrentDirectoryPart) > MAX_PATH)
        {
            DPRINT1("Directory name too long\n");
            SetLastError(ERROR_DIRECTORY);
            goto Cleanup;
        }
    }

⌨️ 快捷键说明

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