Beispiel #1
0
KESYSAPI
PPROCESS
KEAPI
PsCreateProcess(
	)
/*++
	Create process allocating new space for PROCESS
--*/
{
	if (!SUCCESS(SeAccessCheck (SE_1_CREATE_PROCESS, 0)))
		return NULL;

	PPROCESS Process = (PPROCESS) ExAllocateHeap( FALSE, sizeof(PROCESS) );
	PspCreateProcess( Process );
	MmCreateAddressSpace( Process );

	PVOID Arguments[1] = {
		Process
	};

	ExProcessCallbackList (
		&PsCreateProcessCallbackList,
		3,
		Arguments
		);

	return Process;
}
Beispiel #2
0
BOOLEAN
PspInitPhase0 (
    IN PLOADER_PARAMETER_BLOCK LoaderBlock
    )

/*++

Routine Description:

    This routine performs phase 0 process structure initialization.
    During this phase, the initial system process, phase 1 initialization
    thread, and reaper threads are created. All object types and other
    process structures are created and initialized.

Arguments:

    None.

Return Value:

    TRUE - Initialization was successful.

    FALSE - Initialization Failed.

--*/

{

    PLDR_DATA_TABLE_ENTRY DataTableEntry1;
    PLDR_DATA_TABLE_ENTRY DataTableEntry2;
    UNICODE_STRING NameString;
    PLIST_ENTRY NextEntry;
    OBJECT_ATTRIBUTES ObjectAttributes;
    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
    HANDLE ThreadHandle;
    PETHREAD Thread;
    MM_SYSTEMSIZE SystemSize;

    PsPrioritySeperation = 2;
    SystemSize = MmQuerySystemSize();
    PspDefaultPagefileLimit = (ULONG)-1;

    if ( sizeof(TEB) > 4096 || sizeof(PEB) > 4096 ) {
        KeBugCheckEx(PROCESS_INITIALIZATION_FAILED,99,sizeof(TEB),sizeof(PEB),99);
        }

    switch ( SystemSize ) {

        case MmMediumSystem :
            PsMinimumWorkingSet += 10;
            PsMaximumWorkingSet += 100;
            break;

        case MmLargeSystem :
            PsMinimumWorkingSet += 30;
            PsMaximumWorkingSet += 300;
            break;

        case MmSmallSystem :
        default:
            break;
        }

    if ( MmIsThisAnNtAsSystem() ) {
        PspForegroundQuantum[0] = 6*THREAD_QUANTUM;
        PspForegroundQuantum[1] = 6*THREAD_QUANTUM;
        PspForegroundQuantum[2] = 6*THREAD_QUANTUM;
        }
    else {

        //
        // For Workstation:
        //
        // BG is THREAD_QUANTUM
        // FG is THREAD_QUANTUM                 50/50 fg/bg
        // FG is 2 * THREAD_QUANTUM             65/35 fg/bg
        // FG is 3 * THREAD_QUANTUM             75/25 fg/bg
        //

        PspForegroundQuantum[0] = THREAD_QUANTUM;
        PspForegroundQuantum[1] = 2*THREAD_QUANTUM;
        PspForegroundQuantum[2] = 3*THREAD_QUANTUM;
        }
    //
    // Quotas grow as needed automatically
    //

    if ( !PspDefaultPagedLimit ) {
        PspDefaultPagedLimit = 0;
        }
    if ( !PspDefaultNonPagedLimit ) {
        PspDefaultNonPagedLimit = 0;
        }

    if ( PspDefaultNonPagedLimit == 0 && PspDefaultPagedLimit == 0) {
        PspDoingGiveBacks = TRUE;
        }
    else {
        PspDoingGiveBacks = FALSE;
        }


    PspDefaultPagedLimit *= PSP_1MB;
    PspDefaultNonPagedLimit *= PSP_1MB;

    if (PspDefaultPagefileLimit != -1) {
        PspDefaultPagefileLimit *= PSP_1MB;
        }

    //
    // Initialize the process security fields lock and the process lock.
    //

    ExInitializeFastMutex( &PspProcessLockMutex );
    ExInitializeFastMutex( &PspProcessSecurityLock );

    //
    // Initialize the loaded module list executive resource and spin lock.
    //

    ExInitializeResource( &PsLoadedModuleResource );
    KeInitializeSpinLock( &PsLoadedModuleSpinLock );
    KeInitializeSpinLock( &PspEventPairLock );

    //
    // Initialize the loaded module listheads.
    //

    PsIdleProcess = PsGetCurrentProcess();
    PsIdleProcess->Pcb.KernelTime = 0;
    PsIdleProcess->Pcb.KernelTime = 0;


    InitializeListHead(&PsLoadedModuleList);

    //
    // Scan the loaded module list and allocate and initialize a data table
    // entry for each module. The data table entry is inserted in the loaded
    // module list and the initialization order list in the order specified
    // in the loader parameter block. The data table entry is inserted in the
    // memory order list in memory order.
    //

    NextEntry = LoaderBlock->LoadOrderListHead.Flink;
    DataTableEntry2 = CONTAINING_RECORD(NextEntry,
                                        LDR_DATA_TABLE_ENTRY,
                                        InLoadOrderLinks);
    PsNtosImageBase = DataTableEntry2->DllBase;

    DataTableEntry2 = (PLDR_DATA_TABLE_ENTRY) NextEntry->Flink;
    DataTableEntry2 = CONTAINING_RECORD(DataTableEntry2,
                                        LDR_DATA_TABLE_ENTRY,
                                        InLoadOrderLinks);
    PsHalImageBase = DataTableEntry2->DllBase;

    while (NextEntry != &LoaderBlock->LoadOrderListHead) {


        DataTableEntry2 = CONTAINING_RECORD(NextEntry,
                                            LDR_DATA_TABLE_ENTRY,
                                            InLoadOrderLinks);

        //
        // Allocate a data table entry.
        //

        DataTableEntry1 = ExAllocatePool(NonPagedPool,
                                         sizeof(LDR_DATA_TABLE_ENTRY) +
                               DataTableEntry2->FullDllName.MaximumLength +
                                 DataTableEntry2->BaseDllName.MaximumLength +
                                 sizeof(ULONG) + sizeof(ULONG));

        if (DataTableEntry1 == NULL) {
            return FALSE;
        }

        //
        // Copy the data table entry.
        //

        *DataTableEntry1 = *DataTableEntry2;

        //
        // Copy the strings.
        //

        DataTableEntry1->FullDllName.Buffer = (PWSTR)((PCHAR)DataTableEntry1 +
                                     ROUND_UP(sizeof(LDR_DATA_TABLE_ENTRY),
                                              sizeof(ULONG)));

        RtlMoveMemory (DataTableEntry1->FullDllName.Buffer,
                       DataTableEntry2->FullDllName.Buffer,
                       DataTableEntry1->FullDllName.MaximumLength);

        DataTableEntry1->BaseDllName.Buffer =
                        (PWSTR)((PCHAR)DataTableEntry1->FullDllName.Buffer +
                          ROUND_UP(DataTableEntry1->FullDllName.MaximumLength,
                                   sizeof(ULONG)));

        RtlMoveMemory (DataTableEntry1->BaseDllName.Buffer,
                       DataTableEntry2->BaseDllName.Buffer,
                       DataTableEntry1->BaseDllName.MaximumLength);

        //
        // Insert the data table entry in the load order list in the order
        // they are specified.
        //

        InsertTailList(&PsLoadedModuleList,
                       &DataTableEntry1->InLoadOrderLinks);

        NextEntry = NextEntry->Flink;
    }


    //
    // Initialize the common fields of the Object Type Prototype record
    //

    RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) );
    ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer );
    ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
    ObjectTypeInitializer.SecurityRequired = TRUE;
    ObjectTypeInitializer.PoolType = NonPagedPool;
    ObjectTypeInitializer.InvalidAttributes = OBJ_PERMANENT |
                                              OBJ_EXCLUSIVE |
                                              OBJ_OPENIF;


    //
    // Create Object types for Thread and Process Objects.
    //

    RtlInitUnicodeString(&NameString, L"Process");
    ObjectTypeInitializer.DefaultPagedPoolCharge = PSP_PROCESS_PAGED_CHARGE;
    ObjectTypeInitializer.DefaultNonPagedPoolCharge = PSP_PROCESS_NONPAGED_CHARGE;
    ObjectTypeInitializer.DeleteProcedure = PspProcessDelete;
    ObjectTypeInitializer.ValidAccessMask = PROCESS_ALL_ACCESS;
    ObjectTypeInitializer.GenericMapping = PspProcessMapping;

    if ( !NT_SUCCESS(ObCreateObjectType(&NameString,
                                     &ObjectTypeInitializer,
                                     (PSECURITY_DESCRIPTOR) NULL,
                                     &PsProcessType
                                     )) ){
        return FALSE;
    }

    RtlInitUnicodeString(&NameString, L"Thread");
    ObjectTypeInitializer.DefaultPagedPoolCharge = PSP_THREAD_PAGED_CHARGE;
    ObjectTypeInitializer.DefaultNonPagedPoolCharge = PSP_THREAD_NONPAGED_CHARGE;
    ObjectTypeInitializer.DeleteProcedure = PspThreadDelete;
    ObjectTypeInitializer.ValidAccessMask = THREAD_ALL_ACCESS;
    ObjectTypeInitializer.GenericMapping = PspThreadMapping;

    if ( !NT_SUCCESS(ObCreateObjectType(&NameString,
                                     &ObjectTypeInitializer,
                                     (PSECURITY_DESCRIPTOR) NULL,
                                     &PsThreadType
                                     )) ){
        return FALSE;
    }

    //
    // Initialize active process list head and mutex
    //

    InitializeListHead(&PsActiveProcessHead);
    ExInitializeFastMutex(&PspActiveProcessMutex);

    //
    // Initialize CID handle table.
    //
    // N.B. The CID handle table is removed from the handle table list so
    //      it will not be enumerated for object handle queries.
    //

    PspCidTable = ExCreateHandleTable(NULL, 0, 0);
    if ( ! PspCidTable ) {
        return FALSE;
    }
    ExRemoveHandleTable(PspCidTable);

