static VOID SetupLdrScanBootDrivers(PLIST_ENTRY BootDriverListHead, HINF InfHandle, LPCSTR SearchPath) { INFCONTEXT InfContext, dirContext; BOOLEAN Status; LPCSTR Media, DriverName, dirIndex, ImagePath; WCHAR ServiceName[256]; WCHAR ImagePathW[256]; /* Open inf section */ if (!InfFindFirstLine(InfHandle, "SourceDisksFiles", NULL, &InfContext)) return; /* Load all listed boot drivers */ do { if (InfGetDataField(&InfContext, 7, &Media) && InfGetDataField(&InfContext, 0, &DriverName) && InfGetDataField(&InfContext, 13, &dirIndex)) { if ((strcmp(Media, "x") == 0) && InfFindFirstLine(InfHandle, "Directories", dirIndex, &dirContext) && InfGetDataField(&dirContext, 1, &ImagePath)) { /* Convert name to widechar */ swprintf(ServiceName, L"%S", DriverName); /* Prepare image path */ swprintf(ImagePathW, L"%S", ImagePath); wcscat(ImagePathW, L"\\"); wcscat(ImagePathW, ServiceName); /* Remove .sys extension */ ServiceName[wcslen(ServiceName) - 4] = 0; /* Add it to the list */ Status = WinLdrAddDriverToList(BootDriverListHead, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", ImagePathW, ServiceName); if (!Status) { ERR("could not add boot driver %s, %s\n", SearchPath, DriverName); return; } } } } while (InfFindNextLine(&InfContext, &InfContext)); }
VOID WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN LPCSTR DirectoryPath) { LONG rc = 0; FRLDRHKEY hGroupKey, hOrderKey, hServiceKey, hDriverKey; LPWSTR GroupNameBuffer; WCHAR ServiceName[256]; ULONG OrderList[128]; ULONG BufferSize; ULONG Index; ULONG TagIndex; LPWSTR GroupName; ULONG ValueSize; ULONG ValueType; ULONG StartValue; ULONG TagValue; WCHAR DriverGroup[256]; ULONG DriverGroupSize; CHAR ImagePath[256]; WCHAR TempImagePath[256]; BOOLEAN Status; /* get 'service group order' key */ rc = RegOpenKey(NULL, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder", &hGroupKey); if (rc != ERROR_SUCCESS) { TRACE_CH(ODYSSEY, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc); return; } /* get 'group order list' key */ rc = RegOpenKey(NULL, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList", &hOrderKey); if (rc != ERROR_SUCCESS) { TRACE_CH(ODYSSEY, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc); return; } /* enumerate drivers */ rc = RegOpenKey(NULL, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services", &hServiceKey); if (rc != ERROR_SUCCESS) { TRACE_CH(ODYSSEY, "Failed to open the 'Services' key (rc %d)\n", (int)rc); return; } /* Get the Name Group */ BufferSize = 4096; GroupNameBuffer = MmHeapAlloc(BufferSize); rc = RegQueryValue(hGroupKey, L"List", NULL, (PUCHAR)GroupNameBuffer, &BufferSize); TRACE_CH(ODYSSEY, "RegQueryValue(): rc %d\n", (int)rc); if (rc != ERROR_SUCCESS) return; TRACE_CH(ODYSSEY, "BufferSize: %d \n", (int)BufferSize); TRACE_CH(ODYSSEY, "GroupNameBuffer: '%S' \n", GroupNameBuffer); /* Loop through each group */ GroupName = GroupNameBuffer; while (*GroupName) { TRACE("Driver group: '%S'\n", GroupName); /* Query the Order */ BufferSize = sizeof(OrderList); rc = RegQueryValue(hOrderKey, GroupName, NULL, (PUCHAR)OrderList, &BufferSize); if (rc != ERROR_SUCCESS) OrderList[0] = 0; /* enumerate all drivers */ for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) { Index = 0; while (TRUE) { /* Get the Driver's Name */ ValueSize = sizeof(ServiceName); rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize); //TRACE_CH(ODYSSEY, "RegEnumKey(): rc %d\n", (int)rc); /* Makre sure it's valid, and check if we're done */ if (rc == ERROR_NO_MORE_ITEMS) break; if (rc != ERROR_SUCCESS) { MmHeapFree(GroupNameBuffer); return; } //TRACE_CH(ODYSSEY, "Service %d: '%S'\n", (int)Index, ServiceName); /* open driver Key */ rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey); if (rc == ERROR_SUCCESS) { /* Read the Start Value */ ValueSize = sizeof(ULONG); rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize); if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1; //TRACE_CH(ODYSSEY, " Start: %x \n", (int)StartValue); /* Read the Tag */ ValueSize = sizeof(ULONG); rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize); if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1; //TRACE_CH(ODYSSEY, " Tag: %x \n", (int)TagValue); /* Read the driver's group */ DriverGroupSize = sizeof(DriverGroup); rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize); //TRACE_CH(ODYSSEY, " Group: '%S' \n", DriverGroup); /* Make sure it should be started */ if ((StartValue == 0) && (TagValue == OrderList[TagIndex]) && (_wcsicmp(DriverGroup, GroupName) == 0)) { /* Get the Driver's Location */ ValueSize = sizeof(TempImagePath); rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize); /* Write the whole path if it suceeded, else prepare to fail */ if (rc != ERROR_SUCCESS) { TRACE_CH(ODYSSEY, "ImagePath: not found\n"); TempImagePath[0] = 0; sprintf(ImagePath, "%s\\system32\\drivers\\%S.sys", DirectoryPath, ServiceName); } else if (TempImagePath[0] != L'\\') { sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath); } else { sprintf(ImagePath, "%S", TempImagePath); TRACE_CH(ODYSSEY, "ImagePath: '%s'\n", ImagePath); } TRACE("Adding boot driver: '%s'\n", ImagePath); Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", TempImagePath, ServiceName); if (!Status) ERR("Failed to add boot driver\n"); } else { //TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n", // ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName); } } Index++; } } Index = 0; while (TRUE) { /* Get the Driver's Name */ ValueSize = sizeof(ServiceName); rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize); //TRACE_CH(ODYSSEY, "RegEnumKey(): rc %d\n", (int)rc); if (rc == ERROR_NO_MORE_ITEMS) break; if (rc != ERROR_SUCCESS) { MmHeapFree(GroupNameBuffer); return; } //TRACE_CH(ODYSSEY, "Service %d: '%S'\n", (int)Index, ServiceName); /* open driver Key */ rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey); if (rc == ERROR_SUCCESS) { /* Read the Start Value */ ValueSize = sizeof(ULONG); rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize); if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1; //TRACE_CH(ODYSSEY, " Start: %x \n", (int)StartValue); /* Read the Tag */ ValueSize = sizeof(ULONG); rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize); if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1; //TRACE_CH(ODYSSEY, " Tag: %x \n", (int)TagValue); /* Read the driver's group */ DriverGroupSize = sizeof(DriverGroup); rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize); //TRACE_CH(ODYSSEY, " Group: '%S' \n", DriverGroup); for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) { if (TagValue == OrderList[TagIndex]) break; } if ((StartValue == 0) && (TagIndex > OrderList[0]) && (_wcsicmp(DriverGroup, GroupName) == 0)) { ValueSize = sizeof(TempImagePath); rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize); if (rc != ERROR_SUCCESS) { TRACE_CH(ODYSSEY, "ImagePath: not found\n"); TempImagePath[0] = 0; sprintf(ImagePath, "%ssystem32\\drivers\\%S.sys", DirectoryPath, ServiceName); } else if (TempImagePath[0] != L'\\') { sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath); } else { sprintf(ImagePath, "%S", TempImagePath); TRACE_CH(ODYSSEY, "ImagePath: '%s'\n", ImagePath); } TRACE(" Adding boot driver: '%s'\n", ImagePath); Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", TempImagePath, ServiceName); if (!Status) ERR(" Failed to add boot driver\n"); } else { //TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n", // ServiceName, StartValue, TagValue, DriverGroup, GroupName); } } Index++; } /* Move to the next group name */ GroupName = GroupName + wcslen(GroupName) + 1; } /* Free allocated memory */ MmHeapFree(GroupNameBuffer); }
BOOLEAN WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN LPCSTR DirectoryPath, IN LPCSTR HiveName) { ULONG FileId; CHAR FullHiveName[256]; LONG Status; FILEINFORMATION FileInfo; ULONG HiveFileSize; ULONG_PTR HiveDataPhysical; PVOID HiveDataVirtual; ULONG BytesRead; LPCWSTR FsService; /* Concatenate path and filename to get the full name */ strcpy(FullHiveName, DirectoryPath); strcat(FullHiveName, HiveName); //Print(L"Loading %s...\n", FullHiveName); Status = ArcOpen(FullHiveName, OpenReadOnly, &FileId); if (Status != ESUCCESS) { UiMessageBox("Opening hive file failed!"); return FALSE; } /* Get the file length */ Status = ArcGetFileInformation(FileId, &FileInfo); if (Status != ESUCCESS) { ArcClose(FileId); UiMessageBox("Hive file has 0 size!"); return FALSE; } HiveFileSize = FileInfo.EndingAddress.LowPart; /* Round up the size to page boundary and alloc memory */ HiveDataPhysical = (ULONG_PTR)MmAllocateMemoryWithType( MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT, LoaderRegistryData); if (HiveDataPhysical == 0) { ArcClose(FileId); UiMessageBox("Unable to alloc memory for a hive!"); return FALSE; } /* Convert address to virtual */ HiveDataVirtual = PaToVa((PVOID)HiveDataPhysical); /* Fill LoaderBlock's entries */ LoaderBlock->RegistryLength = HiveFileSize; LoaderBlock->RegistryBase = HiveDataVirtual; /* Finally read from file to the memory */ Status = ArcRead(FileId, (PVOID)HiveDataPhysical, HiveFileSize, &BytesRead); if (Status != ESUCCESS) { ArcClose(FileId); UiMessageBox("Unable to read from hive file!"); return FALSE; } // Add boot filesystem driver to the list FsService = FsGetServiceName(FileId); if (FsService) { TRACE(" Adding filesystem service %S\n", FsService); Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", NULL, (LPWSTR)FsService); if (!Status) TRACE(" Failed to add filesystem service\n"); } else { TRACE(" No required filesystem service\n"); } ArcClose(FileId); return TRUE; }