ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

wlregistry.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.