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