diff options
Diffstat (limited to '')
| -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 | } |
