aboutsummaryrefslogtreecommitdiff
path: root/src/dutil/regutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/dutil/regutil.cpp137
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
5static PFN_REGCREATEKEYEXW vpfnRegCreateKeyExW = ::RegCreateKeyExW; 20static PFN_REGCREATEKEYEXW vpfnRegCreateKeyExW = ::RegCreateKeyExW;
6static PFN_REGOPENKEYEXW vpfnRegOpenKeyExW = ::RegOpenKeyExW; 21static PFN_REGOPENKEYEXW vpfnRegOpenKeyExW = ::RegOpenKeyExW;
7static PFN_REGDELETEKEYEXW vpfnRegDeleteKeyExW = NULL; 22static 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
119LExit: 134LExit:
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
176LExit: 191LExit:
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
261LExit: 276LExit:
@@ -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
358LExit: 373LExit:
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.");
380LExit: 395LExit:
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
431LExit: 446LExit:
@@ -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
505LExit: 520LExit:
@@ -516,7 +531,7 @@ LExit:
516HRESULT DAPI RegReadStringArray( 531HRESULT 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
648LExit: 663LExit:
@@ -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
683LExit: 698LExit:
@@ -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
716LExit: 731LExit:
@@ -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
738LExit: 753LExit:
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
861LExit: 876LExit:
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
883LExit: 898LExit:
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
903LExit: 918LExit:
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
923LExit: 938LExit:
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
957LExit: 972LExit: