xref: /reactos/ntoskrnl/ke/config.c (revision b5218987)
1 /*
2  * PROJECT:         ReactOS Kernel
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            ntoskrnl/ke/config.c
5  * PURPOSE:         Configuration Tree Routines
6  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* FUNCTIONS *****************************************************************/
16 
17 /*
18  * @implemented
19  */
20 INIT_FUNCTION
21 PCONFIGURATION_COMPONENT_DATA
22 NTAPI
23 KeFindConfigurationEntry(IN PCONFIGURATION_COMPONENT_DATA Child,
24                          IN CONFIGURATION_CLASS Class,
25                          IN CONFIGURATION_TYPE Type,
26                          IN PULONG ComponentKey OPTIONAL)
27 {
28     PCONFIGURATION_COMPONENT_DATA NextLink = NULL;
29 
30     /* Start Search at Root */
31     return KeFindConfigurationNextEntry(Child,
32                                         Class,
33                                         Type,
34                                         ComponentKey,
35                                         &NextLink);
36 }
37 
38 /*
39  * @implemented
40  */
41 INIT_FUNCTION
42 PCONFIGURATION_COMPONENT_DATA
43 NTAPI
44 KeFindConfigurationNextEntry(IN PCONFIGURATION_COMPONENT_DATA Child,
45                              IN CONFIGURATION_CLASS Class,
46                              IN CONFIGURATION_TYPE Type,
47                              IN PULONG ComponentKey OPTIONAL,
48                              IN PCONFIGURATION_COMPONENT_DATA *NextLink)
49 {
50     ULONG Key = 0;
51     ULONG Mask = 0;
52     PCONFIGURATION_COMPONENT_DATA Sibling;
53     PCONFIGURATION_COMPONENT_DATA ReturnEntry;
54 
55     /* If we did get a key, then use it instead */
56     if (ComponentKey)
57     {
58         Key = *ComponentKey;
59         Mask = -1;
60     }
61 
62     /* Loop the Components until we find a a match */
63     while (Child)
64     {
65         /* Check if we are starting somewhere already */
66         if (*NextLink)
67         {
68             /* If we've found the place where we started, clear and continue */
69             if (Child == *NextLink) *NextLink = NULL;
70         }
71         else
72         {
73             /* Try to get a match */
74             if ((Child->ComponentEntry.Class) == Class &&
75                 (Child->ComponentEntry.Type) == Type &&
76                 (Child->ComponentEntry.Key & Mask) == Key)
77             {
78                 /* Match found */
79                 return Child;
80             }
81         }
82 
83         /* Now we've also got to lookup the siblings */
84         Sibling = Child->Sibling;
85         while (Sibling)
86         {
87             /* Check if we are starting somewhere already */
88             if (*NextLink)
89             {
90                 /* If we've found the place where we started, clear and continue */
91                 if (Sibling == *NextLink) *NextLink = NULL;
92             }
93             else
94             {
95                 /* Try to get a match */
96                 if ((Sibling->ComponentEntry.Class == Class) &&
97                     (Sibling->ComponentEntry.Type == Type) &&
98                     (Sibling->ComponentEntry.Key & Mask) == Key)
99                 {
100                     /* Match found */
101                     return Sibling;
102                 }
103             }
104 
105             /* We've got to check if the Sibling has a Child as well */
106             if (Sibling->Child)
107             {
108                 /* We're just going to call ourselves again */
109                 ReturnEntry = KeFindConfigurationNextEntry(Sibling->Child,
110                                                            Class,
111                                                            Type,
112                                                            ComponentKey,
113                                                            NextLink);
114                 if (ReturnEntry) return ReturnEntry;
115             }
116 
117             /* Next Sibling */
118             Sibling = Sibling->Sibling;
119         }
120 
121         /* Next Child */
122         Child = Child->Child;
123     }
124 
125     /* If we got here, nothing was found */
126     return NULL;
127 }
128