diff options
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/rexutil.cpp')
-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 | } |