ReactOS 0.4.15-dev-8100-g1887773
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.
 
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 84 of file cmboot.c.

89{
92 HCELL_INDEX SelectCell, AutoSelectCell, SelectValueCell, ControlSetCell;
93 HCELL_INDEX CurrentValueCell;
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");
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 */
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}
struct NameRec_ * Name
Definition: cdprocs.h:460
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:457
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
union node Node
Definition: types.h:1255
Status
Definition: gdiplustypes.h:25
#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
#define L(x)
Definition: ntvdm.h:50
#define REG_DWORD
Definition: sdbapi.c:596
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
__wchar_t WCHAR
Definition: xmlstorage.h:180

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 */
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 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:618
static BOOLEAN CmpIsSafe(_In_ PHHIVE Hive, _In_ HCELL_INDEX SafeBootCell, _In_ HCELL_INDEX DriverCell)
Definition: cmboot.c:1081
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
ULONG InitSafeBootMode
Definition: init.c:71
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
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
ULONG ErrorControl
Definition: cmboot.h:19
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
PCWSTR BootFileSystem
Definition: winldr.c:30
#define SERVICE_ERROR_CRITICAL
Definition: cmtypes.h:984

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,
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}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
base of all file and directory entries
Definition: entries.h:83
UNICODE_STRING RegistryPath
Definition: arc.h:249
UNICODE_STRING FilePath
Definition: arc.h:248
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 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}
static BOOLEAN CmpOrderGroup(_In_ PBOOT_DRIVER_NODE StartNode, _In_ PBOOT_DRIVER_NODE EndNode)
Definition: cmboot.c:956
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 902 of file cmboot.c.

906{
908 PCM_KEY_VALUE ListValue;
909 HCELL_INDEX ControlCell, GroupOrder, ListCell;
910 UNICODE_STRING Name, OrderList;
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}
#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:828
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#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().