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 } 187