ReactOS  0.4.13-dev-259-g5ca9c9c
cmboot.c File Reference
#include "ntoskrnl.h"
#include "debug.h"
Include dependency graph for cmboot.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

INIT_FUNCTION HCELL_INDEX NTAPI CmpFindControlSet (IN PHHIVE SystemHive, IN HCELL_INDEX RootCell, IN PUNICODE_STRING SelectKeyName, OUT PBOOLEAN AutoSelect)
 
INIT_FUNCTION ULONG NTAPI CmpFindTagIndex (IN PHHIVE Hive, IN HCELL_INDEX TagCell, IN HCELL_INDEX GroupOrderCell, IN PUNICODE_STRING GroupName)
 
INIT_FUNCTION BOOLEAN NTAPI CmpAddDriverToList (IN PHHIVE Hive, IN HCELL_INDEX DriverCell, IN HCELL_INDEX GroupOrderCell, IN PUNICODE_STRING RegistryPath, IN PLIST_ENTRY BootDriverListHead)
 
INIT_FUNCTION BOOLEAN NTAPI CmpIsLoadType (IN PHHIVE Hive, IN HCELL_INDEX Cell, IN SERVICE_LOAD_TYPE LoadType)
 
INIT_FUNCTION BOOLEAN NTAPI CmpFindDrivers (IN PHHIVE Hive, IN HCELL_INDEX ControlSet, IN SERVICE_LOAD_TYPE LoadType, IN PWCHAR BootFileSystem OPTIONAL, IN PLIST_ENTRY DriverListHead)
 
INIT_FUNCTION BOOLEAN NTAPI CmpDoSort (IN PLIST_ENTRY DriverListHead, IN PUNICODE_STRING OrderList)
 
INIT_FUNCTION BOOLEAN NTAPI CmpSortDriverList (IN PHHIVE Hive, IN HCELL_INDEX ControlSet, IN PLIST_ENTRY DriverListHead)
 
INIT_FUNCTION BOOLEAN NTAPI CmpOrderGroup (IN PBOOT_DRIVER_NODE StartNode, IN PBOOT_DRIVER_NODE EndNode)
 
INIT_FUNCTION BOOLEAN NTAPI CmpResolveDriverDependencies (IN PLIST_ENTRY DriverListHead)
 
INIT_FUNCTION BOOLEAN NTAPI CmpIsSafe (IN PHHIVE Hive, IN HCELL_INDEX SafeBootCell, IN HCELL_INDEX DriverCell)
 

Variables

ULONG InitSafeBootMode
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file cmboot.c.

Function Documentation

◆ CmpAddDriverToList()

INIT_FUNCTION BOOLEAN NTAPI CmpAddDriverToList ( IN PHHIVE  Hive,
IN HCELL_INDEX  DriverCell,
IN HCELL_INDEX  GroupOrderCell,
IN PUNICODE_STRING  RegistryPath,
IN PLIST_ENTRY  BootDriverListHead 
)

Definition at line 185 of file cmboot.c.

