Something went wrong. Try again.
Reactos
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068/* * PROJECT: ReactOS Kernel * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/ex/init.c * PURPOSE: Executive Initialization Code * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * Eric Kohl */
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>#include <reactos/buildno.h>#include "inbv/logo.h"
#define NDEBUG#include <debug.h>
/* This is the size that we can expect from the win 2003 loader */#define LOADER_PARAMETER_EXTENSION_MIN_SIZE \ RTL_SIZEOF_THROUGH_FIELD(LOADER_PARAMETER_EXTENSION, AcpiTableSize)
/* Temporary hack */CODE_SEG("INIT")BOOLEANNTAPIMmArmInitSystem( IN ULONG Phase, IN PLOADER_PARAMETER_BLOCK LoaderBlock);
typedef struct _INIT_BUFFER{ WCHAR DebugBuffer[256]; CHAR VersionBuffer[256]; CHAR BootlogHeader[256]; CHAR VersionNumber[24]; RTL_USER_PROCESS_INFORMATION ProcessInfo; WCHAR RegistryBuffer[256];} INIT_BUFFER, *PINIT_BUFFER;
/* DATA **********************************************************************/
/* NT Version Info */ULONG NtMajorVersion = VER_PRODUCTMAJORVERSION;ULONG NtMinorVersion = VER_PRODUCTMINORVERSION;#if DBG /* Checked Build */ULONG NtBuildNumber = VER_PRODUCTBUILD | 0xC0000000;#else /* Free Build */ULONG NtBuildNumber = VER_PRODUCTBUILD;#endif
/* NT System Info */ULONG NtGlobalFlag = 0;ULONG ExSuiteMask;
/* Cm Version Info */ULONG CmNtSpBuildNumber;ULONG CmNtCSDVersion;ULONG CmNtCSDReleaseType;UNICODE_STRING CmVersionString;UNICODE_STRING CmCSDVersionString;
CHAR NtBuildLab[] = KERNEL_VERSION_BUILD_STR "." REACTOS_COMPILER_NAME "_" REACTOS_COMPILER_VERSION;
/* Init flags and settings */ULONG ExpInitializationPhase;BOOLEAN ExpInTextModeSetup;BOOLEAN IoRemoteBootClient;ULONG InitSafeBootMode;BOOLEAN InitIsWinPEMode, InitWinPEModeType;BOOLEAN SosEnabled; // Used by driver.c!IopDisplayLoadingMessage()
/* NT Boot Path */UNICODE_STRING NtSystemRoot;
/* NT Initial User Application */WCHAR NtInitialUserProcessBuffer[128] = L"\\SystemRoot\\System32\\smss.exe";ULONG NtInitialUserProcessBufferLength = sizeof(NtInitialUserProcessBuffer) - sizeof(WCHAR);ULONG NtInitialUserProcessBufferType = REG_SZ;
/* Boot NLS information */PVOID ExpNlsTableBase;ULONG ExpAnsiCodePageDataOffset, ExpOemCodePageDataOffset;ULONG ExpUnicodeCaseTableDataOffset;NLSTABLEINFO ExpNlsTableInfo;SIZE_T ExpNlsTableSize;PVOID ExpNlsSectionPointer;
/* CMOS Timer Sanity */BOOLEAN ExCmosClockIsSane = TRUE;BOOLEAN ExpRealTimeIsUniversal;
/* FUNCTIONS ****************************************************************/
CODE_SEG("INIT")NTSTATUSNTAPIExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock){ UNICODE_STRING LinkName; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE LinkHandle; NTSTATUS Status; ANSI_STRING AnsiName; CHAR Buffer[256]; ANSI_STRING TargetString; UNICODE_STRING TargetName;
/* Initialize the ArcName tree */ RtlInitUnicodeString(&LinkName, L"\\ArcName"); InitializeObjectAttributes(&ObjectAttributes, &LinkName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, SePublicDefaultUnrestrictedSd);
/* Create it */ Status = NtCreateDirectoryObject(&LinkHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { /* Failed */ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 1, 0, 0); }
/* Close the LinkHandle */ NtClose(LinkHandle);
/* Initialize the Device tree */ RtlInitUnicodeString(&LinkName, L"\\Device"); InitializeObjectAttributes(&ObjectAttributes, &LinkName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, SePublicDefaultUnrestrictedSd);
/* Create it */ Status = NtCreateDirectoryObject(&LinkHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { /* Failed */ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 2, 0, 0); }
/* Close the LinkHandle */ ObCloseHandle(LinkHandle, KernelMode);
/* Create the system root symlink name */ RtlInitAnsiString(&AnsiName, "\\SystemRoot"); Status = RtlAnsiStringToUnicodeString(&LinkName, &AnsiName, TRUE); if (!NT_SUCCESS(Status)) { /* Failed */ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 3, 0, 0); }
/* Initialize the attributes for the link */ InitializeObjectAttributes(&ObjectAttributes, &LinkName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, SePublicDefaultUnrestrictedSd);
/* Build the ARC name */ sprintf(Buffer, "\\ArcName\\%s%s", LoaderBlock->ArcBootDeviceName, LoaderBlock->NtBootPathName); Buffer[strlen(Buffer) - 1] = ANSI_NULL;
/* Convert it to Unicode */ RtlInitString(&TargetString, Buffer); Status = RtlAnsiStringToUnicodeString(&TargetName, &TargetString, TRUE); if (!NT_SUCCESS(Status)) { /* We failed, bugcheck */ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 4, 0, 0); }
/* Create it */ Status = NtCreateSymbolicLinkObject(&LinkHandle, SYMBOLIC_LINK_ALL_ACCESS, &ObjectAttributes, &TargetName);
/* Free the strings */ RtlFreeUnicodeString(&LinkName); RtlFreeUnicodeString(&TargetName);
/* Check if creating the link failed */ if (!NT_SUCCESS(Status)) { /* Failed */ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 5, 0, 0); }
/* Close the handle and return success */ ObCloseHandle(LinkHandle, KernelMode); return STATUS_SUCCESS;}
CODE_SEG("INIT")VOIDNTAPIExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock){ LARGE_INTEGER SectionSize; NTSTATUS Status; HANDLE NlsSection; PVOID SectionBase = NULL; SIZE_T ViewSize = 0; LARGE_INTEGER SectionOffset = {{0, 0}}; PLIST_ENTRY ListHead, NextEntry; PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; ULONG NlsTablesEncountered = 0; SIZE_T NlsTableSizes[3] = {0, 0, 0}; /* 3 NLS tables */
/* Check if this is boot-time phase 0 initialization */ if (!ExpInitializationPhase) { /* Loop the memory descriptors */ ListHead = &LoaderBlock->MemoryDescriptorListHead; NextEntry = ListHead->Flink; while (NextEntry != ListHead) { /* Get the current block */ MdBlock = CONTAINING_RECORD(NextEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
/* Check if this is an NLS block */ if (MdBlock->MemoryType == LoaderNlsData) { /* Increase the table size */ ExpNlsTableSize += MdBlock->PageCount * PAGE_SIZE;
/* FreeLdr-specific */ NlsTableSizes[NlsTablesEncountered] = MdBlock->PageCount * PAGE_SIZE; NlsTablesEncountered++; ASSERT(NlsTablesEncountered < 4); }
/* Go to the next block */ NextEntry = MdBlock->ListEntry.Flink; }
/* Allocate the a new buffer since loader memory will be freed */ ExpNlsTableBase = ExAllocatePoolWithTag(NonPagedPool, ExpNlsTableSize, TAG_RTLI); if (!ExpNlsTableBase) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
/* Copy the codepage data in its new location. */ if (NlsTablesEncountered == 1) { /* Ntldr-way boot process */ RtlCopyMemory(ExpNlsTableBase, LoaderBlock->NlsData->AnsiCodePageData, ExpNlsTableSize); } else { /* * In NT, the memory blocks are contiguous, but in ReactOS they aren't, * so unless someone fixes FreeLdr, we'll have to use this icky hack. */ RtlCopyMemory(ExpNlsTableBase, LoaderBlock->NlsData->AnsiCodePageData, NlsTableSizes[0]);
RtlCopyMemory((PVOID)((ULONG_PTR)ExpNlsTableBase + NlsTableSizes[0]), LoaderBlock->NlsData->OemCodePageData, NlsTableSizes[1]);
RtlCopyMemory((PVOID)((ULONG_PTR)ExpNlsTableBase + NlsTableSizes[0] + NlsTableSizes[1]), LoaderBlock->NlsData->UnicodeCodePageData, NlsTableSizes[2]); /* End of Hack */ }
/* Initialize and reset the NLS TAbles */ RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase + ExpAnsiCodePageDataOffset), (PVOID)((ULONG_PTR)ExpNlsTableBase + ExpOemCodePageDataOffset), (PVOID)((ULONG_PTR)ExpNlsTableBase + ExpUnicodeCaseTableDataOffset), &ExpNlsTableInfo); RtlResetRtlTranslations(&ExpNlsTableInfo); return; }
/* Set the section size */ SectionSize.QuadPart = ExpNlsTableSize;
/* Create the NLS Section */ Status = ZwCreateSection(&NlsSection, SECTION_ALL_ACCESS, NULL, &SectionSize, PAGE_READWRITE, SEC_COMMIT | 0x1, NULL); if (!NT_SUCCESS(Status)) { /* Failed */ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 1, 0, 0); }
/* Get a pointer to the section */ Status = ObReferenceObjectByHandle(NlsSection, SECTION_ALL_ACCESS, MmSectionObjectType, KernelMode, &ExpNlsSectionPointer, NULL); ObCloseHandle(NlsSection, KernelMode); if (!NT_SUCCESS(Status)) { /* Failed */ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 2, 0, 0); }
/* Map the NLS Section in system space */ Status = MmMapViewInSystemSpace(ExpNlsSectionPointer, &SectionBase, &ExpNlsTableSize); if (!NT_SUCCESS(Status)) { /* Failed */ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 3, 0, 0); }
/* Copy the codepage data in its new location. */ ASSERT(SectionBase >= MmSystemRangeStart); RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize);
/* Free the previously allocated buffer and set the new location */ ExFreePoolWithTag(ExpNlsTableBase, TAG_RTLI); ExpNlsTableBase = SectionBase;
/* Initialize the NLS Tables */ RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase + ExpAnsiCodePageDataOffset), (PVOID)((ULONG_PTR)ExpNlsTableBase + ExpOemCodePageDataOffset), (PVOID)((ULONG_PTR)ExpNlsTableBase + ExpUnicodeCaseTableDataOffset), &ExpNlsTableInfo); RtlResetRtlTranslations(&ExpNlsTableInfo);
/* Reset the base to 0 */ SectionBase = NULL;
/* Map the section in the system process */ Status = MmMapViewOfSection(ExpNlsSectionPointer, PsGetCurrentProcess(), &SectionBase, 0L, 0L, &SectionOffset, &ViewSize, ViewShare, 0L, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { /* Failed */ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 5, 0, 0); }
/* Copy the table into the system process and set this as the base */ RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize); ExpNlsTableBase = SectionBase;}
CODE_SEG("INIT")VOIDNTAPIExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer, OUT PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, OUT PCHAR *ProcessEnvironment){ NTSTATUS Status; SIZE_T Size; PWSTR p; UNICODE_STRING NullString = RTL_CONSTANT_STRING(L""); UNICODE_STRING SmssName, Environment, SystemDriveString, DebugString; PVOID EnvironmentPtr = NULL; PRTL_USER_PROCESS_INFORMATION ProcessInformation; PRTL_USER_PROCESS_PARAMETERS ProcessParams = NULL;
NullString.Length = sizeof(WCHAR);
/* Use the initial buffer, after the strings */ ProcessInformation = &InitBuffer->ProcessInfo;
/* Allocate memory for the process parameters */ Size = sizeof(*ProcessParams) + ((MAX_WIN32_PATH * 6) * sizeof(WCHAR)); Status = ZwAllocateVirtualMemory(NtCurrentProcess(), (PVOID*)&ProcessParams, 0, &Size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { /* Failed, display error */ _snwprintf(InitBuffer->DebugBuffer, sizeof(InitBuffer->DebugBuffer)/sizeof(WCHAR), L"INIT: Unable to allocate Process Parameters. 0x%lx", Status); RtlInitUnicodeString(&DebugString, InitBuffer->DebugBuffer); ZwDisplayString(&DebugString);
/* Bugcheck the system */ KeBugCheckEx(SESSION1_INITIALIZATION_FAILED, Status, 0, 0, 0); }
/* Setup the basic header, and give the process the low 1MB to itself */ ProcessParams->Length = (ULONG)Size; ProcessParams->MaximumLength = (ULONG)Size; ProcessParams->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED | RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB;
/* Allocate a page for the environment */ Size = PAGE_SIZE; Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &EnvironmentPtr, 0, &Size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { /* Failed, display error */ _snwprintf(InitBuffer->DebugBuffer, sizeof(InitBuffer->DebugBuffer)/sizeof(WCHAR), L"INIT: Unable to allocate Process Environment. 0x%lx", Status); RtlInitUnicodeString(&DebugString, InitBuffer->DebugBuffer); ZwDisplayString(&DebugString);
/* Bugcheck the system */ KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, Status, 0, 0, 0); }
/* Write the pointer */ ProcessParams->Environment = EnvironmentPtr;
/* Make a buffer for the DOS path */ p = (PWSTR)(ProcessParams + 1); ProcessParams->CurrentDirectory.DosPath.Buffer = p; ProcessParams->CurrentDirectory.DosPath.MaximumLength = MAX_WIN32_PATH * sizeof(WCHAR);
/* Copy the DOS path */ RtlCopyUnicodeString(&ProcessParams->CurrentDirectory.DosPath, &NtSystemRoot);
/* Make a buffer for the DLL Path */ p = (PWSTR)((PCHAR)ProcessParams->CurrentDirectory.DosPath.Buffer + ProcessParams->CurrentDirectory.DosPath.MaximumLength); ProcessParams->DllPath.Buffer = p; ProcessParams->DllPath.MaximumLength = MAX_WIN32_PATH * sizeof(WCHAR);
/* Copy the DLL path and append the system32 directory */ RtlCopyUnicodeString(&ProcessParams->DllPath, &ProcessParams->CurrentDirectory.DosPath); RtlAppendUnicodeToString(&ProcessParams->DllPath, L"\\System32");
/* Make a buffer for the image name */ p = (PWSTR)((PCHAR)ProcessParams->DllPath.Buffer + ProcessParams->DllPath.MaximumLength); ProcessParams->ImagePathName.Buffer = p; ProcessParams->ImagePathName.MaximumLength = MAX_WIN32_PATH * sizeof(WCHAR);
/* Make sure the buffer is a valid string which within the given length */ if ((NtInitialUserProcessBufferType != REG_SZ) || ((NtInitialUserProcessBufferLength != MAXULONG) && ((NtInitialUserProcessBufferLength < sizeof(WCHAR)) || (NtInitialUserProcessBufferLength > sizeof(NtInitialUserProcessBuffer) - sizeof(WCHAR))))) { /* Invalid initial process string, bugcheck */ KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, STATUS_INVALID_PARAMETER, NtInitialUserProcessBufferType, NtInitialUserProcessBufferLength, sizeof(NtInitialUserProcessBuffer)); }
/* Cut out anything after a space */ p = NtInitialUserProcessBuffer; while ((*p) && (*p != L' ')) p++;
/* Set the image path length */ ProcessParams->ImagePathName.Length = (USHORT)((PCHAR)p - (PCHAR)NtInitialUserProcessBuffer);
/* Copy the actual buffer */ RtlCopyMemory(ProcessParams->ImagePathName.Buffer, NtInitialUserProcessBuffer, ProcessParams->ImagePathName.Length);
/* Null-terminate it */ ProcessParams->ImagePathName.Buffer[ProcessParams->ImagePathName.Length / sizeof(WCHAR)] = UNICODE_NULL;
/* Make a buffer for the command line */ p = (PWSTR)((PCHAR)ProcessParams->ImagePathName.Buffer + ProcessParams->ImagePathName.MaximumLength); ProcessParams->CommandLine.Buffer = p; ProcessParams->CommandLine.MaximumLength = MAX_WIN32_PATH * sizeof(WCHAR);
/* Add the image name to the command line */ RtlAppendUnicodeToString(&ProcessParams->CommandLine, NtInitialUserProcessBuffer);
/* Create the environment string */ RtlInitEmptyUnicodeString(&Environment, ProcessParams->Environment, (USHORT)Size);
/* Append the DLL path to it */ RtlAppendUnicodeToString(&Environment, L"Path="); RtlAppendUnicodeStringToString(&Environment, &ProcessParams->DllPath); RtlAppendUnicodeStringToString(&Environment, &NullString);
/* Create the system drive string */ SystemDriveString = NtSystemRoot; SystemDriveString.Length = 2 * sizeof(WCHAR);
/* Append it to the environment */ RtlAppendUnicodeToString(&Environment, L"SystemDrive="); RtlAppendUnicodeStringToString(&Environment, &SystemDriveString); RtlAppendUnicodeStringToString(&Environment, &NullString);
/* Append the system root to the environment */ RtlAppendUnicodeToString(&Environment, L"SystemRoot="); RtlAppendUnicodeStringToString(&Environment, &NtSystemRoot); RtlAppendUnicodeStringToString(&Environment, &NullString);
/* Prepare the prefetcher */ //CcPfBeginBootPhase(150);
/* Create SMSS process */ SmssName = ProcessParams->ImagePathName; Status = RtlCreateUserProcess(&SmssName, OBJ_CASE_INSENSITIVE, RtlDeNormalizeProcessParams(ProcessParams), NULL, NULL, NULL, FALSE, NULL, NULL, ProcessInformation); if (!NT_SUCCESS(Status)) { /* Failed, display error */ _snwprintf(InitBuffer->DebugBuffer, sizeof(InitBuffer->DebugBuffer)/sizeof(WCHAR), L"INIT: Unable to create Session Manager. 0x%lx", Status); RtlInitUnicodeString(&DebugString, InitBuffer->DebugBuffer); ZwDisplayString(&DebugString);
/* Bugcheck the system */ KeBugCheckEx(SESSION3_INITIALIZATION_FAILED, Status, 0, 0, 0); }
/* Resume the thread */ Status = ZwResumeThread(ProcessInformation->ThreadHandle, NULL); if (!NT_SUCCESS(Status)) { /* Failed, display error */ _snwprintf(InitBuffer->DebugBuffer, sizeof(InitBuffer->DebugBuffer)/sizeof(WCHAR), L"INIT: Unable to resume Session Manager. 0x%lx", Status); RtlInitUnicodeString(&DebugString, InitBuffer->DebugBuffer); ZwDisplayString(&DebugString);
/* Bugcheck the system */ KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0); }
/* Return success */ *ProcessParameters = ProcessParams; *ProcessEnvironment = EnvironmentPtr;}
CODE_SEG("INIT")ULONGNTAPIExComputeTickCountMultiplier(IN ULONG ClockIncrement){ ULONG MsRemainder = 0, MsIncrement; ULONG IncrementRemainder; ULONG i;
/* Count the number of milliseconds for each clock interrupt */ MsIncrement = ClockIncrement / (10 * 1000);
/* Count the remainder from the division above, with 24-bit precision */ IncrementRemainder = ClockIncrement - (MsIncrement * (10 * 1000)); for (i= 0; i < 24; i++) { /* Shift the remainders */ MsRemainder <<= 1; IncrementRemainder <<= 1;
/* Check if we've went past 1 ms */ if (IncrementRemainder >= (10 * 1000)) { /* Increase the remainder by one, and substract from increment */ IncrementRemainder -= (10 * 1000); MsRemainder |= 1; } }
/* Return the increment */ return (MsIncrement << 24) | MsRemainder;}
CODE_SEG("INIT")BOOLEANNTAPIExpInitSystemPhase0(VOID){ /* Initialize EXRESOURCE Support */ ExpResourceInitialization();
/* Initialize the environment lock */ ExInitializeFastMutex(&ExpEnvironmentLock);
/* Initialize the lookaside lists and locks */ ExpInitLookasideLists();
/* Initialize the Firmware Table resource and listhead */ InitializeListHead(&ExpFirmwareTableProviderListHead); ExInitializeResourceLite(&ExpFirmwareTableResource); ExInitializeResourceLite(&ExpTimeRefreshLock);
/* Set the suite mask to maximum and return */ ExSuiteMask = 0xFFFFFFFF; return TRUE;}
CODE_SEG("INIT")BOOLEANNTAPIExpInitSystemPhase1(VOID){ /* Initialize worker threads */ ExpInitializeWorkerThreads();
/* Initialize pushlocks */ ExpInitializePushLocks();
/* Initialize events and event pairs */ if (ExpInitializeEventImplementation() == FALSE) { DPRINT1("Executive: Event initialization failed\n"); return FALSE; } if (ExpInitializeEventPairImplementation() == FALSE) { DPRINT1("Executive: Event Pair initialization failed\n"); return FALSE; }
/* Initialize mutants */ if (ExpInitializeMutantImplementation() == FALSE) { DPRINT1("Executive: Mutant initialization failed\n"); return FALSE; }
/* Initialize callbacks */ if (ExpInitializeCallbacks() == FALSE) { DPRINT1("Executive: Callback initialization failed\n"); return FALSE; }
/* Initialize semaphores */ if (ExpInitializeSemaphoreImplementation() == FALSE) { DPRINT1("Executive: Semaphore initialization failed\n"); return FALSE; }
/* Initialize timers */ if (ExpInitializeTimerImplementation() == FALSE) { DPRINT1("Executive: Timer initialization failed\n"); return FALSE; }
/* Initialize profiling */ if (ExpInitializeProfileImplementation() == FALSE) { DPRINT1("Executive: Profile initialization failed\n"); return FALSE; }
/* Initialize UUIDs */ if (ExpUuidInitialization() == FALSE) { DPRINT1("Executive: Uuid initialization failed\n"); return FALSE; }
/* Initialize keyed events */ if (ExpInitializeKeyedEventImplementation() == FALSE) { DPRINT1("Executive: Keyed event initialization failed\n"); return FALSE; }
/* Initialize Win32K */ if (ExpWin32kInit() == FALSE) { DPRINT1("Executive: Win32 initialization failed\n"); return FALSE; } return TRUE;}
CODE_SEG("INIT")BOOLEANNTAPIExInitSystem(VOID){ /* Check the initialization phase */ switch (ExpInitializationPhase) { case 0:
/* Do Phase 0 */ return ExpInitSystemPhase0();
case 1:
/* Do Phase 1 */ return ExpInitSystemPhase1();
default:
/* Don't know any other phase! Bugcheck! */ KeBugCheck(UNEXPECTED_INITIALIZATION_CALL); return FALSE; }}
CODE_SEG("INIT")BOOLEANNTAPIExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock){ PLOADER_PARAMETER_EXTENSION Extension;
/* Get the loader extension */ Extension = LoaderBlock->Extension;
/* Validate the size (Windows 2003 loader doesn't provide more) */ if (Extension->Size < LOADER_PARAMETER_EXTENSION_MIN_SIZE) return FALSE;
/* Don't validate upper versions */ if (Extension->MajorVersion > VER_PRODUCTMAJORVERSION) return TRUE;
/* Fail if this is NT 4 */ if (Extension->MajorVersion < VER_PRODUCTMAJORVERSION) return FALSE;
/* Fail if this is XP */ if (Extension->MinorVersion < VER_PRODUCTMINORVERSION) return FALSE;
/* This is 2003 or newer, approve it */ return TRUE;}
static CODE_SEG("INIT")VOIDExpLoadBootSymbols( _In_ PLOADER_PARAMETER_BLOCK LoaderBlock){ PLIST_ENTRY NextEntry; PLDR_DATA_TABLE_ENTRY LdrEntry; NTSTATUS Status; ULONG i; ULONG Count, Length; PWCHAR Name; STRING ImageName; CHAR NameBuffer[256];
/* Loop over the boot modules list */ for (NextEntry = LoaderBlock->LoadOrderListHead.Flink, i = 0; NextEntry != &LoaderBlock->LoadOrderListHead; NextEntry = NextEntry->Flink, ++i) { /* Skip the first two images: HAL and kernel */ if (i < 2) continue;
/* Get the entry */ LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); if (LdrEntry->FullDllName.Buffer[0] == L'\\') { /* We have a name, read its data */ Name = LdrEntry->FullDllName.Buffer; Length = LdrEntry->FullDllName.Length / sizeof(WCHAR);
/* Check if our buffer can hold it */ if (sizeof(NameBuffer) < Length + sizeof(ANSI_NULL)) { /* It's too long */ Status = STATUS_BUFFER_OVERFLOW; } else { /* Copy the name */ Count = 0; do { /* Do cheap Unicode to ANSI conversion */ NameBuffer[Count++] = (CHAR)*Name++; } while (Count < Length);
/* Null-terminate */ NameBuffer[Count] = ANSI_NULL; Status = STATUS_SUCCESS; } } else { /* Safely print the string into our buffer */ Status = RtlStringCbPrintfA(NameBuffer, sizeof(NameBuffer), "%S\\System32\\Drivers\\%wZ", &SharedUserData->NtSystemRoot[2], &LdrEntry->BaseDllName); }
/* Check if the buffer is OK */ if (NT_SUCCESS(Status)) { /* Load the symbols */ RtlInitString(&ImageName, NameBuffer); DbgLoadImageSymbols(&ImageName, LdrEntry->DllBase, (ULONG_PTR)PsGetCurrentProcessId()); }
#ifdef CONFIG_SMP /* Check that the image is safe to use if we have more than one CPU */ if (!MmVerifyImageIsOkForMpUse(LdrEntry->DllBase)) { KeBugCheckEx(UP_DRIVER_ON_MP_SYSTEM, (ULONG_PTR)LdrEntry->DllBase, 0, 0, 0); }#endif // CONFIG_SMP }}
CODE_SEG("INIT")VOIDNTAPIExBurnMemory(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN ULONG_PTR PagesToDestroy, IN TYPE_OF_MEMORY MemoryType){ PLIST_ENTRY ListEntry; PMEMORY_ALLOCATION_DESCRIPTOR MemDescriptor;
DPRINT1("Burn RAM amount: %lu pages\n", PagesToDestroy);
/* Loop the memory descriptors, beginning at the end */ for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Blink; ListEntry != &LoaderBlock->MemoryDescriptorListHead; ListEntry = ListEntry->Blink) { /* Get the memory descriptor structure */ MemDescriptor = CONTAINING_RECORD(ListEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
/* Is memory free there or is it temporary? */ if (MemDescriptor->MemoryType == LoaderFree || MemDescriptor->MemoryType == LoaderFirmwareTemporary) { /* Check if the descriptor has more pages than we want */ if (MemDescriptor->PageCount > PagesToDestroy) { /* Change block's page count, ntoskrnl doesn't care much */ MemDescriptor->PageCount -= PagesToDestroy; break; } else { /* Change block type */ MemDescriptor->MemoryType = MemoryType; PagesToDestroy -= MemDescriptor->PageCount;
/* Check if we are done */ if (PagesToDestroy == 0) break; } } }}
CODE_SEG("INIT")VOIDNTAPIExpInitializeExecutive(IN ULONG Cpu, IN PLOADER_PARAMETER_BLOCK LoaderBlock){ PNLS_DATA_BLOCK NlsData; CHAR Buffer[256]; ANSI_STRING AnsiPath; NTSTATUS Status; PCHAR CommandLine, PerfMem; ULONG PerfMemUsed; PLDR_DATA_TABLE_ENTRY NtosEntry; PMESSAGE_RESOURCE_ENTRY MsgEntry; ANSI_STRING CSDString; size_t Remaining = 0; PCHAR RcEnd = NULL; CHAR VersionBuffer[65];
/* Validate Loader */ if (!ExpIsLoaderValid(LoaderBlock)) { /* Invalid loader version */ KeBugCheckEx(MISMATCHED_HAL, 3, LoaderBlock->Extension->Size, LoaderBlock->Extension->MajorVersion, LoaderBlock->Extension->MinorVersion); }
/* Initialize PRCB pool lookaside pointers */ ExInitPoolLookasidePointers();
/* Check if this is an application CPU */ if (Cpu) { /* Then simply initialize it with HAL */ if (!HalInitSystem(ExpInitializationPhase, LoaderBlock)) { /* Initialization failed */ KeBugCheck(HAL_INITIALIZATION_FAILED); }
/* We're done */ return; }
/* Assume no text-mode or remote boot */ ExpInTextModeSetup = FALSE; IoRemoteBootClient = FALSE;
/* Check if we have a setup loader block */ if (LoaderBlock->SetupLdrBlock) { /* Check if this is text-mode setup */ if (LoaderBlock->SetupLdrBlock->Flags & SETUPLDR_TEXT_MODE) ExpInTextModeSetup = TRUE;
/* Check if this is network boot */ if (LoaderBlock->SetupLdrBlock->Flags & SETUPLDR_REMOTE_BOOT) { /* Set variable */ IoRemoteBootClient = TRUE;
/* Make sure we're actually booting off the network */ ASSERT(!_memicmp(LoaderBlock->ArcBootDeviceName, "net(0)", 6)); } }
/* Set phase to 0 */ ExpInitializationPhase = 0;
/* Get boot command line */ CommandLine = LoaderBlock->LoadOptions; if (CommandLine) { /* Upcase it for comparison and check if we're in performance mode */ _strupr(CommandLine); PerfMem = strstr(CommandLine, "PERFMEM"); if (PerfMem) { /* Check if the user gave a number of bytes to use */ PerfMem = strstr(PerfMem, "="); if (PerfMem) { /* Read the number of pages we'll use */ PerfMemUsed = atol(PerfMem + 1) * (1024 * 1024 / PAGE_SIZE); if (PerfMemUsed) { /* FIXME: TODO */ DPRINT1("BBT performance mode not yet supported." "/PERFMEM option ignored.\n"); } } }
/* Check if we're burning memory */ PerfMem = strstr(CommandLine, "BURNMEMORY"); if (PerfMem) { /* Check if the user gave a number of bytes to use */ PerfMem = strstr(PerfMem, "="); if (PerfMem) { /* Read the number of pages we'll use */ PerfMemUsed = atol(PerfMem + 1) * (1024 * 1024 / PAGE_SIZE); if (PerfMemUsed) ExBurnMemory(LoaderBlock, PerfMemUsed, LoaderBad); } } }
/* Setup NLS Base and offsets */ NlsData = LoaderBlock->NlsData; ExpNlsTableBase = NlsData->AnsiCodePageData; ExpAnsiCodePageDataOffset = 0; ExpOemCodePageDataOffset = (ULONG)((ULONG_PTR)NlsData->OemCodePageData - (ULONG_PTR)NlsData->AnsiCodePageData); ExpUnicodeCaseTableDataOffset = (ULONG)((ULONG_PTR)NlsData->UnicodeCodePageData - (ULONG_PTR)NlsData->AnsiCodePageData);
/* Initialize the NLS Tables */ RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase + ExpAnsiCodePageDataOffset), (PVOID)((ULONG_PTR)ExpNlsTableBase + ExpOemCodePageDataOffset), (PVOID)((ULONG_PTR)ExpNlsTableBase + ExpUnicodeCaseTableDataOffset), &ExpNlsTableInfo); RtlResetRtlTranslations(&ExpNlsTableInfo);
/* Now initialize the HAL */ if (!HalInitSystem(ExpInitializationPhase, LoaderBlock)) { /* HAL failed to initialize, bugcheck */ KeBugCheck(HAL_INITIALIZATION_FAILED); }
/* Make sure interrupts are active now */ _enable();
/* Clear the crypto exponent */ SharedUserData->CryptoExponent = 0;
/* Set global flags for the checked build */#if DBG NtGlobalFlag |= FLG_ENABLE_CLOSE_EXCEPTIONS | FLG_ENABLE_KDEBUG_SYMBOL_LOAD;#endif
/* Setup NT System Root Path */ sprintf(Buffer, "C:%s", LoaderBlock->NtBootPathName);
/* Convert to ANSI_STRING and null-terminate it */ RtlInitString(&AnsiPath, Buffer); Buffer[--AnsiPath.Length] = ANSI_NULL;
/* Get the string from KUSER_SHARED_DATA's buffer */ RtlInitEmptyUnicodeString(&NtSystemRoot, SharedUserData->NtSystemRoot, sizeof(SharedUserData->NtSystemRoot));
/* Now fill it in */ Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &AnsiPath, FALSE); if (!NT_SUCCESS(Status)) KeBugCheck(SESSION3_INITIALIZATION_FAILED);
/* Setup bugcheck messages */ KiInitializeBugCheck();
/* Setup initial system settings */ CmGetSystemControlValues(LoaderBlock->RegistryBase, CmControlVector);
/* Set the Service Pack Number and add it to the CSD Version number if needed */ CmNtSpBuildNumber = VER_PRODUCTBUILD_QFE; if (((CmNtCSDVersion & 0xFFFF0000) == 0) && (CmNtCSDReleaseType == 1)) { CmNtCSDVersion |= (VER_PRODUCTBUILD_QFE << 16); }
/* Add loaded CmNtGlobalFlag value */ NtGlobalFlag |= CmNtGlobalFlag;
/* Initialize the executive at phase 0 */ if (!ExInitSystem()) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
/* Initialize the memory manager at phase 0 */ if (!MmArmInitSystem(0, LoaderBlock)) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
/* Load boot symbols */ ExpLoadBootSymbols(LoaderBlock);
/* Check if we should break after symbol load */ if (KdBreakAfterSymbolLoad) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
/* Check if this loader is compatible with NT 5.2 */ if (LoaderBlock->Extension->Size >= sizeof(LOADER_PARAMETER_EXTENSION)) { /* Setup headless terminal settings */ HeadlessInit(LoaderBlock); }
/* Set system ranges */#ifdef _M_AMD64 SharedUserData->Reserved1 = MM_HIGHEST_USER_ADDRESS_WOW64; SharedUserData->Reserved3 = MM_SYSTEM_RANGE_START_WOW64;#else SharedUserData->Reserved1 = (ULONG_PTR)MmHighestUserAddress; SharedUserData->Reserved3 = (ULONG_PTR)MmSystemRangeStart;#endif
/* Make a copy of the NLS Tables */ ExpInitNls(LoaderBlock);
/* Get the kernel's load entry */ NtosEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
/* Check if this is a service pack */ if (CmNtCSDVersion & 0xFFFF) { /* Get the service pack string */ Status = RtlFindMessage(NtosEntry->DllBase, RT_MESSAGETABLE, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), WINDOWS_NT_CSD_STRING, &MsgEntry); if (NT_SUCCESS(Status)) { /* Setup the string */ RtlInitAnsiString(&CSDString, (PCHAR)MsgEntry->Text);
/* Remove trailing newline */ while ((CSDString.Length > 0) && ((CSDString.Buffer[CSDString.Length - 1] == '\r') || (CSDString.Buffer[CSDString.Length - 1] == '\n'))) { /* Skip the trailing character */ CSDString.Length--; }
/* Fill the buffer with version information */ Status = RtlStringCbPrintfA(Buffer, sizeof(Buffer), "%Z %u%c", &CSDString, (CmNtCSDVersion & 0xFF00) >> 8, (CmNtCSDVersion & 0xFF) ? 'A' + (CmNtCSDVersion & 0xFF) - 1 : ANSI_NULL); } else { /* Build default string */ Status = RtlStringCbPrintfA(Buffer, sizeof(Buffer), "CSD %04x", CmNtCSDVersion); }
/* Check for success */ if (!NT_SUCCESS(Status)) { /* Fail */ KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); } } else { /* Then this is a beta */ Status = RtlStringCbCopyExA(Buffer, sizeof(Buffer), VER_PRODUCTBETA_STR, NULL, &Remaining, 0); if (!NT_SUCCESS(Status)) { /* Fail */ KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); }
/* Update length */ CmCSDVersionString.MaximumLength = sizeof(Buffer) - (USHORT)Remaining; }
/* Check if we have an RC number */ if ((CmNtCSDVersion & 0xFFFF0000) && (CmNtCSDReleaseType == 1)) { /* Check if we have no version data yet */ if (!(*Buffer)) { /* Set defaults */ Remaining = sizeof(Buffer); RcEnd = Buffer; } else { /* Add comma and space */ Status = RtlStringCbCatExA(Buffer, sizeof(Buffer), ", ", &RcEnd, &Remaining, 0); if (!NT_SUCCESS(Status)) { /* Fail */ KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); } }
/* Add the version format string */ Status = RtlStringCbPrintfA(RcEnd, Remaining, "v.%u", (CmNtCSDVersion & 0xFFFF0000) >> 16); if (!NT_SUCCESS(Status)) { /* Fail */ KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); } }
/* Now setup the final string */ RtlInitAnsiString(&CSDString, Buffer); Status = RtlAnsiStringToUnicodeString(&CmCSDVersionString, &CSDString, TRUE); if (!NT_SUCCESS(Status)) { /* Fail */ KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); }
/* Add our version */ Status = RtlStringCbPrintfA(VersionBuffer, sizeof(VersionBuffer), "%u.%u", VER_PRODUCTMAJORVERSION, VER_PRODUCTMINORVERSION); if (!NT_SUCCESS(Status)) { /* Fail */ KeBugCheckEx(PHASE0_INITIALIZATION_FAILED, Status, 0, 0, 0); }
/* Build the final version string */ RtlCreateUnicodeStringFromAsciiz(&CmVersionString, VersionBuffer);
/* Check if the user wants a kernel stack trace database */ if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) { /* FIXME: TODO */ DPRINT1("Kernel-mode stack trace support not yet present." "FLG_KERNEL_STACK_TRACE_DB flag ignored.\n"); }
/* Check if he wanted exception logging */ if (NtGlobalFlag & FLG_ENABLE_EXCEPTION_LOGGING) { /* FIXME: TODO */ DPRINT1("Kernel-mode exception logging support not yet present." "FLG_ENABLE_EXCEPTION_LOGGING flag ignored.\n"); }
/* Initialize the Handle Table */ ExpInitializeHandleTables();
#if DBG /* On checked builds, allocate the system call count table */ KeServiceDescriptorTable[0].Count = ExAllocatePoolWithTag(NonPagedPool, KiServiceLimit * sizeof(ULONG), 'llaC');
/* Use it for the shadow table too */ KeServiceDescriptorTableShadow[0].Count = KeServiceDescriptorTable[0].Count;
/* Make sure allocation succeeded */ if (KeServiceDescriptorTable[0].Count) { /* Zero the call counts to 0 */ RtlZeroMemory(KeServiceDescriptorTable[0].Count, KiServiceLimit * sizeof(ULONG)); }#endif
/* Create the Basic Object Manager Types to allow new Object Types */ if (!ObInitSystem()) KeBugCheck(OBJECT_INITIALIZATION_FAILED);
/* Load basic Security for other Managers */ if (!SeInitSystem()) KeBugCheck(SECURITY_INITIALIZATION_FAILED);
/* Initialize the Process Manager */ if (!PsInitSystem(LoaderBlock)) KeBugCheck(PROCESS_INITIALIZATION_FAILED);
/* Initialize the PnP Manager */ if (!PpInitSystem()) KeBugCheck(PP0_INITIALIZATION_FAILED);
/* Initialize the User-Mode Debugging Subsystem */ DbgkInitialize();
/* Calculate the tick count multiplier */ ExpTickCountMultiplier = ExComputeTickCountMultiplier(KeMaximumIncrement); SharedUserData->TickCountMultiplier = ExpTickCountMultiplier;
/* Set the OS Version */ SharedUserData->NtMajorVersion = NtMajorVersion; SharedUserData->NtMinorVersion = NtMinorVersion;
/* Set the machine type */ SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_NATIVE; SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_NATIVE;
/* ReactOS magic */ *(PULONG)(KI_USER_SHARED_DATA + PAGE_SIZE - sizeof(ULONG)) = 0x8eac705;}
VOIDNTAPIMmFreeLoaderBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock);
CODE_SEG("INIT")VOIDNTAPIPhase1InitializationDiscard(IN PVOID Context){ PLOADER_PARAMETER_BLOCK LoaderBlock = Context; NTSTATUS Status, MsgStatus; TIME_FIELDS TimeFields; LARGE_INTEGER SystemBootTime, UniversalBootTime, OldTime, Timeout; BOOLEAN NoGuiBoot, ResetBias = FALSE, AlternateShell = FALSE; PLDR_DATA_TABLE_ENTRY NtosEntry; PMESSAGE_RESOURCE_ENTRY MsgEntry; PCHAR CommandLine, Y2KHackRequired, SafeBoot, Environment; PCHAR StringBuffer, EndBuffer, BeginBuffer, MpString = ""; PINIT_BUFFER InitBuffer; ANSI_STRING TempString; ULONG LastTzBias, Length, YearHack = 0, Disposition, MessageCode = 0; SIZE_T Size; size_t Remaining; PRTL_USER_PROCESS_INFORMATION ProcessInfo; KEY_VALUE_PARTIAL_INFORMATION KeyPartialInfo; UNICODE_STRING KeyName; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE KeyHandle, OptionHandle; PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
/* Allocate the initialization buffer */ InitBuffer = ExAllocatePoolWithTag(NonPagedPool, sizeof(INIT_BUFFER), TAG_INIT); if (!InitBuffer) { /* Bugcheck */ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 8, 0, 0); }
/* Set to phase 1 */ ExpInitializationPhase = 1;
/* Set us at maximum priority */ KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY);
/* Do Phase 1 HAL Initialization */ if (!HalInitSystem(1, LoaderBlock)) KeBugCheck(HAL1_INITIALIZATION_FAILED);
/* Get the command line and upcase it */ CommandLine = (LoaderBlock->LoadOptions ? _strupr(LoaderBlock->LoadOptions) : NULL);
/* Check if GUI Boot is enabled */ NoGuiBoot = (CommandLine && strstr(CommandLine, "NOGUIBOOT") != NULL);
/* Get the SOS setting */ SosEnabled = (CommandLine && strstr(CommandLine, "SOS") != NULL);
/* Setup the boot video driver */ InbvEnableBootDriver(!NoGuiBoot); InbvDriverInitialize(LoaderBlock, IDB_MAX_RESOURCES);
/* Check if GUI boot is enabled */ if (!NoGuiBoot) { /* It is, display the boot logo and enable printing strings */ InbvEnableDisplayString(SosEnabled); DisplayBootBitmap(SosEnabled); } else { /* Release display ownership if not using GUI boot */ InbvNotifyDisplayOwnershipLost(NULL);
/* Don't allow boot-time strings */ InbvEnableDisplayString(FALSE); }
/* Check if this is LiveCD (WinPE) mode */ if (CommandLine && strstr(CommandLine, "MININT") != NULL) { /* Setup WinPE Settings */ InitIsWinPEMode = TRUE; InitWinPEModeType |= (strstr(CommandLine, "INRAM") != NULL) ? 0x80000000 : 0x00000001; }
/* Get the kernel's load entry */ NtosEntry = CONTAINING_RECORD(LoaderBlock->LoadOrderListHead.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
/* Find the banner message */ MsgStatus = RtlFindMessage(NtosEntry->DllBase, RT_MESSAGETABLE, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), WINDOWS_NT_BANNER, &MsgEntry);
/* Setup defaults and check if we have a version string */ StringBuffer = InitBuffer->VersionBuffer; BeginBuffer = StringBuffer; EndBuffer = StringBuffer; Remaining = sizeof(InitBuffer->VersionBuffer); if (CmCSDVersionString.Length) { /* Print the version string */ Status = RtlStringCbPrintfExA(StringBuffer, Remaining, &EndBuffer, &Remaining, 0, ": %wZ", &CmCSDVersionString); if (!NT_SUCCESS(Status)) { /* Bugcheck */ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); } } else { /* No version */ *EndBuffer = ANSI_NULL; /* Null-terminate the string */ }
/* Skip over the null-terminator to start a new string */ ++EndBuffer; --Remaining;
/* Build the version number */ StringBuffer = InitBuffer->VersionNumber; Status = RtlStringCbPrintfA(StringBuffer, sizeof(InitBuffer->VersionNumber), "%u.%u", VER_PRODUCTMAJORVERSION, VER_PRODUCTMINORVERSION); if (!NT_SUCCESS(Status)) { /* Bugcheck */ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); }
/* Check if we had found a banner message */ if (NT_SUCCESS(MsgStatus)) { /* Create the banner message */ /* ReactOS specific: Report ReactOS version, NtBuildLab information and reported NT kernel version */ Status = RtlStringCbPrintfA(EndBuffer, Remaining, (PCHAR)MsgEntry->Text, KERNEL_VERSION_STR, NtBuildLab, StringBuffer, NtBuildNumber & 0xFFFF, BeginBuffer); if (!NT_SUCCESS(Status)) { /* Bugcheck */ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); } } else { /* Use hard-coded banner message */ Status = RtlStringCbCopyA(EndBuffer, Remaining, "REACTOS (R)\r\n"); if (!NT_SUCCESS(Status)) { /* Bugcheck */ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 7, 0, 0); } }
/* Display the version string on-screen */ InbvDisplayString(EndBuffer);
/* Initialize Power Subsystem in Phase 0 */ if (!PoInitSystem(0)) KeBugCheck(INTERNAL_POWER_ERROR);
/* Check for Y2K hack */ Y2KHackRequired = CommandLine ? strstr(CommandLine, "YEAR") : NULL; if (Y2KHackRequired) Y2KHackRequired = strstr(Y2KHackRequired, "="); if (Y2KHackRequired) YearHack = atol(Y2KHackRequired + 1);
/* Query the clock */ if ((ExCmosClockIsSane) && (HalQueryRealTimeClock(&TimeFields))) { /* Check if we're using the Y2K hack */ if (Y2KHackRequired) TimeFields.Year = (CSHORT)YearHack;
/* Convert to time fields */ RtlTimeFieldsToTime(&TimeFields, &SystemBootTime); UniversalBootTime = SystemBootTime;
/* Check if real time is GMT */ if (!ExpRealTimeIsUniversal) { /* Check if we don't have a valid bias */ if (ExpLastTimeZoneBias == MAXULONG) { /* Reset */ ResetBias = TRUE; ExpLastTimeZoneBias = ExpAltTimeZoneBias; }
/* Calculate the bias in seconds */ ExpTimeZoneBias.QuadPart = Int32x32To64(ExpLastTimeZoneBias * 60, 10000000);
/* Set the boot time-zone bias */ SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.HighPart; SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.LowPart; SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.HighPart;
/* Convert the boot time to local time, and set it */ UniversalBootTime.QuadPart = SystemBootTime.QuadPart + ExpTimeZoneBias.QuadPart; }
/* Update the system time and notify the system */ KeSetSystemTime(&UniversalBootTime, &OldTime, FALSE, NULL); PoNotifySystemTimeSet();
/* Remember this as the boot time */ KeBootTime = UniversalBootTime; KeBootTimeBias = 0; }
#ifdef CONFIG_SMP /* * IMPORTANT NOTE: * Because ReactOS is a "nice" OS, we do not care _at all_ * about any number of registered/licensed processors: * no usage of KeRegisteredProcessors nor KeLicensedProcessors. */ if (CommandLine) { PSTR Option;
/* Check for NUMPROC: maximum number of logical processors * that can be started (including dynamically) at run-time */ Option = strstr(CommandLine, "NUMPROC"); if (Option) Option = strstr(Option, "="); if (Option) KeNumprocSpecified = atol(Option + 1);
/* Check for BOOTPROC (NT6+ and ReactOS): maximum number * of logical processors that can be started at boot-time */ Option = strstr(CommandLine, "BOOTPROC"); if (Option) Option = strstr(Option, "="); if (Option) KeBootprocSpecified = atol(Option + 1);
/* Check for MAXPROC (NT6+ and ReactOS): forces the kernel to report * as existing the maximum number of processors that can be handled */ if (strstr(CommandLine, "MAXPROC")) KeMaximumProcessors = MAXIMUM_PROCESSORS; }
/* Start Application Processors */ KeStartAllProcessors();#endif
/* Initialize all processors */ if (!HalAllProcessorsStarted()) KeBugCheck(HAL1_INITIALIZATION_FAILED);
#ifdef CONFIG_SMP /* HACK: We should use RtlFindMessage and not only fallback to this */ MpString = "MultiProcessor Kernel\r\n";#endif
/* Setup the "MP" String */ RtlInitAnsiString(&TempString, MpString);
/* Make sure to remove the \r\n if we actually have a string */ while ((TempString.Length > 0) && ((TempString.Buffer[TempString.Length - 1] == '\r') || (TempString.Buffer[TempString.Length - 1] == '\n'))) { /* Skip the trailing character */ TempString.Length--; }
/* Get the information string from our resource file */ MsgStatus = RtlFindMessage(NtosEntry->DllBase, RT_MESSAGETABLE, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), KeNumberProcessors > 1 ? WINDOWS_NT_INFO_STRING_PLURAL : WINDOWS_NT_INFO_STRING, &MsgEntry);
/* Get total RAM size, in MiB */ /* Round size up. Assumed to better match actual physical RAM size */ Size = ALIGN_UP_BY(MmNumberOfPhysicalPages * PAGE_SIZE, 1024 * 1024) / (1024 * 1024);
/* Create the string */ StringBuffer = InitBuffer->VersionBuffer; Status = RtlStringCbPrintfA(StringBuffer, sizeof(InitBuffer->VersionBuffer), NT_SUCCESS(MsgStatus) ? (PCHAR)MsgEntry->Text : "%u System Processor [%Iu MB Memory] %Z\r\n", KeNumberProcessors, Size, &TempString); if (!NT_SUCCESS(Status)) { /* Bugcheck */ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 4, 0, 0); }
/* Display RAM and CPU count */ InbvDisplayString(StringBuffer);
/* Update the progress bar */ InbvUpdateProgressBar(5);
/* Call OB initialization again */ if (!ObInitSystem()) KeBugCheck(OBJECT1_INITIALIZATION_FAILED);
/* Initialize Basic System Objects and Worker Threads */ if (!ExInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 1, 0);
/* Initialize the later stages of the kernel */ if (!KeInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 2, 0);
/* Call KD Providers at Phase 1 */ if (!KdInitSystem(ExpInitializationPhase, KeLoaderBlock)) { /* Failed, bugcheck */ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 3, 0); }
/* Initialize the SRM in Phase 1 */ if (!SeInitSystem()) KeBugCheck(SECURITY1_INITIALIZATION_FAILED);
/* Update the progress bar */ InbvUpdateProgressBar(10);
/* Create SystemRoot Link */ Status = ExpCreateSystemRootLink(LoaderBlock); if (!NT_SUCCESS(Status)) { /* Failed to create the system root link */ KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 0, 0, 0); }
/* Set up Region Maps, Sections and the Paging File */ if (!MmInitSystem(1, LoaderBlock)) KeBugCheck(MEMORY1_INITIALIZATION_FAILED);
/* Create NLS section */ ExpInitNls(LoaderBlock);
/* Initialize Cache Views */ if (!CcInitializeCacheManager()) KeBugCheck(CACHE_INITIALIZATION_FAILED);
/* Initialize the Registry */ if (!CmInitSystem1()) KeBugCheck(CONFIG_INITIALIZATION_FAILED);
/* Initialize Prefetcher */ CcPfInitializePrefetcher();
/* Update progress bar */ InbvUpdateProgressBar(15);
/* Update timezone information */ LastTzBias = ExpLastTimeZoneBias; ExRefreshTimeZoneInformation(&SystemBootTime);
/* Check if we're resetting timezone data */ if (ResetBias) { /* Convert the local time to system time */ ExLocalTimeToSystemTime(&SystemBootTime, &UniversalBootTime); KeBootTime = UniversalBootTime; KeBootTimeBias = 0;
/* Set the new time */ KeSetSystemTime(&UniversalBootTime, &OldTime, FALSE, NULL); } else { /* Check if the timezone switched and update the time */ if (LastTzBias != ExpLastTimeZoneBias) ZwSetSystemTime(NULL, NULL); }
/* Initialize the File System Runtime Library */ if (!FsRtlInitSystem()) KeBugCheck(FILE_INITIALIZATION_FAILED);
/* Initialize range lists */ RtlInitializeRangeListPackage();
/* Report all resources used by HAL */ HalReportResourceUsage();
/* Call the debugger DLL */ KdDebuggerInitialize1(LoaderBlock);
/* Setup PnP Manager in phase 1 */ if (!PpInitSystem()) KeBugCheck(PP1_INITIALIZATION_FAILED);
/* Update progress bar */ InbvUpdateProgressBar(20);
/* Initialize LPC */ if (!LpcInitSystem()) KeBugCheck(LPC_INITIALIZATION_FAILED);
/* Make sure we have a command line */ if (CommandLine) { /* Check if this is a safe mode boot */ SafeBoot = strstr(CommandLine, "SAFEBOOT:"); if (SafeBoot) { /* Check what kind of boot this is */ SafeBoot += 9; if (!strncmp(SafeBoot, "MINIMAL", 7)) { /* Minimal mode */ InitSafeBootMode = 1; SafeBoot += 7; MessageCode = BOOTING_IN_SAFEMODE_MINIMAL; } else if (!strncmp(SafeBoot, "NETWORK", 7)) { /* With Networking */ InitSafeBootMode = 2; SafeBoot += 7; MessageCode = BOOTING_IN_SAFEMODE_NETWORK; } else if (!strncmp(SafeBoot, "DSREPAIR", 8)) { /* Domain Server Repair */ InitSafeBootMode = 3; SafeBoot += 8; MessageCode = BOOTING_IN_SAFEMODE_DSREPAIR;
} else { /* Invalid */ InitSafeBootMode = 0; }
/* Check if there's any settings left */ if (*SafeBoot) { /* Check if an alternate shell was requested */ if (!strncmp(SafeBoot, "(ALTERNATESHELL)", 16)) { /* Remember this for later */ AlternateShell = TRUE; } }
/* Find the message to print out */ Status = RtlFindMessage(NtosEntry->DllBase, RT_MESSAGETABLE, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), MessageCode, &MsgEntry); if (NT_SUCCESS(Status)) { /* Display it */ InbvDisplayString((PCSTR)MsgEntry->Text); } } }
/* Make sure we have a command line */ if (CommandLine) { /* Check if bootlogging is enabled */ if (strstr(CommandLine, "BOOTLOG")) { /* Find the message to print out */ Status = RtlFindMessage(NtosEntry->DllBase, RT_MESSAGETABLE, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), BOOTLOG_ENABLED, &MsgEntry); if (NT_SUCCESS(Status)) { /* Display it */ InbvDisplayString((PCSTR)MsgEntry->Text); }
/* Setup boot logging */ //IopInitializeBootLogging(LoaderBlock, InitBuffer->BootlogHeader); } }
/* Setup the Executive in Phase 2 */ //ExInitSystemPhase2();
/* Update progress bar */ InbvUpdateProgressBar(25);
/* No KD Time Slip is pending */ KdpTimeSlipPending = 0;
/* Initialize in-place execution support */ XIPInit(LoaderBlock);
/* Set maximum update to 75% */ InbvSetProgressBarSubset(25, 75);
/* Initialize the I/O Subsystem */ if (!IoInitSystem(LoaderBlock)) KeBugCheck(IO1_INITIALIZATION_FAILED);
/* Set maximum update to 100% */ InbvSetProgressBarSubset(0, 100);
/* Are we in safe mode? */ if (InitSafeBootMode) { /* Open the safe boot key */ RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET" L"\\CONTROL\\SAFEBOOT"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); if (NT_SUCCESS(Status)) { /* First check if we have an alternate shell */ if (AlternateShell) { /* Make sure that the registry has one setup */ RtlInitUnicodeString(&KeyName, L"AlternateShell"); Status = NtQueryValueKey(KeyHandle, &KeyName, KeyValuePartialInformation, &KeyPartialInfo, sizeof(KeyPartialInfo), &Length); if (!(NT_SUCCESS(Status) || Status == STATUS_BUFFER_OVERFLOW)) { AlternateShell = FALSE; } }
/* Create the option key */ RtlInitUnicodeString(&KeyName, L"Option"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, KeyHandle, NULL); Status = ZwCreateKey(&OptionHandle, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, &Disposition); NtClose(KeyHandle);
/* Check if the key create worked */ if (NT_SUCCESS(Status)) { /* Write the safe boot type */ RtlInitUnicodeString(&KeyName, L"OptionValue"); NtSetValueKey(OptionHandle, &KeyName, 0, REG_DWORD, &InitSafeBootMode, sizeof(InitSafeBootMode));
/* Check if we have to use an alternate shell */ if (AlternateShell) { /* Remember this for later */ Disposition = TRUE; RtlInitUnicodeString(&KeyName, L"UseAlternateShell"); NtSetValueKey(OptionHandle, &KeyName, 0, REG_DWORD, &Disposition, sizeof(Disposition)); }
/* Close the options key handle */ NtClose(OptionHandle); } } }
/* Are we in Win PE mode? */ if (InitIsWinPEMode) { /* Open the safe control key */ RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET" L"\\CONTROL"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { /* Bugcheck */ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 6, 0, 0); }
/* Create the MiniNT key */ RtlInitUnicodeString(&KeyName, L"MiniNT"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, KeyHandle, NULL); Status = ZwCreateKey(&OptionHandle, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE, &Disposition); if (!NT_SUCCESS(Status)) { /* Bugcheck */ KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 6, 0, 0); }
/* Close the handles */ NtClose(KeyHandle); NtClose(OptionHandle); }
/* FIXME: This doesn't do anything for now */ MmArmInitSystem(2, LoaderBlock);
/* Update progress bar */ InbvUpdateProgressBar(80);
/* Initialize VDM support */#if defined(_M_IX86) KeI386VdmInitialize();#endif
/* Initialize Power Subsystem in Phase 1*/ if (!PoInitSystem(1)) KeBugCheck(INTERNAL_POWER_ERROR);
/* Update progress bar */ InbvUpdateProgressBar(90);
/* Initialize the Process Manager at Phase 1 */ if (!PsInitSystem(LoaderBlock)) KeBugCheck(PROCESS1_INITIALIZATION_FAILED);
/* Make sure nobody touches the loader block again */ if (LoaderBlock == KeLoaderBlock) KeLoaderBlock = NULL; MmFreeLoaderBlock(LoaderBlock); LoaderBlock = Context = NULL;
/* Initialize the SRM in phase 1 */ if (!SeRmInitPhase1()) KeBugCheck(PROCESS1_INITIALIZATION_FAILED);
/* Update progress bar */ InbvUpdateProgressBar(100);
/* Clear the screen */ if (InbvBootDriverInstalled) FinalizeBootLogo();
/* Allow strings to be displayed */ InbvEnableDisplayString(TRUE);
/* Launch initial process */ ProcessInfo = &InitBuffer->ProcessInfo; ExpLoadInitialProcess(InitBuffer, &ProcessParameters, &Environment);
/* Wait 5 seconds for initial process to initialize */ Timeout.QuadPart = Int32x32To64(5, -10000000); Status = ZwWaitForSingleObject(ProcessInfo->ProcessHandle, FALSE, &Timeout); if (Status == STATUS_SUCCESS) { /* Failed, display error */ DPRINT1("INIT: Session Manager terminated.\n");
/* Bugcheck the system if SMSS couldn't initialize */ KeBugCheck(SESSION5_INITIALIZATION_FAILED); }
/* Close process handles */ ZwClose(ProcessInfo->ThreadHandle); ZwClose(ProcessInfo->ProcessHandle);
/* Free the initial process environment */ Size = 0; ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID*)&Environment, &Size, MEM_RELEASE);
/* Free the initial process parameters */ Size = 0; ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID*)&ProcessParameters, &Size, MEM_RELEASE);
/* Increase init phase */ ExpInitializationPhase++;
/* Free the boot buffer */ ExFreePoolWithTag(InitBuffer, TAG_INIT);}
VOIDNTAPIPhase1Initialization(IN PVOID Context){ /* Do the .INIT part of Phase 1 which we can free later */ Phase1InitializationDiscard(Context);
/* Jump into zero page thread */ MmZeroPageThread();}