diff options
Diffstat (limited to '')
| -rw-r--r-- | src/libs/dutil/WixToolset.DUtil/rexutil.cpp | 77 |
1 files changed, 40 insertions, 37 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/rexutil.cpp b/src/libs/dutil/WixToolset.DUtil/rexutil.cpp index 155ca714..ce28beb3 100644 --- a/src/libs/dutil/WixToolset.DUtil/rexutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/rexutil.cpp | |||
| @@ -28,7 +28,7 @@ static ERF verf; | |||
| 28 | static FAKE_FILE vrgffFileTable[FILETABLESIZE]; | 28 | static FAKE_FILE vrgffFileTable[FILETABLESIZE]; |
| 29 | static DWORD vcbRes; | 29 | static DWORD vcbRes; |
| 30 | static LPCBYTE vpbRes; | 30 | static LPCBYTE vpbRes; |
| 31 | static CHAR vszResource[MAX_PATH]; | 31 | static LPSTR vpszResource = NULL; |
| 32 | static REX_CALLBACK_WRITE vpfnWrite = NULL; | 32 | static REX_CALLBACK_WRITE vpfnWrite = NULL; |
| 33 | 33 | ||
| 34 | static HRESULT vhrLastError = S_OK; | 34 | static HRESULT vhrLastError = S_OK; |
| @@ -85,6 +85,8 @@ LExit: | |||
| 85 | { | 85 | { |
| 86 | ::FDIDestroy(vhfdi); | 86 | ::FDIDestroy(vhfdi); |
| 87 | vhfdi = NULL; | 87 | vhfdi = NULL; |
| 88 | |||
| 89 | ReleaseNullStr(vpszResource); | ||
| 88 | } | 90 | } |
| 89 | 91 | ||
| 90 | return hr; | 92 | return hr; |
| @@ -101,6 +103,8 @@ extern "C" void RexUninitialize() | |||
| 101 | { | 103 | { |
| 102 | ::FDIDestroy(vhfdi); | 104 | ::FDIDestroy(vhfdi); |
| 103 | vhfdi = NULL; | 105 | vhfdi = NULL; |
| 106 | |||
| 107 | ReleaseNullStr(vpszResource); | ||
| 104 | } | 108 | } |
| 105 | } | 109 | } |
| 106 | 110 | ||
| @@ -124,12 +128,12 @@ extern "C" HRESULT RexExtract( | |||
| 124 | { | 128 | { |
| 125 | Assert(vhfdi); | 129 | Assert(vhfdi); |
| 126 | HRESULT hr = S_OK; | 130 | HRESULT hr = S_OK; |
| 127 | BOOL fResult; | 131 | BOOL fResult = FALSE; |
| 128 | 132 | ||
| 129 | HRSRC hResInfo = NULL; | 133 | HRSRC hResInfo = NULL; |
| 130 | HANDLE hRes = NULL; | 134 | HANDLE hRes = NULL; |
| 131 | 135 | ||
| 132 | REX_CALLBACK_STRUCT rcs; | 136 | REX_CALLBACK_STRUCT rcs = { }; |
| 133 | 137 | ||
| 134 | // remember the write callback | 138 | // remember the write callback |
| 135 | vpfnWrite = pfnWrite; | 139 | vpfnWrite = pfnWrite; |
| @@ -158,7 +162,7 @@ extern "C" HRESULT RexExtract( | |||
| 158 | // RexExitOnLastError(hr, "failed to convert cabinet resource name to ASCII: %ls", wzResource); | 162 | // RexExitOnLastError(hr, "failed to convert cabinet resource name to ASCII: %ls", wzResource); |
| 159 | //} | 163 | //} |
| 160 | 164 | ||
| 161 | hr = ::StringCchCopyA(vszResource, countof(vszResource), szResource); | 165 | hr = StrAnsiAllocStringAnsi(&vpszResource, szResource, 0); |
| 162 | RexExitOnFailure(hr, "Failed to copy resource name to global."); | 166 | RexExitOnFailure(hr, "Failed to copy resource name to global."); |
| 163 | 167 | ||
| 164 | // | 168 | // |
| @@ -171,7 +175,7 @@ extern "C" HRESULT RexExtract( | |||
| 171 | rcs.pfnProgress = pfnProgress; | 175 | rcs.pfnProgress = pfnProgress; |
| 172 | rcs.pvContext = pvContext; | 176 | rcs.pvContext = pvContext; |
| 173 | 177 | ||
| 174 | fResult = ::FDICopy(vhfdi, vszResource, "", 0, RexCallback, NULL, static_cast<void*>(&rcs)); | 178 | fResult = ::FDICopy(vhfdi, vpszResource, "", 0, RexCallback, NULL, static_cast<void*>(&rcs)); |
| 175 | if (!fResult && !rcs.fStopExtracting) // if something went wrong and it wasn't us just stopping the extraction, then return a failure | 179 | if (!fResult && !rcs.fStopExtracting) // if something went wrong and it wasn't us just stopping the extraction, then return a failure |
| 176 | { | 180 | { |
| 177 | hr = vhrLastError; // TODO: put verf info in trace message here | 181 | hr = vhrLastError; // TODO: put verf info in trace message here |
| @@ -227,7 +231,7 @@ static __callback INT_PTR FAR DIAMONDAPI RexOpen(__in_z char FAR *pszFile, int o | |||
| 227 | RexExitOnFailure(hr, "File table exceeded"); | 231 | RexExitOnFailure(hr, "File table exceeded"); |
| 228 | } | 232 | } |
| 229 | 233 | ||
| 230 | if (0 == lstrcmpA(vszResource, pszFile)) | 234 | if (0 == lstrcmpA(vpszResource, pszFile)) |
| 231 | { | 235 | { |
| 232 | vrgffFileTable[i].fUsed = TRUE; | 236 | vrgffFileTable[i].fUsed = TRUE; |
| 233 | vrgffFileTable[i].fftType = MEMORY_FILE; | 237 | vrgffFileTable[i].fftType = MEMORY_FILE; |
| @@ -436,15 +440,16 @@ static __callback INT_PTR DIAMONDAPI RexCallback(FDINOTIFICATIONTYPE iNotificati | |||
| 436 | HANDLE hFile = INVALID_HANDLE_VALUE; | 440 | HANDLE hFile = INVALID_HANDLE_VALUE; |
| 437 | 441 | ||
| 438 | REX_CALLBACK_STRUCT* prcs = static_cast<REX_CALLBACK_STRUCT*>(pFDINotify->pv); | 442 | REX_CALLBACK_STRUCT* prcs = static_cast<REX_CALLBACK_STRUCT*>(pFDINotify->pv); |
| 439 | LPCSTR sz; | 443 | LPCSTR sz = NULL; |
| 440 | WCHAR wz[MAX_PATH]; | 444 | LPWSTR pwz = NULL; |
| 441 | FILETIME ft; | 445 | LPWSTR pwzPath = NULL; |
| 446 | FILETIME ft = { }; | ||
| 442 | int i = 0; | 447 | int i = 0; |
| 443 | 448 | ||
| 444 | switch (iNotification) | 449 | switch (iNotification) |
| 445 | { | 450 | { |
| 446 | case fdintCOPY_FILE: // beGIN extracting a resource from cabinet | 451 | case fdintCOPY_FILE: // beGIN extracting a resource from cabinet |
| 447 | Assert(pFDINotify->psz1); | 452 | Assert(pFDINotify->psz1 && prcs); |
| 448 | 453 | ||
| 449 | if (prcs->fStopExtracting) | 454 | if (prcs->fStopExtracting) |
| 450 | { | 455 | { |
| @@ -453,55 +458,50 @@ static __callback INT_PTR DIAMONDAPI RexCallback(FDINOTIFICATIONTYPE iNotificati | |||
| 453 | 458 | ||
| 454 | // convert params to useful variables | 459 | // convert params to useful variables |
| 455 | sz = static_cast<LPCSTR>(pFDINotify->psz1); | 460 | sz = static_cast<LPCSTR>(pFDINotify->psz1); |
| 456 | if (!::MultiByteToWideChar(CP_ACP, 0, sz, -1, wz, countof(wz))) | 461 | RexExitOnNull(sz, hr, E_INVALIDARG, "No cabinet file ID given to convert"); |
| 457 | { | 462 | |
| 458 | RexExitWithLastError(hr, "failed to convert cabinet file id to unicode: %s", sz); | 463 | hr = StrAllocStringAnsi(&pwz, sz, 0, CP_ACP); |
| 459 | } | 464 | RexExitOnFailure(hr, "failed to convert cabinet file id to unicode: %hs", sz); |
| 460 | 465 | ||
| 461 | if (prcs->pfnProgress) | 466 | if (prcs->pfnProgress) |
| 462 | { | 467 | { |
| 463 | hr = prcs->pfnProgress(TRUE, wz, prcs->pvContext); | 468 | hr = prcs->pfnProgress(TRUE, pwz, prcs->pvContext); |
| 464 | if (S_OK != hr) | 469 | if (S_OK != hr) |
| 465 | { | 470 | { |
| 466 | ExitFunction(); | 471 | ExitFunction(); |
| 467 | } | 472 | } |
| 468 | } | 473 | } |
| 469 | 474 | ||
| 470 | if (L'*' == *prcs->pwzExtract || 0 == lstrcmpW(prcs->pwzExtract, wz)) | 475 | if (L'*' == *prcs->pwzExtract || 0 == lstrcmpW(prcs->pwzExtract, pwz)) |
| 471 | { | 476 | { |
| 472 | // get the created date for the resource in the cabinet | 477 | // get the created date for the resource in the cabinet |
| 473 | if (!::DosDateTimeToFileTime(pFDINotify->date, pFDINotify->time, &ft)) | 478 | if (!::DosDateTimeToFileTime(pFDINotify->date, pFDINotify->time, &ft)) |
| 474 | { | 479 | { |
| 475 | RexExitWithLastError(hr, "failed to get time for resource: %ls", wz); | 480 | RexExitWithLastError(hr, "failed to get time for resource: %ls", pwz); |
| 476 | } | 481 | } |
| 477 | 482 | ||
| 478 | WCHAR wzPath[MAX_PATH]; | ||
| 479 | |||
| 480 | hr = ::StringCchCopyW(wzPath, countof(wzPath), prcs->pwzExtractDir); | ||
| 481 | RexExitOnFailure(hr, "failed to copy extract directory: %ls for file: %ls", prcs->pwzExtractDir, wz); | ||
| 482 | |||
| 483 | if (L'*' == *prcs->pwzExtract) | 483 | if (L'*' == *prcs->pwzExtract) |
| 484 | { | 484 | { |
| 485 | hr = ::StringCchCatW(wzPath, countof(wzPath), wz); | 485 | hr = PathConcat(prcs->pwzExtractDir, pwz, &pwzPath); |
| 486 | RexExitOnFailure(hr, "failed to concat onto path: %ls file: %ls", wzPath, wz); | 486 | RexExitOnFailure(hr, "failed to concat onto path: %ls file: %ls", prcs->pwzExtractDir, pwz); |
| 487 | } | 487 | } |
| 488 | else | 488 | else |
| 489 | { | 489 | { |
| 490 | Assert(*prcs->pwzExtractName); | 490 | Assert(*prcs->pwzExtractName); |
| 491 | 491 | ||
| 492 | hr = ::StringCchCatW(wzPath, countof(wzPath), prcs->pwzExtractName); | 492 | hr = PathConcat(prcs->pwzExtractDir, prcs->pwzExtractName, &pwzPath); |
| 493 | RexExitOnFailure(hr, "failed to concat onto path: %ls file: %ls", wzPath, prcs->pwzExtractName); | 493 | RexExitOnFailure(hr, "failed to concat onto path: %ls file: %ls", prcs->pwzExtractDir, prcs->pwzExtractName); |
| 494 | } | 494 | } |
| 495 | 495 | ||
| 496 | // Quickly chop off the file name part of the path to ensure the path exists | 496 | // Quickly chop off the file name part of the path to ensure the path exists |
| 497 | // then put the file name back on the path (by putting the first character | 497 | // then put the file name back on the path (by putting the first character |
| 498 | // back over the null terminator). | 498 | // back over the null terminator). |
| 499 | LPWSTR wzFile = PathFile(wzPath); | 499 | LPWSTR wzFile = PathFile(pwzPath); |
| 500 | WCHAR wzFileFirstChar = *wzFile; | 500 | WCHAR wzFileFirstChar = *wzFile; |
| 501 | *wzFile = L'\0'; | 501 | *wzFile = L'\0'; |
| 502 | 502 | ||
| 503 | hr = DirEnsureExists(wzPath, NULL); | 503 | hr = DirEnsureExists(pwzPath, NULL); |
| 504 | RexExitOnFailure(hr, "failed to ensure directory: %ls", wzPath); | 504 | RexExitOnFailure(hr, "failed to ensure directory: %ls", pwzPath); |
| 505 | 505 | ||
| 506 | hr = S_OK; | 506 | hr = S_OK; |
| 507 | 507 | ||
| @@ -524,10 +524,10 @@ static __callback INT_PTR DIAMONDAPI RexCallback(FDINOTIFICATIONTYPE iNotificati | |||
| 524 | } | 524 | } |
| 525 | 525 | ||
| 526 | // open the file | 526 | // open the file |
| 527 | hFile = ::CreateFileW(wzPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | 527 | hFile = ::CreateFileW(pwzPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
| 528 | if (INVALID_HANDLE_VALUE == hFile) | 528 | if (INVALID_HANDLE_VALUE == hFile) |
| 529 | { | 529 | { |
| 530 | RexExitWithLastError(hr, "failed to open file: %ls", wzPath); | 530 | RexExitWithLastError(hr, "failed to open file: %ls", pwzPath); |
| 531 | } | 531 | } |
| 532 | 532 | ||
| 533 | vrgffFileTable[i].fUsed = TRUE; | 533 | vrgffFileTable[i].fUsed = TRUE; |
| @@ -554,20 +554,20 @@ static __callback INT_PTR DIAMONDAPI RexCallback(FDINOTIFICATIONTYPE iNotificati | |||
| 554 | 554 | ||
| 555 | break; | 555 | break; |
| 556 | case fdintCLOSE_FILE_INFO: // resource extraction complete | 556 | case fdintCLOSE_FILE_INFO: // resource extraction complete |
| 557 | Assert(pFDINotify->hf && pFDINotify->psz1); | 557 | Assert(pFDINotify->hf && prcs && pFDINotify->psz1); |
| 558 | 558 | ||
| 559 | // convert params to useful variables | 559 | // convert params to useful variables |
| 560 | sz = static_cast<LPCSTR>(pFDINotify->psz1); | 560 | sz = static_cast<LPCSTR>(pFDINotify->psz1); |
| 561 | if (!::MultiByteToWideChar(CP_ACP, 0, sz, -1, wz, countof(wz))) | 561 | RexExitOnNull(sz, hr, E_INVALIDARG, "No cabinet file ID given to convert"); |
| 562 | { | 562 | |
| 563 | RexExitWithLastError(hr, "failed to convert cabinet file id to unicode: %s", sz); | 563 | hr = StrAllocStringAnsi(&pwz, sz, 0, CP_ACP); |
| 564 | } | 564 | RexExitOnFailure(hr, "failed to convert cabinet file id to unicode: %hs", sz); |
| 565 | 565 | ||
| 566 | RexClose(pFDINotify->hf); | 566 | RexClose(pFDINotify->hf); |
| 567 | 567 | ||
| 568 | if (prcs->pfnProgress) | 568 | if (prcs->pfnProgress) |
| 569 | { | 569 | { |
| 570 | hr = prcs->pfnProgress(FALSE, wz, prcs->pvContext); | 570 | hr = prcs->pfnProgress(FALSE, pwz, prcs->pvContext); |
| 571 | } | 571 | } |
| 572 | 572 | ||
| 573 | if (S_OK == hr && L'*' == *prcs->pwzExtract) // if everything is okay and we're extracting all files, keep going | 573 | if (S_OK == hr && L'*' == *prcs->pwzExtract) // if everything is okay and we're extracting all files, keep going |
| @@ -597,5 +597,8 @@ LExit: | |||
| 597 | vhrLastError = hr; | 597 | vhrLastError = hr; |
| 598 | } | 598 | } |
| 599 | 599 | ||
| 600 | ReleaseStr(pwz); | ||
| 601 | ReleaseStr(pwzPath); | ||
| 602 | |||
| 600 | return (S_OK == hr) ? ipResult : -1; | 603 | return (S_OK == hr) ? ipResult : -1; |
| 601 | } | 604 | } |