190 {
191  PBOOT_DRIVER_NODE DriverNode;
194  ULONG Length;
195  USHORT NameLength;
196  HCELL_INDEX ValueCell, TagCell; PCM_KEY_VALUE Value;
197  PUNICODE_STRING FileName, RegistryString;
199  PULONG ErrorControl;
200  PWCHAR Buffer;
201  ASSERT(Hive->ReleaseCellRoutine == NULL);
202 
203  /* Allocate a driver node and initialize it */
204  DriverNode = CmpAllocate(sizeof(BOOT_DRIVER_NODE), FALSE, TAG_CM);
205  if (!DriverNode) return FALSE;
206  DriverEntry = &DriverNode->ListEntry;
207  DriverEntry->RegistryPath.Buffer = NULL;
208  DriverEntry->FilePath.Buffer = NULL;
209 
210  /* Get the driver cell */
211  Node = HvGetCell(Hive, DriverCell);
212  ASSERT(Node);
213 
214  /* Get the name from the cell */
215  DriverNode->Name.Length = Node->Flags & KEY_COMP_NAME ?
216  CmpCompressedNameSize(Node->Name, Node->NameLength) :
217  Node->NameLength;
218  DriverNode->Name.MaximumLength = DriverNode->Name.Length;
219  NameLength = DriverNode->Name.Length;
220 
221  /* Now allocate the buffer for it and copy the name */
222  DriverNode->Name.Buffer = CmpAllocate(NameLength, FALSE, TAG_CM);
223  if (!DriverNode->Name.Buffer) return FALSE;
224  if (Node->Flags & KEY_COMP_NAME)
225  {
226  /* Compressed name */
227  CmpCopyCompressedName(DriverNode->Name.Buffer,
228  DriverNode->Name.Length,
229  Node->Name,
230  Node->NameLength);
231  }
232  else
233  {
234  /* Normal name */
235  RtlCopyMemory(DriverNode->Name.Buffer, Node->Name, Node->NameLength);
236  }
237 
238  /* Now find the image path */
239  RtlInitUnicodeString(&UnicodeString, L"ImagePath");
240  ValueCell = CmpFindValueByName(Hive, Node, &UnicodeString);
241  if (ValueCell == HCELL_NIL)
242  {
243  /* Couldn't find it, so assume the drivers path */
244  Length = sizeof(L"System32\\Drivers\\") + NameLength + sizeof(L".sys");
245 
246  /* Allocate the path name */
247  FileName = &DriverEntry->FilePath;
248  FileName->Length = 0;
249  FileName->MaximumLength = (USHORT)Length;
250  FileName->Buffer = CmpAllocate(Length, FALSE,TAG_CM);
251  if (!FileName->Buffer) return FALSE;
252 
253  /* Write the path name */
254  RtlAppendUnicodeToString(FileName, L"System32\\Drivers\\");
257  }
258  else
259  {
260  /* Path name exists, so grab it */
261  Value = HvGetCell(Hive, ValueCell);
262  ASSERT(Value);
263 
264  /* Allocate and setup the path name */
265  FileName = &DriverEntry->FilePath;
267  FileName->MaximumLength = FileName->Length = (USHORT)Length;
268  FileName->Buffer = CmpAllocate(Length, FALSE, TAG_CM);
269 
270  /* Transfer the data */
271  if (!(FileName->Buffer) || !(Buffer)) return FALSE;
272  RtlCopyMemory(FileName->Buffer, Buffer, Length);
273  }
274 
275  /* Now build the registry path */
276  RegistryString = &DriverEntry->RegistryPath;
277  RegistryString->Length = 0;
278  RegistryString->MaximumLength = RegistryPath->Length + NameLength;
279  RegistryString->Buffer = CmpAllocate(RegistryString->MaximumLength, FALSE, TAG_CM);
280  if (!RegistryString->Buffer) return FALSE;
281 
282  /* Add the driver name to it */
284  RtlAppendUnicodeStringToString(RegistryString, &DriverNode->Name);
285 
286  /* The entry is done, add it */
287  InsertHeadList(BootDriverListHead, &DriverEntry->Link);
288 
289  /* Now find error control settings */
290  RtlInitUnicodeString(&UnicodeString, L"ErrorControl");
291  ValueCell = CmpFindValueByName(Hive, Node, &UnicodeString);
292  if (ValueCell == HCELL_NIL)
293  {
294  /* Couldn't find it, so assume default */
295  DriverNode->ErrorControl = NormalError;
296  }
297  else
298  {
299  /* Otherwise, read whatever the data says */
300  Value = HvGetCell(Hive, ValueCell);
301  ASSERT(Value);
302  ErrorControl = (PULONG)CmpValueToData(Hive, Value, &Length);
303  ASSERT(ErrorControl);
304  DriverNode->ErrorControl = *ErrorControl;
305  }
306 
307  /* Next, get the group cell */
309  ValueCell = CmpFindValueByName(Hive, Node, &UnicodeString);
310  if (ValueCell == HCELL_NIL)
311  {
312  /* Couldn't find, so set an empty string */
313  RtlInitEmptyUnicodeString(&DriverNode->Group, NULL, 0);
314  }
315  else
316  {
317  /* Found it, read the group value */
318  Value = HvGetCell(Hive, ValueCell);
319  ASSERT(Value);
320 
321  /* Copy it into the node */
322  DriverNode->Group.Buffer = (PWCHAR)CmpValueToData(Hive, Value, &Length);
323  if (!DriverNode->Group.Buffer) return FALSE;
324  DriverNode->Group.Length = (USHORT)Length - sizeof(UNICODE_NULL);
325  DriverNode->Group.MaximumLength = DriverNode->Group.Length;
326  }
327 
328  /* Finally, find the tag */
330  TagCell = CmpFindValueByName(Hive, Node, &UnicodeString);
331  if (TagCell == HCELL_NIL)
332  {
333  /* No tag, so load last */
334  DriverNode->Tag = -1;
335  }
336  else
337  {
338  /* Otherwise, decode it based on tag order */
339  DriverNode->Tag = CmpFindTagIndex(Hive,
340  TagCell,
341  GroupOrderCell,
342  &DriverNode->Group);
343  }
344 
345  /* All done! */
346  return TRUE;
347 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
#define KEY_COMP_NAME
Definition: cmdata.h:35
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
BOOT_DRIVER_LIST_ENTRY ListEntry
Definition: io.h:426
*BytesInUnicodeString PWCH UnicodeString
Definition: rtlfuncs.h:1980
USHORT MaximumLength
Definition: env_spec_w32.h:370
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
ULONG ErrorControl
Definition: io.h:430
PVOID NTAPI CmpAllocate(_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
Definition: bootreg.c:90
#define HCELL_NIL
Definition: hivedata.h:85
uint16_t * PWCHAR
Definition: typedefs.h:54
Definition: arc.h:198
#define UNICODE_NULL
union node Node
Definition: types.h:1255
VOID NTAPI CmpCopyCompressedName(OUT PWCHAR Destination, IN ULONG DestinationLength, IN PWCHAR Source, IN ULONG SourceLength)
Definition: cmname.c:56
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
PCELL_DATA NTAPI CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
Definition: cmvalue.c:167
UNICODE_STRING Name
Definition: io.h:428
HCELL_INDEX NTAPI CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PUNICODE_STRING Name)
Definition: cmvalue.c:99
ULONG Tag
Definition: io.h:429
ULONG HCELL_INDEX
Definition: hivedata.h:80
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define TAG_CM
Definition: cmlib.h:203
static const WCHAR L[]
Definition: oid.c:1250
UNICODE_STRING Group
Definition: io.h:427
struct _FileName FileName
Definition: fatprocs.h:884
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
unsigned int * PULONG
Definition: retypes.h:1
INIT_FUNCTION ULONG NTAPI CmpFindTagIndex(IN PHHIVE Hive, IN HCELL_INDEX TagCell, IN HCELL_INDEX GroupOrderCell, IN PUNICODE_STRING GroupName)
Definition: cmboot.c:135
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
USHORT NTAPI CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
Definition: cmname.c:95
Definition: dlist.c:348

Referenced by CmpFindDrivers().

◆ CmpDoSort()

INIT_FUNCTION BOOLEAN NTAPI CmpDoSort ( IN PLIST_ENTRY  DriverListHead,
IN PUNICODE_STRING  OrderList 
)

Definition at line 505 of file cmboot.c.

507 {
508  PWCHAR Current, End = NULL;
509  PLIST_ENTRY NextEntry;
510  UNICODE_STRING GroupName;
511  PBOOT_DRIVER_NODE CurrentNode;
512 
513  /* We're going from end to start, so get to the last group and keep going */
514  Current = &OrderList->Buffer[OrderList->Length / sizeof(WCHAR)];
515  while (Current > OrderList->Buffer)
516  {
517  /* Scan the current string */
518  do
519  {
520  if (*Current == UNICODE_NULL) End = Current;
521  } while ((*(--Current - 1) != UNICODE_NULL) && (Current != OrderList->Buffer));
522 
523  /* This is our cleaned up string for this specific group */
524  ASSERT(End != NULL);
525  GroupName.Length = (USHORT)(End - Current) * sizeof(WCHAR);
526  GroupName.MaximumLength = GroupName.Length;
527  GroupName.Buffer = Current;
528 
529  /* Now loop the driver list */
530  NextEntry = DriverListHead->Flink;
531  while (NextEntry != DriverListHead)
532  {
533  /* Get this node */
534  CurrentNode = CONTAINING_RECORD(NextEntry,
536  ListEntry.Link);
537 
538  /* Get the next entry now since we'll do a relink */
539  NextEntry = CurrentNode->ListEntry.Link.Flink;
540 
541  /* Is there a group name and does it match the current group? */
542  if ((CurrentNode->Group.Buffer) &&
543  (RtlEqualUnicodeString(&GroupName, &CurrentNode->Group, TRUE)))
544  {
545  /* Remove from this location and re-link in the new one */
546  RemoveEntryList(&CurrentNode->ListEntry.Link);
547  InsertHeadList(DriverListHead, &CurrentNode->ListEntry.Link);
548  }
549  }
550 
551  /* Move on */
552  Current--;
553  }
554 
555  /* All done */
556  return TRUE;
557 }
#define TRUE
Definition: types.h:120
BOOT_DRIVER_LIST_ENTRY ListEntry
Definition: io.h:426
USHORT MaximumLength
Definition: env_spec_w32.h:370
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
uint16_t * PWCHAR
Definition: typedefs.h:54
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
__wchar_t WCHAR
Definition: xmlstorage.h:180
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: typedefs.h:117
UNICODE_STRING Group
Definition: io.h:427
unsigned short USHORT
Definition: pedump.c:61
LIST_ENTRY Link
Definition: arc.h:200
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)

Referenced by CmpSortDriverList().

◆ CmpFindControlSet()

INIT_FUNCTION HCELL_INDEX NTAPI CmpFindControlSet ( IN PHHIVE  SystemHive,
IN HCELL_INDEX  RootCell,
IN PUNICODE_STRING  SelectKeyName,
OUT PBOOLEAN  AutoSelect 
)

Definition at line 25 of file cmboot.c.

29 {
32  HCELL_INDEX SelectCell, AutoSelectCell, SelectValueCell, ControlSetCell;
33  HCELL_INDEX CurrentValueCell;
34  PCM_KEY_VALUE KeyValue;
35  ULONG Length;
36  PULONG ControlSetId;
37  ANSI_STRING ControlSetAnsiName;
38  CHAR Buffer[128];
39  WCHAR WideBuffer[128];
41  PULONG CurrentData;
42 
43  /* Sanity check */
44  ASSERT(SystemHive->ReleaseCellRoutine == NULL);
45 
46  /* Get the Select subkey */
47  RtlInitUnicodeString(&KeyName, L"select");
48  Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell);
49  if (!Node) return HCELL_NIL;
50  SelectCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
51  if (SelectCell == HCELL_NIL) return SelectCell;
52 
53  /* Get AutoSelect value */
54  RtlInitUnicodeString(&KeyName, L"AutoSelect");
55  Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
56  if (!Node) return HCELL_NIL;
57  AutoSelectCell = CmpFindValueByName(SystemHive, Node, &KeyName);
58  if (AutoSelectCell == HCELL_NIL)
59  {
60  /* Assume TRUE if the value is missing. */
61  *AutoSelect = TRUE;
62  }
63  else
64  {
65  /* Read the value */
66  KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, AutoSelectCell);
67  if (KeyValue == NULL) return HCELL_NIL;
68 
69  /* Convert it to a boolean */
70  *AutoSelect = *(PBOOLEAN)CmpValueToData(SystemHive, KeyValue, &Length);
71  }
72 
73  /* Now find the control set being looked up */
74  Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
75  if (!Node) return HCELL_NIL;
76  SelectValueCell = CmpFindValueByName(SystemHive, Node, SelectKeyName);
77  if (SelectValueCell == HCELL_NIL) return SelectValueCell;
78 
79  /* Read the value (corresponding to the CCS ID) */
80  KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, SelectValueCell);
81  if (!KeyValue) return HCELL_NIL;
82  if (KeyValue->Type != REG_DWORD) return HCELL_NIL;
83  ControlSetId = (PULONG)CmpValueToData(SystemHive, KeyValue, &Length);
84 
85  /* Now build an Ansi String for the CCS's Name */
86  sprintf(Buffer, "ControlSet%03lu", *ControlSetId);
87  ControlSetAnsiName.Length = (USHORT)strlen(Buffer);
88  ControlSetAnsiName.MaximumLength = (USHORT)strlen(Buffer);
89  ControlSetAnsiName.Buffer = Buffer;
90 
91  /* And convert it to Unicode... */
92  KeyName.MaximumLength = 256;
93  KeyName.Buffer = WideBuffer;
95  &ControlSetAnsiName,
96  FALSE);
97  if (!NT_SUCCESS(Status)) return HCELL_NIL;
98 
99  /* Now open it */
100  Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell);
101  if (!Node) return HCELL_NIL;
102  ControlSetCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
103  if (ControlSetCell == HCELL_NIL) return ControlSetCell;
104 
105  /* Get the value of the "Current" CCS */
106  RtlInitUnicodeString(&KeyName, L"Current");
107  Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
108  if (!Node) return HCELL_NIL;
109  CurrentValueCell = CmpFindValueByName(SystemHive, Node, &KeyName);
110 
111  /* Make sure it exists */
112  if (CurrentValueCell != HCELL_NIL)
113  {
114  /* Get the current value and make sure its a ULONG */
115  KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, CurrentValueCell);
116  if (!KeyValue) return HCELL_NIL;
117  if (KeyValue->Type == REG_DWORD)
118  {
119  /* Get the data and update it */
120  CurrentData = (PULONG)CmpValueToData(SystemHive,
121  KeyValue,
122  &Length);
123  if (!CurrentData) return HCELL_NIL;
124  *CurrentData = *ControlSetId;
125  }
126  }
127 
128  /* Return the CCS Cell */
129  return ControlSetCell;
130 }
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
#define TRUE
Definition: types.h:120
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
#define HCELL_NIL
Definition: hivedata.h:85
#define sprintf(buf, format,...)
Definition: sprintf.c:55
union node Node
Definition: types.h:1255
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
smooth NULL
Definition: ftsmooth.c:416
struct _CM_KEY_NODE * PCM_KEY_NODE
Definition: bufpool.h:45
USHORT MaximumLength
Definition: env_spec_w32.h:377
PCELL_DATA NTAPI CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
Definition: cmvalue.c:167
HCELL_INDEX NTAPI CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PUNICODE_STRING Name)
Definition: cmvalue.c:99
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG HCELL_INDEX
Definition: hivedata.h:80
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
char * PBOOLEAN
Definition: retypes.h:11
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
unsigned short USHORT
Definition: pedump.c:61
struct _CM_KEY_VALUE * PCM_KEY_VALUE
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
ULONG Type
Definition: cmdata.h:128
unsigned int * PULONG
Definition: retypes.h:1
static CMHIVE SystemHive
Definition: registry.c:57
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define REG_DWORD
Definition: sdbapi.c:596
HCELL_INDEX NTAPI CmpFindSubKeyByName(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName)
Definition: cmindex.c:683
Definition: dlist.c:348

