xref: /reactos/dll/win32/iphlpapi/registry.c (revision 9393fc32)
1 #include "iphlpapi_private.h"
2 
GetLongestChildKeyName(HANDLE RegHandle)3 int GetLongestChildKeyName( HANDLE RegHandle ) {
4   LONG Status;
5   DWORD MaxAdapterName;
6 
7   Status = RegQueryInfoKeyW(RegHandle,
8 			    NULL,
9 			    NULL,
10 			    NULL,
11 			    NULL,
12 			    &MaxAdapterName,
13 			    NULL,
14 			    NULL,
15 			    NULL,
16 			    NULL,
17 			    NULL,
18 			    NULL);
19   if (Status == ERROR_SUCCESS)
20     return MaxAdapterName + 1;
21   else
22     return -1;
23 }
24 
OpenChildKeyRead(HANDLE RegHandle,PWCHAR ChildKeyName,PHKEY ReturnHandle)25 LONG OpenChildKeyRead( HANDLE RegHandle,
26 		       PWCHAR ChildKeyName,
27 		       PHKEY ReturnHandle ) {
28   return RegOpenKeyExW( RegHandle,
29 			ChildKeyName,
30 			0,
31 			KEY_READ,
32 			ReturnHandle );
33 }
34 
35 /*
36  * Yields a malloced value that must be freed.
37  */
38 
GetNthChildKeyName(HANDLE RegHandle,DWORD n)39 PWCHAR GetNthChildKeyName( HANDLE RegHandle, DWORD n ) {
40   LONG Status;
41   int MaxAdapterName = GetLongestChildKeyName( RegHandle );
42   PWCHAR Value;
43   DWORD ValueLen;
44 
45   if (MaxAdapterName == -1)
46     return 0;
47 
48   ValueLen = MaxAdapterName;
49   Value = (PWCHAR)HeapAlloc( GetProcessHeap(), 0, MaxAdapterName * sizeof(WCHAR) );
50   if (!Value) return 0;
51 
52   Status = RegEnumKeyExW( RegHandle, n, Value, &ValueLen,
53 			  NULL, NULL, NULL, NULL );
54   if (Status != ERROR_SUCCESS) {
55     HeapFree(GetProcessHeap(), 0, Value);
56     return 0;
57   } else {
58     Value[ValueLen] = 0;
59     return Value;
60   }
61 }
62 
ConsumeChildKeyName(PWCHAR Name)63 void ConsumeChildKeyName( PWCHAR Name ) {
64   if (Name) HeapFree( GetProcessHeap(), 0, Name );
65 }
66 
QueryRegistryValue(HANDLE RegHandle,PWCHAR ValueName,LPDWORD RegistryType,LPDWORD Length)67 PVOID QueryRegistryValue(HANDLE RegHandle, PWCHAR ValueName, LPDWORD RegistryType, LPDWORD Length)
68 {
69     PVOID ReadValue = NULL;
70     DWORD Error;
71 
72     *Length = 0;
73     *RegistryType = REG_NONE;
74 
75     while (TRUE)
76     {
77         Error = RegQueryValueExW(RegHandle, ValueName, NULL, RegistryType, ReadValue, Length);
78         if (Error == ERROR_SUCCESS)
79         {
80             if (ReadValue) break;
81         }
82         else if (Error == ERROR_MORE_DATA)
83         {
84             HeapFree(GetProcessHeap(), 0, ReadValue);
85         }
86         else break;
87 
88         ReadValue = HeapAlloc(GetProcessHeap(), 0, *Length);
89         if (!ReadValue) return NULL;
90     }
91 
92     if (Error != ERROR_SUCCESS)
93     {
94         if (ReadValue) HeapFree(GetProcessHeap(), 0, ReadValue);
95 
96         *Length = 0;
97         *RegistryType = REG_NONE;
98         ReadValue = NULL;
99     }
100 
101     return ReadValue;
102 }
103 
TerminateReadString(PWCHAR String,DWORD Length)104 PWCHAR TerminateReadString(PWCHAR String, DWORD Length)
105 {
106     PWCHAR TerminatedString;
107 
108     TerminatedString = HeapAlloc(GetProcessHeap(), 0, Length + sizeof(WCHAR));
109     if (TerminatedString == NULL)
110         return NULL;
111 
112     memcpy(TerminatedString, String, Length);
113 
114     TerminatedString[Length / sizeof(WCHAR)] = UNICODE_NULL;
115 
116     return TerminatedString;
117 }
118 
QueryRegistryValueString(HANDLE RegHandle,PWCHAR ValueName)119 PWCHAR QueryRegistryValueString( HANDLE RegHandle, PWCHAR ValueName )
120 {
121     PWCHAR String, TerminatedString;
122     DWORD Type, Length;
123 
124     String = QueryRegistryValue(RegHandle, ValueName, &Type, &Length);
125     if (!String) return NULL;
126     if (Type != REG_SZ)
127     {
128         DbgPrint("Type mismatch for %S (%d != %d)\n", ValueName, Type, REG_SZ);
129         //HeapFree(GetProcessHeap(), 0, String);
130         //return NULL;
131     }
132 
133     TerminatedString = TerminateReadString(String, Length);
134     HeapFree(GetProcessHeap(), 0, String);
135     if (!TerminatedString) return NULL;
136 
137     return TerminatedString;
138 }
139 
ConsumeRegValueString(PWCHAR Value)140 void ConsumeRegValueString( PWCHAR Value ) {
141   if (Value) HeapFree(GetProcessHeap(), 0, Value);
142 }
143 
QueryRegistryValueStringMulti(HANDLE RegHandle,PWCHAR ValueName)144 PWCHAR *QueryRegistryValueStringMulti( HANDLE RegHandle, PWCHAR ValueName ) {
145     PWCHAR String, TerminatedString, Tmp;
146     PWCHAR *Table;
147     DWORD Type, Length, i, j;
148 
149     String = QueryRegistryValue(RegHandle, ValueName, &Type, &Length);
150     if (!String) return NULL;
151     if (Type != REG_MULTI_SZ)
152     {
153         DbgPrint("Type mismatch for %S (%d != %d)\n", ValueName, Type, REG_MULTI_SZ);
154         //HeapFree(GetProcessHeap(), 0, String);
155         //return NULL;
156     }
157 
158     TerminatedString = TerminateReadString(String, Length);
159     HeapFree(GetProcessHeap(), 0, String);
160     if (!TerminatedString) return NULL;
161 
162     for (Tmp = TerminatedString, i = 0; *Tmp; Tmp++, i++) while (*Tmp) Tmp++;
163 
164     Table = HeapAlloc(GetProcessHeap(), 0, (i + 1) * sizeof(PWCHAR));
165     if (!Table)
166     {
167         HeapFree(GetProcessHeap(), 0, TerminatedString);
168         return NULL;
169     }
170 
171     for (Tmp = TerminatedString, j = 0; *Tmp; Tmp++, j++)
172     {
173         PWCHAR Orig = Tmp;
174 
175         for (i = 0; *Tmp; i++, Tmp++);
176 
177         Table[j] = HeapAlloc(GetProcessHeap(), 0, i * sizeof(WCHAR));
178         memcpy(Table[j], Orig, i * sizeof(WCHAR));
179     }
180 
181     Table[j] = NULL;
182 
183     HeapFree(GetProcessHeap(), 0, TerminatedString);
184 
185     return Table;
186 }
187