ReactOS 0.4.17-dev-1281-g065abb3
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_NODE * PBOOT_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.
 
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.
 
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.
 
BOOLEAN NTAPI CmpResolveDriverDependencies (_Inout_ PLIST_ENTRY DriverListHead)
 Removes potential circular dependencies (cycles) and sorts the driver list.
 
VOID NTAPI CmpFreeDriverList (_In_ PHHIVE Hive, _Inout_ PLIST_ENTRY DriverListHead)
 Empties the driver list and frees all allocated driver nodes in it.
 

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 82 of file cmboot.c.

87{
90 HCELL_INDEX SelectCell, AutoSelectCell, SelectValueCell, ControlSetCell;
91 HCELL_INDEX CurrentValueCell;
95 PULONG CurrentData;
96 PULONG ControlSetId;
97 WCHAR Buffer[128];
98
99 /* Sanity check: We shouldn't need to release any acquired cells */
101
102 /* Get the Select key */
103 RtlInitUnicodeString(&Name, L"select");
105 if (!Node) return HCELL_NIL;
106 SelectCell = CmpFindSubKeyByName(SystemHive, Node, &Name);
107 if (SelectCell == HCELL_NIL) return HCELL_NIL;
108
109 /* Get AutoSelect value */
110 RtlInitUnicodeString(&Name, L"AutoSelect");
111 Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
112 if (!Node) return HCELL_NIL;
113 AutoSelectCell = CmpFindValueByName(SystemHive, Node, &Name);
114 if (AutoSelectCell == HCELL_NIL)
115 {
116 /* Assume TRUE if the value is missing */
117 *AutoSelect = TRUE;
118 }
119 else
120 {
121 /* Read the value */
122 Value = (PCM_KEY_VALUE)HvGetCell(SystemHive, AutoSelectCell);
123 if (!Value) return HCELL_NIL;
124 // if (Value->Type != REG_DWORD) return HCELL_NIL;
125
126 /* Convert it to a boolean */
127 CurrentData = (PULONG)CmpValueToData(SystemHive, Value, &Length);
128 if (!CurrentData) return HCELL_NIL;
129 // if (Length < sizeof(ULONG)) return HCELL_NIL;
130
131 *AutoSelect = *(PBOOLEAN)CurrentData;
132 }
133
134 /* Now find the control set being looked up */
135 Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
136 if (!Node) return HCELL_NIL;
137 SelectValueCell = CmpFindValueByName(SystemHive, Node, SelectKeyName);
138 if (SelectValueCell == HCELL_NIL) return HCELL_NIL;
139
140 /* Read the value (corresponding to the CCS ID) */
141 Value = (PCM_KEY_VALUE)HvGetCell(SystemHive, SelectValueCell);
142 if (!Value) return HCELL_NIL;
143 if (Value->Type != REG_DWORD) return HCELL_NIL;
144 ControlSetId = (PULONG)CmpValueToData(SystemHive, Value, &Length);
145 if (!ControlSetId) return HCELL_NIL;
146 if (Length < sizeof(ULONG)) return HCELL_NIL;
147
148 /* Now build the CCS's Name */
150 L"ControlSet%03lu", *ControlSetId);
151 if (!NT_SUCCESS(Status)) return HCELL_NIL;
152 /* RtlStringCbPrintfW ensures the buffer to be NULL-terminated */
154
155 /* Now open it */
157 if (!Node) return HCELL_NIL;
158 ControlSetCell = CmpFindSubKeyByName(SystemHive, Node, &Name);
159 if (ControlSetCell == HCELL_NIL) return HCELL_NIL;
160
161 /* Get the value of the "Current" CCS */
162 RtlInitUnicodeString(&Name, L"Current");
163 Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
164 if (!Node) return HCELL_NIL;
165 CurrentValueCell = CmpFindValueByName(SystemHive, Node, &Name);
166
167 /* Make sure it exists */
168 if (CurrentValueCell != HCELL_NIL)
169 {
170 /* Get the current value and make sure it's a ULONG */
171 Value = (PCM_KEY_VALUE)HvGetCell(SystemHive, CurrentValueCell);
172 if (!Value) return HCELL_NIL;
173 if (Value->Type == REG_DWORD)
174 {
175 /* Get the data and update it */
176 CurrentData = (PULONG)CmpValueToData(SystemHive, Value, &Length);
177 if (!CurrentData) return HCELL_NIL;
178 if (Length < sizeof(ULONG)) return HCELL_NIL;
179
180 *CurrentData = *ControlSetId;
181 }
182 }
183
184 /* Return the CCS cell */
185 return ControlSetCell;
186}
LONG NTSTATUS
Definition: precomp.h:26
PHHIVE SystemHive
Definition: registry.c:33
Definition: bufpool.h:45
struct _CM_KEY_NODE * PCM_KEY_NODE
struct _CM_KEY_VALUE * PCM_KEY_VALUE
HCELL_INDEX NTAPI CmpFindSubKeyByName(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName)
Definition: cmindex.c:683
HCELL_INDEX NTAPI CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PCUNICODE_STRING Name)
Definition: cmvalue.c:99
PCELL_DATA NTAPI CmpValueToData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length)
Definition: cmvalue.c:167
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:473
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
union node Node
Definition: types.h:1255
#define L(x)
Definition: resources.c:13
Status
Definition: gdiplustypes.h:24
#define HCELL_NIL
Definition: hivedata.h:110
ULONG HCELL_INDEX
Definition: hivedata.h:105
#define ASSERT(a)
Definition: mode.c:44
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
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
short WCHAR
Definition: pedump.c:58
#define REG_DWORD
Definition: sdbapi.c:615
PRELEASE_CELL_ROUTINE ReleaseCellRoutine
Definition: hivedata.h:317
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PBOOLEAN
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
Definition: dlist.c:348
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

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 677 of file cmboot.c.

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

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 1222 of file cmboot.c.

