diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index 73bac3bcaf7..f7d04c116d2 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.60 2000/08/30 19:33:28 dwelch Exp $ +/* $Id: main.c,v 1.61 2000/08/31 00:11:15 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -23,12 +23,13 @@ #include #include #include +#include #include #include #include -//#define NDEBUG +#define NDEBUG #include /* DATA *********************************************************************/ @@ -40,21 +41,311 @@ LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock; /* FUNCTIONS ****************************************************************/ -static VOID CreateSystemRootLink (LPWSTR Device) +static VOID +CreateSystemRootLink (PCSZ ParameterLine) { UNICODE_STRING LinkName; UNICODE_STRING DeviceName; + UNICODE_STRING ArcName; + UNICODE_STRING BootPath; + PCHAR ParamBuffer; + PWCHAR ArcNameBuffer; + PCHAR p; + NTSTATUS Status; + ULONG Length; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE Handle; + /* create local parameter line copy */ + ParamBuffer = ExAllocatePool (PagedPool, 256); + strcpy (ParamBuffer, (char *)ParameterLine); + + DPRINT("%s\n", ParamBuffer); + /* Format: \ [options...] */ + + /* cut options off */ + p = strchr (ParamBuffer, ' '); + if (p) + *p = 0; + DPRINT("%s\n", ParamBuffer); + + /* extract path */ + p = strchr (ParamBuffer, '\\'); + if (p) + { + DPRINT("Boot path: %s\n", p); + RtlCreateUnicodeStringFromAsciiz (&BootPath, p); + *p = 0; + } + else + { + DPRINT("Boot path: %s\n", "\\"); + RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\"); + } + DPRINT("Arc name: %s\n", ParamBuffer); + + /* Only arc name left - build full arc name */ + ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR)); + swprintf (ArcNameBuffer, + L"\\ArcName\\%S", ParamBuffer); + RtlInitUnicodeString (&ArcName, ArcNameBuffer); + DPRINT("Arc name: %wZ\n", &ArcName); + + /* free ParamBuffer */ + ExFreePool (ParamBuffer); + + /* allocate device name string */ + DeviceName.Length = 0; + DeviceName.MaximumLength = 256 * sizeof(WCHAR); + DeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR)); + + InitializeObjectAttributes (&ObjectAttributes, + &ArcName, + 0, + NULL, + NULL); + + Status = NtOpenSymbolicLinkObject (&Handle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes); + RtlFreeUnicodeString (&ArcName); + if (!NT_SUCCESS(Status)) + { + RtlFreeUnicodeString (&BootPath); + RtlFreeUnicodeString (&DeviceName); + DbgPrint("NtOpenSymbolicLinkObject() failed (Status %x)\n", + Status); + + KeBugCheck (0x0); + } + + Status = NtQuerySymbolicLinkObject (Handle, + &DeviceName, + &Length); + NtClose (Handle); + if (!NT_SUCCESS(Status)) + { + RtlFreeUnicodeString (&BootPath); + RtlFreeUnicodeString (&DeviceName); + DbgPrint("NtQuerySymbolicObject() failed (Status %x)\n", + Status); + + KeBugCheck (0x0); + } + DPRINT("Length: %lu DeviceName: %wZ\n", Length, &DeviceName); + + RtlAppendUnicodeStringToString (&DeviceName, + &BootPath); + + RtlFreeUnicodeString (&BootPath); + DPRINT("DeviceName: %wZ\n", &DeviceName); + + /* create the '\SystemRoot' link */ RtlInitUnicodeString (&LinkName, L"\\SystemRoot"); - RtlInitUnicodeString (&DeviceName, - Device); + Status = IoCreateSymbolicLink (&LinkName, + &DeviceName); + RtlFreeUnicodeString (&DeviceName); + if (!NT_SUCCESS(Status)) + { + DbgPrint("IoCreateSymbolicLink() failed (Status %x)\n", + Status); - IoCreateSymbolicLink (&LinkName, - &DeviceName); + KeBugCheck (0x0); + } + + /* + * FIXME: test if '\SystemRoot' (LinkName)can be opened, + * otherwise crash it! + */ } + +static VOID +InitSystemSharedUserPage (PCSZ ParameterLine) +{ + PKUSER_SHARED_DATA SharedPage; + + UNICODE_STRING ArcDeviceName; + UNICODE_STRING ArcName; + UNICODE_STRING BootPath; + UNICODE_STRING DriveDeviceName; + UNICODE_STRING DriveName; + WCHAR DriveNameBuffer[20]; + PCHAR ParamBuffer; + PWCHAR ArcNameBuffer; + PCHAR p; + NTSTATUS Status; + ULONG Length; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE Handle; + ULONG i; + BOOLEAN BootDriveFound; + + SharedPage = (PKUSER_SHARED_DATA)KERNEL_SHARED_DATA_BASE; + SharedPage->DosDeviceMap = 0; + SharedPage->NtProductType = NtProductWinNt; + for (i = 0; i < 32; i++) + { + SharedPage->DosDeviceDriveType[i] = 0; + } + + BootDriveFound = FALSE; + + /* + * Retrieve the current dos system path + * (e.g.: C:\reactos) from the given arc path + * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos) + * Format: "\ [options...]" + */ + + /* create local parameter line copy */ + ParamBuffer = ExAllocatePool (PagedPool, 256); + strcpy (ParamBuffer, (char *)ParameterLine); + DPRINT("%s\n", ParamBuffer); + + /* cut options off */ + p = strchr (ParamBuffer, ' '); + if (p) + { + *p = 0; + } + DPRINT("%s\n", ParamBuffer); + + /* extract path */ + p = strchr (ParamBuffer, '\\'); + if (p) + { + DPRINT("Boot path: %s\n", p); + RtlCreateUnicodeStringFromAsciiz (&BootPath, p); + *p = 0; + } + else + { + DPRINT("Boot path: %s\n", "\\"); + RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\"); + } + DPRINT("Arc name: %s\n", ParamBuffer); + + /* Only arc name left - build full arc name */ + ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR)); + swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer); + RtlInitUnicodeString (&ArcName, ArcNameBuffer); + DPRINT("Arc name: %wZ\n", &ArcName); + + /* free ParamBuffer */ + ExFreePool (ParamBuffer); + + /* allocate arc device name string */ + ArcDeviceName.Length = 0; + ArcDeviceName.MaximumLength = 256 * sizeof(WCHAR); + ArcDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR)); + + InitializeObjectAttributes (&ObjectAttributes, + &ArcName, + 0, + NULL, + NULL); + + Status = NtOpenSymbolicLinkObject (&Handle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes); + RtlFreeUnicodeString (&ArcName); + if (!NT_SUCCESS(Status)) + { + RtlFreeUnicodeString (&BootPath); + RtlFreeUnicodeString (&ArcDeviceName); + DbgPrint("NtOpenSymbolicLinkObject() failed (Status %x)\n", + Status); + + KeBugCheck (0x0); + } + + Status = NtQuerySymbolicLinkObject (Handle, + &ArcDeviceName, + &Length); + NtClose (Handle); + if (!NT_SUCCESS(Status)) + { + RtlFreeUnicodeString (&BootPath); + RtlFreeUnicodeString (&ArcDeviceName); + DbgPrint("NtQuerySymbolicObject() failed (Status %x)\n", + Status); + + KeBugCheck (0x0); + } + DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName); + + + /* allocate device name string */ + DriveDeviceName.Length = 0; + DriveDeviceName.MaximumLength = 256 * sizeof(WCHAR); + DriveDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR)); + + for (i = 0; i < 26; i++) + { + swprintf (DriveNameBuffer, L"\\??\\%C:", 'A' + i); + RtlInitUnicodeString (&DriveName, + DriveNameBuffer); + + InitializeObjectAttributes (&ObjectAttributes, + &DriveName, + 0, + NULL, + NULL); + + Status = NtOpenSymbolicLinkObject (&Handle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed to open link %wZ\n", + &DriveName); + continue; + } + + Status = NtQuerySymbolicLinkObject (Handle, + &DriveDeviceName, + &Length); + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed query open link %wZ\n", + &DriveName); + continue; + } + DPRINT("Opened link: %wZ ==> %wZ\n", + &DriveName, &DriveDeviceName); + + if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE)) + { + DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath); + swprintf (SharedPage->NtSystemRoot, + L"%C:%wZ", 'A' + i, &BootPath); + + BootDriveFound = TRUE; + } + + NtClose (Handle); + + /* set bit in dos drives bitmap (drive available) */ + SharedPage->DosDeviceMap |= (1<DosDeviceMap); + + if (BootDriveFound == FALSE) + { + DbgPrint("No system drive found!\n"); + KeBugCheck (0x0); + } +} + + void _main (PLOADER_PARAMETER_BLOCK LoaderBlock) /* * FUNCTION: Called by the boot loader to start the kernel @@ -78,7 +369,8 @@ void _main (PLOADER_PARAMETER_BLOCK LoaderBlock) * Initializes the kernel parameter line. * This should be done by the boot loader. */ -// strcpy (KeLoaderBlock.kernel_parameters, "/DEBUGPORT=SCREEN"); + strcpy (KeLoaderBlock.kernel_parameters, + "multi(0)disk(0)rdisk(0)partition(1)\\reactos /DEBUGPORT=SCREEN"); /* * Initialization phase 0 @@ -86,10 +378,7 @@ void _main (PLOADER_PARAMETER_BLOCK LoaderBlock) HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock); KeInit1(); KeLowerIrql(DISPATCH_LEVEL); - - DbgPrint("kernel_parameters %s\n", - KeLoaderBlock.kernel_parameters); - + /* * Display version number and copyright/warranty message */ @@ -148,34 +437,33 @@ void _main (PLOADER_PARAMETER_BLOCK LoaderBlock) */ DPRINT1("%d files loaded\n",KeLoaderBlock.nr_files); - /* Pass 1: load registry chunks passed in */ - start = KERNEL_BASE + PAGE_ROUND_UP(KeLoaderBlock.module_length[0]); - for (i = 1; i < KeLoaderBlock.nr_files; i++) - { - if (!strcmp ((PCHAR) start, "REGEDIT4")) - { - DPRINT1("process registry chunk at %08lx\n", start); - CmImportHive((PCHAR) start); - } - start = start + KeLoaderBlock.module_length[i]; - } + /* Pass 1: load registry chunks passed in */ + start = KERNEL_BASE + PAGE_ROUND_UP(KeLoaderBlock.module_length[0]); + for (i = 1; i < KeLoaderBlock.nr_files; i++) + { + if (!strcmp ((PCHAR) start, "REGEDIT4")) + { + DPRINT1("process registry chunk at %08lx\n", start); + CmImportHive((PCHAR) start); + } + start = start + KeLoaderBlock.module_length[i]; + } - /* Pass 2: process boot loaded drivers */ - start = KERNEL_BASE + PAGE_ROUND_UP(KeLoaderBlock.module_length[0]); - start1 = start + KeLoaderBlock.module_length[1]; - for (i=1;iNtSystemRoot, - L"C:\\reactos"); - - ((PKUSER_SHARED_DATA)KERNEL_SHARED_DATA_BASE)->NtProductType = NtProductWinNt; - + /* + * Initialize shared user page: + * - set dos system path, dos device map, etc. + */ + InitSystemSharedUserPage (KeLoaderBlock.kernel_parameters); /* * Launch initial process