diff options
Diffstat (limited to '')
-rw-r--r-- | src/dutil/regutil.cpp | 137 |
1 files changed, 76 insertions, 61 deletions
diff --git a/src/dutil/regutil.cpp b/src/dutil/regutil.cpp index 1b13af81..e1ef19e8 100644 --- a/src/dutil/regutil.cpp +++ b/src/dutil/regutil.cpp | |||
@@ -2,6 +2,21 @@ | |||
2 | 2 | ||
3 | #include "precomp.h" | 3 | #include "precomp.h" |
4 | 4 | ||
5 | |||
6 | // Exit macros | ||
7 | #define RegExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_REGUTIL, x, s, __VA_ARGS__) | ||
8 | #define RegExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_REGUTIL, x, s, __VA_ARGS__) | ||
9 | #define RegExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_REGUTIL, x, s, __VA_ARGS__) | ||
10 | #define RegExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_REGUTIL, x, s, __VA_ARGS__) | ||
11 | #define RegExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_REGUTIL, x, s, __VA_ARGS__) | ||
12 | #define RegExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_REGUTIL, x, s, __VA_ARGS__) | ||
13 | #define RegExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_REGUTIL, p, x, e, s, __VA_ARGS__) | ||
14 | #define RegExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_REGUTIL, p, x, s, __VA_ARGS__) | ||
15 | #define RegExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_REGUTIL, p, x, e, s, __VA_ARGS__) | ||
16 | #define RegExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_REGUTIL, p, x, s, __VA_ARGS__) | ||
17 | #define RegExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_REGUTIL, e, x, s, __VA_ARGS__) | ||
18 | #define RegExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_REGUTIL, g, x, s, __VA_ARGS__) | ||
19 | |||
5 | static PFN_REGCREATEKEYEXW vpfnRegCreateKeyExW = ::RegCreateKeyExW; | 20 | static PFN_REGCREATEKEYEXW vpfnRegCreateKeyExW = ::RegCreateKeyExW; |
6 | static PFN_REGOPENKEYEXW vpfnRegOpenKeyExW = ::RegOpenKeyExW; | 21 | static PFN_REGOPENKEYEXW vpfnRegOpenKeyExW = ::RegOpenKeyExW; |
7 | static PFN_REGDELETEKEYEXW vpfnRegDeleteKeyExW = NULL; | 22 | static PFN_REGDELETEKEYEXW vpfnRegDeleteKeyExW = NULL; |
@@ -34,7 +49,7 @@ extern "C" HRESULT DAPI RegInitialize( | |||
34 | HRESULT hr = S_OK; | 49 | HRESULT hr = S_OK; |
35 | 50 | ||
36 | hr = LoadSystemLibrary(L"AdvApi32.dll", &vhAdvApi32Dll); | 51 | hr = LoadSystemLibrary(L"AdvApi32.dll", &vhAdvApi32Dll); |
37 | ExitOnFailure(hr, "Failed to load AdvApi32.dll"); | 52 | RegExitOnFailure(hr, "Failed to load AdvApi32.dll"); |
38 | 53 | ||
39 | // ignore failures - if this doesn't exist, we'll fall back to RegDeleteKeyW | 54 | // ignore failures - if this doesn't exist, we'll fall back to RegDeleteKeyW |
40 | vpfnRegDeleteKeyExWFromLibrary = reinterpret_cast<PFN_REGDELETEKEYEXW>(::GetProcAddress(vhAdvApi32Dll, "RegDeleteKeyExW")); | 55 | vpfnRegDeleteKeyExWFromLibrary = reinterpret_cast<PFN_REGDELETEKEYEXW>(::GetProcAddress(vhAdvApi32Dll, "RegDeleteKeyExW")); |
@@ -114,7 +129,7 @@ extern "C" HRESULT DAPI RegCreate( | |||
114 | DWORD er = ERROR_SUCCESS; | 129 | DWORD er = ERROR_SUCCESS; |
115 | 130 | ||
116 | er = vpfnRegCreateKeyExW(hkRoot, wzSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, dwAccess, NULL, phk, NULL); | 131 | er = vpfnRegCreateKeyExW(hkRoot, wzSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, dwAccess, NULL, phk, NULL); |
117 | ExitOnWin32Error(er, hr, "Failed to create registry key."); | 132 | RegExitOnWin32Error(er, hr, "Failed to create registry key."); |
118 | 133 | ||
119 | LExit: | 134 | LExit: |
120 | return hr; | 135 | return hr; |
@@ -140,7 +155,7 @@ HRESULT DAPI RegCreateEx( | |||
140 | DWORD dwDisposition; | 155 | DWORD dwDisposition; |
141 | 156 | ||
142 | er = vpfnRegCreateKeyExW(hkRoot, wzSubKey, 0, NULL, fVolatile ? REG_OPTION_VOLATILE : REG_OPTION_NON_VOLATILE, dwAccess, pSecurityAttributes, phk, &dwDisposition); | 157 | er = vpfnRegCreateKeyExW(hkRoot, wzSubKey, 0, NULL, fVolatile ? REG_OPTION_VOLATILE : REG_OPTION_NON_VOLATILE, dwAccess, pSecurityAttributes, phk, &dwDisposition); |
143 | ExitOnWin32Error(er, hr, "Failed to create registry key."); | 158 | RegExitOnWin32Error(er, hr, "Failed to create registry key."); |
144 | 159 | ||
145 | if (pfCreated) | 160 | if (pfCreated) |
146 | { | 161 | { |
@@ -171,7 +186,7 @@ extern "C" HRESULT DAPI RegOpen( | |||
171 | { | 186 | { |
172 | ExitFunction1(hr = E_FILENOTFOUND); | 187 | ExitFunction1(hr = E_FILENOTFOUND); |
173 | } | 188 | } |
174 | ExitOnWin32Error(er, hr, "Failed to open registry key."); | 189 | RegExitOnWin32Error(er, hr, "Failed to open registry key."); |
175 | 190 | ||
176 | LExit: | 191 | LExit: |
177 | return hr; | 192 | return hr; |
@@ -199,7 +214,7 @@ extern "C" HRESULT DAPI RegDelete( | |||
199 | if (!vfRegInitialized && REG_KEY_DEFAULT != kbKeyBitness) | 214 | if (!vfRegInitialized && REG_KEY_DEFAULT != kbKeyBitness) |
200 | { | 215 | { |
201 | hr = E_INVALIDARG; | 216 | hr = E_INVALIDARG; |
202 | ExitOnFailure(hr, "RegInitialize must be called first in order to RegDelete() a key with non-default bit attributes!"); | 217 | RegExitOnFailure(hr, "RegInitialize must be called first in order to RegDelete() a key with non-default bit attributes!"); |
203 | } | 218 | } |
204 | 219 | ||
205 | switch (kbKeyBitness) | 220 | switch (kbKeyBitness) |
@@ -222,18 +237,18 @@ extern "C" HRESULT DAPI RegDelete( | |||
222 | { | 237 | { |
223 | ExitFunction1(hr = S_OK); | 238 | ExitFunction1(hr = S_OK); |
224 | } | 239 | } |
225 | ExitOnFailure(hr, "Failed to open this key for enumerating subkeys", wzSubKey); | 240 | RegExitOnFailure(hr, "Failed to open this key for enumerating subkeys: %ls", wzSubKey); |
226 | 241 | ||
227 | // Yes, keep enumerating the 0th item, because we're deleting it every time | 242 | // Yes, keep enumerating the 0th item, because we're deleting it every time |
228 | while (E_NOMOREITEMS != (hr = RegKeyEnum(hkKey, 0, &pszEnumeratedSubKey))) | 243 | while (E_NOMOREITEMS != (hr = RegKeyEnum(hkKey, 0, &pszEnumeratedSubKey))) |
229 | { | 244 | { |
230 | ExitOnFailure(hr, "Failed to enumerate key 0"); | 245 | RegExitOnFailure(hr, "Failed to enumerate key 0"); |
231 | 246 | ||
232 | hr = PathConcat(wzSubKey, pszEnumeratedSubKey, &pszRecursiveSubKey); | 247 | hr = PathConcat(wzSubKey, pszEnumeratedSubKey, &pszRecursiveSubKey); |
233 | ExitOnFailure(hr, "Failed to concatenate paths while recursively deleting subkeys. Path1: %ls, Path2: %ls", wzSubKey, pszEnumeratedSubKey); | 248 | RegExitOnFailure(hr, "Failed to concatenate paths while recursively deleting subkeys. Path1: %ls, Path2: %ls", wzSubKey, pszEnumeratedSubKey); |
234 | 249 | ||
235 | hr = RegDelete(hkRoot, pszRecursiveSubKey, kbKeyBitness, fDeleteTree); | 250 | hr = RegDelete(hkRoot, pszRecursiveSubKey, kbKeyBitness, fDeleteTree); |
236 | ExitOnFailure(hr, "Failed to recursively delete subkey: %ls", pszRecursiveSubKey); | 251 | RegExitOnFailure(hr, "Failed to recursively delete subkey: %ls", pszRecursiveSubKey); |
237 | } | 252 | } |
238 | 253 | ||
239 | hr = S_OK; | 254 | hr = S_OK; |
@@ -246,7 +261,7 @@ extern "C" HRESULT DAPI RegDelete( | |||
246 | { | 261 | { |
247 | ExitFunction1(hr = E_FILENOTFOUND); | 262 | ExitFunction1(hr = E_FILENOTFOUND); |
248 | } | 263 | } |
249 | ExitOnWin32Error(er, hr, "Failed to delete registry key (ex)."); | 264 | RegExitOnWin32Error(er, hr, "Failed to delete registry key (ex)."); |
250 | } | 265 | } |
251 | else | 266 | else |
252 | { | 267 | { |
@@ -255,7 +270,7 @@ extern "C" HRESULT DAPI RegDelete( | |||
255 | { | 270 | { |
256 | ExitFunction1(hr = E_FILENOTFOUND); | 271 | ExitFunction1(hr = E_FILENOTFOUND); |
257 | } | 272 | } |
258 | ExitOnWin32Error(er, hr, "Failed to delete registry key."); | 273 | RegExitOnWin32Error(er, hr, "Failed to delete registry key."); |
259 | } | 274 | } |
260 | 275 | ||
261 | LExit: | 276 | LExit: |
@@ -284,7 +299,7 @@ extern "C" HRESULT DAPI RegKeyEnum( | |||
284 | if (psczKey && *psczKey) | 299 | if (psczKey && *psczKey) |
285 | { | 300 | { |
286 | hr = StrMaxLength(*psczKey, reinterpret_cast<DWORD_PTR*>(&cch)); | 301 | hr = StrMaxLength(*psczKey, reinterpret_cast<DWORD_PTR*>(&cch)); |
287 | ExitOnFailure(hr, "Failed to determine length of string."); | 302 | RegExitOnFailure(hr, "Failed to determine length of string."); |
288 | } | 303 | } |
289 | 304 | ||
290 | if (2 > cch) | 305 | if (2 > cch) |
@@ -292,18 +307,18 @@ extern "C" HRESULT DAPI RegKeyEnum( | |||
292 | cch = 2; | 307 | cch = 2; |
293 | 308 | ||
294 | hr = StrAlloc(psczKey, cch); | 309 | hr = StrAlloc(psczKey, cch); |
295 | ExitOnFailure(hr, "Failed to allocate string to minimum size."); | 310 | RegExitOnFailure(hr, "Failed to allocate string to minimum size."); |
296 | } | 311 | } |
297 | 312 | ||
298 | er = vpfnRegEnumKeyExW(hk, dwIndex, *psczKey, &cch, NULL, NULL, NULL, NULL); | 313 | er = vpfnRegEnumKeyExW(hk, dwIndex, *psczKey, &cch, NULL, NULL, NULL, NULL); |
299 | if (ERROR_MORE_DATA == er) | 314 | if (ERROR_MORE_DATA == er) |
300 | { | 315 | { |
301 | er = vpfnRegQueryInfoKeyW(hk, NULL, NULL, NULL, NULL, &cch, NULL, NULL, NULL, NULL, NULL, NULL); | 316 | er = vpfnRegQueryInfoKeyW(hk, NULL, NULL, NULL, NULL, &cch, NULL, NULL, NULL, NULL, NULL, NULL); |
302 | ExitOnWin32Error(er, hr, "Failed to get max size of subkey name under registry key."); | 317 | RegExitOnWin32Error(er, hr, "Failed to get max size of subkey name under registry key."); |
303 | 318 | ||
304 | ++cch; // add one because RegQueryInfoKeyW() returns the length of the subkeys without the null terminator. | 319 | ++cch; // add one because RegQueryInfoKeyW() returns the length of the subkeys without the null terminator. |
305 | hr = StrAlloc(psczKey, cch); | 320 | hr = StrAlloc(psczKey, cch); |
306 | ExitOnFailure(hr, "Failed to allocate string bigger for enum registry key."); | 321 | RegExitOnFailure(hr, "Failed to allocate string bigger for enum registry key."); |
307 | 322 | ||
308 | er = vpfnRegEnumKeyExW(hk, dwIndex, *psczKey, &cch, NULL, NULL, NULL, NULL); | 323 | er = vpfnRegEnumKeyExW(hk, dwIndex, *psczKey, &cch, NULL, NULL, NULL, NULL); |
309 | } | 324 | } |
@@ -311,7 +326,7 @@ extern "C" HRESULT DAPI RegKeyEnum( | |||
311 | { | 326 | { |
312 | ExitFunction1(hr = E_NOMOREITEMS); | 327 | ExitFunction1(hr = E_NOMOREITEMS); |
313 | } | 328 | } |
314 | ExitOnWin32Error(er, hr, "Failed to enum registry key."); | 329 | RegExitOnWin32Error(er, hr, "Failed to enum registry key."); |
315 | 330 | ||
316 | // Always ensure the registry key name is null terminated. | 331 | // Always ensure the registry key name is null terminated. |
317 | #pragma prefast(push) | 332 | #pragma prefast(push) |
@@ -340,20 +355,20 @@ HRESULT DAPI RegValueEnum( | |||
340 | DWORD cbValueName = 0; | 355 | DWORD cbValueName = 0; |
341 | 356 | ||
342 | er = vpfnRegQueryInfoKeyW(hk, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &cbValueName, NULL, NULL, NULL); | 357 | er = vpfnRegQueryInfoKeyW(hk, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &cbValueName, NULL, NULL, NULL); |
343 | ExitOnWin32Error(er, hr, "Failed to get max size of value name under registry key."); | 358 | RegExitOnWin32Error(er, hr, "Failed to get max size of value name under registry key."); |
344 | 359 | ||
345 | // Add one for null terminator | 360 | // Add one for null terminator |
346 | ++cbValueName; | 361 | ++cbValueName; |
347 | 362 | ||
348 | hr = StrAlloc(psczName, cbValueName); | 363 | hr = StrAlloc(psczName, cbValueName); |
349 | ExitOnFailure(hr, "Failed to allocate array for registry value name"); | 364 | RegExitOnFailure(hr, "Failed to allocate array for registry value name"); |
350 | 365 | ||
351 | er = vpfnRegEnumValueW(hk, dwIndex, *psczName, &cbValueName, NULL, pdwType, NULL, NULL); | 366 | er = vpfnRegEnumValueW(hk, dwIndex, *psczName, &cbValueName, NULL, pdwType, NULL, NULL); |
352 | if (ERROR_NO_MORE_ITEMS == er) | 367 | if (ERROR_NO_MORE_ITEMS == er) |
353 | { | 368 | { |
354 | ExitFunction1(hr = E_NOMOREITEMS); | 369 | ExitFunction1(hr = E_NOMOREITEMS); |
355 | } | 370 | } |
356 | ExitOnWin32Error(er, hr, "Failed to enumerate registry value"); | 371 | RegExitOnWin32Error(er, hr, "Failed to enumerate registry value"); |
357 | 372 | ||
358 | LExit: | 373 | LExit: |
359 | return hr; | 374 | return hr; |
@@ -376,7 +391,7 @@ HRESULT DAPI RegGetType( | |||
376 | { | 391 | { |
377 | ExitFunction1(hr = E_FILENOTFOUND); | 392 | ExitFunction1(hr = E_FILENOTFOUND); |
378 | } | 393 | } |
379 | ExitOnWin32Error(er, hr, "Failed to read registry value."); | 394 | RegExitOnWin32Error(er, hr, "Failed to read registry value."); |
380 | LExit: | 395 | LExit: |
381 | 396 | ||
382 | return hr; | 397 | return hr; |
@@ -400,20 +415,20 @@ HRESULT DAPI RegReadBinary( | |||
400 | DWORD dwType = 0; | 415 | DWORD dwType = 0; |
401 | 416 | ||
402 | er = vpfnRegQueryValueExW(hk, wzName, NULL, &dwType, NULL, &cb); | 417 | er = vpfnRegQueryValueExW(hk, wzName, NULL, &dwType, NULL, &cb); |
403 | ExitOnWin32Error(er, hr, "Failed to get size of registry value."); | 418 | RegExitOnWin32Error(er, hr, "Failed to get size of registry value."); |
404 | 419 | ||
405 | // Zero-length binary values can exist | 420 | // Zero-length binary values can exist |
406 | if (0 < cb) | 421 | if (0 < cb) |
407 | { | 422 | { |
408 | pbBuffer = static_cast<LPBYTE>(MemAlloc(cb, FALSE)); | 423 | pbBuffer = static_cast<LPBYTE>(MemAlloc(cb, FALSE)); |
409 | ExitOnNull(pbBuffer, hr, E_OUTOFMEMORY, "Failed to allocate buffer for binary registry value."); | 424 | RegExitOnNull(pbBuffer, hr, E_OUTOFMEMORY, "Failed to allocate buffer for binary registry value."); |
410 | 425 | ||
411 | er = vpfnRegQueryValueExW(hk, wzName, NULL, &dwType, pbBuffer, &cb); | 426 | er = vpfnRegQueryValueExW(hk, wzName, NULL, &dwType, pbBuffer, &cb); |
412 | if (E_FILENOTFOUND == HRESULT_FROM_WIN32(er)) | 427 | if (E_FILENOTFOUND == HRESULT_FROM_WIN32(er)) |
413 | { | 428 | { |
414 | ExitFunction1(hr = E_FILENOTFOUND); | 429 | ExitFunction1(hr = E_FILENOTFOUND); |
415 | } | 430 | } |
416 | ExitOnWin32Error(er, hr, "Failed to read registry value."); | 431 | RegExitOnWin32Error(er, hr, "Failed to read registry value."); |
417 | } | 432 | } |
418 | 433 | ||
419 | if (REG_BINARY == dwType) | 434 | if (REG_BINARY == dwType) |
@@ -425,7 +440,7 @@ HRESULT DAPI RegReadBinary( | |||
425 | else | 440 | else |
426 | { | 441 | { |
427 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); | 442 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); |
428 | ExitOnRootFailure(hr, "Error reading binary registry value due to unexpected data type: %u", dwType); | 443 | RegExitOnRootFailure(hr, "Error reading binary registry value due to unexpected data type: %u", dwType); |
429 | } | 444 | } |
430 | 445 | ||
431 | LExit: | 446 | LExit: |
@@ -455,7 +470,7 @@ extern "C" HRESULT DAPI RegReadString( | |||
455 | if (psczValue && *psczValue) | 470 | if (psczValue && *psczValue) |
456 | { | 471 | { |
457 | hr = StrMaxLength(*psczValue, reinterpret_cast<DWORD_PTR*>(&cch)); | 472 | hr = StrMaxLength(*psczValue, reinterpret_cast<DWORD_PTR*>(&cch)); |
458 | ExitOnFailure(hr, "Failed to determine length of string."); | 473 | RegExitOnFailure(hr, "Failed to determine length of string."); |
459 | } | 474 | } |
460 | 475 | ||
461 | if (2 > cch) | 476 | if (2 > cch) |
@@ -463,7 +478,7 @@ extern "C" HRESULT DAPI RegReadString( | |||
463 | cch = 2; | 478 | cch = 2; |
464 | 479 | ||
465 | hr = StrAlloc(psczValue, cch); | 480 | hr = StrAlloc(psczValue, cch); |
466 | ExitOnFailure(hr, "Failed to allocate string to minimum size."); | 481 | RegExitOnFailure(hr, "Failed to allocate string to minimum size."); |
467 | } | 482 | } |
468 | 483 | ||
469 | cb = sizeof(WCHAR) * (cch - 1); // subtract one to ensure there will be a space at the end of the string for the null terminator. | 484 | cb = sizeof(WCHAR) * (cch - 1); // subtract one to ensure there will be a space at the end of the string for the null terminator. |
@@ -472,7 +487,7 @@ extern "C" HRESULT DAPI RegReadString( | |||
472 | { | 487 | { |
473 | cch = cb / sizeof(WCHAR) + 1; // add one to ensure there will be space at the end for the null terminator | 488 | cch = cb / sizeof(WCHAR) + 1; // add one to ensure there will be space at the end for the null terminator |
474 | hr = StrAlloc(psczValue, cch); | 489 | hr = StrAlloc(psczValue, cch); |
475 | ExitOnFailure(hr, "Failed to allocate string bigger for registry value."); | 490 | RegExitOnFailure(hr, "Failed to allocate string bigger for registry value."); |
476 | 491 | ||
477 | er = vpfnRegQueryValueExW(hk, wzName, NULL, &dwType, reinterpret_cast<LPBYTE>(*psczValue), &cb); | 492 | er = vpfnRegQueryValueExW(hk, wzName, NULL, &dwType, reinterpret_cast<LPBYTE>(*psczValue), &cb); |
478 | } | 493 | } |
@@ -480,7 +495,7 @@ extern "C" HRESULT DAPI RegReadString( | |||
480 | { | 495 | { |
481 | ExitFunction1(hr = E_FILENOTFOUND); | 496 | ExitFunction1(hr = E_FILENOTFOUND); |
482 | } | 497 | } |
483 | ExitOnWin32Error(er, hr, "Failed to read registry key."); | 498 | RegExitOnWin32Error(er, hr, "Failed to read registry key."); |
484 | 499 | ||
485 | if (REG_SZ == dwType || REG_EXPAND_SZ == dwType) | 500 | if (REG_SZ == dwType || REG_EXPAND_SZ == dwType) |
486 | { | 501 | { |
@@ -490,16 +505,16 @@ extern "C" HRESULT DAPI RegReadString( | |||
490 | if (REG_EXPAND_SZ == dwType) | 505 | if (REG_EXPAND_SZ == dwType) |
491 | { | 506 | { |
492 | hr = StrAllocString(&sczExpand, *psczValue, 0); | 507 | hr = StrAllocString(&sczExpand, *psczValue, 0); |
493 | ExitOnFailure(hr, "Failed to copy registry value to expand."); | 508 | RegExitOnFailure(hr, "Failed to copy registry value to expand."); |
494 | 509 | ||
495 | hr = PathExpand(psczValue, sczExpand, PATH_EXPAND_ENVIRONMENT); | 510 | hr = PathExpand(psczValue, sczExpand, PATH_EXPAND_ENVIRONMENT); |
496 | ExitOnFailure(hr, "Failed to expand registry value: %ls", *psczValue); | 511 | RegExitOnFailure(hr, "Failed to expand registry value: %ls", *psczValue); |
497 | } | 512 | } |
498 | } | 513 | } |
499 | else | 514 | else |
500 | { | 515 | { |
501 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); | 516 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); |
502 | ExitOnRootFailure(hr, "Error reading string registry value due to unexpected data type: %u", dwType); | 517 | RegExitOnRootFailure(hr, "Error reading string registry value due to unexpected data type: %u", dwType); |
503 | } | 518 | } |
504 | 519 | ||
505 | LExit: | 520 | LExit: |
@@ -516,7 +531,7 @@ LExit: | |||
516 | HRESULT DAPI RegReadStringArray( | 531 | HRESULT DAPI RegReadStringArray( |
517 | __in HKEY hk, | 532 | __in HKEY hk, |
518 | __in_z_opt LPCWSTR wzName, | 533 | __in_z_opt LPCWSTR wzName, |
519 | __deref_out_ecount_opt(pcStrings) LPWSTR** prgsczStrings, | 534 | __deref_out_ecount_opt(*pcStrings) LPWSTR** prgsczStrings, |
520 | __out DWORD *pcStrings | 535 | __out DWORD *pcStrings |
521 | ) | 536 | ) |
522 | { | 537 | { |
@@ -534,7 +549,7 @@ HRESULT DAPI RegReadStringArray( | |||
534 | { | 549 | { |
535 | cch = cb / sizeof(WCHAR); | 550 | cch = cb / sizeof(WCHAR); |
536 | hr = StrAlloc(&sczValue, cch); | 551 | hr = StrAlloc(&sczValue, cch); |
537 | ExitOnFailure(hr, "Failed to allocate string for registry value."); | 552 | RegExitOnFailure(hr, "Failed to allocate string for registry value."); |
538 | 553 | ||
539 | er = vpfnRegQueryValueExW(hk, wzName, NULL, &dwType, reinterpret_cast<LPBYTE>(sczValue), &cb); | 554 | er = vpfnRegQueryValueExW(hk, wzName, NULL, &dwType, reinterpret_cast<LPBYTE>(sczValue), &cb); |
540 | } | 555 | } |
@@ -542,18 +557,18 @@ HRESULT DAPI RegReadStringArray( | |||
542 | { | 557 | { |
543 | ExitFunction1(hr = E_FILENOTFOUND); | 558 | ExitFunction1(hr = E_FILENOTFOUND); |
544 | } | 559 | } |
545 | ExitOnWin32Error(er, hr, "Failed to read registry key."); | 560 | RegExitOnWin32Error(er, hr, "Failed to read registry key."); |
546 | 561 | ||
547 | if (cb / sizeof(WCHAR) != cch) | 562 | if (cb / sizeof(WCHAR) != cch) |
548 | { | 563 | { |
549 | hr = E_UNEXPECTED; | 564 | hr = E_UNEXPECTED; |
550 | ExitOnFailure(hr, "The size of registry value %ls unexpected changed between 2 reads", wzName); | 565 | RegExitOnFailure(hr, "The size of registry value %ls unexpected changed between 2 reads", wzName); |
551 | } | 566 | } |
552 | 567 | ||
553 | if (REG_MULTI_SZ != dwType) | 568 | if (REG_MULTI_SZ != dwType) |
554 | { | 569 | { |
555 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); | 570 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); |
556 | ExitOnRootFailure(hr, "Tried to read string array, but registry value %ls is of an incorrect type", wzName); | 571 | RegExitOnRootFailure(hr, "Tried to read string array, but registry value %ls is of an incorrect type", wzName); |
557 | } | 572 | } |
558 | 573 | ||
559 | // Value exists, but is empty, so no strings to return. | 574 | // Value exists, but is empty, so no strings to return. |
@@ -568,7 +583,7 @@ HRESULT DAPI RegReadStringArray( | |||
568 | if (L'\0' != sczValue[cch-1] || L'\0' != sczValue[cch-2]) | 583 | if (L'\0' != sczValue[cch-1] || L'\0' != sczValue[cch-2]) |
569 | { | 584 | { |
570 | hr = E_INVALIDARG; | 585 | hr = E_INVALIDARG; |
571 | ExitOnFailure(hr, "Tried to read string array, but registry value %ls is invalid (isn't double-null-terminated)", wzName); | 586 | RegExitOnFailure(hr, "Tried to read string array, but registry value %ls is invalid (isn't double-null-terminated)", wzName); |
572 | } | 587 | } |
573 | 588 | ||
574 | cch = cb / sizeof(WCHAR); | 589 | cch = cb / sizeof(WCHAR); |
@@ -583,7 +598,7 @@ HRESULT DAPI RegReadStringArray( | |||
583 | // There's one string for every null character encountered (except the extra 1 at the end of the string) | 598 | // There's one string for every null character encountered (except the extra 1 at the end of the string) |
584 | *pcStrings = dwNullCharacters - 1; | 599 | *pcStrings = dwNullCharacters - 1; |
585 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID *>(prgsczStrings), *pcStrings, sizeof(LPWSTR), 0); | 600 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID *>(prgsczStrings), *pcStrings, sizeof(LPWSTR), 0); |
586 | ExitOnFailure(hr, "Failed to resize array while reading REG_MULTI_SZ value"); | 601 | RegExitOnFailure(hr, "Failed to resize array while reading REG_MULTI_SZ value"); |
587 | 602 | ||
588 | #pragma prefast(push) | 603 | #pragma prefast(push) |
589 | #pragma prefast(disable:26010) | 604 | #pragma prefast(disable:26010) |
@@ -591,7 +606,7 @@ HRESULT DAPI RegReadStringArray( | |||
591 | for (DWORD i = 0; i < *pcStrings; ++i) | 606 | for (DWORD i = 0; i < *pcStrings; ++i) |
592 | { | 607 | { |
593 | hr = StrAllocString(&(*prgsczStrings)[i], wzSource, 0); | 608 | hr = StrAllocString(&(*prgsczStrings)[i], wzSource, 0); |
594 | ExitOnFailure(hr, "Failed to allocate copy of string"); | 609 | RegExitOnFailure(hr, "Failed to allocate copy of string"); |
595 | 610 | ||
596 | // Skip past this string | 611 | // Skip past this string |
597 | wzSource += lstrlenW(wzSource) + 1; | 612 | wzSource += lstrlenW(wzSource) + 1; |
@@ -630,19 +645,19 @@ extern "C" HRESULT DAPI RegReadVersion( | |||
630 | if (REG_SZ == dwType || REG_EXPAND_SZ == dwType) | 645 | if (REG_SZ == dwType || REG_EXPAND_SZ == dwType) |
631 | { | 646 | { |
632 | hr = RegReadString(hk, wzName, &sczVersion); | 647 | hr = RegReadString(hk, wzName, &sczVersion); |
633 | ExitOnFailure(hr, "Failed to read registry version as string."); | 648 | RegExitOnFailure(hr, "Failed to read registry version as string."); |
634 | 649 | ||
635 | hr = FileVersionFromStringEx(sczVersion, 0, pdw64Version); | 650 | hr = FileVersionFromStringEx(sczVersion, 0, pdw64Version); |
636 | ExitOnFailure(hr, "Failed to convert registry string to version."); | 651 | RegExitOnFailure(hr, "Failed to convert registry string to version."); |
637 | } | 652 | } |
638 | else if (REG_QWORD == dwType) | 653 | else if (REG_QWORD == dwType) |
639 | { | 654 | { |
640 | ExitOnWin32Error(er, hr, "Failed to read registry key."); | 655 | RegExitOnWin32Error(er, hr, "Failed to read registry key."); |
641 | } | 656 | } |
642 | else // unexpected data type | 657 | else // unexpected data type |
643 | { | 658 | { |
644 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); | 659 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); |
645 | ExitOnRootFailure(hr, "Error reading version registry value due to unexpected data type: %u", dwType); | 660 | RegExitOnRootFailure(hr, "Error reading version registry value due to unexpected data type: %u", dwType); |
646 | } | 661 | } |
647 | 662 | ||
648 | LExit: | 663 | LExit: |
@@ -672,12 +687,12 @@ extern "C" HRESULT DAPI RegReadNumber( | |||
672 | { | 687 | { |
673 | ExitFunction1(hr = E_FILENOTFOUND); | 688 | ExitFunction1(hr = E_FILENOTFOUND); |
674 | } | 689 | } |
675 | ExitOnWin32Error(er, hr, "Failed to query registry key value."); | 690 | RegExitOnWin32Error(er, hr, "Failed to query registry key value."); |
676 | 691 | ||
677 | if (REG_DWORD != dwType) | 692 | if (REG_DWORD != dwType) |
678 | { | 693 | { |
679 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); | 694 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); |
680 | ExitOnRootFailure(hr, "Error reading version registry value due to unexpected data type: %u", dwType); | 695 | RegExitOnRootFailure(hr, "Error reading version registry value due to unexpected data type: %u", dwType); |
681 | } | 696 | } |
682 | 697 | ||
683 | LExit: | 698 | LExit: |
@@ -705,12 +720,12 @@ extern "C" HRESULT DAPI RegReadQword( | |||
705 | { | 720 | { |
706 | ExitFunction1(hr = E_FILENOTFOUND); | 721 | ExitFunction1(hr = E_FILENOTFOUND); |
707 | } | 722 | } |
708 | ExitOnWin32Error(er, hr, "Failed to query registry key value."); | 723 | RegExitOnWin32Error(er, hr, "Failed to query registry key value."); |
709 | 724 | ||
710 | if (REG_QWORD != dwType) | 725 | if (REG_QWORD != dwType) |
711 | { | 726 | { |
712 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); | 727 | hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATATYPE); |
713 | ExitOnRootFailure(hr, "Error reading version registry value due to unexpected data type: %u", dwType); | 728 | RegExitOnRootFailure(hr, "Error reading version registry value due to unexpected data type: %u", dwType); |
714 | } | 729 | } |
715 | 730 | ||
716 | LExit: | 731 | LExit: |
@@ -733,7 +748,7 @@ HRESULT DAPI RegWriteBinary( | |||
733 | DWORD er = ERROR_SUCCESS; | 748 | DWORD er = ERROR_SUCCESS; |
734 | 749 | ||
735 | er = vpfnRegSetValueExW(hk, wzName, 0, REG_BINARY, pbBuffer, cbBuffer); | 750 | er = vpfnRegSetValueExW(hk, wzName, 0, REG_BINARY, pbBuffer, cbBuffer); |
736 | ExitOnWin32Error(er, hr, "Failed to write binary registry value with name: %ls", wzName); | 751 | RegExitOnWin32Error(er, hr, "Failed to write binary registry value with name: %ls", wzName); |
737 | 752 | ||
738 | LExit: | 753 | LExit: |
739 | return hr; | 754 | return hr; |
@@ -788,7 +803,7 @@ extern "C" HRESULT DAPI RegWriteStringFormatted( | |||
788 | va_start(args, szFormat); | 803 | va_start(args, szFormat); |
789 | hr = StrAllocFormattedArgs(&sczValue, szFormat, args); | 804 | hr = StrAllocFormattedArgs(&sczValue, szFormat, args); |
790 | va_end(args); | 805 | va_end(args); |
791 | ExitOnFailure(hr, "Failed to allocate %ls value.", wzName); | 806 | RegExitOnFailure(hr, "Failed to allocate %ls value.", wzName); |
792 | 807 | ||
793 | hr = WriteStringToRegistry(hk, wzName, sczValue, REG_SZ); | 808 | hr = WriteStringToRegistry(hk, wzName, sczValue, REG_SZ); |
794 | 809 | ||
@@ -832,18 +847,18 @@ HRESULT DAPI RegWriteStringArray( | |||
832 | { | 847 | { |
833 | dwTemp = dwTotalStringSize; | 848 | dwTemp = dwTotalStringSize; |
834 | hr = ::DWordAdd(dwTemp, 1 + lstrlenW(rgwzValues[i]), &dwTotalStringSize); | 849 | hr = ::DWordAdd(dwTemp, 1 + lstrlenW(rgwzValues[i]), &dwTotalStringSize); |
835 | ExitOnFailure(hr, "DWORD Overflow while adding length of string to write REG_MULTI_SZ"); | 850 | RegExitOnFailure(hr, "DWORD Overflow while adding length of string to write REG_MULTI_SZ"); |
836 | } | 851 | } |
837 | 852 | ||
838 | hr = StrAlloc(&sczWriteValue, dwTotalStringSize); | 853 | hr = StrAlloc(&sczWriteValue, dwTotalStringSize); |
839 | ExitOnFailure(hr, "Failed to allocate space for string while writing REG_MULTI_SZ"); | 854 | RegExitOnFailure(hr, "Failed to allocate space for string while writing REG_MULTI_SZ"); |
840 | 855 | ||
841 | wzCopyDestination = sczWriteValue; | 856 | wzCopyDestination = sczWriteValue; |
842 | dwTemp = dwTotalStringSize; | 857 | dwTemp = dwTotalStringSize; |
843 | for (DWORD i = 0; i < cValues; ++i) | 858 | for (DWORD i = 0; i < cValues; ++i) |
844 | { | 859 | { |
845 | hr = ::StringCchCopyW(wzCopyDestination, dwTotalStringSize, rgwzValues[i]); | 860 | hr = ::StringCchCopyW(wzCopyDestination, dwTotalStringSize, rgwzValues[i]); |
846 | ExitOnFailure(hr, "failed to copy string: %ls", rgwzValues[i]); | 861 | RegExitOnFailure(hr, "failed to copy string: %ls", rgwzValues[i]); |
847 | 862 | ||
848 | dwTemp -= lstrlenW(rgwzValues[i]) + 1; | 863 | dwTemp -= lstrlenW(rgwzValues[i]) + 1; |
849 | wzCopyDestination += lstrlenW(rgwzValues[i]) + 1; | 864 | wzCopyDestination += lstrlenW(rgwzValues[i]) + 1; |
@@ -853,10 +868,10 @@ HRESULT DAPI RegWriteStringArray( | |||
853 | } | 868 | } |
854 | 869 | ||
855 | hr = ::DWordMult(dwTotalStringSize, sizeof(WCHAR), &cbTotalStringSize); | 870 | hr = ::DWordMult(dwTotalStringSize, sizeof(WCHAR), &cbTotalStringSize); |
856 | ExitOnFailure(hr, "Failed to get total string size in bytes"); | 871 | RegExitOnFailure(hr, "Failed to get total string size in bytes"); |
857 | 872 | ||
858 | er = vpfnRegSetValueExW(hk, wzName, 0, REG_MULTI_SZ, reinterpret_cast<const BYTE *>(wzWriteValue), cbTotalStringSize); | 873 | er = vpfnRegSetValueExW(hk, wzName, 0, REG_MULTI_SZ, reinterpret_cast<const BYTE *>(wzWriteValue), cbTotalStringSize); |
859 | ExitOnWin32Error(er, hr, "Failed to set registry value to array of strings (first string of which is): %ls", wzWriteValue); | 874 | RegExitOnWin32Error(er, hr, "Failed to set registry value to array of strings (first string of which is): %ls", wzWriteValue); |
860 | 875 | ||
861 | LExit: | 876 | LExit: |
862 | ReleaseStr(sczWriteValue); | 877 | ReleaseStr(sczWriteValue); |
@@ -878,7 +893,7 @@ extern "C" HRESULT DAPI RegWriteNumber( | |||
878 | DWORD er = ERROR_SUCCESS; | 893 | DWORD er = ERROR_SUCCESS; |
879 | 894 | ||
880 | er = vpfnRegSetValueExW(hk, wzName, 0, REG_DWORD, reinterpret_cast<const BYTE *>(&dwValue), sizeof(dwValue)); | 895 | er = vpfnRegSetValueExW(hk, wzName, 0, REG_DWORD, reinterpret_cast<const BYTE *>(&dwValue), sizeof(dwValue)); |
881 | ExitOnWin32Error(er, hr, "Failed to set %ls value.", wzName); | 896 | RegExitOnWin32Error(er, hr, "Failed to set %ls value.", wzName); |
882 | 897 | ||
883 | LExit: | 898 | LExit: |
884 | return hr; | 899 | return hr; |
@@ -898,7 +913,7 @@ extern "C" HRESULT DAPI RegWriteQword( | |||
898 | DWORD er = ERROR_SUCCESS; | 913 | DWORD er = ERROR_SUCCESS; |
899 | 914 | ||
900 | er = vpfnRegSetValueExW(hk, wzName, 0, REG_QWORD, reinterpret_cast<const BYTE *>(&qwValue), sizeof(qwValue)); | 915 | er = vpfnRegSetValueExW(hk, wzName, 0, REG_QWORD, reinterpret_cast<const BYTE *>(&qwValue), sizeof(qwValue)); |
901 | ExitOnWin32Error(er, hr, "Failed to set %ls value.", wzName); | 916 | RegExitOnWin32Error(er, hr, "Failed to set %ls value.", wzName); |
902 | 917 | ||
903 | LExit: | 918 | LExit: |
904 | return hr; | 919 | return hr; |
@@ -918,7 +933,7 @@ extern "C" HRESULT DAPI RegQueryKey( | |||
918 | DWORD er = ERROR_SUCCESS; | 933 | DWORD er = ERROR_SUCCESS; |
919 | 934 | ||
920 | er = vpfnRegQueryInfoKeyW(hk, NULL, NULL, NULL, pcSubKeys, NULL, NULL, pcValues, NULL, NULL, NULL, NULL); | 935 | er = vpfnRegQueryInfoKeyW(hk, NULL, NULL, NULL, pcSubKeys, NULL, NULL, pcValues, NULL, NULL, NULL, NULL); |
921 | ExitOnWin32Error(er, hr, "Failed to get the number of subkeys and values under registry key."); | 936 | RegExitOnWin32Error(er, hr, "Failed to get the number of subkeys and values under registry key."); |
922 | 937 | ||
923 | LExit: | 938 | LExit: |
924 | return hr; | 939 | return hr; |
@@ -938,11 +953,11 @@ static HRESULT WriteStringToRegistry( | |||
938 | 953 | ||
939 | if (wzValue) | 954 | if (wzValue) |
940 | { | 955 | { |
941 | hr = ::StringCbLengthW(wzValue, DWORD_MAX, reinterpret_cast<size_t*>(&cbValue)); | 956 | hr = ::StringCbLengthW(wzValue, STRSAFE_MAX_CCH * sizeof(TCHAR), reinterpret_cast<size_t*>(&cbValue)); |
942 | ExitOnFailure(hr, "Failed to determine length of registry value: %ls", wzName); | 957 | RegExitOnFailure(hr, "Failed to determine length of registry value: %ls", wzName); |
943 | 958 | ||
944 | er = vpfnRegSetValueExW(hk, wzName, 0, dwType, reinterpret_cast<const BYTE *>(wzValue), cbValue); | 959 | er = vpfnRegSetValueExW(hk, wzName, 0, dwType, reinterpret_cast<const BYTE *>(wzValue), cbValue); |
945 | ExitOnWin32Error(er, hr, "Failed to set registry value: %ls", wzName); | 960 | RegExitOnWin32Error(er, hr, "Failed to set registry value: %ls", wzName); |
946 | } | 961 | } |
947 | else | 962 | else |
948 | { | 963 | { |
@@ -951,7 +966,7 @@ static HRESULT WriteStringToRegistry( | |||
951 | { | 966 | { |
952 | er = ERROR_SUCCESS; | 967 | er = ERROR_SUCCESS; |
953 | } | 968 | } |
954 | ExitOnWin32Error(er, hr, "Failed to delete registry value: %ls", wzName); | 969 | RegExitOnWin32Error(er, hr, "Failed to delete registry value: %ls", wzName); |
955 | } | 970 | } |
956 | 971 | ||
957 | LExit: | 972 | LExit: |