1225{
1227 PBOOT_DRIVER_NODE DriverNode;
1228
1229 /* Loop through the list and remove each driver node */
1230 while (!IsListEmpty(DriverListHead))
1231 {
1232 /* Get the driver node */
1233 Entry = RemoveHeadList(DriverListHead);
1234 DriverNode = CONTAINING_RECORD(Entry,
1236 ListEntry.Link);
1237
1238 /* Free any allocated string buffers, then the node */
1239 if (DriverNode->ListEntry.RegistryPath.Buffer)
1240 {
1241 Hive->Free(DriverNode->ListEntry.RegistryPath.Buffer,
1243 }
1244 if (DriverNode->ListEntry.FilePath.Buffer)
1245 {
1246 Hive->Free(DriverNode->ListEntry.FilePath.Buffer,
1247 DriverNode->ListEntry.FilePath.MaximumLength);
1248 }
1249 if (DriverNode->Name.Buffer)
1250 {
1251 Hive->Free(DriverNode->Name.Buffer,
1252 DriverNode->Name.MaximumLength);
1253 }
1254 Hive->Free(DriverNode, sizeof(BOOT_DRIVER_NODE));
1255 }
1256}
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
UNICODE_STRING RegistryPath
Definition: arc.h:337
UNICODE_STRING FilePath
Definition: arc.h:336
BOOT_DRIVER_LIST_ENTRY ListEntry
Definition: cmboot.h:15
UNICODE_STRING Name
Definition: cmboot.h:17
Definition: typedefs.h:120
USHORT MaximumLength
Definition: env_spec_w32.h:370

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 1028 of file cmboot.c.

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

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 900 of file cmboot.c.

904{
906 PCM_KEY_VALUE ListValue;
907 HCELL_INDEX ControlCell, GroupOrder, ListCell;
908 UNICODE_STRING Name, OrderList;
910
911 /* Sanity check: We shouldn't need to release any acquired cells */
912 ASSERT(Hive->ReleaseCellRoutine == NULL);
913
914 /* Open the control key */
915 Node = (PCM_KEY_NODE)HvGetCell(Hive, ControlSet);
916 if (!Node) return FALSE;
917 RtlInitUnicodeString(&Name, L"Control");
918 ControlCell = CmpFindSubKeyByName(Hive, Node, &Name);
919 if (ControlCell == HCELL_NIL) return FALSE;
920
921 /* Open the service group order */
922 Node = (PCM_KEY_NODE)HvGetCell(Hive, ControlCell);
923 if (!Node) return FALSE;
924 RtlInitUnicodeString(&Name, L"ServiceGroupOrder");
925 GroupOrder = CmpFindSubKeyByName(Hive, Node, &Name);
926 if (GroupOrder == HCELL_NIL) return FALSE;
927
928 /* Open the list key */
929 Node = (PCM_KEY_NODE)HvGetCell(Hive, GroupOrder);
930 if (!Node) return FALSE;
931 RtlInitUnicodeString(&Name, L"list");
932 ListCell = CmpFindValueByName(Hive, Node, &Name);
933 if (ListCell == HCELL_NIL) return FALSE;
934
935 /* Read the actual list */
936 ListValue = (PCM_KEY_VALUE)HvGetCell(Hive, ListCell);
937 if (!ListValue) return FALSE;
938 if (ListValue->Type != REG_MULTI_SZ) return FALSE;
939
940 /* Copy it into a buffer */
941 OrderList.Buffer = (PWCHAR)CmpValueToData(Hive, ListValue, &Length);
942 if (!OrderList.Buffer) return FALSE;
943 if (!IS_NULL_TERMINATED(OrderList.Buffer, Length)) return FALSE;
944 OrderList.Length = (USHORT)Length - sizeof(UNICODE_NULL);
945 OrderList.MaximumLength = OrderList.Length;
946
947 /* And start the sort algorithm */
948 return CmpDoSort(DriverListHead, &OrderList);
949}
#define IS_NULL_TERMINATED(Buffer, Size)
Definition: cmboot.c:41
static BOOLEAN CmpDoSort(_Inout_ PLIST_ENTRY DriverListHead, _In_ PCUNICODE_STRING OrderList)
Performs the driver list sorting, according to the ordering list.
Definition: cmboot.c:826
#define REG_MULTI_SZ
Definition: nt_native.h:1504
#define UNICODE_NULL
unsigned short USHORT
Definition: pedump.c:61
ULONG Type
Definition: cmdata.h:128
uint16_t * PWCHAR
Definition: typedefs.h:56

Referenced by CmGetSystemDriverList(), and WinLdrScanRegistry().