Synchronize with trunk revision 59636 (just before Alex's CreateProcess revamp).
[reactos.git] / dll / win32 / iphlpapi / registry.c
1 #include "iphlpapi_private.h"
2
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
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
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
63 void ConsumeChildKeyName( PWCHAR Name ) {
64 if (Name) HeapFree( GetProcessHeap(), 0, Name );
65 }
66
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
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
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
140 void ConsumeRegValueString( PWCHAR Value ) {
141 if (Value) HeapFree(GetProcessHeap(), 0, Value);
142 }
143
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 }