#ifdef i386

    //
    // Ldt Initialization
    //

    if ( !NT_SUCCESS(PspLdtInitialize()) ) {
        return FALSE;
    }

    //
    // Vdm support Initialization
    //

    if ( !NT_SUCCESS(PspVdmInitialize()) ) {
        return FALSE;
    }

#endif

    //
    // Initialize Reaper Data Structures
    //

    InitializeListHead(&PsReaperListHead);
    ExInitializeWorkItem(&PsReaperWorkItem, PspReaper, NULL);

    //
    // Get a pointer to the system access token.
    // This token is used by the boot process, so we can take the pointer
    // from there.
    //

    PspBootAccessToken = PsGetCurrentProcess()->Token;

    InitializeObjectAttributes( &ObjectAttributes,
                                NULL,
                                0,
                                NULL,
                                NULL
                              ); // FIXFIX

    if ( !NT_SUCCESS(PspCreateProcess(
                    &PspInitialSystemProcessHandle,
                    PROCESS_ALL_ACCESS,
                    &ObjectAttributes,
                    0L,
                    FALSE,
                    0L,
                    0L,
                    0L
                    )) ) {
        return FALSE;
    }

    if ( !NT_SUCCESS(ObReferenceObjectByHandle(
                                        PspInitialSystemProcessHandle,
                                        0L,
                                        PsProcessType,
                                        KernelMode,
                                        (PVOID *)&PsInitialSystemProcess,
                                        NULL
                                        )) ) {

        return FALSE;
    }

    strcpy(&PsGetCurrentProcess()->ImageFileName[0],"Idle");
    strcpy(&PsInitialSystemProcess->ImageFileName[0],"System");

    //
    // Phase 1 System initialization
    //

    if ( !NT_SUCCESS(PsCreateSystemThread(
                    &ThreadHandle,
                    THREAD_ALL_ACCESS,
                    &ObjectAttributes,
                    0L,
                    NULL,
                    Phase1Initialization,
                    (PVOID)LoaderBlock
                    )) ) {
        return FALSE;
    }


    if ( !NT_SUCCESS(ObReferenceObjectByHandle(
                        ThreadHandle,
                        0L,
                        PsThreadType,
                        KernelMode,
                        (PVOID *)&Thread,
                        NULL
                        )) ) {

        return FALSE;
    }

    ZwClose( ThreadHandle );

