summaryrefslogtreecommitdiff
path: root/src/libs/dutil/WixToolset.DUtil/cabutil.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/cabutil.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/cabutil.cpp')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/cabutil.cpp68
1 files changed, 33 insertions, 35 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/cabutil.cpp b/src/libs/dutil/WixToolset.DUtil/cabutil.cpp
index f3629d57..57463e1a 100644
--- a/src/libs/dutil/WixToolset.DUtil/cabutil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/cabutil.cpp
@@ -261,15 +261,15 @@ static HRESULT DAPI CabOperation(
261 ) 261 )
262{ 262{
263 HRESULT hr = S_OK; 263 HRESULT hr = S_OK;
264 BOOL fResult; 264 BOOL fResult = FALSE;
265 265
266 LPWSTR sczCabinet = NULL; 266 LPWSTR sczCabinet = NULL;
267 LPWSTR pwz = NULL; 267 LPWSTR pwz = NULL;
268 CHAR szCabDirectory[MAX_PATH * 4]; // Make sure these are big enough for UTF-8 strings 268 LPSTR pszCabDirectory = NULL;
269 CHAR szCabFile[MAX_PATH * 4]; 269 CHAR szCabFile[MAX_PATH * 4] = { }; // Make sure this is big enough for UTF-8 strings
270 270
271 CAB_CALLBACK_STRUCT ccs; 271 CAB_CALLBACK_STRUCT ccs = { };
272 PFNFDINOTIFY pfnFdiNotify; 272 PFNFDINOTIFY pfnFdiNotify = NULL;
273 273
274 // 274 //
275 // ensure the cabinet.dll is loaded 275 // ensure the cabinet.dll is loaded
@@ -299,15 +299,13 @@ static HRESULT DAPI CabOperation(
299 // If a full path was not provided, use the relative current directory. 299 // If a full path was not provided, use the relative current directory.
300 if (wzCabinet == pwz) 300 if (wzCabinet == pwz)
301 { 301 {
302 hr = ::StringCchCopyA(szCabDirectory, countof(szCabDirectory), ".\\"); 302 hr = StrAnsiAllocStringAnsi(&pszCabDirectory, ".\\", 0);
303 CabExitOnFailure(hr, "Failed to copy relative current directory as cabinet directory."); 303 CabExitOnFailure(hr, "Failed to copy relative current directory as cabinet directory.");
304 } 304 }
305 else 305 else
306 { 306 {
307 if (!::WideCharToMultiByte(CP_UTF8, 0, sczCabinet, -1, szCabDirectory, countof(szCabDirectory), NULL, NULL)) 307 hr = StrAnsiAllocString(&pszCabDirectory, sczCabinet, 0, CP_UTF8);
308 { 308 CabExitOnFailure(hr, "failed to convert cabinet directory to ASCII: %ls", sczCabinet);
309 CabExitWithLastError(hr, "failed to convert cabinet directory to ASCII: %ls", sczCabinet);
310 }
311 } 309 }
312 310
313 // 311 //
@@ -331,7 +329,7 @@ static HRESULT DAPI CabOperation(
331 v_pfnNetFx11Notify = pfnNotify; 329 v_pfnNetFx11Notify = pfnNotify;
332 pfnFdiNotify = FDINotify; 330 pfnFdiNotify = FDINotify;
333 } 331 }
334 fResult = vpfnFDICopy(vhfdi, szCabFile, szCabDirectory, 0, pfnFdiNotify, NULL, static_cast<void*>(&ccs)); 332 fResult = vpfnFDICopy(vhfdi, szCabFile, pszCabDirectory, 0, pfnFdiNotify, NULL, static_cast<void*>(&ccs));
335 if (!fResult && !ccs.fStopExtracting) // if something went wrong and it wasn't us just stopping the extraction, then return a failure 333 if (!fResult && !ccs.fStopExtracting) // if something went wrong and it wasn't us just stopping the extraction, then return a failure
336 { 334 {
337 CabExitWithLastError(hr, "failed to extract cabinet file: %ls", sczCabinet); 335 CabExitWithLastError(hr, "failed to extract cabinet file: %ls", sczCabinet);
@@ -339,6 +337,7 @@ static HRESULT DAPI CabOperation(
339 337
340LExit: 338LExit:
341 ReleaseStr(sczCabinet); 339 ReleaseStr(sczCabinet);
340 ReleaseStr(pszCabDirectory);
342 v_pfnNetFx11Notify = NULL; 341 v_pfnNetFx11Notify = NULL;
343 342
344 return hr; 343 return hr;
@@ -493,14 +492,15 @@ static __callback INT_PTR DIAMONDAPI CabExtractCallback(__in FDINOTIFICATIONTYPE
493 INT_PTR ipResult = 0; // result to return on success 492 INT_PTR ipResult = 0; // result to return on success
494 493
495 CAB_CALLBACK_STRUCT* pccs = static_cast<CAB_CALLBACK_STRUCT*>(pFDINotify->pv); 494 CAB_CALLBACK_STRUCT* pccs = static_cast<CAB_CALLBACK_STRUCT*>(pFDINotify->pv);
496 LPCSTR sz; 495 LPCSTR sz = NULL;
497 WCHAR wz[MAX_PATH]; 496 LPWSTR pwz = NULL;
498 FILETIME ft; 497 LPWSTR pwzPath = NULL;
498 FILETIME ft = { };
499 499
500 switch (iNotification) 500 switch (iNotification)
501 { 501 {
502 case fdintCOPY_FILE: // begin extracting a resource from cabinet 502 case fdintCOPY_FILE: // begin extracting a resource from cabinet
503 CabExitOnNull(pFDINotify->psz1, hr, E_INVALIDARG, "No cabinet file ID given to convert"); 503 Assert(pccs && pFDINotify->psz1);
504 CabExitOnNull(pccs, hr, E_INVALIDARG, "Failed to call cabextract callback, because no callback struct was provided"); 504 CabExitOnNull(pccs, hr, E_INVALIDARG, "Failed to call cabextract callback, because no callback struct was provided");
505 505
506 if (pccs->fStopExtracting) 506 if (pccs->fStopExtracting)
@@ -510,40 +510,37 @@ static __callback INT_PTR DIAMONDAPI CabExtractCallback(__in FDINOTIFICATIONTYPE
510 510
511 // convert params to useful variables 511 // convert params to useful variables
512 sz = static_cast<LPCSTR>(pFDINotify->psz1); 512 sz = static_cast<LPCSTR>(pFDINotify->psz1);
513 if (!::MultiByteToWideChar(CP_ACP, 0, sz, -1, wz, countof(wz))) 513 CabExitOnNull(sz, hr, E_INVALIDARG, "No cabinet file ID given to convert");
514 { 514
515 CabExitWithLastError(hr, "failed to convert cabinet file id to unicode: %s", sz); 515 hr = StrAllocStringAnsi(&pwz, sz, 0, CP_ACP);
516 } 516 CabExitOnFailure(hr, "failed to convert cabinet file id to unicode: %hs", sz);
517 517
518 if (pccs->pfnProgress) 518 if (pccs->pfnProgress)
519 { 519 {
520 hr = pccs->pfnProgress(TRUE, wz, pccs->pvContext); 520 hr = pccs->pfnProgress(TRUE, pwz, pccs->pvContext);
521 if (S_OK != hr) 521 if (S_OK != hr)
522 { 522 {
523 ExitFunction(); 523 ExitFunction();
524 } 524 }
525 } 525 }
526 526
527 if (L'*' == *pccs->pwzExtract || 0 == lstrcmpW(pccs->pwzExtract, wz)) 527 if (L'*' == *pccs->pwzExtract || 0 == lstrcmpW(pccs->pwzExtract, pwz))
528 { 528 {
529 // get the created date for the resource in the cabinet 529 // get the created date for the resource in the cabinet
530 FILETIME ftLocal; 530 FILETIME ftLocal;
531 if (!::DosDateTimeToFileTime(pFDINotify->date, pFDINotify->time, &ftLocal)) 531 if (!::DosDateTimeToFileTime(pFDINotify->date, pFDINotify->time, &ftLocal))
532 { 532 {
533 CabExitWithLastError(hr, "failed to get time for resource: %ls", wz); 533 CabExitWithLastError(hr, "failed to get time for resource: %ls", pwz);
534 } 534 }
535 ::LocalFileTimeToFileTime(&ftLocal, &ft); 535 ::LocalFileTimeToFileTime(&ftLocal, &ft);
536 536
537 WCHAR wzPath[MAX_PATH]; 537 hr = PathConcat(pccs->pwzExtractDir, pwz, &pwzPath);
538 hr = ::StringCchCopyW(wzPath, countof(wzPath), pccs->pwzExtractDir); 538 CabExitOnFailure(hr, "failed to concat onto path: %ls file: %ls", pccs->pwzExtractDir, pwz);
539 CabExitOnFailure(hr, "failed to copy in extract directory: %ls for file: %ls", pccs->pwzExtractDir, wz);
540 hr = ::StringCchCatW(wzPath, countof(wzPath), wz);
541 CabExitOnFailure(hr, "failed to concat onto path: %ls file: %ls", wzPath, wz);
542 539
543 hFile = OpenFileWithRetry(wzPath, GENERIC_WRITE, CREATE_ALWAYS); 540 hFile = OpenFileWithRetry(pwzPath, GENERIC_WRITE, CREATE_ALWAYS);
544 if (INVALID_HANDLE_VALUE == hFile) 541 if (INVALID_HANDLE_VALUE == hFile)
545 { 542 {
546 CabExitWithLastError(hr, "failed to create file: %ls", wzPath); 543 CabExitWithLastError(hr, "failed to create file: %ls", pwzPath);
547 } 544 }
548 545
549 ::SetFileTime(hFile, &ft, &ft, &ft); // try to set the file time (who cares if it fails) 546 ::SetFileTime(hFile, &ft, &ft, &ft); // try to set the file time (who cares if it fails)
@@ -567,17 +564,15 @@ static __callback INT_PTR DIAMONDAPI CabExtractCallback(__in FDINOTIFICATIONTYPE
567 564
568 break; 565 break;
569 case fdintCLOSE_FILE_INFO: // resource extraction complete 566 case fdintCLOSE_FILE_INFO: // resource extraction complete
570 Assert(pFDINotify->hf && pFDINotify->psz1); 567 Assert(pFDINotify->hf && pccs && pFDINotify->psz1);
571 CabExitOnNull(pccs, hr, E_INVALIDARG, "Failed to call cabextract callback, because no callback struct was provided"); 568 CabExitOnNull(pccs, hr, E_INVALIDARG, "Failed to call cabextract callback, because no callback struct was provided");
572 569
573 // convert params to useful variables 570 // convert params to useful variables
574 sz = static_cast<LPCSTR>(pFDINotify->psz1); 571 sz = static_cast<LPCSTR>(pFDINotify->psz1);
575 CabExitOnNull(sz, hr, E_INVALIDARG, "Failed to convert cabinet file id, because no cabinet file id was provided"); 572 CabExitOnNull(sz, hr, E_INVALIDARG, "Failed to convert cabinet file id, because no cabinet file id was provided");
576 573
577 if (!::MultiByteToWideChar(CP_ACP, 0, sz, -1, wz, countof(wz))) 574 hr = StrAllocStringAnsi(&pwz, sz, 0, CP_ACP);
578 { 575 CabExitOnFailure(hr, "failed to convert cabinet file id to unicode: %hs", sz);
579 CabExitWithLastError(hr, "failed to convert cabinet file id to unicode: %s", sz);
580 }
581 576
582 if (NULL != pFDINotify->hf) // just close the file 577 if (NULL != pFDINotify->hf) // just close the file
583 { 578 {
@@ -586,7 +581,7 @@ static __callback INT_PTR DIAMONDAPI CabExtractCallback(__in FDINOTIFICATIONTYPE
586 581
587 if (pccs->pfnProgress) 582 if (pccs->pfnProgress)
588 { 583 {
589 hr = pccs->pfnProgress(FALSE, wz, pccs->pvContext); 584 hr = pccs->pfnProgress(FALSE, pwz, pccs->pvContext);
590 } 585 }
591 586
592 if (S_OK == hr && L'*' == *pccs->pwzExtract) // if everything is okay and we're extracting all files, keep going 587 if (S_OK == hr && L'*' == *pccs->pwzExtract) // if everything is okay and we're extracting all files, keep going
@@ -613,5 +608,8 @@ static __callback INT_PTR DIAMONDAPI CabExtractCallback(__in FDINOTIFICATIONTYPE
613LExit: 608LExit:
614 ReleaseFileHandle(hFile); 609 ReleaseFileHandle(hFile);
615 610
611 ReleaseStr(pwz);
612 ReleaseStr(pwzPath);
613
616 return (S_OK == hr) ? ipResult : -1; 614 return (S_OK == hr) ? ipResult : -1;
617} 615}