summaryrefslogtreecommitdiff
path: root/src/libs/dutil/WixToolset.DUtil/rexutil.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-06-24 12:28:27 -0500
committerSean Hall <r.sean.hall@gmail.com>2022-06-27 11:14:21 -0500
commiteb53852d7ae6838e54525eb57df1d8ce8a722f9b (patch)
tree7fa05bd6df1bce2e20d87c5fbacc1c658dc000aa /src/libs/dutil/WixToolset.DUtil/rexutil.cpp
parent6ee12a64cb75097a238e60d4fd0ea542e8312214 (diff)
downloadwix-eb53852d7ae6838e54525eb57df1d8ce8a722f9b.tar.gz
wix-eb53852d7ae6838e54525eb57df1d8ce8a722f9b.tar.bz2
wix-eb53852d7ae6838e54525eb57df1d8ce8a722f9b.zip
Add longPathAware to Burn manifest to support long paths.
Fixes 3455
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/rexutil.cpp')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/rexutil.cpp77
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;
28static FAKE_FILE vrgffFileTable[FILETABLESIZE]; 28static FAKE_FILE vrgffFileTable[FILETABLESIZE];
29static DWORD vcbRes; 29static DWORD vcbRes;
30static LPCBYTE vpbRes; 30static LPCBYTE vpbRes;
31static CHAR vszResource[MAX_PATH]; 31static LPSTR vpszResource = NULL;
32static REX_CALLBACK_WRITE vpfnWrite = NULL; 32static REX_CALLBACK_WRITE vpfnWrite = NULL;
33 33
34static HRESULT vhrLastError = S_OK; 34static 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}