Referenced by CmGetSystemControlValues(), and CmGetSystemDriverList().

◆ CmpFindDrivers()

INIT_FUNCTION BOOLEAN NTAPI CmpFindDrivers ( IN PHHIVE  Hive,
IN HCELL_INDEX  ControlSet,
IN SERVICE_LOAD_TYPE  LoadType,
IN PWCHAR BootFileSystem  OPTIONAL,
IN PLIST_ENTRY  DriverListHead 
)

Definition at line 383 of file cmboot.c.

388 {
389  HCELL_INDEX ServicesCell, ControlCell, GroupOrderCell, DriverCell;
390  HCELL_INDEX SafeBootCell = HCELL_NIL;
392  ULONG i;
393  WCHAR Buffer[128];
394  UNICODE_STRING UnicodeString, KeyPath;
395  PBOOT_DRIVER_NODE FsNode;
396  PCM_KEY_NODE ControlNode, ServicesNode, Node;
397  ASSERT(Hive->ReleaseCellRoutine == NULL);
398 
399  /* Open the control set key */
400  ControlNode = HvGetCell(Hive, ControlSet);
401  ASSERT(ControlNode);
402 
403  /* Get services cell */
404  RtlInitUnicodeString(&Name, L"Services");
405  ServicesCell = CmpFindSubKeyByName(Hive, ControlNode, &Name);
406  if (ServicesCell == HCELL_NIL) return FALSE;
407 
408  /* Open services key */
409  ServicesNode = HvGetCell(Hive, ServicesCell);
410  ASSERT(ServicesNode);
411 
412  /* Get control cell */
413  RtlInitUnicodeString(&Name, L"Control");
414  ControlCell = CmpFindSubKeyByName(Hive, ControlNode, &Name);
415  if (ControlCell == HCELL_NIL) return FALSE;
416 
417  /* Get the group order cell and read it */
418  RtlInitUnicodeString(&Name, L"GroupOrderList");
419  Node = HvGetCell(Hive, ControlCell);
420  ASSERT(Node);
421  GroupOrderCell = CmpFindSubKeyByName(Hive, Node, &Name);
422  if (GroupOrderCell == HCELL_NIL) return FALSE;
423 
424  /* Get Safe Boot cell */
425  if(InitSafeBootMode)
426  {
427  /* Open the Safe Boot key */
428  RtlInitUnicodeString(&Name, L"SafeBoot");
429  Node = HvGetCell(Hive, ControlCell);
430  ASSERT(Node);
431  SafeBootCell = CmpFindSubKeyByName(Hive, Node, &Name);
432  if (SafeBootCell == HCELL_NIL) return FALSE;
433 
434  /* Open the correct start key (depending on the mode) */
435  Node = HvGetCell(Hive, SafeBootCell);
436  ASSERT(Node);
437  switch(InitSafeBootMode)
438  {
439  /* NOTE: Assumes MINIMAL (1) and DSREPAIR (3) load same items */
440  case 1:
441  case 3: RtlInitUnicodeString(&Name, L"Minimal"); break;
442  case 2: RtlInitUnicodeString(&Name, L"Network"); break;
443  default: return FALSE;
444  }
445  SafeBootCell = CmpFindSubKeyByName(Hive, Node, &Name);
446  if(SafeBootCell == HCELL_NIL) return FALSE;
447  }
448 
449  /* Build the root registry path */
450  RtlInitEmptyUnicodeString(&KeyPath, Buffer, sizeof(Buffer));
451  RtlAppendUnicodeToString(&KeyPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
452 
453  /* Find the first subkey (ie: the first driver or service) */
454  i = 0;
455  DriverCell = CmpFindSubKeyByNumber(Hive, ServicesNode, i);
456  while (DriverCell != HCELL_NIL)
457  {
458  /* Make sure it's a driver of this start type AND is "safe" to load */
459  if (CmpIsLoadType(Hive, DriverCell, LoadType) &&
460  CmpIsSafe(Hive, SafeBootCell, DriverCell))
461  {
462  /* Add it to the list */
463  CmpAddDriverToList(Hive,
464  DriverCell,
465  GroupOrderCell,
466  &KeyPath,
467  DriverListHead);
468 
469  }
470 
471  /* Try the next subkey */
472  DriverCell = CmpFindSubKeyByNumber(Hive, ServicesNode, ++i);
473  }
474 
475  /* Check if we have a boot file system */
476  if (BootFileSystem)
477  {
478  /* Find it */
479  RtlInitUnicodeString(&UnicodeString, BootFileSystem);
480  DriverCell = CmpFindSubKeyByName(Hive, ServicesNode, &UnicodeString);
481  if (DriverCell != HCELL_NIL)
482  {
483  /* Always add it to the list */
484  CmpAddDriverToList(Hive,
485  DriverCell,
486  GroupOrderCell,
487  &KeyPath,
488  DriverListHead);
489 
490  /* Mark it as critical so it always loads */
491  FsNode = CONTAINING_RECORD(DriverListHead->Flink,
493  ListEntry.Link);
495  }
496  }
497 
498  /* We're done! */
499  return TRUE;
500 }
#define TRUE
Definition: types.h:120
*BytesInUnicodeString PWCH UnicodeString
Definition: rtlfuncs.h:1980
ULONG ErrorControl
Definition: io.h:430
HCELL_INDEX NTAPI CmpFindSubKeyByNumber(IN PHHIVE Hive, IN PCM_KEY_NODE Node, IN ULONG Number)
Definition: cmindex.c:600
#define HCELL_NIL
Definition: hivedata.h:85
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
union node Node
Definition: types.h:1255
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
struct NameRec_ * Name
Definition: cdprocs.h:464
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
__wchar_t WCHAR
Definition: xmlstorage.h:180
ULONG HCELL_INDEX
Definition: hivedata.h:80
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static const WCHAR L[]
Definition: oid.c:1250
INIT_FUNCTION BOOLEAN NTAPI CmpIsSafe(IN PHHIVE Hive, IN HCELL_INDEX SafeBootCell, IN HCELL_INDEX DriverCell)
Definition: cmboot.c:724
ULONG InitSafeBootMode
Definition: init.c:68
INIT_FUNCTION BOOLEAN NTAPI CmpIsLoadType(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN SERVICE_LOAD_TYPE LoadType)
Definition: cmboot.c:352
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
INIT_FUNCTION BOOLEAN NTAPI CmpAddDriverToList(IN PHHIVE Hive, IN HCELL_INDEX DriverCell, IN HCELL_INDEX GroupOrderCell, IN PUNICODE_STRING RegistryPath, IN PLIST_ENTRY BootDriverListHead)
Definition: cmboot.c:185
#define SERVICE_ERROR_CRITICAL
Definition: cmtypes.h:982
HCELL_INDEX NTAPI CmpFindSubKeyByName(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName)
Definition: cmindex.c:683
Definition: dlist.c:348

Referenced by CmGetSystemDriverList().

◆ CmpFindTagIndex()

INIT_FUNCTION ULONG NTAPI CmpFindTagIndex ( IN PHHIVE  Hive,
IN HCELL_INDEX  TagCell,
IN HCELL_INDEX  GroupOrderCell,
IN PUNICODE_STRING  GroupName 
)

Definition at line 135 of file cmboot.c.

139 {
140  PCM_KEY_VALUE TagValue, Value;
141  HCELL_INDEX OrderCell;
142  PULONG TagOrder, DriverTag;
143  ULONG CurrentTag, Length;
145  BOOLEAN BufferAllocated;
146  ASSERT(Hive->ReleaseCellRoutine == NULL);
147 
148  /* Get the tag */
149  Value = HvGetCell(Hive, TagCell);
150  ASSERT(Value);
151  DriverTag = (PULONG)CmpValueToData(Hive, Value, &Length);
152  ASSERT(DriverTag);
153 
154  /* Get the order array */
155  Node = HvGetCell(Hive, GroupOrderCell);
156  ASSERT(Node);
157  OrderCell = CmpFindValueByName(Hive, Node, GroupName);
158  if (OrderCell == HCELL_NIL) return -2;
159 
160  /* And read it */
161  TagValue = HvGetCell(Hive, OrderCell);
162  CmpGetValueData(Hive, TagValue, &Length, (PVOID*)&TagOrder, &BufferAllocated, &OrderCell);
163  ASSERT(TagOrder);
164 
165  /* Parse each tag */
166  for (CurrentTag = 1; CurrentTag <= TagOrder[0]; CurrentTag++)
167  {
168  /* Find a match */
169  if (TagOrder[CurrentTag] == *DriverTag)
170  {
171  /* Found it -- return the tag */
172  if (BufferAllocated) ExFreePool(TagOrder);
173  return CurrentTag;
174  }
175  }
176 
177  /* No matches, so assume next to last ordering */
178  if (BufferAllocated) ExFreePool(TagOrder);
179  return -2;
180 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
BOOLEAN NTAPI CmpGetValueData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length, OUT PVOID *Buffer, OUT PBOOLEAN BufferAllocated, OUT PHCELL_INDEX CellToRelease)
Definition: cmvalue.c:125
#define HCELL_NIL
Definition: hivedata.h:85
union node Node
Definition: types.h:1255
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PCELL_DATA NTAPI CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
Definition: cmvalue.c:167
HCELL_INDEX NTAPI CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PUNICODE_STRING Name)
Definition: cmvalue.c:99
ULONG HCELL_INDEX
Definition: hivedata.h:80
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
Definition: dlist.c:348

