ReactOS  0.4.15-dev-5112-g22d8c0f
cmboot.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _BOOT_DRIVER_NODE
 

Typedefs

typedef struct _BOOT_DRIVER_NODE BOOT_DRIVER_NODE
 
typedef struct _BOOT_DRIVER_NODEPBOOT_DRIVER_NODE
 

Functions

HCELL_INDEX NTAPI CmpFindControlSet (_In_ PHHIVE SystemHive, _In_ HCELL_INDEX RootCell, _In_ PCUNICODE_STRING SelectKeyName, _Out_ PBOOLEAN AutoSelect)
 Finds the corresponding "HKLM\SYSTEM\ControlSetXXX" system control set registry key, according to the "Current", "Default", or "LastKnownGood" values in the "HKLM\SYSTEM\Select" registry key. More...
 
BOOLEAN NTAPI CmpFindDrivers (_In_ PHHIVE Hive, _In_ HCELL_INDEX ControlSet, _In_ SERVICE_LOAD_TYPE LoadType, _In_opt_ PCWSTR BootFileSystem, _Inout_ PLIST_ENTRY DriverListHead)
 Enumerates all drivers within the given control set and load type, present in the "Services" sub-key, and inserts them into the driver list. More...
 
BOOLEAN NTAPI CmpSortDriverList (_In_ PHHIVE Hive, _In_ HCELL_INDEX ControlSet, _Inout_ PLIST_ENTRY DriverListHead)
 Sorts the driver list, according to the drivers' group load ordering. More...
 
BOOLEAN NTAPI CmpResolveDriverDependencies (_Inout_ PLIST_ENTRY DriverListHead)
 Removes potential circular dependencies (cycles) and sorts the driver list. More...
 
VOID NTAPI CmpFreeDriverList (_In_ PHHIVE Hive, _Inout_ PLIST_ENTRY DriverListHead)
 Empties the driver list and frees all allocated driver nodes in it. More...
 

Typedef Documentation

◆ BOOT_DRIVER_NODE

◆ PBOOT_DRIVER_NODE

Function Documentation

◆ CmpFindControlSet()

HCELL_INDEX NTAPI CmpFindControlSet ( _In_ PHHIVE  SystemHive,
_In_ HCELL_INDEX  RootCell,
_In_ PCUNICODE_STRING  SelectKeyName,
_Out_ PBOOLEAN  AutoSelect 
)

Finds the corresponding "HKLM\SYSTEM\ControlSetXXX" system control set registry key, according to the "Current", "Default", or "LastKnownGood" values in the "HKLM\SYSTEM\Select" registry key.

Parameters
[in]SystemHiveThe SYSTEM hive.
[in]RootCellThe root cell of the SYSTEM hive.
[in]SelectKeyNameThe control set to check for: either "Current", "Default", or "LastKnownGood", the value of which selects the corresponding "HKLM\SYSTEM\ControlSetXXX" control set registry key.
[out]AutoSelectValue of the "AutoSelect" registry value (unused).
Returns
The control set registry key's hive cell (if found), or HCELL_NIL.

Definition at line 84 of file cmboot.c.

