diff options
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/cabutil.cpp')
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/cabutil.cpp | 68 |
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 | ||
340 | LExit: | 338 | LExit: |
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 | |||
613 | LExit: | 608 | LExit: |
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 | } |