Referenced by CmpAddDriverToList().

◆ CmpIsLoadType()

INIT_FUNCTION BOOLEAN NTAPI CmpIsLoadType ( IN PHHIVE  Hive,
IN HCELL_INDEX  Cell,
IN SERVICE_LOAD_TYPE  LoadType 
)

Definition at line 352 of file cmboot.c.

355 {
357  HCELL_INDEX ValueCell;
358  UNICODE_STRING ValueString = RTL_CONSTANT_STRING(L"Start");
360  ULONG Length;
361  PLONG Data;
362  ASSERT(Hive->ReleaseCellRoutine == NULL);
363 
364  /* Open the start cell */
365  Node = HvGetCell(Hive, Cell);
366  ASSERT(Node);
367  ValueCell = CmpFindValueByName(Hive, Node, &ValueString);
368  if (ValueCell == HCELL_NIL) return FALSE;
369 
370  /* Read the start value */
371  Value = HvGetCell(Hive, ValueCell);
372  ASSERT(Value);
373  Data = (PLONG)CmpValueToData(Hive, Value, &Length);
374  ASSERT(Data);
375 
376  /* Return if the type matches */
377  return (*Data == LoadType);
378 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
#define HCELL_NIL
Definition: hivedata.h:85
union node Node
Definition: types.h:1255
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
smooth NULL
Definition: ftsmooth.c:416
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
PCELL_DATA NTAPI CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
Definition: cmvalue.c:167
HCELL_INDEX NTAPI CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PUNICODE_STRING Name)
Definition: cmvalue.c:99
ULONG HCELL_INDEX
Definition: hivedata.h:80
Definition: bzip2.c:1694
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static const WCHAR L[]
Definition: oid.c:1250
unsigned int ULONG
Definition: retypes.h:1
signed int * PLONG
Definition: retypes.h:5
Definition: dlist.c:348
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by CmpFindDrivers().

