diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dutil/cabutil.cpp | 52 | ||||
| -rw-r--r-- | src/dutil/fileutil.cpp | 128 | ||||
| -rw-r--r-- | src/dutil/inc/fileutil.h | 9 | ||||
| -rw-r--r-- | src/dutil/inc/regutil.h | 13 | ||||
| -rw-r--r-- | src/dutil/regutil.cpp | 59 | ||||
| -rw-r--r-- | src/dutil/wiutil.cpp | 18 |
6 files changed, 265 insertions, 14 deletions
diff --git a/src/dutil/cabutil.cpp b/src/dutil/cabutil.cpp index 4a6f7b7b..5d77e483 100644 --- a/src/dutil/cabutil.cpp +++ b/src/dutil/cabutil.cpp | |||
| @@ -102,6 +102,29 @@ LExit: | |||
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | 104 | ||
| 105 | static HANDLE OpenFileWithRetry( | ||
| 106 | __in LPCWSTR wzPath, | ||
| 107 | __in DWORD dwDesiredAccess, | ||
| 108 | __in DWORD dwCreationDisposition | ||
| 109 | ) | ||
| 110 | { | ||
| 111 | HANDLE hFile = INVALID_HANDLE_VALUE; | ||
| 112 | |||
| 113 | for (DWORD i = 0; i < 30; ++i) | ||
| 114 | { | ||
| 115 | hFile = ::CreateFileW(wzPath, dwDesiredAccess, FILE_SHARE_READ, NULL, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL); | ||
| 116 | if (INVALID_HANDLE_VALUE != hFile) | ||
| 117 | { | ||
| 118 | break; | ||
| 119 | } | ||
| 120 | |||
| 121 | ::Sleep(100); | ||
| 122 | } | ||
| 123 | |||
| 124 | return hFile; | ||
| 125 | } | ||
| 126 | |||
| 127 | |||
| 105 | /******************************************************************** | 128 | /******************************************************************** |
| 106 | CabInitialize - initializes internal static variables | 129 | CabInitialize - initializes internal static variables |
| 107 | 130 | ||
| @@ -340,6 +363,7 @@ static __callback void DIAMONDAPI CabExtractFree(__in LPVOID pvData) | |||
| 340 | static __callback INT_PTR FAR DIAMONDAPI CabExtractOpen(__in_z PSTR pszFile, __in int oflag, __in int pmode) | 363 | static __callback INT_PTR FAR DIAMONDAPI CabExtractOpen(__in_z PSTR pszFile, __in int oflag, __in int pmode) |
| 341 | { | 364 | { |
| 342 | HRESULT hr = S_OK; | 365 | HRESULT hr = S_OK; |
| 366 | HANDLE hFile = INVALID_HANDLE_VALUE; | ||
| 343 | INT_PTR pFile = -1; | 367 | INT_PTR pFile = -1; |
| 344 | LPWSTR sczCabFile = NULL; | 368 | LPWSTR sczCabFile = NULL; |
| 345 | 369 | ||
| @@ -353,19 +377,24 @@ static __callback INT_PTR FAR DIAMONDAPI CabExtractOpen(__in_z PSTR pszFile, __i | |||
| 353 | hr = StrAllocStringAnsi(&sczCabFile, pszFile, 0, CP_UTF8); | 377 | hr = StrAllocStringAnsi(&sczCabFile, pszFile, 0, CP_UTF8); |
| 354 | CabExitOnFailure(hr, "Failed to convert UTF8 cab file name to wide character string"); | 378 | CabExitOnFailure(hr, "Failed to convert UTF8 cab file name to wide character string"); |
| 355 | 379 | ||
| 356 | pFile = reinterpret_cast<INT_PTR>(::CreateFileW(sczCabFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)); | 380 | hFile = OpenFileWithRetry(sczCabFile, GENERIC_READ, OPEN_EXISTING); |
| 357 | if (INVALID_HANDLE_VALUE == reinterpret_cast<HANDLE>(pFile)) | 381 | if (INVALID_HANDLE_VALUE == hFile) |
| 358 | { | 382 | { |
| 359 | CabExitWithLastError(hr, "failed to open file: %ls", sczCabFile); | 383 | CabExitWithLastError(hr, "failed to open file: %ls", sczCabFile); |
| 360 | } | 384 | } |
| 361 | 385 | ||
| 386 | pFile = reinterpret_cast<INT_PTR>(hFile); | ||
| 387 | |||
| 362 | if (vdw64EmbeddedOffset) | 388 | if (vdw64EmbeddedOffset) |
| 363 | { | 389 | { |
| 364 | hr = CabExtractSeek(pFile, 0, 0); | 390 | hr = CabExtractSeek(pFile, 0, 0); |
| 365 | CabExitOnFailure(hr, "Failed to seek to embedded offset %I64d", vdw64EmbeddedOffset); | 391 | CabExitOnFailure(hr, "Failed to seek to embedded offset %I64d", vdw64EmbeddedOffset); |
| 366 | } | 392 | } |
| 367 | 393 | ||
| 394 | hFile = INVALID_HANDLE_VALUE; | ||
| 395 | |||
| 368 | LExit: | 396 | LExit: |
| 397 | ReleaseFileHandle(hFile); | ||
| 369 | ReleaseStr(sczCabFile); | 398 | ReleaseStr(sczCabFile); |
| 370 | 399 | ||
| 371 | return FAILED(hr) ? -1 : pFile; | 400 | return FAILED(hr) ? -1 : pFile; |
| @@ -460,6 +489,7 @@ static __callback INT_PTR DIAMONDAPI CabExtractCallback(__in FDINOTIFICATIONTYPE | |||
| 460 | Assert(pFDINotify->pv); | 489 | Assert(pFDINotify->pv); |
| 461 | 490 | ||
| 462 | HRESULT hr = S_OK; | 491 | HRESULT hr = S_OK; |
| 492 | HANDLE hFile = INVALID_HANDLE_VALUE; | ||
| 463 | INT_PTR ipResult = 0; // result to return on success | 493 | INT_PTR ipResult = 0; // result to return on success |
| 464 | 494 | ||
| 465 | CAB_CALLBACK_STRUCT* pccs = static_cast<CAB_CALLBACK_STRUCT*>(pFDINotify->pv); | 495 | CAB_CALLBACK_STRUCT* pccs = static_cast<CAB_CALLBACK_STRUCT*>(pFDINotify->pv); |
| @@ -503,7 +533,6 @@ static __callback INT_PTR DIAMONDAPI CabExtractCallback(__in FDINOTIFICATIONTYPE | |||
| 503 | CabExitWithLastError(hr, "failed to get time for resource: %ls", wz); | 533 | CabExitWithLastError(hr, "failed to get time for resource: %ls", wz); |
| 504 | } | 534 | } |
| 505 | ::LocalFileTimeToFileTime(&ftLocal, &ft); | 535 | ::LocalFileTimeToFileTime(&ftLocal, &ft); |
| 506 | |||
| 507 | 536 | ||
| 508 | WCHAR wzPath[MAX_PATH]; | 537 | WCHAR wzPath[MAX_PATH]; |
| 509 | hr = ::StringCchCopyW(wzPath, countof(wzPath), pccs->pwzExtractDir); | 538 | hr = ::StringCchCopyW(wzPath, countof(wzPath), pccs->pwzExtractDir); |
| @@ -511,21 +540,24 @@ static __callback INT_PTR DIAMONDAPI CabExtractCallback(__in FDINOTIFICATIONTYPE | |||
| 511 | hr = ::StringCchCatW(wzPath, countof(wzPath), wz); | 540 | hr = ::StringCchCatW(wzPath, countof(wzPath), wz); |
| 512 | CabExitOnFailure(hr, "failed to concat onto path: %ls file: %ls", wzPath, wz); | 541 | CabExitOnFailure(hr, "failed to concat onto path: %ls file: %ls", wzPath, wz); |
| 513 | 542 | ||
| 514 | ipResult = reinterpret_cast<INT_PTR>(::CreateFileW(wzPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)); | 543 | hFile = OpenFileWithRetry(wzPath, GENERIC_WRITE, CREATE_ALWAYS); |
| 515 | if (INVALID_HANDLE_VALUE == reinterpret_cast<HANDLE>(ipResult)) | 544 | if (INVALID_HANDLE_VALUE == hFile) |
| 516 | { | 545 | { |
| 517 | CabExitWithLastError(hr, "failed to create file: %ls", wzPath); | 546 | CabExitWithLastError(hr, "failed to create file: %ls", wzPath); |
| 518 | } | 547 | } |
| 519 | 548 | ||
| 520 | ::SetFileTime(reinterpret_cast<HANDLE>(ipResult), &ft, &ft, &ft); // try to set the file time (who cares if it fails) | 549 | ::SetFileTime(hFile, &ft, &ft, &ft); // try to set the file time (who cares if it fails) |
| 521 | 550 | ||
| 522 | if (::SetFilePointer(reinterpret_cast<HANDLE>(ipResult), pFDINotify->cb, NULL, FILE_BEGIN)) // try to set the end of the file (don't worry if this fails) | 551 | if (::SetFilePointer(hFile, pFDINotify->cb, NULL, FILE_BEGIN)) // try to set the end of the file (don't worry if this fails) |
| 523 | { | 552 | { |
| 524 | if (::SetEndOfFile(reinterpret_cast<HANDLE>(ipResult))) | 553 | if (::SetEndOfFile(hFile)) |
| 525 | { | 554 | { |
| 526 | ::SetFilePointer(reinterpret_cast<HANDLE>(ipResult), 0, NULL, FILE_BEGIN); // reset the file pointer | 555 | ::SetFilePointer(hFile, 0, NULL, FILE_BEGIN); // reset the file pointer |
| 527 | } | 556 | } |
| 528 | } | 557 | } |
| 558 | |||
| 559 | ipResult = reinterpret_cast<INT_PTR>(hFile); | ||
| 560 | hFile = INVALID_HANDLE_VALUE; | ||
| 529 | } | 561 | } |
| 530 | else // resource wasn't requested, skip it | 562 | else // resource wasn't requested, skip it |
| 531 | { | 563 | { |
| @@ -579,5 +611,7 @@ static __callback INT_PTR DIAMONDAPI CabExtractCallback(__in FDINOTIFICATIONTYPE | |||
| 579 | }; | 611 | }; |
| 580 | 612 | ||
| 581 | LExit: | 613 | LExit: |
| 614 | ReleaseFileHandle(hFile); | ||
| 615 | |||
| 582 | return (S_OK == hr) ? ipResult : -1; | 616 | return (S_OK == hr) ? ipResult : -1; |
| 583 | } | 617 | } |
diff --git a/src/dutil/fileutil.cpp b/src/dutil/fileutil.cpp index c76017de..06a44b45 100644 --- a/src/dutil/fileutil.cpp +++ b/src/dutil/fileutil.cpp | |||
| @@ -1106,6 +1106,134 @@ LExit: | |||
| 1106 | 1106 | ||
| 1107 | 1107 | ||
| 1108 | /******************************************************************* | 1108 | /******************************************************************* |
| 1109 | FileCopyUsingHandlesWithProgress | ||
| 1110 | |||
| 1111 | *******************************************************************/ | ||
| 1112 | extern "C" HRESULT DAPI FileCopyUsingHandlesWithProgress( | ||
| 1113 | __in HANDLE hSource, | ||
| 1114 | __in HANDLE hTarget, | ||
| 1115 | __in DWORD64 cbCopy, | ||
| 1116 | __in_opt LPPROGRESS_ROUTINE lpProgressRoutine, | ||
| 1117 | __in_opt LPVOID lpData, | ||
| 1118 | __in_opt LPBOOL pbCancel, | ||
| 1119 | __out_opt DWORD64* pcbCopied | ||
| 1120 | ) | ||
| 1121 | { | ||
| 1122 | HRESULT hr = S_OK; | ||
| 1123 | BOOL fStop = FALSE; | ||
| 1124 | BOOL fCanceled = FALSE; | ||
| 1125 | DWORD64 cbTotalCopied = 0; | ||
| 1126 | BYTE rgbData[64 * 1024]; | ||
| 1127 | DWORD cbRead = 0; | ||
| 1128 | |||
| 1129 | LARGE_INTEGER liSourceSize = { }; | ||
| 1130 | LARGE_INTEGER liTotalCopied = { }; | ||
| 1131 | LARGE_INTEGER liZero = { }; | ||
| 1132 | DWORD dwResult = 0; | ||
| 1133 | |||
| 1134 | hr = FileSizeByHandle(hSource, &liSourceSize.QuadPart); | ||
| 1135 | FileExitOnFailure(hr, "Failed to get size of source."); | ||
| 1136 | |||
| 1137 | if (0 < cbCopy && cbCopy < (DWORD64)liSourceSize.QuadPart) | ||
| 1138 | { | ||
| 1139 | liSourceSize.QuadPart = cbCopy; | ||
| 1140 | } | ||
| 1141 | |||
| 1142 | dwResult = lpProgressRoutine(liSourceSize, liTotalCopied, liZero, liZero, 0, CALLBACK_STREAM_SWITCH, hSource, hTarget, lpData); | ||
| 1143 | switch (dwResult) | ||
| 1144 | { | ||
| 1145 | case PROGRESS_CONTINUE: | ||
| 1146 | break; | ||
| 1147 | |||
| 1148 | case PROGRESS_CANCEL: | ||
| 1149 | fCanceled = TRUE; | ||
| 1150 | fStop = TRUE; | ||
| 1151 | break; | ||
| 1152 | |||
| 1153 | case PROGRESS_STOP: | ||
| 1154 | fStop = TRUE; | ||
| 1155 | break; | ||
| 1156 | |||
| 1157 | case PROGRESS_QUIET: | ||
| 1158 | lpProgressRoutine = NULL; | ||
| 1159 | break; | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | // Set size of the target file. | ||
| 1163 | ::SetFilePointerEx(hTarget, liSourceSize, NULL, FILE_BEGIN); | ||
| 1164 | |||
| 1165 | if (!::SetEndOfFile(hTarget)) | ||
| 1166 | { | ||
| 1167 | FileExitWithLastError(hr, "Failed to set end of target file."); | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | if (!::SetFilePointerEx(hTarget, liZero, NULL, FILE_BEGIN)) | ||
| 1171 | { | ||
| 1172 | FileExitWithLastError(hr, "Failed to reset target file pointer."); | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | // Copy with progress. | ||
| 1176 | while (!fStop && (0 == cbCopy || cbTotalCopied < cbCopy)) | ||
| 1177 | { | ||
| 1178 | cbRead = static_cast<DWORD>((0 == cbCopy) ? countof(rgbData) : min(countof(rgbData), cbCopy - cbTotalCopied)); | ||
| 1179 | if (!::ReadFile(hSource, rgbData, cbRead, &cbRead, NULL)) | ||
| 1180 | { | ||
| 1181 | FileExitWithLastError(hr, "Failed to read from source."); | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | if (cbRead) | ||
| 1185 | { | ||
| 1186 | hr = FileWriteHandle(hTarget, rgbData, cbRead); | ||
| 1187 | FileExitOnFailure(hr, "Failed to write to target."); | ||
| 1188 | |||
| 1189 | cbTotalCopied += cbRead; | ||
| 1190 | |||
| 1191 | if (lpProgressRoutine) | ||
| 1192 | { | ||
| 1193 | liTotalCopied.QuadPart = cbTotalCopied; | ||
| 1194 | dwResult = lpProgressRoutine(liSourceSize, liTotalCopied, liZero, liZero, 0, CALLBACK_CHUNK_FINISHED, hSource, hTarget, lpData); | ||
| 1195 | switch (dwResult) | ||
| 1196 | { | ||
| 1197 | case PROGRESS_CONTINUE: | ||
| 1198 | break; | ||
| 1199 | |||
| 1200 | case PROGRESS_CANCEL: | ||
| 1201 | fCanceled = TRUE; | ||
| 1202 | fStop = TRUE; | ||
| 1203 | break; | ||
| 1204 | |||
| 1205 | case PROGRESS_STOP: | ||
| 1206 | fStop = TRUE; | ||
| 1207 | break; | ||
| 1208 | |||
| 1209 | case PROGRESS_QUIET: | ||
| 1210 | lpProgressRoutine = NULL; | ||
| 1211 | break; | ||
| 1212 | } | ||
| 1213 | } | ||
| 1214 | } | ||
| 1215 | else | ||
| 1216 | { | ||
| 1217 | fStop = TRUE; | ||
| 1218 | } | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | LExit: | ||
| 1222 | if (pbCancel) | ||
| 1223 | { | ||
| 1224 | *pbCancel = fCanceled; | ||
| 1225 | } | ||
| 1226 | |||
| 1227 | if (pcbCopied) | ||
| 1228 | { | ||
| 1229 | *pcbCopied = cbTotalCopied; | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | return hr; | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | |||
| 1236 | /******************************************************************* | ||
| 1109 | FileEnsureCopy | 1237 | FileEnsureCopy |
| 1110 | 1238 | ||
| 1111 | *******************************************************************/ | 1239 | *******************************************************************/ |
diff --git a/src/dutil/inc/fileutil.h b/src/dutil/inc/fileutil.h index 7caa62b8..48830043 100644 --- a/src/dutil/inc/fileutil.h +++ b/src/dutil/inc/fileutil.h | |||
| @@ -148,6 +148,15 @@ HRESULT DAPI FileCopyUsingHandles( | |||
| 148 | __in DWORD64 cbCopy, | 148 | __in DWORD64 cbCopy, |
| 149 | __out_opt DWORD64* pcbCopied | 149 | __out_opt DWORD64* pcbCopied |
| 150 | ); | 150 | ); |
| 151 | HRESULT DAPI FileCopyUsingHandlesWithProgress( | ||
| 152 | __in HANDLE hSource, | ||
| 153 | __in HANDLE hTarget, | ||
| 154 | __in DWORD64 cbCopy, | ||
| 155 | __in_opt LPPROGRESS_ROUTINE lpProgressRoutine, | ||
| 156 | __in_opt LPVOID lpData, | ||
| 157 | __in_opt LPBOOL pbCancel, | ||
| 158 | __out_opt DWORD64* pcbCopied | ||
| 159 | ); | ||
| 151 | HRESULT DAPI FileEnsureCopy( | 160 | HRESULT DAPI FileEnsureCopy( |
| 152 | __in_z LPCWSTR wzSource, | 161 | __in_z LPCWSTR wzSource, |
| 153 | __in_z LPCWSTR wzTarget, | 162 | __in_z LPCWSTR wzTarget, |
diff --git a/src/dutil/inc/regutil.h b/src/dutil/inc/regutil.h index 2f09d244..75284940 100644 --- a/src/dutil/inc/regutil.h +++ b/src/dutil/inc/regutil.h | |||
| @@ -226,6 +226,19 @@ HRESULT DAPI RegQueryKey( | |||
| 226 | __out_opt DWORD* pcSubKeys, | 226 | __out_opt DWORD* pcSubKeys, |
| 227 | __out_opt DWORD* pcValues | 227 | __out_opt DWORD* pcValues |
| 228 | ); | 228 | ); |
| 229 | HRESULT DAPI RegKeyReadNumber( | ||
| 230 | __in HKEY hk, | ||
| 231 | __in_z LPCWSTR wzSubKey, | ||
| 232 | __in_z_opt LPCWSTR wzName, | ||
| 233 | __in BOOL f64Bit, | ||
| 234 | __out DWORD* pdwValue | ||
| 235 | ); | ||
| 236 | BOOL DAPI RegValueExists( | ||
| 237 | __in HKEY hk, | ||
| 238 | __in_z LPCWSTR wzSubKey, | ||
| 239 | __in_z_opt LPCWSTR wzName, | ||
| 240 | __in BOOL f64Bit | ||
| 241 | ); | ||
| 229 | 242 | ||
| 230 | #ifdef __cplusplus | 243 | #ifdef __cplusplus |
| 231 | } | 244 | } |
diff --git a/src/dutil/regutil.cpp b/src/dutil/regutil.cpp index e1ef19e8..afd2d089 100644 --- a/src/dutil/regutil.cpp +++ b/src/dutil/regutil.cpp | |||
| @@ -283,7 +283,7 @@ LExit: | |||
| 283 | 283 | ||
| 284 | 284 | ||
| 285 | /******************************************************************** | 285 | /******************************************************************** |
| 286 | RegKeyEnum - enumerates a registry key. | 286 | RegKeyEnum - enumerates child registry keys. |
| 287 | 287 | ||
| 288 | *********************************************************************/ | 288 | *********************************************************************/ |
| 289 | extern "C" HRESULT DAPI RegKeyEnum( | 289 | extern "C" HRESULT DAPI RegKeyEnum( |
| @@ -340,7 +340,7 @@ LExit: | |||
| 340 | 340 | ||
| 341 | 341 | ||
| 342 | /******************************************************************** | 342 | /******************************************************************** |
| 343 | RegValueEnum - enumerates a registry value. | 343 | RegValueEnum - enumerates registry values. |
| 344 | 344 | ||
| 345 | *********************************************************************/ | 345 | *********************************************************************/ |
| 346 | HRESULT DAPI RegValueEnum( | 346 | HRESULT DAPI RegValueEnum( |
| @@ -939,6 +939,61 @@ LExit: | |||
| 939 | return hr; | 939 | return hr; |
| 940 | } | 940 | } |
| 941 | 941 | ||
| 942 | /******************************************************************** | ||
| 943 | RegKeyReadNumber - reads a DWORD registry key value as a number from | ||
| 944 | a specified subkey. | ||
| 945 | |||
| 946 | *********************************************************************/ | ||
| 947 | extern "C" HRESULT DAPI RegKeyReadNumber( | ||
| 948 | __in HKEY hk, | ||
| 949 | __in_z LPCWSTR wzSubKey, | ||
| 950 | __in_z_opt LPCWSTR wzName, | ||
| 951 | __in BOOL f64Bit, | ||
| 952 | __out DWORD* pdwValue | ||
| 953 | ) | ||
| 954 | { | ||
| 955 | HRESULT hr = S_OK; | ||
| 956 | HKEY hkKey = NULL; | ||
| 957 | |||
| 958 | hr = RegOpen(hk, wzSubKey, KEY_READ | f64Bit ? KEY_WOW64_64KEY : 0, &hkKey); | ||
| 959 | RegExitOnFailure(hr, "Failed to open key: %ls", wzSubKey); | ||
| 960 | |||
| 961 | hr = RegReadNumber(hkKey, wzName, pdwValue); | ||
| 962 | RegExitOnFailure(hr, "Failed to read value: %ls/@%ls", wzSubKey, wzName); | ||
| 963 | |||
| 964 | LExit: | ||
| 965 | ReleaseRegKey(hkKey); | ||
| 966 | |||
| 967 | return hr; | ||
| 968 | } | ||
| 969 | |||
| 970 | /******************************************************************** | ||
| 971 | RegValueExists - determines whether a named value exists in a | ||
| 972 | specified subkey. | ||
| 973 | |||
| 974 | *********************************************************************/ | ||
| 975 | extern "C" BOOL DAPI RegValueExists( | ||
| 976 | __in HKEY hk, | ||
| 977 | __in_z LPCWSTR wzSubKey, | ||
| 978 | __in_z_opt LPCWSTR wzName, | ||
| 979 | __in BOOL f64Bit | ||
| 980 | ) | ||
| 981 | { | ||
| 982 | HRESULT hr = S_OK; | ||
| 983 | HKEY hkKey = NULL; | ||
| 984 | DWORD dwType = 0; | ||
| 985 | |||
| 986 | hr = RegOpen(hk, wzSubKey, KEY_READ | f64Bit ? KEY_WOW64_64KEY : 0, &hkKey); | ||
| 987 | RegExitOnFailure(hr, "Failed to open key: %ls", wzSubKey); | ||
| 988 | |||
| 989 | hr = RegGetType(hkKey, wzName, &dwType); | ||
| 990 | RegExitOnFailure(hr, "Failed to read value type: %ls/@%ls", wzSubKey, wzName); | ||
| 991 | |||
| 992 | LExit: | ||
| 993 | ReleaseRegKey(hkKey); | ||
| 994 | |||
| 995 | return SUCCEEDED(hr); | ||
| 996 | } | ||
| 942 | 997 | ||
| 943 | static HRESULT WriteStringToRegistry( | 998 | static HRESULT WriteStringToRegistry( |
| 944 | __in HKEY hk, | 999 | __in HKEY hk, |
diff --git a/src/dutil/wiutil.cpp b/src/dutil/wiutil.cpp index ffbfe85a..f1984266 100644 --- a/src/dutil/wiutil.cpp +++ b/src/dutil/wiutil.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | // Exit macros | 6 | // Exit macros |
| 7 | #define WiuExitTrace(x, s, ...) ExitTraceSource(DUTIL_SOURCE_WIUTIL, x, s, __VA_ARGS__) | ||
| 7 | #define WiuExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_WIUTIL, x, s, __VA_ARGS__) | 8 | #define WiuExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_WIUTIL, x, s, __VA_ARGS__) |
| 8 | #define WiuExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_WIUTIL, x, s, __VA_ARGS__) | 9 | #define WiuExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_WIUTIL, x, s, __VA_ARGS__) |
| 9 | #define WiuExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_WIUTIL, x, s, __VA_ARGS__) | 10 | #define WiuExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_WIUTIL, x, s, __VA_ARGS__) |
| @@ -692,12 +693,23 @@ extern "C" HRESULT DAPI WiuEnumRelatedProductCodes( | |||
| 692 | 693 | ||
| 693 | if (fReturnHighestVersionOnly) | 694 | if (fReturnHighestVersionOnly) |
| 694 | { | 695 | { |
| 695 | // get the version | 696 | // try to get the version but if the product registration is broken |
| 697 | // (for whatever reason), skip this product | ||
| 696 | hr = WiuGetProductInfo(wzCurrentProductCode, L"VersionString", &sczInstalledVersion); | 698 | hr = WiuGetProductInfo(wzCurrentProductCode, L"VersionString", &sczInstalledVersion); |
| 697 | WiuExitOnFailure(hr, "Failed to get version for product code: %ls", wzCurrentProductCode); | 699 | if (FAILED(hr)) |
| 700 | { | ||
| 701 | WiuExitTrace(hr, "Could not get product version for product code: %ls, skipping...", wzCurrentProductCode); | ||
| 702 | continue; | ||
| 703 | } | ||
| 698 | 704 | ||
| 705 | // try to parse the product version but if it is corrupt (for whatever | ||
| 706 | // reason), skip it | ||
| 699 | hr = FileVersionFromStringEx(sczInstalledVersion, 0, &qwCurrentVersion); | 707 | hr = FileVersionFromStringEx(sczInstalledVersion, 0, &qwCurrentVersion); |
| 700 | WiuExitOnFailure(hr, "Failed to convert version: %ls to DWORD64 for product code: %ls", sczInstalledVersion, wzCurrentProductCode); | 708 | if (FAILED(hr)) |
| 709 | { | ||
| 710 | WiuExitTrace(hr, "Could not convert version: %ls to DWORD64 for product code: %ls, skipping...", sczInstalledVersion, wzCurrentProductCode); | ||
| 711 | continue; | ||
| 712 | } | ||
| 701 | 713 | ||
| 702 | // if this is the first product found then it is the highest version (for now) | 714 | // if this is the first product found then it is the highest version (for now) |
| 703 | if (0 == *pcRelatedProducts) | 715 | if (0 == *pcRelatedProducts) |
