- Timestamp:
- Jan 19, 2022 12:31:01 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.cpp
r93340 r93343 157 157 RT_ZERO(StartupInfo); 158 158 StartupInfo.cb = sizeof(StartupInfo); 159 StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);160 StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);161 StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);159 StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); 160 StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); 161 StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); 162 162 StartupInfo.dwFlags = STARTF_USESTDHANDLES; 163 163 #ifndef DEBUG … … 520 520 LONG rc; 521 521 WCHAR wszValue[_MAX_PATH]; 522 if (GetPrivateProfileStringW(pwszSection, pwszValue, NULL, 523 wszValue, sizeof(wszValue), pwszFileName) > 0) 524 { 525 HKEY hkBranding; 526 WCHAR wszKey[_MAX_PATH]; 527 522 if (GetPrivateProfileStringW(pwszSection, pwszValue, NULL, wszValue, sizeof(wszValue), pwszFileName) > 0) 523 { 524 WCHAR wszKey[_MAX_PATH + 64]; 528 525 if (wcsicmp(L"General", pwszSection) != 0) 529 526 swprintf_s(wszKey, RT_ELEMENTS(wszKey), L"SOFTWARE\\%S\\VirtualBox\\Branding\\%s", VBOX_VENDOR_SHORT, pwszSection); … … 531 528 swprintf_s(wszKey, RT_ELEMENTS(wszKey), L"SOFTWARE\\%S\\VirtualBox\\Branding", VBOX_VENDOR_SHORT); 532 529 530 HKEY hkBranding = NULL; 533 531 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszKey, 0, KEY_WRITE, &hkBranding); 534 532 if (rc == ERROR_SUCCESS) … … 550 548 } 551 549 552 UINT CopyDir(MSIHANDLE hModule, const WCHAR *pwszDestDir, const WCHAR *pwszSourceDir) 553 { 554 UINT rc; 555 WCHAR wszDest[_MAX_PATH + 1]; 556 WCHAR wszSource[_MAX_PATH + 1]; 557 558 swprintf_s(wszDest, RT_ELEMENTS(wszDest), L"%s%c", pwszDestDir, L'\0'); 559 swprintf_s(wszSource, RT_ELEMENTS(wszSource), L"%s%c", pwszSourceDir, L'\0'); 550 /** 551 * @note Both paths strings must have an extra terminator. 552 */ 553 static UINT CopyDir(MSIHANDLE hModule, const WCHAR *pwszzDstDir, const WCHAR *pwszzSrcDir) 554 { 555 NonStandardAssert(pwszzDstDir[wcslen(pwszzDstDir) + 1] == '\0'); 556 NonStandardAssert(pwszzSrcDir[wcslen(pwszzSrcDir) + 1] == '\0'); 560 557 561 558 SHFILEOPSTRUCTW s = {0}; 562 559 s.hwnd = NULL; 563 560 s.wFunc = FO_COPY; 564 s.pTo = wszDest;565 s.pFrom = wszSource;561 s.pTo = pwszzDstDir; 562 s.pFrom = pwszzSrcDir; 566 563 s.fFlags = FOF_SILENT 567 564 | FOF_NOCONFIRMATION … … 569 566 | FOF_NOERRORUI; 570 567 571 logStringF(hModule, L"CopyDir: DestDir=%s, SourceDir=%s", wszDest, wszSource);568 logStringF(hModule, L"CopyDir: pwszzDstDir=%s, pwszzSrcDir=%s", pwszzDstDir, pwszzSrcDir); 572 569 int r = SHFileOperationW(&s); 573 570 if (r == 0) 574 rc = ERROR_SUCCESS; 575 else 576 { 577 logStringF(hModule, L"CopyDir: Copy operation returned status %#x", r); 578 rc = ERROR_GEN_FAILURE; 579 } 580 return rc; 581 } 582 583 UINT RemoveDir(MSIHANDLE hModule, const WCHAR *pwszDestDir) 584 { 585 UINT rc; 586 WCHAR wszDest[_MAX_PATH + 1]; 587 588 swprintf_s(wszDest, RT_ELEMENTS(wszDest), L"%s%c", pwszDestDir, L'\0'); 571 return ERROR_SUCCESS; 572 logStringF(hModule, L"CopyDir: Copy operation returned status %#x", r); 573 return ERROR_GEN_FAILURE; 574 } 575 576 /** 577 * @note The directory string must have two zero terminators! 578 */ 579 static UINT RemoveDir(MSIHANDLE hModule, const WCHAR *pwszzDstDir) 580 { 581 NonStandardAssert(pwszzDstDir[wcslen(pwszzDstDir) + 1] == '\0'); 589 582 590 583 SHFILEOPSTRUCTW s = {0}; 591 584 s.hwnd = NULL; 592 585 s.wFunc = FO_DELETE; 593 s.pFrom = wszDest;586 s.pFrom = pwszzDstDir; 594 587 s.fFlags = FOF_SILENT 595 588 | FOF_NOCONFIRMATION … … 597 590 | FOF_NOERRORUI; 598 591 599 logStringF(hModule, L"RemoveDir: DestDir=%s", wszDest);592 logStringF(hModule, L"RemoveDir: pwszzDstDir=%s", pwszzDstDir); 600 593 int r = SHFileOperationW(&s); 601 594 if (r == 0) 602 rc = ERROR_SUCCESS; 603 else 604 { 605 logStringF(hModule, L"RemoveDir: Remove operation returned status %#x", r); 606 rc = ERROR_GEN_FAILURE; 607 } 608 return rc; 609 } 610 611 UINT RenameDir(MSIHANDLE hModule, const WCHAR *pwszDestDir, const WCHAR *pwszSourceDir) 612 { 613 UINT rc; 614 WCHAR wszDest[_MAX_PATH + 1]; 615 WCHAR wszSource[_MAX_PATH + 1]; 616 617 swprintf_s(wszDest, RT_ELEMENTS(wszDest), L"%s%c", pwszDestDir, L'\0'); 618 swprintf_s(wszSource, RT_ELEMENTS(wszSource), L"%s%c", pwszSourceDir, L'\0'); 595 return ERROR_SUCCESS; 596 logStringF(hModule, L"RemoveDir: Remove operation returned status %#x", r); 597 return ERROR_GEN_FAILURE; 598 } 599 600 /** 601 * @note Both paths strings must have an extra terminator. 602 */ 603 static UINT RenameDir(MSIHANDLE hModule, const WCHAR *pwszzDstDir, const WCHAR *pwszzSrcDir) 604 { 605 NonStandardAssert(pwszzDstDir[wcslen(pwszzDstDir) + 1] == '\0'); 606 NonStandardAssert(pwszzSrcDir[wcslen(pwszzSrcDir) + 1] == '\0'); 619 607 620 608 SHFILEOPSTRUCTW s = {0}; 621 609 s.hwnd = NULL; 622 610 s.wFunc = FO_RENAME; 623 s.pTo = wszDest;624 s.pFrom = wszSource;611 s.pTo = pwszzDstDir; 612 s.pFrom = pwszzSrcDir; 625 613 s.fFlags = FOF_SILENT 626 614 | FOF_NOCONFIRMATION … … 628 616 | FOF_NOERRORUI; 629 617 630 logStringF(hModule, L"RenameDir: DestDir=%s, SourceDir=%s", wszDest, wszSource);618 logStringF(hModule, L"RenameDir: pwszzDstDir=%s, pwszzSrcDir=%s", pwszzDstDir, pwszzSrcDir); 631 619 int r = SHFileOperationW(&s); 632 620 if (r == 0) 633 rc = ERROR_SUCCESS; 634 else 635 { 636 logStringF(hModule, L"RenameDir: Rename operation returned status %#x", r); 637 rc = ERROR_GEN_FAILURE; 638 } 639 return rc; 621 return ERROR_SUCCESS; 622 logStringF(hModule, L"RenameDir: Rename operation returned status %#x", r); 623 return ERROR_GEN_FAILURE; 624 } 625 626 /** RTPathAppend-like function. */ 627 static UINT AppendToPath(wchar_t *pwszPath, size_t cwcPath, wchar_t *pwszAppend, bool fDoubleTerm = false) 628 { 629 size_t cwcCurPath = wcslen(pwszPath); 630 size_t cwcSlash = cwcCurPath > 1 && RTPATH_IS_SLASH(pwszPath[cwcCurPath - 1]) ? 0 : 1; 631 while (RTPATH_IS_SLASH(*pwszAppend)) 632 pwszAppend++; 633 size_t cwcAppend = wcslen(pwszAppend); 634 if (cwcCurPath + cwcCurPath + cwcAppend + fDoubleTerm < cwcPath) 635 { 636 if (cwcSlash) 637 pwszPath[cwcCurPath++] = '\\'; 638 memcpy(&pwszPath[cwcCurPath], pwszAppend, (cwcAppend + 1) * sizeof(wchar_t)); 639 if (fDoubleTerm) 640 pwszPath[cwcCurPath + cwcAppend + 1] = '\0'; 641 return ERROR_SUCCESS; 642 } 643 return ERROR_BUFFER_OVERFLOW; 644 } 645 646 /** RTPathJoin-like function. */ 647 static UINT JoinPaths(wchar_t *pwszPath, size_t cwcPath, wchar_t *pwszPath1, wchar_t *pwszAppend, bool fDoubleTerm = false) 648 { 649 size_t cwcCurPath = wcslen(pwszPath1); 650 if (cwcCurPath < cwcPath) 651 { 652 memcpy(pwszPath, pwszPath1, (cwcCurPath + 1) * sizeof(wchar_t)); 653 return AppendToPath(pwszPath, cwcPath, pwszAppend, fDoubleTerm); 654 } 655 return ERROR_BUFFER_OVERFLOW; 640 656 } 641 657 642 658 UINT __stdcall UninstallBranding(MSIHANDLE hModule) 643 659 { 644 UINT rc;645 660 logStringF(hModule, L"UninstallBranding: Handling branding file ..."); 646 661 647 WCHAR wszPathTargetDir[_MAX_PATH]; 648 649 rc = VBoxGetMsiProp(hModule, L"CustomActionData", wszPathTargetDir, sizeof(wszPathTargetDir)); 662 WCHAR wszPath[RTPATH_MAX]; 663 UINT rc = VBoxGetMsiProp(hModule, L"CustomActionData", wszPath, sizeof(wszPath)); 650 664 if (rc == ERROR_SUCCESS) 651 665 { 652 /** @todo Check trailing slash after %s. */ 653 /** @todo r=bird: using swprintf_s for formatting paths without checking for 654 * overflow not good. You're dodging the buffer overflow issue only to end up 655 * with incorrect behavior! (Truncated file/dir names) 656 * 657 * This applies almost to all swprintf_s calls in this file!! 658 */ 659 WCHAR wszPathDest[_MAX_PATH]; 660 swprintf_s(wszPathDest, RT_ELEMENTS(wszPathDest), L"%scustom", wszPathTargetDir); 661 rc = RemoveDir(hModule, wszPathDest); 662 if (rc != ERROR_SUCCESS) 663 { 664 /* Check for hidden .custom directory and remove it. */ 665 swprintf_s(wszPathDest, RT_ELEMENTS(wszPathDest), L"%s.custom", wszPathTargetDir); 666 rc = RemoveDir(hModule, wszPathDest); 667 } 666 size_t const cwcPath = wcslen(wszPath); 667 rc = AppendToPath(wszPath, RTPATH_MAX, L"custom", true /*fDoubleTerm*/); 668 if (rc == ERROR_SUCCESS) 669 rc = RemoveDir(hModule, wszPath); 670 671 /* Check for .custom directory from a failed install and remove it. */ 672 wszPath[cwcPath] = '\0'; 673 rc = AppendToPath(wszPath, RTPATH_MAX, L".custom", true /*fDoubleTerm*/); 674 if (rc == ERROR_SUCCESS) 675 rc = RemoveDir(hModule, wszPath); 668 676 } 669 677 … … 674 682 UINT __stdcall InstallBranding(MSIHANDLE hModule) 675 683 { 676 UINT rc;677 684 logStringF(hModule, L"InstallBranding: Handling branding file ..."); 678 685 679 WCHAR wszPathMSI[_MAX_PATH]; 680 rc = VBoxGetMsiProp(hModule, L"SOURCEDIR", wszPathMSI, sizeof(wszPathMSI)); 686 /* 687 * Get the paths. 688 */ 689 wchar_t wszSrcPath[RTPATH_MAX]; 690 UINT rc = VBoxGetMsiProp(hModule, L"SOURCEDIR", wszSrcPath, RT_ELEMENTS(wszSrcPath)); 681 691 if (rc == ERROR_SUCCESS) 682 692 { 683 WCHAR wszPathTargetDir[_MAX_PATH];684 rc = VBoxGetMsiProp(hModule, L"CustomActionData", wsz PathTargetDir, sizeof(wszPathTargetDir));693 wchar_t wszDstPath[RTPATH_MAX]; 694 rc = VBoxGetMsiProp(hModule, L"CustomActionData", wszDstPath, RT_ELEMENTS(wszDstPath) - 1); 685 695 if (rc == ERROR_SUCCESS) 686 696 { 687 /** @todo Check for trailing slash after %s. */ 688 WCHAR wszPathDest[_MAX_PATH]; 689 swprintf_s(wszPathDest, RT_ELEMENTS(wszPathDest), L"%s", wszPathTargetDir); 690 691 WCHAR wszPathSource[_MAX_PATH]; 692 swprintf_s(wszPathSource, RT_ELEMENTS(wszPathSource), L"%s.custom", wszPathMSI); 693 rc = CopyDir(hModule, wszPathDest, wszPathSource); 697 /* 698 * First we copy the src\.custom dir to the target. 699 */ 700 rc = AppendToPath(wszSrcPath, RT_ELEMENTS(wszSrcPath) - 1, L".custom", true /*fDoubleTerm*/); 694 701 if (rc == ERROR_SUCCESS) 695 702 { 696 swprintf_s(wszPathDest, RT_ELEMENTS(wszPathDest), L"%scustom", wszPathTargetDir); 697 swprintf_s(wszPathSource, RT_ELEMENTS(wszPathSource), L"%s.custom", wszPathTargetDir); 698 rc = RenameDir(hModule, wszPathDest, wszPathSource); 703 rc = CopyDir(hModule, wszDstPath, wszSrcPath); 704 if (rc == ERROR_SUCCESS) 705 { 706 /* 707 * The rename the '.custom' directory we now got in the target area to 'custom'. 708 */ 709 rc = JoinPaths(wszSrcPath, RT_ELEMENTS(wszSrcPath), wszDstPath, L".custom", true /*fDoubleTerm*/); 710 if (rc == ERROR_SUCCESS) 711 { 712 rc = AppendToPath(wszDstPath, RT_ELEMENTS(wszDstPath), L"custom", true /*fDoubleTerm*/); 713 if (rc == ERROR_SUCCESS) 714 rc = RenameDir(hModule, wszDstPath, wszSrcPath); 715 } 716 } 699 717 } 700 718 } … … 1628 1646 { 1629 1647 WCHAR wszRegLocation[256]; 1630 swprintf(wszRegLocation, 1631 L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s", 1632 pwszGUID); 1648 swprintf_s(wszRegLocation, RT_ELEMENTS(wszRegLocation), 1649 L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s", pwszGUID); 1633 1650 LONG lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszRegLocation, 0, KEY_READ, &hkeyNetwork); 1634 if ( (lStatus != ERROR_SUCCESS)|| !hkeyNetwork)1651 if (lStatus != ERROR_SUCCESS || !hkeyNetwork) 1635 1652 SetErrBreak((hModule, L"VBox HostInterfaces: Host interface network was not found in registry (%s)! [1]", 1636 1653 wszRegLocation)); 1637 1654 1638 1655 lStatus = RegOpenKeyExW(hkeyNetwork, L"Connection", 0, KEY_READ, &hkeyConnection); 1639 if ( (lStatus != ERROR_SUCCESS)|| !hkeyConnection)1656 if (lStatus != ERROR_SUCCESS || !hkeyConnection) 1640 1657 SetErrBreak((hModule, L"VBox HostInterfaces: Host interface network was not found in registry (%s)! [2]", 1641 1658 wszRegLocation)); … … 1643 1660 DWORD len = sizeof(wszPnPInstanceId); 1644 1661 DWORD dwKeyType; 1645 lStatus = RegQueryValueExW(hkeyConnection, L"PnPInstanceID", NULL, 1646 &dwKeyType, (LPBYTE)&wszPnPInstanceId[0], &len); 1647 if ((lStatus != ERROR_SUCCESS) || (dwKeyType != REG_SZ)) 1662 lStatus = RegQueryValueExW(hkeyConnection, L"PnPInstanceID", NULL, &dwKeyType, (LPBYTE)&wszPnPInstanceId[0], &len); 1663 if (lStatus != ERROR_SUCCESS || (dwKeyType != REG_SZ)) 1648 1664 SetErrBreak((hModule, L"VBox HostInterfaces: Host interface network was not found in registry (%s)! [3]", 1649 1665 wszRegLocation));
Note:
See TracChangeset
for help on using the changeset viewer.