89 {
92  HCELL_INDEX SelectCell, AutoSelectCell, SelectValueCell, ControlSetCell;
93  HCELL_INDEX CurrentValueCell;
95  ULONG Length;
97  PULONG CurrentData;
98  PULONG ControlSetId;
99  WCHAR Buffer[128];
100 
101  /* Sanity check: We shouldn't need to release any acquired cells */
103 
104  /* Get the Select key */
105  RtlInitUnicodeString(&Name, L"select");
106  Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell);
107  if (!Node) return HCELL_NIL;
108  SelectCell = CmpFindSubKeyByName(SystemHive, Node, &Name);
109  if (SelectCell == HCELL_NIL) return HCELL_NIL;
110 
111  /* Get AutoSelect value */
112  RtlInitUnicodeString(&Name, L"AutoSelect");
113  Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
114  if (!Node) return HCELL_NIL;
115  AutoSelectCell = CmpFindValueByName(SystemHive, Node, &Name);
116  if (AutoSelectCell == HCELL_NIL)
117  {
118  /* Assume TRUE if the value is missing */
119  *AutoSelect = TRUE;
120  }
121  else
122  {
123  /* Read the value */
124  Value = (PCM_KEY_VALUE)HvGetCell(SystemHive, AutoSelectCell);
125  if (!Value) return HCELL_NIL;
126  // if (Value->Type != REG_DWORD) return HCELL_NIL;
127 
128  /* Convert it to a boolean */
129  CurrentData = (PULONG)CmpValueToData(SystemHive, Value, &Length);
130  if (!CurrentData) return HCELL_NIL;
131  // if (Length < sizeof(ULONG)) return HCELL_NIL;
132 
133  *AutoSelect = *(PBOOLEAN)CurrentData;
134  }
135 
136  /* Now find the control set being looked up */
137  Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
138  if (!Node) return HCELL_NIL;
139  SelectValueCell = CmpFindValueByName(SystemHive, Node, SelectKeyName);
140  if (SelectValueCell == HCELL_NIL) return HCELL_NIL;
141 
142  /* Read the value (corresponding to the CCS ID) */
143  Value = (PCM_KEY_VALUE)HvGetCell(SystemHive, SelectValueCell);
144  if (!Value) return HCELL_NIL;
145  if (Value->Type != REG_DWORD) return HCELL_NIL;
146  ControlSetId = (PULONG)CmpValueToData(SystemHive, Value, &Length);
147  if (!ControlSetId) return HCELL_NIL;
148  if (Length < sizeof(ULONG)) return HCELL_NIL;
149 
150  /* Now build the CCS's Name */
152  L"ControlSet%03lu", *ControlSetId);
153  if (!NT_SUCCESS(Status)) return HCELL_NIL;
154  /* RtlStringCbPrintfW ensures the buffer to be NULL-terminated */
156 
157  /* Now open it */
158  Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell);
159  if (!Node) return HCELL_NIL;
160  ControlSetCell = CmpFindSubKeyByName(SystemHive, Node, &Name);
161  if (ControlSetCell == HCELL_NIL) return HCELL_NIL;
162 
163  /* Get the value of the "Current" CCS */
164  RtlInitUnicodeString(&Name, L"Current");
165  Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
166  if (!Node) return HCELL_NIL;
167  CurrentValueCell = CmpFindValueByName(SystemHive, Node, &Name);
168 
169  /* Make sure it exists */
170  if (CurrentValueCell != HCELL_NIL)
171  {
172  /* Get the current value and make sure it's a ULONG */
173  Value = (PCM_KEY_VALUE)HvGetCell(SystemHive, CurrentValueCell);
174  if (!Value) return HCELL_NIL;
175  if (Value->Type == REG_DWORD)
176  {
177  /* Get the data and update it */
178  CurrentData = (PULONG)CmpValueToData(SystemHive, Value, &Length);
179  if (!CurrentData) return HCELL_NIL;
180  if (Length < sizeof(ULONG)) return HCELL_NIL;
181 
182  *CurrentData = *ControlSetId;
183  }
184  }
185 
186  /* Return the CCS cell */
187  return ControlSetCell;
188 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define HCELL_NIL
Definition: hivedata.h:85
PHHIVE SystemHive
Definition: registry.c:32
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:381
#define L(x)
Definition: ntvdm.h:50
union node Node
Definition: types.h:1255
struct NameRec_ * Name
Definition: cdprocs.h:459
struct _CM_KEY_NODE * PCM_KEY_NODE
Definition: bufpool.h:45
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
Status
Definition: gdiplustypes.h:24
PCELL_DATA NTAPI CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
Definition: cmvalue.c:167
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
ULONG HCELL_INDEX
Definition: hivedata.h:80
char * PBOOLEAN
Definition: retypes.h:11
HCELL_INDEX NTAPI CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PCUNICODE_STRING Name)
Definition: cmvalue.c:99
struct _CM_KEY_VALUE * PCM_KEY_VALUE
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#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
PRELEASE_CELL_ROUTINE ReleaseCellRoutine
Definition: hivedata.h:292
Definition: dlist.c:348