◆ CmpIsSafe()

INIT_FUNCTION BOOLEAN NTAPI CmpIsSafe ( IN PHHIVE  Hive,
IN HCELL_INDEX  SafeBootCell,
IN HCELL_INDEX  DriverCell 
)

Definition at line 724 of file cmboot.c.

727 {
728  PCM_KEY_NODE SafeBootNode;
729  PCM_KEY_NODE DriverNode;
730  PCM_KEY_VALUE KeyValue;
731  HCELL_INDEX CellIndex;
732  ULONG Length = 0;
734  PWCHAR OriginalName;
735  ASSERT(Hive->ReleaseCellRoutine == NULL);
736 
737  /* Driver key node (mandatory) */
738  ASSERT(DriverCell != HCELL_NIL);
739  DriverNode = HvGetCell(Hive, DriverCell);
740  ASSERT(DriverNode);
741 
742  /* Safe boot key node (optional but return TRUE if not present) */
743  if(SafeBootCell == HCELL_NIL) return TRUE;
744  SafeBootNode = HvGetCell(Hive, SafeBootCell);
745  if(!SafeBootNode) return FALSE;
746 
747  /* Search by the name from the group */
748  RtlInitUnicodeString(&Name, L"Group");
749  CellIndex = CmpFindValueByName(Hive, DriverNode, &Name);
750  if(CellIndex != HCELL_NIL)
751  {
752  KeyValue = HvGetCell(Hive, CellIndex);
753  ASSERT(KeyValue);
754  if (KeyValue->Type == REG_SZ || KeyValue->Type == REG_EXPAND_SZ)
755  {
756  /* Compose the search 'key' */
757  Name.Buffer = (PWCHAR)CmpValueToData(Hive, KeyValue, &Length);
758  if (!Name.Buffer) return FALSE;
759  Name.Length = (USHORT)Length - sizeof(UNICODE_NULL);
760  Name.MaximumLength = Name.Length;
761  /* Search for corresponding key in the Safe Boot key */
762  CellIndex = CmpFindSubKeyByName(Hive, SafeBootNode, &Name);
763  if(CellIndex != HCELL_NIL) return TRUE;
764  }
765  }
766 
767  /* Group has not been found - find driver name */
768  Name.Length = DriverNode->Flags & KEY_COMP_NAME ?
769  CmpCompressedNameSize(DriverNode->Name,
770  DriverNode->NameLength) :
771  DriverNode->NameLength;
772  Name.MaximumLength = Name.Length;
773  /* Now allocate the buffer for it and copy the name */
774  Name.Buffer = CmpAllocate(Name.Length, FALSE, TAG_CM);
775  if (!Name.Buffer) return FALSE;
776  if (DriverNode->Flags & KEY_COMP_NAME)
777  {
778  /* Compressed name */
780  Name.Length,
781  DriverNode->Name,
782  DriverNode->NameLength);
783  }
784  else
785  {
786  /* Normal name */
787  RtlCopyMemory(Name.Buffer, DriverNode->Name, DriverNode->NameLength);
788  }
789  CellIndex = CmpFindSubKeyByName(Hive, SafeBootNode, &Name);
791  if(CellIndex != HCELL_NIL) return TRUE;
792 
793  /* Not group or driver name - search by image name */
794  RtlInitUnicodeString(&Name, L"ImagePath");
795  CellIndex = CmpFindValueByName(Hive, DriverNode, &Name);
796  if(CellIndex != HCELL_NIL)
797  {
798  KeyValue = HvGetCell(Hive, CellIndex);
799  ASSERT(KeyValue);
800  if (KeyValue->Type == REG_SZ || KeyValue->Type == REG_EXPAND_SZ)
801  {
802  /* Compose the search 'key' */
803  OriginalName = (PWCHAR)CmpValueToData(Hive, KeyValue, &Length);
804  if (!OriginalName) return FALSE;
805  /* Get the base image file name */
806  Name.Buffer = wcsrchr(OriginalName, L'\\');
807  if (!Name.Buffer) return FALSE;
808  ++Name.Buffer;
809  /* Length of the base name must be >=1 */
810  Name.Length = (USHORT)Length - (USHORT)((PUCHAR)Name.Buffer - (PUCHAR)OriginalName)
811  - sizeof(UNICODE_NULL);
812  if(Name.Length < 1) return FALSE;
813  Name.MaximumLength = Name.Length;
814  /* Search for corresponding key in the Safe Boot key */
815  CellIndex = CmpFindSubKeyByName(Hive, SafeBootNode, &Name);
816  if(CellIndex != HCELL_NIL) return TRUE;
817  }
818  }
819  /* Nothing found - nothing else to search */
820  return FALSE;
821 }
#define KEY_COMP_NAME
Definition: cmdata.h:35
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:116
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
unsigned char * PUCHAR
Definition: retypes.h:3
PVOID NTAPI CmpAllocate(_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
Definition: bootreg.c:90
#define HCELL_NIL
Definition: hivedata.h:85
uint16_t * PWCHAR
Definition: typedefs.h:54
USHORT NameLength
Definition: cmdata.h:114
#define UNICODE_NULL
VOID NTAPI CmpCopyCompressedName(OUT PWCHAR Destination, IN ULONG DestinationLength, IN PWCHAR Source, IN ULONG SourceLength)
Definition: cmname.c:56
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
struct NameRec_ * Name
Definition: cdprocs.h:464
smooth NULL
Definition: ftsmooth.c:416
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
PCELL_DATA NTAPI CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
Definition: cmvalue.c:167
HCELL_INDEX NTAPI CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PUNICODE_STRING Name)
Definition: cmvalue.c:99
ULONG HCELL_INDEX
Definition: hivedata.h:80
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define TAG_CM
Definition: cmlib.h:203
static const WCHAR L[]
Definition: oid.c:1250
unsigned short USHORT
Definition: pedump.c:61
ULONG Type
Definition: cmdata.h:128
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
HCELL_INDEX NTAPI CmpFindSubKeyByName(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName)
Definition: cmindex.c:683
USHORT NTAPI CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
Definition: cmname.c:95
USHORT Flags
Definition: cmdata.h:93
#define REG_SZ
Definition: layer.c:22

