Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenwlregistry.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: EFI Windows Loader 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: freeldr/winldr/wlregistry.c 00005 * PURPOSE: Registry support functions 00006 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) 00007 */ 00008 00009 /* INCLUDES ***************************************************************/ 00010 00011 #include <freeldr.h> 00012 #include <debug.h> 00013 00014 DBG_DEFAULT_CHANNEL(WINDOWS); 00015 00016 // The only global var here, used to mark mem pages as NLS in WinLdrSetupMemoryLayout() 00017 ULONG TotalNLSSize = 0; 00018 00019 static BOOLEAN 00020 WinLdrGetNLSNames(LPSTR AnsiName, 00021 LPSTR OemName, 00022 LPSTR LangName); 00023 00024 static VOID 00025 WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead, 00026 IN LPCSTR DirectoryPath); 00027 00028 00029 /* FUNCTIONS **************************************************************/ 00030 00031 BOOLEAN 00032 WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, 00033 IN LPCSTR DirectoryPath, 00034 IN LPCSTR HiveName) 00035 { 00036 ULONG FileId; 00037 CHAR FullHiveName[256]; 00038 LONG Status; 00039 FILEINFORMATION FileInfo; 00040 ULONG HiveFileSize; 00041 ULONG_PTR HiveDataPhysical; 00042 PVOID HiveDataVirtual; 00043 ULONG BytesRead; 00044 LPCWSTR FsService; 00045 00046 /* Concatenate path and filename to get the full name */ 00047 strcpy(FullHiveName, DirectoryPath); 00048 strcat(FullHiveName, HiveName); 00049 //Print(L"Loading %s...\n", FullHiveName); 00050 Status = ArcOpen(FullHiveName, OpenReadOnly, &FileId); 00051 00052 if (Status != ESUCCESS) 00053 { 00054 UiMessageBox("Opening hive file failed!"); 00055 return FALSE; 00056 } 00057 00058 /* Get the file length */ 00059 Status = ArcGetFileInformation(FileId, &FileInfo); 00060 00061 if (Status != ESUCCESS) 00062 { 00063 ArcClose(FileId); 00064 UiMessageBox("Hive file has 0 size!"); 00065 return FALSE; 00066 } 00067 HiveFileSize = FileInfo.EndingAddress.LowPart; 00068 00069 /* Round up the size to page boundary and alloc memory */ 00070 HiveDataPhysical = (ULONG_PTR)MmAllocateMemoryWithType( 00071 MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT, 00072 LoaderRegistryData); 00073 00074 if (HiveDataPhysical == 0) 00075 { 00076 ArcClose(FileId); 00077 UiMessageBox("Unable to alloc memory for a hive!"); 00078 return FALSE; 00079 } 00080 00081 /* Convert address to virtual */ 00082 HiveDataVirtual = PaToVa((PVOID)HiveDataPhysical); 00083 00084 /* Fill LoaderBlock's entries */ 00085 LoaderBlock->RegistryLength = HiveFileSize; 00086 LoaderBlock->RegistryBase = HiveDataVirtual; 00087 00088 /* Finally read from file to the memory */ 00089 Status = ArcRead(FileId, (PVOID)HiveDataPhysical, HiveFileSize, &BytesRead); 00090 if (Status != ESUCCESS) 00091 { 00092 ArcClose(FileId); 00093 UiMessageBox("Unable to read from hive file!"); 00094 return FALSE; 00095 } 00096 00097 // Add boot filesystem driver to the list 00098 FsService = FsGetServiceName(FileId); 00099 if (FsService) 00100 { 00101 TRACE(" Adding filesystem service %S\n", FsService); 00102 Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead, 00103 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", 00104 NULL, 00105 (LPWSTR)FsService); 00106 if (!Status) 00107 TRACE(" Failed to add filesystem service\n"); 00108 } 00109 else 00110 { 00111 TRACE(" No required filesystem service\n"); 00112 } 00113 00114 ArcClose(FileId); 00115 return TRUE; 00116 } 00117 00118 BOOLEAN WinLdrInitSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, 00119 IN LPCSTR DirectoryPath) 00120 { 00121 CHAR SearchPath[1024]; 00122 BOOLEAN Status; 00123 00124 // There is a simple logic here: try to load usual hive (system), if it 00125 // fails, then give system.alt a try, and finally try a system.sav 00126 00127 // FIXME: For now we only try system 00128 strcpy(SearchPath, DirectoryPath); 00129 strcat(SearchPath, "SYSTEM32\\CONFIG\\"); 00130 Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM"); 00131 00132 // Fail if failed... 00133 if (!Status) 00134 return FALSE; 00135 00136 // Initialize in-memory registry 00137 RegInitializeRegistry(); 00138 00139 // Import what was loaded 00140 Status = RegImportBinaryHive((PCHAR)VaToPa(LoaderBlock->RegistryBase), LoaderBlock->RegistryLength); 00141 if (!Status) 00142 { 00143 UiMessageBox("Importing binary hive failed!"); 00144 return FALSE; 00145 } 00146 00147 // Initialize the 'CurrentControlSet' link 00148 if (RegInitCurrentControlSet(FALSE) != ERROR_SUCCESS) 00149 { 00150 UiMessageBox("Initializing CurrentControlSet link failed!"); 00151 return FALSE; 00152 } 00153 00154 return TRUE; 00155 } 00156 00157 BOOLEAN WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, 00158 IN LPCSTR DirectoryPath) 00159 { 00160 CHAR SearchPath[1024]; 00161 CHAR AnsiName[256], OemName[256], LangName[256]; 00162 BOOLEAN Status; 00163 00164 // Scan registry and prepare boot drivers list 00165 WinLdrScanRegistry(&LoaderBlock->BootDriverListHead, DirectoryPath); 00166 00167 // Get names of NLS files 00168 Status = WinLdrGetNLSNames(AnsiName, OemName, LangName); 00169 if (!Status) 00170 { 00171 UiMessageBox("Getting NLS names from registry failed!"); 00172 return FALSE; 00173 } 00174 00175 TRACE("NLS data %s %s %s\n", AnsiName, OemName, LangName); 00176 00177 // Load NLS data 00178 strcpy(SearchPath, DirectoryPath); 00179 strcat(SearchPath, "SYSTEM32\\"); 00180 Status = WinLdrLoadNLSData(LoaderBlock, SearchPath, AnsiName, OemName, LangName); 00181 TRACE("NLS data loaded with status %d\n", Status); 00182 00183 /* TODO: Load OEM HAL font */ 00184 00185 00186 return TRUE; 00187 } 00188 00189 00190 /* PRIVATE FUNCTIONS ******************************************************/ 00191 00192 // Queries registry for those three file names 00193 static BOOLEAN 00194 WinLdrGetNLSNames(LPSTR AnsiName, 00195 LPSTR OemName, 00196 LPSTR LangName) 00197 { 00198 LONG rc = ERROR_SUCCESS; 00199 FRLDRHKEY hKey; 00200 WCHAR szIdBuffer[80]; 00201 WCHAR NameBuffer[80]; 00202 ULONG BufferSize; 00203 00204 /* open the codepage key */ 00205 rc = RegOpenKey(NULL, 00206 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage", 00207 &hKey); 00208 if (rc != ERROR_SUCCESS) 00209 { 00210 //strcpy(szErrorOut, "Couldn't open CodePage registry key"); 00211 return FALSE; 00212 } 00213 00214 /* get ANSI codepage */ 00215 BufferSize = sizeof(szIdBuffer); 00216 rc = RegQueryValue(hKey, L"ACP", NULL, (PUCHAR)szIdBuffer, &BufferSize); 00217 if (rc != ERROR_SUCCESS) 00218 { 00219 //strcpy(szErrorOut, "Couldn't get ACP NLS setting"); 00220 return FALSE; 00221 } 00222 00223 BufferSize = sizeof(NameBuffer); 00224 rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize); 00225 if (rc != ERROR_SUCCESS) 00226 { 00227 //strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable"); 00228 //return FALSE; 00229 wcscpy(NameBuffer, L"c_1252.nls"); // HACK: ReactOS bug #6727 00230 } 00231 sprintf(AnsiName, "%S", NameBuffer); 00232 00233 /* get OEM codepage */ 00234 BufferSize = sizeof(szIdBuffer); 00235 rc = RegQueryValue(hKey, L"OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize); 00236 if (rc != ERROR_SUCCESS) 00237 { 00238 //strcpy(szErrorOut, "Couldn't get OEMCP NLS setting"); 00239 return FALSE; 00240 } 00241 00242 BufferSize = sizeof(NameBuffer); 00243 rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize); 00244 if (rc != ERROR_SUCCESS) 00245 { 00246 //strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable"); 00247 //return FALSE; 00248 wcscpy(NameBuffer, L"c_437.nls"); // HACK: ReactOS bug #6727 00249 } 00250 sprintf(OemName, "%S", NameBuffer); 00251 00252 /* open the language key */ 00253 rc = RegOpenKey(NULL, 00254 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language", 00255 &hKey); 00256 if (rc != ERROR_SUCCESS) 00257 { 00258 //strcpy(szErrorOut, "Couldn't open Language registry key"); 00259 return FALSE; 00260 } 00261 00262 /* get the Unicode case table */ 00263 BufferSize = sizeof(szIdBuffer); 00264 rc = RegQueryValue(hKey, L"Default", NULL, (PUCHAR)szIdBuffer, &BufferSize); 00265 if (rc != ERROR_SUCCESS) 00266 { 00267 //strcpy(szErrorOut, "Couldn't get Language Default setting"); 00268 return FALSE; 00269 } 00270 00271 BufferSize = sizeof(NameBuffer); 00272 rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize); 00273 if (rc != ERROR_SUCCESS) 00274 { 00275 //strcpy(szErrorOut, "Language Default setting exists, but isn't readable"); 00276 return FALSE; 00277 } 00278 sprintf(LangName, "%S", NameBuffer); 00279 00280 return TRUE; 00281 } 00282 00283 00284 BOOLEAN 00285 WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, 00286 IN LPCSTR DirectoryPath, 00287 IN LPCSTR AnsiFileName, 00288 IN LPCSTR OemFileName, 00289 IN LPCSTR LanguageFileName) 00290 { 00291 CHAR FileName[255]; 00292 ULONG AnsiFileId; 00293 ULONG OemFileId; 00294 ULONG LanguageFileId; 00295 ULONG AnsiFileSize, OemFileSize, LanguageFileSize; 00296 ULONG TotalSize; 00297 ULONG_PTR NlsDataBase; 00298 PVOID NlsVirtual; 00299 BOOLEAN AnsiEqualsOem = FALSE; 00300 FILEINFORMATION FileInfo; 00301 ULONG BytesRead, Status; 00302 00303 /* There may be a case, when OEM and ANSI page coincide */ 00304 if (!strcmp(AnsiFileName, OemFileName)) 00305 AnsiEqualsOem = TRUE; 00306 00307 /* Open file with ANSI and store its size */ 00308 //Print(L"Loading %s...\n", Filename); 00309 strcpy(FileName, DirectoryPath); 00310 strcat(FileName, AnsiFileName); 00311 Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId); 00312 00313 if (Status != ESUCCESS) 00314 goto Failure; 00315 00316 Status = ArcGetFileInformation(AnsiFileId, &FileInfo); 00317 if (Status != ESUCCESS) 00318 goto Failure; 00319 AnsiFileSize = FileInfo.EndingAddress.LowPart; 00320 TRACE("AnsiFileSize: %d\n", AnsiFileSize); 00321 ArcClose(AnsiFileId); 00322 00323 /* Open OEM file and store its length */ 00324 if (AnsiEqualsOem) 00325 { 00326 OemFileSize = 0; 00327 } 00328 else 00329 { 00330 //Print(L"Loading %s...\n", Filename); 00331 strcpy(FileName, DirectoryPath); 00332 strcat(FileName, OemFileName); 00333 Status = ArcOpen(FileName, OpenReadOnly, &OemFileId); 00334 00335 if (Status != ESUCCESS) 00336 goto Failure; 00337 00338 Status = ArcGetFileInformation(OemFileId, &FileInfo); 00339 if (Status != ESUCCESS) 00340 goto Failure; 00341 OemFileSize = FileInfo.EndingAddress.LowPart; 00342 ArcClose(OemFileId); 00343 } 00344 TRACE("OemFileSize: %d\n", OemFileSize); 00345 00346 /* And finally open the language codepage file and store its length */ 00347 //Print(L"Loading %s...\n", Filename); 00348 strcpy(FileName, DirectoryPath); 00349 strcat(FileName, LanguageFileName); 00350 Status = ArcOpen(FileName, OpenReadOnly, &LanguageFileId); 00351 00352 if (Status != ESUCCESS) 00353 goto Failure; 00354 00355 Status = ArcGetFileInformation(LanguageFileId, &FileInfo); 00356 if (Status != ESUCCESS) 00357 goto Failure; 00358 LanguageFileSize = FileInfo.EndingAddress.LowPart; 00359 ArcClose(LanguageFileId); 00360 TRACE("LanguageFileSize: %d\n", LanguageFileSize); 00361 00362 /* Sum up all three length, having in mind that every one of them 00363 must start at a page boundary => thus round up each file to a page */ 00364 TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) + 00365 MM_SIZE_TO_PAGES(OemFileSize) + 00366 MM_SIZE_TO_PAGES(LanguageFileSize); 00367 00368 /* Store it for later marking the pages as NlsData type */ 00369 TotalNLSSize = TotalSize; 00370 00371 NlsDataBase = (ULONG_PTR)MmAllocateMemoryWithType(TotalSize*MM_PAGE_SIZE, LoaderNlsData); 00372 00373 if (NlsDataBase == 0) 00374 goto Failure; 00375 00376 NlsVirtual = PaToVa((PVOID)NlsDataBase); 00377 LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual; 00378 LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual + 00379 (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT)); 00380 LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual + 00381 (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) + 00382 (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT)); 00383 00384 /* Ansi and OEM data are the same - just set pointers to the same area */ 00385 if (AnsiEqualsOem) 00386 LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData; 00387 00388 00389 /* Now actually read the data into memory, starting with Ansi file */ 00390 strcpy(FileName, DirectoryPath); 00391 strcat(FileName, AnsiFileName); 00392 Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId); 00393 00394 if (Status != ESUCCESS) 00395 goto Failure; 00396 00397 Status = ArcRead(AnsiFileId, VaToPa(LoaderBlock->NlsData->AnsiCodePageData), AnsiFileSize, &BytesRead); 00398 00399 if (Status != ESUCCESS) 00400 goto Failure; 00401 00402 ArcClose(AnsiFileId); 00403 00404 /* OEM now, if it doesn't equal Ansi of course */ 00405 if (!AnsiEqualsOem) 00406 { 00407 strcpy(FileName, DirectoryPath); 00408 strcat(FileName, OemFileName); 00409 Status = ArcOpen(FileName, OpenReadOnly, &OemFileId); 00410 00411 if (Status != ESUCCESS) 00412 goto Failure; 00413 00414 Status = ArcRead(OemFileId, VaToPa(LoaderBlock->NlsData->OemCodePageData), OemFileSize, &BytesRead); 00415 00416 if (Status != ESUCCESS) 00417 goto Failure; 00418 00419 ArcClose(OemFileId); 00420 } 00421 00422 /* finally the language file */ 00423 strcpy(FileName, DirectoryPath); 00424 strcat(FileName, LanguageFileName); 00425 Status = ArcOpen(FileName, OpenReadOnly, &LanguageFileId); 00426 00427 if (Status != ESUCCESS) 00428 goto Failure; 00429 00430 Status = ArcRead(LanguageFileId, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData), LanguageFileSize, &BytesRead); 00431 00432 if (Status != ESUCCESS) 00433 goto Failure; 00434 00435 ArcClose(LanguageFileId); 00436 00437 // 00438 // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK 00439 // Should go to WinLdrLoadOemHalFont(), when it will be implemented 00440 // 00441 LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData); 00442 00443 /* Convert NlsTables address to VA */ 00444 LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData); 00445 00446 return TRUE; 00447 00448 Failure: 00449 //UiMessageBox("Error reading NLS file %s\n", Filename); 00450 UiMessageBox("Error reading NLS file!"); 00451 return FALSE; 00452 } 00453 00454 static VOID 00455 WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead, 00456 IN LPCSTR DirectoryPath) 00457 { 00458 LONG rc = 0; 00459 FRLDRHKEY hGroupKey, hOrderKey, hServiceKey, hDriverKey; 00460 LPWSTR GroupNameBuffer; 00461 WCHAR ServiceName[256]; 00462 ULONG OrderList[128]; 00463 ULONG BufferSize; 00464 ULONG Index; 00465 ULONG TagIndex; 00466 LPWSTR GroupName; 00467 00468 ULONG ValueSize; 00469 ULONG ValueType; 00470 ULONG StartValue; 00471 ULONG TagValue; 00472 WCHAR DriverGroup[256]; 00473 ULONG DriverGroupSize; 00474 00475 CHAR ImagePath[256]; 00476 WCHAR TempImagePath[256]; 00477 00478 BOOLEAN Status; 00479 00480 /* get 'service group order' key */ 00481 rc = RegOpenKey(NULL, 00482 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder", 00483 &hGroupKey); 00484 if (rc != ERROR_SUCCESS) { 00485 00486 TRACE_CH(REACTOS, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc); 00487 return; 00488 } 00489 00490 /* get 'group order list' key */ 00491 rc = RegOpenKey(NULL, 00492 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList", 00493 &hOrderKey); 00494 if (rc != ERROR_SUCCESS) { 00495 00496 TRACE_CH(REACTOS, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc); 00497 return; 00498 } 00499 00500 /* enumerate drivers */ 00501 rc = RegOpenKey(NULL, 00502 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services", 00503 &hServiceKey); 00504 if (rc != ERROR_SUCCESS) { 00505 00506 TRACE_CH(REACTOS, "Failed to open the 'Services' key (rc %d)\n", (int)rc); 00507 return; 00508 } 00509 00510 /* Get the Name Group */ 00511 BufferSize = 4096; 00512 GroupNameBuffer = MmHeapAlloc(BufferSize); 00513 rc = RegQueryValue(hGroupKey, L"List", NULL, (PUCHAR)GroupNameBuffer, &BufferSize); 00514 TRACE_CH(REACTOS, "RegQueryValue(): rc %d\n", (int)rc); 00515 if (rc != ERROR_SUCCESS) 00516 return; 00517 TRACE_CH(REACTOS, "BufferSize: %d \n", (int)BufferSize); 00518 TRACE_CH(REACTOS, "GroupNameBuffer: '%S' \n", GroupNameBuffer); 00519 00520 /* Loop through each group */ 00521 GroupName = GroupNameBuffer; 00522 while (*GroupName) 00523 { 00524 TRACE("Driver group: '%S'\n", GroupName); 00525 00526 /* Query the Order */ 00527 BufferSize = sizeof(OrderList); 00528 rc = RegQueryValue(hOrderKey, GroupName, NULL, (PUCHAR)OrderList, &BufferSize); 00529 if (rc != ERROR_SUCCESS) OrderList[0] = 0; 00530 00531 /* enumerate all drivers */ 00532 for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) 00533 { 00534 Index = 0; 00535 00536 while (TRUE) 00537 { 00538 /* Get the Driver's Name */ 00539 ValueSize = sizeof(ServiceName); 00540 rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize); 00541 //TRACE_CH(REACTOS, "RegEnumKey(): rc %d\n", (int)rc); 00542 00543 /* Makre sure it's valid, and check if we're done */ 00544 if (rc == ERROR_NO_MORE_ITEMS) 00545 break; 00546 if (rc != ERROR_SUCCESS) 00547 { 00548 MmHeapFree(GroupNameBuffer); 00549 return; 00550 } 00551 //TRACE_CH(REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName); 00552 00553 /* open driver Key */ 00554 rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey); 00555 if (rc == ERROR_SUCCESS) 00556 { 00557 /* Read the Start Value */ 00558 ValueSize = sizeof(ULONG); 00559 rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize); 00560 if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1; 00561 //TRACE_CH(REACTOS, " Start: %x \n", (int)StartValue); 00562 00563 /* Read the Tag */ 00564 ValueSize = sizeof(ULONG); 00565 rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize); 00566 if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1; 00567 //TRACE_CH(REACTOS, " Tag: %x \n", (int)TagValue); 00568 00569 /* Read the driver's group */ 00570 DriverGroupSize = sizeof(DriverGroup); 00571 rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize); 00572 //TRACE_CH(REACTOS, " Group: '%S' \n", DriverGroup); 00573 00574 /* Make sure it should be started */ 00575 if ((StartValue == 0) && 00576 (TagValue == OrderList[TagIndex]) && 00577 (_wcsicmp(DriverGroup, GroupName) == 0)) { 00578 00579 /* Get the Driver's Location */ 00580 ValueSize = sizeof(TempImagePath); 00581 rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize); 00582 00583 /* Write the whole path if it suceeded, else prepare to fail */ 00584 if (rc != ERROR_SUCCESS) { 00585 TRACE_CH(REACTOS, "ImagePath: not found\n"); 00586 TempImagePath[0] = 0; 00587 sprintf(ImagePath, "%s\\system32\\drivers\\%S.sys", DirectoryPath, ServiceName); 00588 } else if (TempImagePath[0] != L'\\') { 00589 sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath); 00590 } else { 00591 sprintf(ImagePath, "%S", TempImagePath); 00592 TRACE_CH(REACTOS, "ImagePath: '%s'\n", ImagePath); 00593 } 00594 00595 TRACE("Adding boot driver: '%s'\n", ImagePath); 00596 00597 Status = WinLdrAddDriverToList(BootDriverListHead, 00598 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", 00599 TempImagePath, 00600 ServiceName); 00601 00602 if (!Status) 00603 ERR("Failed to add boot driver\n"); 00604 } else 00605 { 00606 //TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n", 00607 // ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName); 00608 } 00609 } 00610 00611 Index++; 00612 } 00613 } 00614 00615 Index = 0; 00616 while (TRUE) 00617 { 00618 /* Get the Driver's Name */ 00619 ValueSize = sizeof(ServiceName); 00620 rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize); 00621 00622 //TRACE_CH(REACTOS, "RegEnumKey(): rc %d\n", (int)rc); 00623 if (rc == ERROR_NO_MORE_ITEMS) 00624 break; 00625 if (rc != ERROR_SUCCESS) 00626 { 00627 MmHeapFree(GroupNameBuffer); 00628 return; 00629 } 00630 //TRACE_CH(REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName); 00631 00632 /* open driver Key */ 00633 rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey); 00634 if (rc == ERROR_SUCCESS) 00635 { 00636 /* Read the Start Value */ 00637 ValueSize = sizeof(ULONG); 00638 rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize); 00639 if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1; 00640 //TRACE_CH(REACTOS, " Start: %x \n", (int)StartValue); 00641 00642 /* Read the Tag */ 00643 ValueSize = sizeof(ULONG); 00644 rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize); 00645 if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1; 00646 //TRACE_CH(REACTOS, " Tag: %x \n", (int)TagValue); 00647 00648 /* Read the driver's group */ 00649 DriverGroupSize = sizeof(DriverGroup); 00650 rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize); 00651 //TRACE_CH(REACTOS, " Group: '%S' \n", DriverGroup); 00652 00653 for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) { 00654 if (TagValue == OrderList[TagIndex]) break; 00655 } 00656 00657 if ((StartValue == 0) && 00658 (TagIndex > OrderList[0]) && 00659 (_wcsicmp(DriverGroup, GroupName) == 0)) { 00660 00661 ValueSize = sizeof(TempImagePath); 00662 rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize); 00663 if (rc != ERROR_SUCCESS) { 00664 TRACE_CH(REACTOS, "ImagePath: not found\n"); 00665 TempImagePath[0] = 0; 00666 sprintf(ImagePath, "%ssystem32\\drivers\\%S.sys", DirectoryPath, ServiceName); 00667 } else if (TempImagePath[0] != L'\\') { 00668 sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath); 00669 } else { 00670 sprintf(ImagePath, "%S", TempImagePath); 00671 TRACE_CH(REACTOS, "ImagePath: '%s'\n", ImagePath); 00672 } 00673 TRACE(" Adding boot driver: '%s'\n", ImagePath); 00674 00675 Status = WinLdrAddDriverToList(BootDriverListHead, 00676 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\", 00677 TempImagePath, 00678 ServiceName); 00679 00680 if (!Status) 00681 ERR(" Failed to add boot driver\n"); 00682 } else 00683 { 00684 //TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n", 00685 // ServiceName, StartValue, TagValue, DriverGroup, GroupName); 00686 } 00687 } 00688 00689 Index++; 00690 } 00691 00692 /* Move to the next group name */ 00693 GroupName = GroupName + wcslen(GroupName) + 1; 00694 } 00695 00696 /* Free allocated memory */ 00697 MmHeapFree(GroupNameBuffer); 00698 } 00699 00700 BOOLEAN 00701 WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead, 00702 LPWSTR RegistryPath, 00703 LPWSTR ImagePath, 00704 LPWSTR ServiceName) 00705 { 00706 PBOOT_DRIVER_LIST_ENTRY BootDriverEntry; 00707 NTSTATUS Status; 00708 USHORT PathLength; 00709 00710 BootDriverEntry = MmHeapAlloc(sizeof(BOOT_DRIVER_LIST_ENTRY)); 00711 00712 if (!BootDriverEntry) 00713 return FALSE; 00714 00715 // DTE will be filled during actual load of the driver 00716 BootDriverEntry->LdrEntry = NULL; 00717 00718 // Check - if we have a valid ImagePath, if not - we need to build it 00719 // like "System32\\Drivers\\blah.sys" 00720 if (ImagePath && (wcslen(ImagePath) > 0)) 00721 { 00722 // Just copy ImagePath to the corresponding field in the structure 00723 PathLength = (USHORT)wcslen(ImagePath) * sizeof(WCHAR) + sizeof(UNICODE_NULL); 00724 00725 BootDriverEntry->FilePath.Length = 0; 00726 BootDriverEntry->FilePath.MaximumLength = PathLength; 00727 BootDriverEntry->FilePath.Buffer = MmHeapAlloc(PathLength); 00728 00729 if (!BootDriverEntry->FilePath.Buffer) 00730 { 00731 MmHeapFree(BootDriverEntry); 00732 return FALSE; 00733 } 00734 00735 Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ImagePath); 00736 if (!NT_SUCCESS(Status)) 00737 { 00738 MmHeapFree(BootDriverEntry->FilePath.Buffer); 00739 MmHeapFree(BootDriverEntry); 00740 return FALSE; 00741 } 00742 } 00743 else 00744 { 00745 // we have to construct ImagePath ourselves 00746 PathLength = (USHORT)wcslen(ServiceName)*sizeof(WCHAR) + sizeof(L"system32\\drivers\\.sys"); 00747 BootDriverEntry->FilePath.Length = 0; 00748 BootDriverEntry->FilePath.MaximumLength = PathLength; 00749 BootDriverEntry->FilePath.Buffer = MmHeapAlloc(PathLength); 00750 00751 if (!BootDriverEntry->FilePath.Buffer) 00752 { 00753 MmHeapFree(BootDriverEntry); 00754 return FALSE; 00755 } 00756 00757 Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L"system32\\drivers\\"); 00758 if (!NT_SUCCESS(Status)) 00759 { 00760 MmHeapFree(BootDriverEntry->FilePath.Buffer); 00761 MmHeapFree(BootDriverEntry); 00762 return FALSE; 00763 } 00764 00765 Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ServiceName); 00766 if (!NT_SUCCESS(Status)) 00767 { 00768 MmHeapFree(BootDriverEntry->FilePath.Buffer); 00769 MmHeapFree(BootDriverEntry); 00770 return FALSE; 00771 } 00772 00773 Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L".sys"); 00774 if (!NT_SUCCESS(Status)) 00775 { 00776 MmHeapFree(BootDriverEntry->FilePath.Buffer); 00777 MmHeapFree(BootDriverEntry); 00778 return FALSE; 00779 } 00780 } 00781 00782 // Add registry path 00783 PathLength = (USHORT)(wcslen(RegistryPath) + wcslen(ServiceName))*sizeof(WCHAR) + sizeof(UNICODE_NULL); 00784 BootDriverEntry->RegistryPath.Length = 0; 00785 BootDriverEntry->RegistryPath.MaximumLength = PathLength; 00786 BootDriverEntry->RegistryPath.Buffer = MmHeapAlloc(PathLength); 00787 if (!BootDriverEntry->RegistryPath.Buffer) 00788 return FALSE; 00789 00790 Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, RegistryPath); 00791 if (!NT_SUCCESS(Status)) 00792 return FALSE; 00793 00794 Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, ServiceName); 00795 if (!NT_SUCCESS(Status)) 00796 return FALSE; 00797 00798 // Insert entry at top of the list 00799 InsertTailList(BootDriverListHead, &BootDriverEntry->Link); 00800 00801 return TRUE; 00802 } Generated on Sat May 26 2012 04:18:05 for ReactOS by
1.7.6.1
|