Referenced by CmGetSystemControlValues(), CmGetSystemDriverList(), and RegInitCurrentControlSet().

◆ CmpFindDrivers()

BOOLEAN NTAPI CmpFindDrivers ( _In_ PHHIVE  Hive,
_In_ HCELL_INDEX  ControlSet,
_In_ SERVICE_LOAD_TYPE  LoadType,
_In_opt_ PCWSTR  BootFileSystem,
_Inout_ PLIST_ENTRY  DriverListHead 
)

Enumerates all drivers within the given control set and load type, present in the "Services" sub-key, and inserts them into the driver list.

Parameters
[in]HiveThe SYSTEM hive.
[in]ControlSetThe control set registry key's hive cell.
[in]LoadTypeThe load type the driver should match.
[in]BootFileSystemOptional name of the boot file system, for which to insert its corresponding driver.
[in,out]DriverListHeadThe driver list where to insert the enumerated drivers.
Returns
TRUE if the drivers have been successfully enumerated and inserted, FALSE if not.

Definition at line 679 of file cmboot.c.

685 {
686  HCELL_INDEX ServicesCell, ControlCell, GroupOrderCell, DriverCell;
687  HCELL_INDEX SafeBootCell = HCELL_NIL;
688  ULONG i;
690  UNICODE_STRING KeyPath;
691  PCM_KEY_NODE ControlNode, ServicesNode, Node;
692  PBOOT_DRIVER_NODE FsNode;
693 
694  /* Sanity check: We shouldn't need to release any acquired cells */
695  ASSERT(Hive->ReleaseCellRoutine == NULL);
696 
697  /* Open the control set key */
698  ControlNode = (PCM_KEY_NODE)HvGetCell(Hive, ControlSet);
699  if (!ControlNode) return FALSE;
700 
701  /* Get services cell */
702  RtlInitUnicodeString(&Name, L"Services");
703  ServicesCell = CmpFindSubKeyByName(Hive, ControlNode, &Name);
704  if (ServicesCell == HCELL_NIL) return FALSE;
705 
706  /* Open services key */
707  ServicesNode = (PCM_KEY_NODE)HvGetCell(Hive, ServicesCell);
708  if (!ServicesNode) return FALSE;
709 
710  /* Get control cell */
711  RtlInitUnicodeString(&Name, L"Control");
712  ControlCell = CmpFindSubKeyByName(Hive, ControlNode, &Name);
713  if (ControlCell == HCELL_NIL) return FALSE;
714 
715  /* Get the group order cell and read it */
716  Node = (PCM_KEY_NODE)HvGetCell(Hive, ControlCell);
717  if (!Node) return FALSE;
718  RtlInitUnicodeString(&Name, L"GroupOrderList");
719  GroupOrderCell = CmpFindSubKeyByName(Hive, Node, &Name);
720  if (GroupOrderCell == HCELL_NIL) return FALSE;
721 
722  /* Get Safe Boot cell */
723  if (InitSafeBootMode)
724  {
725  /* Open the Safe Boot key */
726  RtlInitUnicodeString(&Name, L"SafeBoot");
727  Node = (PCM_KEY_NODE)HvGetCell(Hive, ControlCell);
728  if (!Node) return FALSE;
729  SafeBootCell = CmpFindSubKeyByName(Hive, Node, &Name);
730  if (SafeBootCell == HCELL_NIL) return FALSE;
731 
732  /* Open the correct start key (depending on the mode) */
733  Node = (PCM_KEY_NODE)HvGetCell(Hive, SafeBootCell);
734  if (!Node) return FALSE;
735  switch (InitSafeBootMode)
736  {
737  /* NOTE: Assumes MINIMAL (1) and DSREPAIR (3) load same items */
738  case 1:
739  case 3: RtlInitUnicodeString(&Name, L"Minimal"); break;
740  case 2: RtlInitUnicodeString(&Name, L"Network"); break;
741  default: return FALSE;
742  }
743  SafeBootCell = CmpFindSubKeyByName(Hive, Node, &Name);
744  if (SafeBootCell == HCELL_NIL) return FALSE;
745  }
746 
747  /* Build the root registry path */
748  RtlInitUnicodeString(&KeyPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
749 
750  /* Enumerate each sub-key */
751  i = 0;
752  DriverCell = CmpFindSubKeyByNumber(Hive, ServicesNode, i);
753  while (DriverCell != HCELL_NIL)
754  {
755  /* Make sure it's a driver of this start type AND is "safe" to load */
756  if (CmpIsLoadType(Hive, DriverCell, LoadType) &&
757  CmpIsSafe(Hive, SafeBootCell, DriverCell))
758  {
759  /* Add it to the list */
760  if (!CmpAddDriverToList(Hive,
761  DriverCell,
762  GroupOrderCell,
763  &KeyPath,
764  DriverListHead))
765  {
766  CMTRACE(CM_BOOT_DEBUG, " Failed to add boot driver\n");
767  }
768  }
769 
770  /* Go to the next sub-key */
771  DriverCell = CmpFindSubKeyByNumber(Hive, ServicesNode, ++i);
772  }
773 
774  /* Check if we have a boot file system */
775  if (BootFileSystem)
776  {
777  /* Find it */
779  DriverCell = CmpFindSubKeyByName(Hive, ServicesNode, &Name);
780  if (DriverCell != HCELL_NIL)
781  {
782  CMTRACE(CM_BOOT_DEBUG, "Adding Boot FileSystem '%S'\n",
784 
785  /* Always add it to the list */
786  if (!CmpAddDriverToList(Hive,
787  DriverCell,
788  GroupOrderCell,
789  &KeyPath,
790  DriverListHead))
791  {
792  CMTRACE(CM_BOOT_DEBUG, " Failed to add boot driver\n");
793  }
794  else
795  {
796  /* Mark it as critical so it always loads */
797  FsNode = CONTAINING_RECORD(DriverListHead->Flink,
799  ListEntry.Link);
801  }
802  }
803  }
804 
805  /* We're done! */
806  return TRUE;
807 }
#define CMTRACE(x, fmt,...)
Definition: cm.h:40
#define TRUE
Definition: types.h:120
ULONG ErrorControl
Definition: cmboot.h:19
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
BOOLEAN NTAPI CmpAddDriverToList(_In_ PHHIVE Hive, _In_ HCELL_INDEX DriverCell, _In_ HCELL_INDEX GroupOrderCell, _In_ PCUNICODE_STRING RegistryPath, _Inout_ PLIST_ENTRY DriverListHead)
Inserts the specified driver entry into the driver list.
Definition: cmboot.c:364
#define CM_BOOT_DEBUG
Definition: cmboot.c:39
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:381
static BOOLEAN CmpIsSafe(_In_ PHHIVE Hive, _In_ HCELL_INDEX SafeBootCell, _In_ HCELL_INDEX DriverCell)
Definition: cmboot.c:1081
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
union node Node
Definition: types.h:1255
struct NameRec_ * Name
Definition: cdprocs.h:459
struct _CM_KEY_NODE * PCM_KEY_NODE
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
PCWSTR BootFileSystem
Definition: winldr.c:30
static BOOLEAN CmpIsLoadType(_In_ PHHIVE Hive, _In_ HCELL_INDEX Cell, _In_ SERVICE_LOAD_TYPE LoadType)
Checks whether the specified driver has the expected load type.
Definition: cmboot.c:618
#define ASSERT(a)
Definition: mode.c:44
ULONG HCELL_INDEX
Definition: hivedata.h:80
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
#define NULL
Definition: types.h:112
ULONG InitSafeBootMode
Definition: init.c:71
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define SERVICE_ERROR_CRITICAL
Definition: cmtypes.h:984
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(), and WinLdrScanRegistry().

◆ CmpFreeDriverList()

VOID NTAPI CmpFreeDriverList ( _In_ PHHIVE  Hive,
_Inout_ PLIST_ENTRY  DriverListHead 
)

Empties the driver list and frees all allocated driver nodes in it.

Parameters
[in]HiveThe SYSTEM hive (used only for the Hive->Free() memory deallocator).
[in,out]DriverListHeadThe driver list to free.
Returns
None

Definition at line 1224 of file cmboot.c.

1227 {
1229  PBOOT_DRIVER_NODE DriverNode;
1230 
1231  /* Loop through the list and remove each driver node */
1232  while (!IsListEmpty(DriverListHead))
1233  {
1234  /* Get the driver node */
1235  Entry = RemoveHeadList(DriverListHead);
1236  DriverNode = CONTAINING_RECORD(Entry,
1238  ListEntry.Link);
1239 
1240  /* Free any allocated string buffers, then the node */
1241  if (DriverNode->ListEntry.RegistryPath.Buffer)
1242  {
1243  Hive->Free(DriverNode->ListEntry.RegistryPath.Buffer,
1244  DriverNode->ListEntry.RegistryPath.MaximumLength);
1245  }
1246  if (DriverNode->ListEntry.FilePath.Buffer)
1247  {
1248  Hive->Free(DriverNode->ListEntry.FilePath.Buffer,
1249  DriverNode->ListEntry.FilePath.MaximumLength);
1250  }
1251  if (DriverNode->Name.Buffer)
1252  {
1253  Hive->Free(DriverNode->Name.Buffer,
1254  DriverNode->Name.MaximumLength);
1255  }
1256  Hive->Free(DriverNode, sizeof(BOOT_DRIVER_NODE));
1257  }
1258 }
BOOT_DRIVER_LIST_ENTRY ListEntry
Definition: cmboot.h:15
struct _Entry Entry
Definition: kefuncs.h:629
USHORT MaximumLength
Definition: env_spec_w32.h:370
UNICODE_STRING FilePath
Definition: arc.h:201
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
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
UNICODE_STRING Name
Definition: cmboot.h:17
Definition: typedefs.h:119
UNICODE_STRING RegistryPath
Definition: arc.h:202
base of all file and directory entries
Definition: entries.h:82

Referenced by CmGetSystemDriverList(), and WinLdrScanRegistry().

◆ CmpResolveDriverDependencies()

BOOLEAN NTAPI CmpResolveDriverDependencies ( _Inout_ PLIST_ENTRY  DriverListHead)

Removes potential circular dependencies (cycles) and sorts the driver list.

Parameters
[in,out]DriverListHeadThe driver list to sort.
Returns
Always TRUE.

Definition at line 1030 of file cmboot.c.

1032 {
1033  PLIST_ENTRY NextEntry;
1034  PBOOT_DRIVER_NODE StartNode, EndNode, CurrentNode;
1035 
1036  /* Loop the list */
1037  NextEntry = DriverListHead->Flink;
1038  while (NextEntry != DriverListHead)
1039  {
1040  /* Find the first entry */
1041  StartNode = CONTAINING_RECORD(NextEntry,
1043  ListEntry.Link);
1044  do
1045  {
1046  /* Find the last entry */
1047  EndNode = CONTAINING_RECORD(NextEntry,
1049  ListEntry.Link);
1050 
1051  /* Get the next entry */
1052  NextEntry = NextEntry->Flink;
1053  CurrentNode = CONTAINING_RECORD(NextEntry,
1055  ListEntry.Link);
1056 
1057  /* If the next entry is back to the top, break out */
1058  if (NextEntry == DriverListHead) break;
1059 
1060  /* Otherwise, check if this entry is equal */
1061  if (!RtlEqualUnicodeString(&StartNode->Group,
1062  &CurrentNode->Group,
1063  TRUE))
1064  {
1065  /* It is, so we've detected a cycle, break out */
1066  break;
1067  }
1068  } while (NextEntry != DriverListHead);
1069 
1070  /* Now we have the correct start and end pointers, so do the sort */
1071  CmpOrderGroup(StartNode, EndNode);
1072  }
1073 
1074  /* We're done */
1075  return TRUE;
1076 }
#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:121
static BOOLEAN CmpOrderGroup(_In_ PBOOT_DRIVER_NODE StartNode, _In_ PBOOT_DRIVER_NODE EndNode)
Definition: cmboot.c:956
Definition: typedefs.h:119
UNICODE_STRING Group
Definition: cmboot.h:16
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)

Referenced by CmGetSystemDriverList(), and WinLdrScanRegistry().

◆ CmpSortDriverList()

BOOLEAN NTAPI CmpSortDriverList ( _In_ PHHIVE  Hive,
_In_ HCELL_INDEX  ControlSet,
_Inout_ PLIST_ENTRY  DriverListHead 
)

Sorts the driver list, according to the drivers' group load ordering.

Parameters
[in]HiveThe SYSTEM hive.
[in]ControlSetThe control set registry key's hive cell.
[in,out]DriverListHeadThe driver list to sort.
Returns
TRUE if sorting has been successfully done, FALSE if not.

Definition at line 902 of file cmboot.c.

906 {
908  PCM_KEY_VALUE ListValue;
909  HCELL_INDEX ControlCell, GroupOrder, ListCell;
910  UNICODE_STRING Name, OrderList;
911  ULONG Length;
912 
913  /* Sanity check: We shouldn't need to release any acquired cells */
914  ASSERT(Hive->ReleaseCellRoutine == NULL);
915 
916  /* Open the control key */
917  Node = (PCM_KEY_NODE)HvGetCell(Hive, ControlSet);
918  if (!Node) return FALSE;
919  RtlInitUnicodeString(&Name, L"Control");
920  ControlCell = CmpFindSubKeyByName(Hive, Node, &Name);
921  if (ControlCell == HCELL_NIL) return FALSE;
922 
923  /* Open the service group order */
924  Node = (PCM_KEY_NODE)HvGetCell(Hive, ControlCell);
925  if (!Node) return FALSE;
926  RtlInitUnicodeString(&Name, L"ServiceGroupOrder");
927  GroupOrder = CmpFindSubKeyByName(Hive, Node, &Name);
928  if (GroupOrder == HCELL_NIL) return FALSE;
929 
930  /* Open the list key */
931  Node = (PCM_KEY_NODE)HvGetCell(Hive, GroupOrder);
932  if (!Node) return FALSE;
933  RtlInitUnicodeString(&Name, L"list");
934  ListCell = CmpFindValueByName(Hive, Node, &Name);
935  if (ListCell == HCELL_NIL) return FALSE;
936 
937  /* Read the actual list */
938  ListValue = (PCM_KEY_VALUE)HvGetCell(Hive, ListCell);
939  if (!ListValue) return FALSE;
940  if (ListValue->Type != REG_MULTI_SZ) return FALSE;
941 
942  /* Copy it into a buffer */
943  OrderList.Buffer = (PWCHAR)CmpValueToData(Hive, ListValue, &Length);
944  if (!OrderList.Buffer) return FALSE;
945  if (!IS_NULL_TERMINATED(OrderList.Buffer, Length)) return FALSE;
946  OrderList.Length = (USHORT)Length - sizeof(UNICODE_NULL);
947  OrderList.MaximumLength = OrderList.Length;
948 
949  /* And start the sort algorithm */
950  return CmpDoSort(DriverListHead, &OrderList);
951 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define HCELL_NIL
Definition: hivedata.h:85
uint16_t * PWCHAR
Definition: typedefs.h:56
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:381
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
union node Node
Definition: types.h:1255
#define REG_MULTI_SZ
Definition: nt_native.h:1501
struct NameRec_ * Name
Definition: cdprocs.h:459
struct _CM_KEY_NODE * PCM_KEY_NODE
static BOOLEAN CmpDoSort(_Inout_ PLIST_ENTRY DriverListHead, _In_ PCUNICODE_STRING OrderList)
Performs the driver list sorting, according to the ordering list.
Definition: cmboot.c:828
PCELL_DATA NTAPI CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
Definition: cmvalue.c:167
#define ASSERT(a)
Definition: mode.c:44
ULONG HCELL_INDEX
Definition: hivedata.h:80
unsigned short USHORT
Definition: pedump.c:61
HCELL_INDEX NTAPI CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PCUNICODE_STRING Name)
Definition: cmvalue.c:99
struct _CM_KEY_VALUE * PCM_KEY_VALUE
ULONG Type
Definition: cmdata.h:128
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define IS_NULL_TERMINATED(Buffer, Size)
Definition: cmboot.c:41
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(), and WinLdrScanRegistry().