Referenced by CmpFindDrivers().

◆ CmpOrderGroup()

INIT_FUNCTION BOOLEAN NTAPI CmpOrderGroup ( IN PBOOT_DRIVER_NODE  StartNode,
IN PBOOT_DRIVER_NODE  EndNode 
)

Definition at line 611 of file cmboot.c.

613 {
614  PBOOT_DRIVER_NODE CurrentNode, PreviousNode;
615  PLIST_ENTRY ListEntry;
616 
617  /* Base case, nothing to do */
618  if (StartNode == EndNode) return TRUE;
619 
620  /* Loop the nodes */
621  CurrentNode = StartNode;
622  do
623  {
624  /* Save this as the previous node */
625  PreviousNode = CurrentNode;
626 
627  /* And move to the next one */
628  ListEntry = CurrentNode->ListEntry.Link.Flink;
629  CurrentNode = CONTAINING_RECORD(ListEntry,
631  ListEntry.Link);
632 
633  /* Check if the previous driver had a bigger tag */
634  if (PreviousNode->Tag > CurrentNode->Tag)
635  {
636  /* Check if we need to update the tail */
637  if (CurrentNode == EndNode)
638  {
639  /* Update the tail */
640  ListEntry = CurrentNode->ListEntry.Link.Blink;
641  EndNode = CONTAINING_RECORD(ListEntry,
643  ListEntry.Link);
644  }
645 
646  /* Remove this driver since we need to move it */
647  RemoveEntryList(&CurrentNode->ListEntry.Link);
648 
649  /* Keep looping until we find a driver with a lower tag than ours */
650  while ((PreviousNode->Tag > CurrentNode->Tag) && (PreviousNode != StartNode))
651  {
652  /* We'll be re-inserted at this spot */
653  ListEntry = PreviousNode->ListEntry.Link.Blink;
654  PreviousNode = CONTAINING_RECORD(ListEntry,
656  ListEntry.Link);
657  }
658 
659  /* Do the insert in the new location */
660  InsertTailList(&PreviousNode->ListEntry.Link, &CurrentNode->ListEntry.Link);
661 
662  /* Update the head, if needed */
663  if (PreviousNode == StartNode) StartNode = CurrentNode;
664  }
665  } while (CurrentNode != EndNode);
666 
667  /* All done */
668  return TRUE;
669 }
#define TRUE
Definition: types.h:120
BOOT_DRIVER_LIST_ENTRY ListEntry
Definition: io.h:426
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
#define InsertTailList(ListHead, Entry)
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
ULONG Tag
Definition: io.h:429
Definition: typedefs.h:117
LIST_ENTRY Link
Definition: arc.h:200