#if DBG
    PspExitProcessEventId = RtlCreateEventId( NULL,
                                              0,
                                              "ExitProcess",
                                              1,
                                              RTL_EVENT_STATUS_PARAM, "ExitStatus", 0
                                            );
    PspPageFaultEventId = RtlCreateEventId( NULL,
                                            0,
                                            "PageFault",
                                            3,
                                            RTL_EVENT_STATUS_PARAM, "", 0,
                                            RTL_EVENT_ADDRESS_PARAM, "PC", 0,
                                            RTL_EVENT_ADDRESS_PARAM, "Va", 0
                                          );
#endif // DBG

    return TRUE;
}
Beispiel #3
0
VOID
KEAPI
PspInitSystem(
	)
/*++
	Initialize process subsystem. Threads already initialized by PsInitSystem
--*/
{
	InitializeListHead (&PsActiveProcessHead);
	PspCreateProcess( &InitialSystemProcess );
	InitialSystemProcess.DirectoryTableBase = MM_PDE_START;
	SystemThread.OwningProcess = &InitialSystemProcess;

	InitializeListHead (&PsReadyListHead);
	InitializeListHead (&PsWaitListHead);

	InitializeListHead (&SystemThread.IrpList);
	ExInitializeMutex (&SystemThread.IrpListLock);

	ExInitializeMutex (&InitialSystemProcess.ObjectTable.TableLock);
	InitialSystemProcess.ObjectTable.HandleTable = (POBJECT_HANDLE) ExAllocateHeap (FALSE, sizeof(OBJECT_HANDLE)*OB_INITIAL_HANDLES);
	ASSERT (InitialSystemProcess.ObjectTable.HandleTable);
	memset (InitialSystemProcess.ObjectTable.HandleTable, 0, sizeof(OBJECT_HANDLE)*OB_INITIAL_HANDLES);
	InitialSystemProcess.ObjectTable.CurrentSize = OB_INITIAL_HANDLES;

	InsertTailList (&InitialSystemProcess.ThreadListHead, &SystemThread.ProcessThreadListEntry);
	InsertTailList (&PsReadyListHead, &SystemThread.SchedulerListEntry);

	InitializeLockedList (&PsCreateThreadCallbackList);
	InitializeLockedList (&PsTerminateThreadCallbackList);
	InitializeLockedList (&PsCreateProcessCallbackList);
	InitializeLockedList (&PsTerminateProcessCallbackList);

	//
	// Initialize SE
	//

	InitializeLockedList (&SeLoggedUsers);

	//
	// Create System user
	//

	SeSystemUser = (PSE_LOGGED_USER) ExAllocateHeap (TRUE, sizeof(SE_LOGGED_USER));
	SeSystemUser->UserId = 0;
	SeSystemUser->GroupId = 0;
	SeSystemUser->Privileges1 = 0xFFFFFFFF;
	SeSystemUser->Privileges2 = 0xFFFFFFFF;
	SeSystemUser->DefaultPrivileges1 = 0xFFFFFFFF;
	SeSystemUser->DefaultPrivileges2 = 0xFFFFFFFF;

	InterlockedInsertTailList (&SeLoggedUsers, &SeSystemUser->LoggedUsersEntry);

	//
	// Create access token for System process
	//

	PSE_ACCESS_TOKEN Token = SeCreateAccessToken (SeSystemUser);
	InitialSystemProcess.AccessToken = Token;
	SystemThread.AccessToken = Token;
	InterlockedIncrement ( (PLONG)&Token->ShareCount); // =2
}