Referenced by CmpResolveDriverDependencies().

◆ CmpResolveDriverDependencies()

INIT_FUNCTION BOOLEAN NTAPI CmpResolveDriverDependencies ( IN PLIST_ENTRY  DriverListHead)

Definition at line 674 of file cmboot.c.

675 {
676  PLIST_ENTRY NextEntry;
677  PBOOT_DRIVER_NODE StartNode, EndNode, CurrentNode;
678 
679  /* Loop the list */
680  NextEntry = DriverListHead->Flink;
681  while (NextEntry != DriverListHead)
682  {
683  /* Find the first entry */
684  StartNode = CONTAINING_RECORD(NextEntry,
686  ListEntry.Link);
687  do
688  {
689  /* Find the last entry */
690  EndNode = CONTAINING_RECORD(NextEntry,
692  ListEntry.Link);
693 
694  /* Get the next entry */
695  NextEntry = NextEntry->Flink;
696  CurrentNode = CONTAINING_RECORD(NextEntry,
698  ListEntry.Link);
699 
700  /* If the next entry is back to the top, break out */
701  if (NextEntry == DriverListHead) break;
702 
703  /* Otherwise, check if this entry is equal */
704  if (!RtlEqualUnicodeString(&StartNode->Group,
705  &CurrentNode->Group,
706  TRUE))
707  {
708  /* It is, so we've detected a cycle, break out */
709  break;
710  }
711  } while (NextEntry != DriverListHead);
712 
713  /* Now we have the correct start and end pointers, so do the sort */
714  CmpOrderGroup(StartNode, EndNode);
715  }
716 
717  /* We're done */
718  return TRUE;
719 }
INIT_FUNCTION BOOLEAN NTAPI CmpOrderGroup(IN PBOOT_DRIVER_NODE StartNode, IN PBOOT_DRIVER_NODE EndNode)
Definition: cmboot.c:611
#define TRUE
Definition: types.h:120
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
Definition: typedefs.h:117
UNICODE_STRING Group
Definition: io.h:427
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)

Referenced by CmGetSystemDriverList().

◆ CmpSortDriverList()

INIT_FUNCTION BOOLEAN NTAPI CmpSortDriverList ( IN PHHIVE  Hive,
IN HCELL_INDEX  ControlSet,
IN PLIST_ENTRY  DriverListHead 
)

Definition at line 562 of file cmboot.c.

565 {
566  HCELL_INDEX Controls, GroupOrder, ListCell;
567  UNICODE_STRING Name, DependList;
568  PCM_KEY_VALUE ListNode;
569  ULONG Length;
571  ASSERT(Hive->ReleaseCellRoutine == NULL);
572 
573  /* Open the control key */
574  Node = HvGetCell(Hive, ControlSet);
575  ASSERT(Node);
576  RtlInitUnicodeString(&Name, L"Control");
577  Controls = CmpFindSubKeyByName(Hive, Node, &Name);
578  if (Controls == HCELL_NIL) return FALSE;
579 
580  /* Open the service group order */
581  Node = HvGetCell(Hive, Controls);
582  ASSERT(Node);
583  RtlInitUnicodeString(&Name, L"ServiceGroupOrder");
584  GroupOrder = CmpFindSubKeyByName(Hive, Node, &Name);
585  if (GroupOrder == HCELL_NIL) return FALSE;
586 
587  /* Open the list key */
588  Node = HvGetCell(Hive, GroupOrder);
589  ASSERT(Node);
590  RtlInitUnicodeString(&Name, L"list");
591  ListCell = CmpFindValueByName(Hive, Node, &Name);
592  if (ListCell == HCELL_NIL) return FALSE;
593 
594  /* Now read the actual list */
595  ListNode = HvGetCell(Hive, ListCell);
596  ASSERT(ListNode);
597  if (ListNode->Type != REG_MULTI_SZ) return FALSE;
598 
599  /* Copy it into a buffer */
600  DependList.Buffer = (PWCHAR)CmpValueToData(Hive, ListNode, &Length);
601  if (!DependList.Buffer) return FALSE;
602  DependList.Length = DependList.MaximumLength = (USHORT)Length - sizeof(UNICODE_NULL);
603 
604  /* And start the recurive sort algorithm */
605  return CmpDoSort(DriverListHead, &DependList);
606 }
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define HCELL_NIL
Definition: hivedata.h:85
uint16_t * PWCHAR
Definition: typedefs.h:54
#define UNICODE_NULL
union node Node
Definition: types.h:1255
#define REG_MULTI_SZ
Definition: nt_native.h:1501
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
struct NameRec_ * Name
Definition: cdprocs.h:464
smooth NULL
Definition: ftsmooth.c:416
PCELL_DATA NTAPI CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
Definition: cmvalue.c:167
HCELL_INDEX NTAPI CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PUNICODE_STRING Name)
Definition: cmvalue.c:99
ULONG HCELL_INDEX
Definition: hivedata.h:80
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static const WCHAR L[]
Definition: oid.c:1250
unsigned short USHORT
Definition: pedump.c:61
ULONG Type
Definition: cmdata.h:128
INIT_FUNCTION BOOLEAN NTAPI CmpDoSort(IN PLIST_ENTRY DriverListHead, IN PUNICODE_STRING OrderList)
Definition: cmboot.c:505
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
HCELL_INDEX NTAPI CmpFindSubKeyByName(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName)
Definition: cmindex.c:683
Definition: dlist.c:348

Referenced by CmGetSystemDriverList().

Variable Documentation

◆ InitSafeBootMode

ULONG InitSafeBootMode

Definition at line 68 of file init.c.

Referenced by CmpFindDrivers().