Changeset 104162 in vbox for trunk/src/VBox/Installer
- Timestamp:
- Apr 4, 2024 5:05:37 PM (11 months ago)
- svn:sync-xref-src-repo-rev:
- 162588
- Location:
- trunk/src/VBox/Installer/win
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Installer/win/InstallHelper/VBoxCommon.cpp
r103676 r104162 39 39 #include <iprt/utf16.h> 40 40 41 #include "VBoxCommon.h" 41 42 43 44 #ifndef TESTCASE 45 /** 46 * Retrieves a MSI property (in UTF-16). 47 * 48 * Convenience function for VBoxGetMsiProp(). 49 * 50 * @returns VBox status code. 51 * @param hMsi MSI handle to use. 52 * @param pwszName Name of property to retrieve. 53 * @param pwszValueBuf Where to store the allocated value on success. 54 * @param cwcValueBuf Size (in WCHARs) of \a pwszValueBuf. 55 */ 42 56 UINT VBoxGetMsiProp(MSIHANDLE hMsi, const WCHAR *pwszName, WCHAR *pwszValueBuf, DWORD cwcValueBuf) 43 57 { 44 RT_BZERO(pwszValueBuf, cwcValueBuf * sizeof(pwszValueBuf[0])); 58 RT_BZERO(pwszValueBuf, cwcValueBuf * sizeof(WCHAR)); 59 return MsiGetPropertyW(hMsi, pwszName, pwszValueBuf, &cwcValueBuf); 60 } 61 #endif 45 62 46 /** @todo r=bird: why do we need to query the size first and then the data.47 * The API should be perfectly capable of doing that without our help. */48 WCHAR wcDummy = 0;49 DWORD cwcNeeded = 0;50 UINT uiRet = MsiGetPropertyW(hMsi, pwszName, &wcDummy, &cwcNeeded);51 if (uiRet == ERROR_MORE_DATA)52 {53 ++cwcNeeded; /* On output does not include terminating null, so add 1. */54 55 if (cwcNeeded > cwcValueBuf)56 return ERROR_MORE_DATA;57 uiRet = MsiGetPropertyW(hMsi, pwszName, pwszValueBuf, &cwcNeeded);58 }59 return uiRet;60 }61 62 #if 0 /* unused */63 63 /** 64 64 * Retrieves a MSI property (in UTF-8). … … 89 89 return rc; 90 90 } 91 #endif92 91 92 #ifndef TESTCASE 93 93 UINT VBoxSetMsiProp(MSIHANDLE hMsi, const WCHAR *pwszName, const WCHAR *pwszValue) 94 94 { 95 95 return MsiSetPropertyW(hMsi, pwszName, pwszValue); 96 96 } 97 #endif 97 98 98 99 UINT VBoxSetMsiPropDWORD(MSIHANDLE hMsi, const WCHAR *pwszName, DWORD dwVal) -
trunk/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.cpp
r103889 r104162 38 38 #include <iprt/win/windows.h> 39 39 40 #include <aclapi.h> 40 41 #include <msi.h> 41 42 #include <msiquery.h> … … 46 47 #include <cfgmgr32.h> 47 48 #include <devguid.h> 49 #include <sddl.h> /* For ConvertSidToStringSidW. */ 48 50 49 51 #include <iprt/win/objbase.h> … … 55 57 #include <iprt/assert.h> 56 58 #include <iprt/alloca.h> 59 #include <iprt/dir.h> 60 #include <iprt/err.h> 61 #include <iprt/file.h> 57 62 #include <iprt/mem.h> 58 63 #include <iprt/path.h> /* RTPATH_MAX, RTPATH_IS_SLASH */ 59 64 #include <iprt/string.h> /* RT_ZERO */ 65 #include <iprt/stream.h> 66 #include <iprt/thread.h> 60 67 #include <iprt/utf16.h> 61 68 … … 79 86 80 87 88 /********************************************************************************************************************************* 89 * Internal structures * 90 *********************************************************************************************************************************/ 91 /** 92 * Structure for keeping a target's directory security context. 93 */ 94 typedef struct TGTDIRSECCTX 95 { 96 /** Initialized status. */ 97 bool fInitialized; 98 /** Handle of the target's parent directory. 99 * 100 * Kept open while the context is around and initialized. */ 101 RTDIR hParentDir; 102 /** Absolute (resolved) path of the target directory. */ 103 char szTargetDirAbs[RTPATH_MAX]; 104 /** Access mask which is forbidden for an ACE of type ACCESS_ALLOWED_ACE_TYPE. */ 105 uint32_t fAccessMaskForbidden; 106 /** Array of well-known SIDs which are forbidden. */ 107 PSID *paWellKnownSidsForbidden; 108 /** Number of entries in \a paWellKnownSidsForbidden. */ 109 size_t cWellKnownSidsForbidden; 110 } TGTDIRSECCTX; 111 /** Pointer to a target's directory security context. */ 112 typedef TGTDIRSECCTX *PTGTDIRSECCTX; 113 114 115 /********************************************************************************************************************************* 116 * Prototypes * 117 *********************************************************************************************************************************/ 118 static void destroyTargetDirSecurityCtx(PTGTDIRSECCTX pCtx); 119 120 121 /********************************************************************************************************************************* 122 * Globals * 123 *********************************************************************************************************************************/ 124 static uint32_t g_cRef = 0; 125 /** Our target directory security context. 126 * 127 * Has to be global in order to keep it around as long as the DLL is being loaded. */ 128 static TGTDIRSECCTX g_TargetDirSecCtx = { 0 }; 129 81 130 82 131 /** … … 87 136 RT_NOREF(hInst, uReason, pReserved); 88 137 138 #ifdef DEBUG 139 WCHAR wszMsg[128]; 140 RTUtf16Printf(wszMsg, RT_ELEMENTS(wszMsg), "DllMain: hInst=%#x, uReason=%u (PID %u), g_cRef=%RU32\n", 141 hInst, uReason, GetCurrentProcessId(), g_cRef); 142 OutputDebugStringW(wszMsg); 143 #endif 144 145 switch (uReason) 146 { 147 case DLL_PROCESS_ATTACH: 148 { 149 g_cRef++; 89 150 #if 0 90 /* 91 * This is a trick for allowing the debugger to be attached, don't know if 92 * there is an official way to do that, but this is a pretty efficient. 93 * 94 * Monitor the debug output in DbgView and be ready to start windbg when 95 * the message below appear. This will happen 3-4 times during install, 96 * and 2-3 times during uninstall. 97 * 98 * Note! The DIFxApp.DLL will automatically trigger breakpoints when a 99 * debugger is attached. Just continue on these. 100 */ 101 if (uReason == DLL_PROCESS_ATTACH) 102 { 103 WCHAR wszMsg[128]; 104 RTUtf16Printf(wszMsg, RT_ELEMENTS(wszMsg), "Waiting for debugger to attach: windbg -g -G -p %u\n", GetCurrentProcessId()); 105 for (unsigned i = 0; i < 128 && !IsDebuggerPresent(); i++) 106 { 107 OutputDebugStringW(wszMsg); 108 Sleep(1001); 109 } 110 Sleep(1002); 111 __debugbreak(); 112 } 151 /* 152 * This is a trick for allowing the debugger to be attached, don't know if 153 * there is an official way to do that, but this is a pretty efficient. 154 * 155 * Monitor the debug output in DbgView and be ready to start windbg when 156 * the message below appear. This will happen 3-4 times during install, 157 * and 2-3 times during uninstall. 158 * 159 * Note! The DIFxApp.DLL will automatically trigger breakpoints when a 160 * debugger is attached. Just continue on these. 161 */ 162 RTUtf16Printf(wszMsg, RT_ELEMENTS(wszMsg), "Waiting for debugger to attach: windbg -g -G -p %u\n", GetCurrentProcessId()); 163 for (unsigned i = 0; i < 128 && !IsDebuggerPresent(); i++) 164 { 165 OutputDebugStringW(wszMsg); 166 Sleep(1001); 167 } 168 Sleep(1002); 169 __debugbreak(); 113 170 #endif 171 break; 172 } 173 174 case DLL_PROCESS_DETACH: 175 { 176 g_cRef--; 177 break; 178 } 179 180 default: 181 break; 182 } 114 183 115 184 return TRUE; … … 117 186 118 187 /** 119 * Format a nd add message to the MSI log.188 * Format a log message and print it to whatever is there (i.e. to the MSI log). 120 189 * 121 190 * UTF-16 strings are formatted using '%ls' (lowercase). 122 191 * ANSI strings are formatted using '%s' (uppercase). 192 * 193 * @returns VBox status code. 194 * @param hInstall MSI installer handle. Optional and can be NULL. 195 * @param pszFmt Format string. 196 * @param ... Variable arguments for format string. 123 197 */ 124 static UINT logStringF(MSIHANDLE hInstall, const char *pszFmt, ...) 125 { 198 static int logStringF(MSIHANDLE hInstall, const char *pszFmt, ...) 199 { 200 RTUTF16 wszVa[RTPATH_MAX + 256]; 201 va_list va; 202 va_start(va, pszFmt); 203 ssize_t cwc = RTUtf16PrintfV(wszVa, RT_ELEMENTS(wszVa), pszFmt, va); 204 va_end(va); 205 206 RTUTF16 wszMsg[RTPATH_MAX + 256]; 207 cwc = RTUtf16Printf(wszMsg, sizeof(wszMsg), "VBoxInstallHelper: %ls", wszVa); 208 if (cwc <= 0) 209 return VERR_BUFFER_OVERFLOW; 210 211 #ifdef DEBUG 212 OutputDebugStringW(wszMsg); 213 #endif 214 #ifdef TESTCASE 215 RTPrintf("%ls\n", wszMsg); 216 #endif 126 217 PMSIHANDLE hMSI = MsiCreateRecord(2 /* cParms */); 127 218 if (hMSI) 128 219 { 129 wchar_t wszBuf[RTPATH_MAX + 256]; 130 va_list va; 131 va_start(va, pszFmt); 132 ssize_t cwc = RTUtf16PrintfV(wszBuf, RT_ELEMENTS(wszBuf), pszFmt, va); 133 va_end(va); 134 135 MsiRecordSetStringW(hMSI, 0, wszBuf); 220 MsiRecordSetStringW(hMSI, 0, wszMsg); 136 221 MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_INFO), hMSI); 137 138 222 MsiCloseHandle(hMSI); 139 return cwc < RT_ELEMENTS(wszBuf) ? ERROR_SUCCESS : ERROR_BUFFER_OVERFLOW;140 } 141 return ERROR_ACCESS_DENIED;223 } 224 225 return cwc < RT_ELEMENTS(wszVa) ? VINF_SUCCESS : VERR_BUFFER_OVERFLOW; 142 226 } 143 227 … … 160 244 #endif 161 245 return ERROR_SUCCESS; 246 } 247 248 /** 249 * Initializes a target security context. 250 * 251 * @returns VBox status code. 252 * @param pCtx Target directory security context to initialize. 253 * @param hModule Windows installer module handle. 254 * @param pszPath Target directory path to use. 255 */ 256 static int initTargetDirSecurityCtx(PTGTDIRSECCTX pCtx, MSIHANDLE hModule, const char *pszPath) 257 { 258 if (pCtx->fInitialized) 259 return VINF_SUCCESS; 260 261 #ifdef DEBUG 262 logStringF(hModule, "initTargetDirSecurityCtx: pszPath=%s\n", pszPath); 263 #endif 264 265 char szPathTemp[RTPATH_MAX]; 266 int vrc = RTStrCopy(szPathTemp, sizeof(szPathTemp), pszPath); 267 if (RT_FAILURE(vrc)) 268 return vrc; 269 270 /* Try to find a parent path which exists. */ 271 char szPathParentAbs[RTPATH_MAX] = { 0 }; 272 for (int i = 0; i < 256; i++) /* Failsafe counter. */ 273 { 274 RTPathStripTrailingSlash(szPathTemp); 275 RTPathStripFilename(szPathTemp); 276 vrc = RTPathReal(szPathTemp, szPathParentAbs, sizeof(szPathParentAbs)); 277 if (RT_SUCCESS(vrc)) 278 break; 279 } 280 281 if (RT_FAILURE(vrc)) 282 { 283 logStringF(hModule, "initTargetDirSecurityCtx: No existing / valid parent directory found (%Rrc), giving up\n", vrc); 284 return vrc; 285 } 286 287 RTDIR hParentDir; 288 vrc = RTDirOpen(&hParentDir, szPathParentAbs); 289 if (RT_FAILURE(vrc)) 290 { 291 logStringF(hModule, "initTargetDirSecurityCtx: Locking parent directory '%s' failed with %Rrc\n", szPathParentAbs, vrc); 292 return vrc; 293 } 294 295 #ifdef DEBUG 296 logStringF(hModule, "initTargetDirSecurityCtx: Locked parent directory '%s'\n", szPathParentAbs); 297 #endif 298 299 char szPathTargetAbs[RTPATH_MAX]; 300 vrc = RTPathReal(pszPath, szPathTargetAbs, sizeof(szPathTargetAbs)); 301 if (RT_FAILURE(vrc)) 302 vrc = RTStrCopy(szPathTargetAbs, sizeof(szPathTargetAbs), pszPath); 303 if (RT_FAILURE(vrc)) 304 { 305 logStringF(hModule, "initTargetDirSecurityCtx: Failed to resolve absolute target path (%Rrc)\n", vrc); 306 return vrc; 307 } 308 309 #ifdef DEBUG 310 logStringF(hModule, "initTargetDirSecurityCtx: szPathTargetAbs=%s, szPathParentAbs=%s\n", szPathTargetAbs, szPathParentAbs); 311 #endif 312 313 /* Target directory validation. */ 314 if ( !RTStrCmp(szPathTargetAbs, szPathParentAbs) /* Don't allow installation into root directories. */ 315 || RTStrStr(szPathTargetAbs, "..")) 316 { 317 logStringF(hModule, "initTargetDirSecurityCtx: Directory '%s' invalid", szPathTargetAbs); 318 vrc = VERR_INVALID_NAME; 319 } 320 321 if (RT_SUCCESS(vrc)) 322 { 323 RTFSOBJINFO fsObjInfo; 324 vrc = RTPathQueryInfo(szPathParentAbs, &fsObjInfo, RTFSOBJATTRADD_NOTHING); 325 if (RT_SUCCESS(vrc)) 326 { 327 if (RTFS_IS_DIRECTORY(fsObjInfo.Attr.fMode)) /* No symlinks or other fun stuff. */ 328 { 329 static WELL_KNOWN_SID_TYPE aForbiddenWellKnownSids[] = 330 { 331 WinNullSid, 332 WinWorldSid, 333 WinAuthenticatedUserSid, 334 WinBuiltinUsersSid, 335 WinBuiltinGuestsSid, 336 WinBuiltinPowerUsersSid 337 }; 338 339 pCtx->paWellKnownSidsForbidden = (PSID *)RTMemAlloc(sizeof(PSID) * RT_ELEMENTS(aForbiddenWellKnownSids)); 340 AssertPtrReturn(pCtx->paWellKnownSidsForbidden, VERR_NO_MEMORY); 341 342 size_t i = 0; 343 for(; i < RT_ELEMENTS(aForbiddenWellKnownSids); i++) 344 { 345 pCtx->paWellKnownSidsForbidden[i] = RTMemAlloc(SECURITY_MAX_SID_SIZE); 346 AssertPtrBreakStmt(pCtx->paWellKnownSidsForbidden, vrc = VERR_NO_MEMORY); 347 DWORD cbSid = SECURITY_MAX_SID_SIZE; 348 if (!CreateWellKnownSid(aForbiddenWellKnownSids[i], NULL, pCtx->paWellKnownSidsForbidden[i], &cbSid)) 349 { 350 vrc = RTErrConvertFromWin32(GetLastError()); 351 logStringF(hModule, "initTargetDirSecurityCtx: Creating SID (index %zu) failed with %Rrc\n", i, vrc); 352 break; 353 } 354 } 355 356 if (RT_SUCCESS(vrc)) 357 { 358 vrc = RTStrCopy(pCtx->szTargetDirAbs, sizeof(pCtx->szTargetDirAbs), szPathTargetAbs); 359 if (RT_SUCCESS(vrc)) 360 { 361 pCtx->fInitialized = true; 362 pCtx->hParentDir = hParentDir; 363 pCtx->cWellKnownSidsForbidden = i; 364 pCtx->fAccessMaskForbidden = FILE_WRITE_DATA 365 | FILE_APPEND_DATA 366 | FILE_WRITE_ATTRIBUTES 367 | FILE_WRITE_EA; 368 369 RTFILE fh; 370 RTFileOpen(&fh, "c:\\temp\\targetdir.ctx", RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_WRITE | RTFILE_O_WRITE); 371 RTFileClose(fh); 372 373 return VINF_SUCCESS; 374 } 375 } 376 } 377 else 378 vrc = VERR_INVALID_NAME; 379 } 380 } 381 382 RTDirClose(hParentDir); 383 384 while (pCtx->cWellKnownSidsForbidden--) 385 { 386 RTMemFree(pCtx->paWellKnownSidsForbidden[pCtx->cWellKnownSidsForbidden]); 387 pCtx->paWellKnownSidsForbidden[pCtx->cWellKnownSidsForbidden] = NULL; 388 } 389 390 logStringF(hModule, "initTargetDirSecurityCtx: Initialization failed failed with %Rrc\n", vrc); 391 return vrc; 392 } 393 394 /** 395 * Destroys a target security context. 396 * 397 * @returns VBox status code. 398 * @param pCtx Target directory security context to destroy. 399 */ 400 static void destroyTargetDirSecurityCtx(PTGTDIRSECCTX pCtx) 401 { 402 if ( !pCtx 403 || !pCtx->fInitialized) 404 return; 405 406 if (pCtx->hParentDir != NIL_RTDIR) 407 { 408 RTDirClose(pCtx->hParentDir); 409 pCtx->hParentDir = NIL_RTDIR; 410 } 411 RT_ZERO(pCtx->szTargetDirAbs); 412 413 for (size_t i = 0; i < pCtx->cWellKnownSidsForbidden; i++) 414 RTMemFree(pCtx->paWellKnownSidsForbidden[i]); 415 pCtx->cWellKnownSidsForbidden = 0; 416 417 RTMemFree(pCtx->paWellKnownSidsForbidden); 418 pCtx->paWellKnownSidsForbidden = NULL; 419 420 RTFileDelete("c:\\temp\\targetdir.ctx"); 421 422 logStringF(NULL, "destroyTargetDirSecurityCtx\n"); 423 } 424 425 #ifdef DEBUG 426 /** 427 * Returns a stingified version of an ACE type. 428 * 429 * @returns Stingified version of an ACE type. 430 * @param uType ACE type. 431 */ 432 inline const char *dbgAceTypeToString(uint8_t uType) 433 { 434 switch (uType) 435 { 436 RT_CASE_RET_STR(ACCESS_ALLOWED_ACE_TYPE); 437 RT_CASE_RET_STR(ACCESS_DENIED_ACE_TYPE); 438 RT_CASE_RET_STR(SYSTEM_AUDIT_ACE_TYPE); 439 RT_CASE_RET_STR(SYSTEM_ALARM_ACE_TYPE); 440 default: break; 441 } 442 443 return "<Invalid>"; 444 } 445 446 /** 447 * Returns an allocated string for a SID containing the user/domain name. 448 * 449 * @returns Allocated string (UTF-8). Must be free'd using RTStrFree(). 450 * @param pSid SID to return allocated string for. 451 */ 452 inline char *dbgSidToNameA(const PSID pSid) 453 { 454 char *pszName = NULL; 455 int vrc = VINF_SUCCESS; 456 457 LPWSTR pwszSid = NULL; 458 if (ConvertSidToStringSid(pSid, &pwszSid)) 459 { 460 SID_NAME_USE SidNameUse; 461 462 WCHAR wszUser[MAX_PATH]; 463 DWORD cbUser = sizeof(wszUser); 464 WCHAR wszDomain[MAX_PATH]; 465 DWORD cbDomain = sizeof(wszDomain); 466 if (LookupAccountSid(NULL, pSid, wszUser, &cbUser, wszDomain, &cbDomain, &SidNameUse)) 467 { 468 RTUTF16 wszName[RTPATH_MAX]; 469 if (RTUtf16Printf(wszName, RT_ELEMENTS(wszName), "%ls%s%ls (%ls)", 470 wszUser, wszDomain[0] == L'\0' ? "" : "\\", wszDomain, pwszSid)) 471 { 472 vrc = RTUtf16ToUtf8(wszName, &pszName); 473 } 474 else 475 vrc = VERR_NO_MEMORY; 476 } 477 else 478 vrc = RTStrAPrintf(&pszName, "<Lookup Error>"); 479 480 LocalFree(pwszSid); 481 } 482 else 483 vrc = VERR_NOT_FOUND; 484 485 return RT_SUCCESS(vrc) ? pszName : "<Invalid>"; 486 } 487 #endif /* DEBUG */ 488 489 /** 490 * Checks a single target path whether it's safe to use or not. 491 * 492 * We check if the given path is owned by "NT Service\TrustedInstaller" and therefore assume that it's safe to use. 493 * 494 * @returns VBox status code. On error the path should be considered unsafe. 495 * @retval VERR_INVALID_NAME if the given path is considered unsafe. 496 * @retval VINF_SUCCESS if the given path is found to be safe to use. 497 * @param hModule Windows installer module handle. 498 * @param pszPath Path to check. 499 */ 500 static int checkTargetDirOne(MSIHANDLE hModule, PTGTDIRSECCTX pCtx, const char *pszPath) 501 { 502 logStringF(hModule, "checkTargetDirOne: Checking '%s' ...", pszPath); 503 504 PRTUTF16 pwszPath; 505 int vrc = RTStrToUtf16(pszPath, &pwszPath); 506 if (RT_FAILURE(vrc)) 507 return vrc; 508 509 PACL pDacl = NULL; 510 PSECURITY_DESCRIPTOR pSecurityDescriptor = { 0 }; 511 DWORD dwErr = GetNamedSecurityInfo(pwszPath, SE_FILE_OBJECT, GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 512 NULL, NULL, NULL, NULL, &pSecurityDescriptor); 513 if (dwErr == ERROR_SUCCESS) 514 { 515 BOOL fDaclPresent = FALSE; 516 BOOL fDaclDefaultedIgnored = FALSE; 517 if (GetSecurityDescriptorDacl(pSecurityDescriptor, &fDaclPresent, 518 &pDacl, &fDaclDefaultedIgnored)) 519 { 520 if ( !fDaclPresent 521 || !pDacl) 522 { 523 /* Bail out early if the DACL isn't provided or is missing. */ 524 vrc = VERR_INVALID_NAME; 525 } 526 else 527 { 528 ACL_SIZE_INFORMATION aclSizeInfo; 529 RT_ZERO(aclSizeInfo); 530 if (GetAclInformation(pDacl, &aclSizeInfo, sizeof(aclSizeInfo), AclSizeInformation)) 531 { 532 for(DWORD idxACE = 0; idxACE < aclSizeInfo.AceCount; idxACE++) 533 { 534 ACE_HEADER *pAceHdr = NULL; 535 if (GetAce(pDacl, idxACE, (LPVOID *)&pAceHdr)) 536 { 537 #ifdef DEBUG 538 logStringF(hModule, "checkTargetDirOne: ACE type=%s, flags=%#x, size=%#x", 539 dbgAceTypeToString(pAceHdr->AceType), pAceHdr->AceFlags, pAceHdr->AceSize); 540 #endif 541 /* Note: We print the ACEs in canonoical order. */ 542 switch (pAceHdr->AceType) 543 { 544 case ACCESS_ALLOWED_ACE_TYPE: /* We're only interested in the ALLOW ACE. */ 545 { 546 ACCESS_ALLOWED_ACE const *pAce = (ACCESS_ALLOWED_ACE *)pAceHdr; 547 PSID const pSid = (PSID)&pAce->SidStart; 548 #ifdef DEBUG 549 char *pszSid = dbgSidToNameA(pSid); 550 logStringF(hModule, "checkTargetDirOne:\t%s fMask=%#x", pszSid, pAce->Mask); 551 RTStrFree(pszSid); 552 #endif 553 /* We check the flags here first for performance reasons. */ 554 if ((pAce->Mask & pCtx->fAccessMaskForbidden) == pCtx->fAccessMaskForbidden) 555 { 556 for (size_t idxSID = 0; idxSID < pCtx->cWellKnownSidsForbidden; idxSID++) 557 { 558 PSID const pSidForbidden = pCtx->paWellKnownSidsForbidden[idxSID]; 559 bool const fForbidden = EqualSid(pSid, pSidForbidden); 560 #ifdef DEBUG 561 char *pszName = dbgSidToNameA(pSidForbidden); 562 logStringF(hModule, "checkTargetDirOne:\t%s : %s", 563 fForbidden ? "** FORBIDDEN **" : "ALLOWED ", pszName); 564 RTStrFree(pszName); 565 #endif /* DEBUG */ 566 if (fForbidden) 567 { 568 vrc = VERR_INVALID_NAME; 569 break; 570 } 571 } 572 } 573 574 break; 575 } 576 577 case ACCESS_DENIED_ACE_TYPE: /* We're only interested in the ALLOW ACE. */ 578 { 579 ACCESS_DENIED_ACE const *pAce = (ACCESS_DENIED_ACE *)pAceHdr; 580 #ifdef DEBUG 581 LPWSTR pwszSid = NULL; 582 ConvertSidToStringSid((PSID)&pAce->SidStart, &pwszSid); 583 584 logStringF(hModule, "checkTargetDirOne:\t%ls fMask=%#x (generic %#x specific %#x)", 585 pwszSid ? pwszSid : L"<Allocation Error>", pAce->Mask); 586 #endif /* DEBUG */ 587 LocalFree(pwszSid); 588 589 /* Ignore everything else. */ 590 break; 591 } 592 } 593 } 594 else 595 dwErr = GetLastError(); 596 597 /* No point in checking further if we failed somewhere above. */ 598 if (RT_FAILURE(vrc)) 599 break; 600 601 } /* for ACE */ 602 } 603 else 604 dwErr = GetLastError(); 605 } 606 } 607 else 608 dwErr = GetLastError(); 609 610 LocalFree(pSecurityDescriptor); 611 } 612 else 613 dwErr = GetLastError(); 614 615 if (RT_SUCCESS(vrc)) 616 vrc = RTErrConvertFromWin32(dwErr); 617 618 #ifdef DEBUG 619 logStringF(hModule, "checkTargetDirOne: Returning %Rrc", vrc); 620 #endif 621 622 if ( RT_FAILURE(vrc) 623 && vrc != VERR_INVALID_NAME) 624 logStringF(hModule, "checkTargetDirOne: Failed with %Rrc (%#x)", vrc, dwErr); 625 626 return vrc; 627 } 628 629 /** 630 * Checks whether the path in the public property INSTALLDIR has the correct ACL permissions and returns whether 631 * it's valid or not. 632 * 633 * Called from the MSI installer as a custom action. 634 * 635 * @returns Success status (acccording to MSI custom actions). 636 * @retval ERROR_SUCCESS if checking the target directory turned out to be valid. 637 * @retval ERROR_NO_NET_OR_BAD_PATH is the target directory is invalid. 638 * @param hModule Windows installer module handle. 639 * 640 * @note Sets private property VBox_Target_Dir_Is_Valid to "1" (true) if the given target path is valid, 641 * or "0" (false) if it is not. An empty target directory is considered to be valid (i.e. INSTALLDIR not set yet). 642 * 643 * @sa @bugref{10616} 644 */ 645 UINT __stdcall CheckTargetDir(MSIHANDLE hModule) 646 { 647 char *pszTargetDir; 648 649 int vrc = VBoxGetMsiPropUtf8(hModule, "INSTALLDIR", &pszTargetDir); 650 if (RT_SUCCESS(vrc)) 651 { 652 logStringF(hModule, "CheckTargetDir: Checking target directory '%s' ...", pszTargetDir); 653 654 if (!RTStrNLen(pszTargetDir, RTPATH_MAX)) 655 { 656 logStringF(hModule, "CheckTargetDir: No INSTALLDIR set (yet), skipping ..."); 657 VBoxSetMsiProp(hModule, L"VBox_Target_Dir_Is_Valid", L"1"); 658 } 659 else 660 { 661 union 662 { 663 RTPATHPARSED Parsed; 664 uint8_t ab[RTPATH_MAX]; 665 } u; 666 667 vrc = RTPathParse(pszTargetDir, &u.Parsed, sizeof(u), RTPATH_STR_F_STYLE_DOS); 668 if (RT_SUCCESS(vrc)) 669 { 670 if (u.Parsed.fProps & RTPATH_PROP_DOTDOT_REFS) 671 vrc = VERR_INVALID_PARAMETER; 672 if (RT_SUCCESS(vrc)) 673 { 674 vrc = initTargetDirSecurityCtx(&g_TargetDirSecCtx, hModule, pszTargetDir); 675 if (RT_SUCCESS(vrc)) 676 { 677 uint16_t idxComp = u.Parsed.cComps; 678 char szPathToCheck[RTPATH_MAX]; 679 while (idxComp > 1) /* We traverse backwards from INSTALLDIR and leave out the root (e.g. C:\"). */ 680 { 681 u.Parsed.cComps = idxComp; 682 vrc = RTPathParsedReassemble(pszTargetDir, &u.Parsed, RTPATH_STR_F_STYLE_DOS, 683 szPathToCheck, sizeof(szPathToCheck)); 684 if (RT_FAILURE(vrc)) 685 break; 686 if (RTDirExists(szPathToCheck)) 687 { 688 vrc = checkTargetDirOne(hModule, &g_TargetDirSecCtx, szPathToCheck); 689 if (RT_FAILURE(vrc)) 690 break; 691 } 692 else 693 logStringF(hModule, "CheckTargetDir: Path '%s' does not exist (yet)", szPathToCheck); 694 idxComp--; 695 } 696 697 destroyTargetDirSecurityCtx(&g_TargetDirSecCtx); 698 } 699 else 700 logStringF(hModule, "CheckTargetDir: initTargetDirSecurityCtx failed with %Rrc\n", vrc); 701 702 if (RT_SUCCESS(vrc)) 703 VBoxSetMsiProp(hModule, L"VBox_Target_Dir_Is_Valid", L"1"); 704 } 705 } 706 else 707 logStringF(hModule, "CheckTargetDir: Parsing path failed with %Rrc", vrc); 708 } 709 710 RTStrFree(pszTargetDir); 711 } 712 713 if (RT_FAILURE(vrc)) /* On failure (or when in doubt), mark the installation directory as invalid. */ 714 { 715 logStringF(hModule, "CheckTargetDir: Checking failed with %Rrc", vrc); 716 VBoxSetMsiProp(hModule, L"VBox_Target_Dir_Is_Valid", L"0"); 717 } 718 719 /* Return back outcome to the MSI engine. */ 720 return RT_SUCCESS(vrc) ? ERROR_SUCCESS : ERROR_NO_NET_OR_BAD_PATH; 162 721 } 163 722 -
trunk/src/VBox/Installer/win/InstallHelper/VBoxInstallHelper.def
r98103 r104162 30 30 IsSerialCheckNeeded 31 31 CheckSerial 32 CheckTargetDir 32 33 IsMSCRTInstalled 33 34 IsPythonInstalled … … 39 40 InstallNetFlt 40 41 UninstallNetFlt 41 42 42 UninstallNetAdp 43 InstallNetLwf 43 44 UninstallNetLwf 44 45 UninstallTAPInstances -
trunk/src/VBox/Installer/win/NLS/de_DE.wxl
r98103 r104162 64 64 <String Id="VB_NetLwfDriver">[ProductName] Treiber für NDIS6-Netzwerkbrücke.</String> 65 65 <String Id="VB_NetAdp6Driver">[ProductName] Treiber für virtuellen Netzwerk-Adapter für NDIS6-Host-only-Netzwerke.</String> 66 67 <String Id="VB_Python">Python-Support für VirtualBox.</String> 66 <String Id="VB_Python">Python-Support für VirtualBox.</String> 68 67 69 68 <!----> … … 76 75 <String Id="SunFound">Eine alte Sun Version von VirtualBox wurde auf diesem Computer gefunden. Bitte deinstallieren Sie diese Version zuerst. Danach können Sie [ProductName] installieren!</String> 77 76 <String Id="InnotekFound">Eine alte innotek Version von VirtualBox wurde auf diesem Computer gefunden. Bitte deinstallieren Sie diese Version zuerst. Danach können Sie [ProductName] installieren!</String> 77 <String Id="InvalidTargetDir">Ungültiges Installationsverzeichnis angegeben. Bitte ein anderes Installationsverzeichnis wählen, um [ProductName] zu installieren.</String> 78 78 79 79 <!----> … … 92 92 <String Id="LicenseAgreementDlg_Accept">Ich &akzeptiere die Bedingungen des Lizenzvertrags.</String> 93 93 <String Id="LicenseAgreementDlg_Decline">Ich &akzeptiere die Bedingungen des Lizenzvertrags nicht.</String> 94 95 <!----> 96 <String Id="InvalidTargetDirDlg_Header">Ungültiges Installationsverzeichnis</String> 97 <String Id="InvalidTargetDirDlg_Desc1">Das gewählte Installationsverzeichnis is ungültig, da dieses nicht den Sicherheitsrichtlinien entspricht.</String> 98 <String Id="InvalidTargetDirDlg_Desc2">Bitte ein anderes Installationsverzeichnis wählen um [ProductName] zu installieren.</String> 94 99 95 100 <!----> -
trunk/src/VBox/Installer/win/NLS/el_GR.wxl
r98103 r104162 64 64 <String Id="VB_NetLwfDriver">Οδηγός [ProductName] για NDIS6 γεφυρωμένα δίκτυα.</String> 65 65 <String Id="VB_NetAdp6Driver">Οδηγός [ProductName] εικονικής κάρτας δικτύου για NDIS6 μόνο-με-οικοδεσπότη δίκτυα.</String> 66 67 66 <String Id="VB_Python">Υποστήριξη Python για το VirtualBox.</String> 68 67 … … 76 75 <String Id="SunFound">Βρέθηκε μία παλιότερη εγκατάσταση του Sun VirtualBox στον υπολογιστή. Καταργήστε πρώτα την εγκατάσταση αυτού του πακέτου και μετά εγκαταστήστε το [ProductName]!</String> 77 76 <String Id="InnotekFound">Βρέθηκε μία παλιότερη εγκατάσταση του innotek VirtualBox στον υπολογιστή. Καταργήστε πρώτα την εγκατάσταση αυτού του πακέτου και μετά εγκαταστήστε το [ProductName]!</String> 77 <String Id="InvalidTargetDir">Invalid installation directory specified! Please use another installation directory to install [ProductName].</String> 78 78 79 79 <!----> … … 92 92 <String Id="LicenseAgreementDlg_Accept">Αποδέχομαι τους όρους της Άδειας Χρήσης</String> 93 93 <String Id="LicenseAgreementDlg_Decline">Δεν αποδέχομαι τους όρους της Άδειας Χρήσης</String> 94 95 <!----> 96 97 <String Id="InvalidTargetDirDlg_Header">Invalid installation directory</String> 98 <String Id="InvalidTargetDirDlg_Desc1">The chosen installation directory is invalid, as it does not meet the security requirements.</String> 99 <String Id="InvalidTargetDirDlg_Desc2">Please choose another directory for installing [ProductName].</String> 94 100 95 101 <!----> -
trunk/src/VBox/Installer/win/NLS/en_US.wxl
r98103 r104162 64 64 <String Id="VB_NetLwfDriver">[ProductName] driver for NDIS6 Bridged Networking.</String> 65 65 <String Id="VB_NetAdp6Driver">[ProductName] virtual network adapter driver for NDIS6 Host-Only Networking.</String> 66 67 66 <String Id="VB_Python">Python support for VirtualBox.</String> 68 67 … … 76 75 <String Id="SunFound">An old Sun VirtualBox installation has been found on this machine. Please uninstall this package first and then install [ProductName]!</String> 77 76 <String Id="InnotekFound">An old innotek VirtualBox installation has been found on this machine. Please uninstall this package first and then install [ProductName]!</String> 77 <String Id="InvalidTargetDir">Invalid installation directory specified! Please use another installation directory to install [ProductName].</String> 78 78 79 79 <!----> … … 92 92 <String Id="LicenseAgreementDlg_Accept">I &accept the terms in the License Agreement</String> 93 93 <String Id="LicenseAgreementDlg_Decline">I &do not accept the terms in the License Agreement</String> 94 95 <!----> 96 97 <String Id="InvalidTargetDirDlg_Header">Invalid installation directory</String> 98 <String Id="InvalidTargetDirDlg_Desc1">The chosen installation directory is invalid, as it does not meet the security requirements.</String> 99 <String Id="InvalidTargetDirDlg_Desc2">Please choose another directory for installing [ProductName].</String> 94 100 95 101 <!----> -
trunk/src/VBox/Installer/win/NLS/fa_IR.wxl
r98103 r104162 59 59 <String Id="VB_NetLwfDriver">[ProductName] driver for NDIS6 Bridged Networking.</String> 60 60 <String Id="VB_NetAdp6Driver">[ProductName] virtual network adapter driver for NDIS6 Host-Only Networking.</String> 61 62 <String Id="VB_Python">پشتیبانی از پایتون برای ویرچوال باکس.</String> 61 <String Id="VB_Python">پشتیبانی از پایتون برای ویرچوال باکس.</String> 63 62 <!----> 64 63 <String Id="NeedAdmin">برای حذف [ProductName] شما نیاز به اجازه مدیر دارید! این راه انداز حالا لغو میشود.</String> … … 69 68 <String Id="SunFound">یک نصب قدیمی ویرچوال باکس روی این رایانه یافت شد. لطفا اول این بسته را حذف سپس [ProductName] را نصب کنید!</String> 70 69 <String Id="InnotekFound">یک نسخه قدیمی نصب ویرچوال باکس در این ماشین یافت شد. لطفا اول این بسته را حذف و سپس [ProductName] را نصب کنید!</String> 70 <String Id="InvalidTargetDir">Invalid installation directory specified! Please use another installation directory to install [ProductName].</String> 71 71 <!----> 72 72 <String Id="CancelDlg_Question">آیا میخواهید نصب [ProductName] را لغو کنید؟</String> … … 79 79 <String Id="LicenseAgreementDlg_Accept">&من ضوابط را در توافقنامه مجوز می پذیرم</String> 80 80 <String Id="LicenseAgreementDlg_Decline">&من ضوابط را در توافقنامه مجوز نمی پذیرم</String> 81 <!----> 82 <String Id="InvalidTargetDirDlg_Header">Invalid installation directory</String> 83 <String Id="InvalidTargetDirDlg_Desc1">The chosen installation directory is invalid, as it does not meet the security requirements.</String> 84 <String Id="InvalidTargetDirDlg_Desc2">Please choose another directory for installing [ProductName].</String> 81 85 <!----> 82 86 <String Id="CheckSerialDlg_Header">شماره سریال</String> -
trunk/src/VBox/Installer/win/NLS/fr_FR.wxl
r98103 r104162 64 64 <String Id="VB_NetLwfDriver">[ProductName] driver for NDIS6 Bridged Networking.</String> 65 65 <String Id="VB_NetAdp6Driver">[ProductName] virtual network adapter driver for NDIS6 Host-Only Networking.</String> 66 67 <String Id="VB_Python">Python support for VirtualBox.</String> 66 <String Id="VB_Python">Python support for VirtualBox.</String> 68 67 69 68 <!----> … … 75 74 <String Id="Only64Bit">Cette application ne marche que sur des systèmes Windows 64-bit. Veuillez installer la version 32-bit de [ProductName]!</String> 76 75 <String Id="InnotekFound">Vous avez une ancienne installation de innotek VirtualBox sur cette machine. Il vous faudra la désinstaller avant de pouvoir installer [ProductName].</String> 76 <String Id="InvalidTargetDir">Invalid installation directory specified! Please use another installation directory to install [ProductName].</String> 77 77 78 78 <!----> … … 91 91 <String Id="LicenseAgreementDlg_Accept">J'&accepte les termes du Contrat de licence</String> 92 92 <String Id="LicenseAgreementDlg_Decline">Je &n'accepte pas les termes du Contrat de licence</String> 93 94 <!----> 95 96 <String Id="InvalidTargetDirDlg_Header">Invalid installation directory</String> 97 <String Id="InvalidTargetDirDlg_Desc1">The chosen installation directory is invalid, as it does not meet the security requirements.</String> 98 <String Id="InvalidTargetDirDlg_Desc2">Please choose another directory for installing [ProductName].</String> 93 99 94 100 <!----> -
trunk/src/VBox/Installer/win/NLS/it_IT.wxl
r98103 r104162 59 59 <String Id="VB_NetLwfDriver">Driver di [ProductName] per la rete con bridge NDIS6.</String> 60 60 <String Id="VB_NetAdp6Driver">Driver di [ProductName] per la scheda di rete virtuale per la rete solo host NDIS6.</String> 61 62 <String Id="VB_Python">Supporto Python per VirtualBox.</String> 61 <String Id="VB_Python">Supporto Python per VirtualBox.</String> 63 62 <!----> 64 63 <String Id="NeedAdmin">Devi avere diritti di amministrazione per (dis)installare [ProductName]! L'installazione sarà interrotta immediatamente.</String> … … 69 68 <String Id="SunFound">Una vecchia installazione di Sun VirtualBox è stata trovata su questa macchina. Disinstalla prima questo pacchetto e poi installa [ProductName]!</String> 70 69 <String Id="InnotekFound">Una vecchia installazione di innotek VirtualBox è stata trovata su questa macchina. Disinstalla prima questo pacchetto e poi installa [ProductName]!</String> 70 <String Id="InvalidTargetDir">Invalid installation directory specified! Please use another installation directory to install [ProductName].</String> 71 71 <!----> 72 72 <String Id="CancelDlg_Question">Sei sicuro di voler annullare l'installazione di [ProductName]?</String> … … 79 79 <String Id="LicenseAgreementDlg_Accept">&Accetto i termini dell'accordo di licenza</String> 80 80 <String Id="LicenseAgreementDlg_Decline">&Non accetto i termini dell'accordo di licenza</String> 81 <!----> 82 <String Id="InvalidTargetDirDlg_Header">Invalid installation directory</String> 83 <String Id="InvalidTargetDirDlg_Desc1">The chosen installation directory is invalid, as it does not meet the security requirements.</String> 84 <String Id="InvalidTargetDirDlg_Desc2">Please choose another directory for installing [ProductName].</String> 81 85 <!----> 82 86 <String Id="CheckSerialDlg_Header">Numero di serie</String> -
trunk/src/VBox/Installer/win/NLS/ru_RU.wxl
r98103 r104162 64 64 <String Id="VB_NetLwfDriver">[ProductName] driver for NDIS6 Bridged Networking.</String> 65 65 <String Id="VB_NetAdp6Driver">[ProductName] virtual network adapter driver for NDIS6 Host-Only Networking.</String> 66 67 66 <String Id="VB_Python">Python support for VirtualBox.</String> 68 67 … … 76 75 <String Id="SunFound">An old Sun VirtualBox installation has been found on this machine. Please uninstall this package first and then install [ProductName]!</String> 77 76 <String Id="InnotekFound">An old innotek VirtualBox installation has been found on this machine. Please uninstall this package first and then install [ProductName]!</String> 77 <String Id="InvalidTargetDir">Invalid installation directory specified! Please use another installation directory to install [ProductName].</String> 78 78 79 79 <!----> … … 92 92 <String Id="LicenseAgreementDlg_Accept">I &accept the terms in the License Agreement</String> 93 93 <String Id="LicenseAgreementDlg_Decline">I &do not accept the terms in the License Agreement</String> 94 95 <!----> 96 97 <String Id="InvalidTargetDirDlg_Header">Invalid installation directory</String> 98 <String Id="InvalidTargetDirDlg_Desc1">The chosen installation directory is invalid, as it does not meet the security requirements.</String> 99 <String Id="InvalidTargetDirDlg_Desc2">Please choose another directory for installing [ProductName].</String> 94 100 95 101 <!----> -
trunk/src/VBox/Installer/win/NLS/tr_TR.wxl
r99363 r104162 64 64 <String Id="VB_NetLwfDriver">NDIS6 Köprü Ağı Oluşturma için [ProductName] sürücüsü.</String> 65 65 <String Id="VB_NetAdp6Driver">NDIS6 Yalnızca-Anamakine Ağı Oluşturma için [ProductName] sanal ağ bağdaştırıcısı sürücüsü.</String> 66 67 <String Id="VB_Python">VirtualBox için Python desteği.</String> 66 <String Id="VB_Python">VirtualBox için Python desteği.</String> 68 67 69 68 <!----> … … 76 75 <String Id="SunFound">Bu makinede eski bir Sun VirtualBox kurulumu bulundu. Lütfen önce bu paketi kaldırın ve sonra [ProductName] yükleyin!</String> 77 76 <String Id="InnotekFound">Bu makinede eski bir innotek VirtualBox kurulumu bulundu. Lütfen önce bu paketi kaldırın ve sonra [ProductName] yükleyin!</String> 77 <String Id="InvalidTargetDir">Invalid installation directory specified! Please use another installation directory to install [ProductName].</String> 78 78 79 79 <!----> … … 92 92 <String Id="LicenseAgreementDlg_Accept">Lisans Sözleşmesi içindeki şartları kabul e&diyorum</String> 93 93 <String Id="LicenseAgreementDlg_Decline">Lisans Sözleşmesi içindeki şartları kabul e&tmiyorum</String> 94 95 <!----> 96 97 <String Id="InvalidTargetDirDlg_Header">Invalid installation directory</String> 98 <String Id="InvalidTargetDirDlg_Desc1">The chosen installation directory is invalid, as it does not meet the security requirements.</String> 99 <String Id="InvalidTargetDirDlg_Desc2">Please choose another directory for installing [ProductName].</String> 94 100 95 101 <!----> -
trunk/src/VBox/Installer/win/NLS/zh_CN.wxl
r98103 r104162 64 64 <String Id="VB_NetLwfDriver">[ProductName] driver for NDIS6 Bridged Networking.</String> 65 65 <String Id="VB_NetAdp6Driver">[ProductName] virtual network adapter driver for NDIS6 Host-Only Networking.</String> 66 67 66 <String Id="VB_Python">VirtualBox 的 Python 支持。</String> 68 67 … … 76 75 <String Id="SunFound">在此计算机发现旧的 Sun VirtualBox 安装。 请先卸载此组件然后安装 [ProductName]!</String> 77 76 <String Id="InnotekFound">在此计算机发现旧的 innotek VirtualBox 安装。 请先卸载此组件然后安装 [ProductName]!</String> 77 <String Id="InvalidTargetDir">Invalid installation directory specified! Please use another installation directory to install [ProductName].</String> 78 78 79 79 <!----> … … 92 92 <String Id="LicenseAgreementDlg_Accept">我接受授权协议中条款(&A)</String> 93 93 <String Id="LicenseAgreementDlg_Decline">我不接受授权协议中条款(&D)</String> 94 95 <!----> 96 97 <String Id="InvalidTargetDirDlg_Header">Invalid installation directory</String> 98 <String Id="InvalidTargetDirDlg_Desc1">The chosen installation directory is invalid, as it does not meet the security requirements.</String> 99 <String Id="InvalidTargetDirDlg_Desc2">Please choose another directory for installing [ProductName].</String> 94 100 95 101 <!----> -
trunk/src/VBox/Installer/win/NLS/zh_TW.wxl
r99363 r104162 64 64 <String Id="VB_NetLwfDriver">[ProductName] 驅動程式針對 NDIS6 橋接網路。</String> 65 65 <String Id="VB_NetAdp6Driver">[ProductName] 虛擬網路介面卡針對 NDIS6 「僅限主機」網路。</String> 66 67 66 <String Id="VB_Python">VirtualBox 的 Python 支援。</String> 68 67 … … 76 75 <String Id="SunFound">在此電腦發現舊的 Sun VirtualBox 安裝。 請先解除安裝此套件然後安裝 [ProductName]!</String> 77 76 <String Id="InnotekFound">在此電腦發現舊的 innotek VirtualBox 安裝。 請先解除安裝此套件然後安裝 [ProductName]!</String> 77 <String Id="InvalidTargetDir">Invalid installation directory specified! Please use another installation directory to install [ProductName].</String> 78 78 79 79 <!----> … … 92 92 <String Id="LicenseAgreementDlg_Accept">我接受授權協議中條款(&A)</String> 93 93 <String Id="LicenseAgreementDlg_Decline">我不接受授權協議中條款(&D)</String> 94 95 <!----> 96 97 <String Id="InvalidTargetDirDlg_Header">Invalid installation directory</String> 98 <String Id="InvalidTargetDirDlg_Desc1">The chosen installation directory is invalid, as it does not meet the security requirements.</String> 99 <String Id="InvalidTargetDirDlg_Desc2">Please choose another directory for installing [ProductName].</String> 94 100 95 101 <!----> -
trunk/src/VBox/Installer/win/UserInterface.wxi
r98103 r104162 207 207 </Dialog> 208 208 209 <!-- Shows a dialog which tells the user that the chosen installation directory is invalid and therefore cannot be used. --> 210 <Dialog Id="VBoxInvalidTargetDirDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes"> 211 212 <!-- The wizard has a bitmap as background. The source is defined as a property below. --> 213 <Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="[DialogBitmap]" /> 214 215 <!-- Title text drawn on the background --> 216 <Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes"> 217 <Text>{\DlgInvalidSerial}!(loc.InvalidTargetDirDlg_Header)</Text> 218 </Control> 219 220 <!-- Text saying what we gonna do --> 221 <Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="130" Transparent="yes" NoPrefix="yes"> 222 <Text>!(loc.InvalidTargetDirDlg_Desc1)</Text> 223 </Control> 224 225 <Control Id="Description2" Type="Text" X="135" Y="95" Width="220" Height="130" Transparent="yes" NoPrefix="yes"> 226 <Text>!(loc.InvalidTargetDirDlg_Desc2)</Text> 227 </Control> 228 229 <!-- And a line for looking nice... --> 230 <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" /> 231 232 <!-- Build number text drawn left bottom --> 233 <Control Id="Build" Type="Text" X="20" Y="247" Width="220" Height="10" Transparent="yes" NoPrefix="yes"> 234 <Text>[Version_text] $(var.Property_Version)</Text> 235 </Control> 236 237 <Control Id="Back" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_Back)"/> 238 239 <!-- Canceling will bring up a confirmation dialog ('SpawnDialog' attribute) --> 240 <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)"> 241 <Publish Event="SpawnDialog" Value="VBoxCancelDlg">1</Publish> 242 </Control> 243 244 </Dialog> 245 209 246 <!-- Dialog used to set another installation path. This is taken from the tutorial template on the web and can also be 210 247 used for package selection etc. if necessary after some tweaking. --> … … 221 258 <Text>!(loc.CustomizeDlg_IconTree)</Text> 222 259 </Control> 223 <Control Id="Tree" Type="SelectionTree" X="25" Y="85" Width="175" Height="95" Property=" _BrowseProperty"260 <Control Id="Tree" Type="SelectionTree" X="25" Y="85" Width="175" Height="95" Property="VBOX_TARGET_DIR" 224 261 Sunken="yes" TabSkip="no" Text="Tree of selections" /> 225 262 <Control Id="Browse" Type="PushButton" X="304" Y="200" Width="56" Height="17" Text="!(loc.ButtonText_Browse)"> … … 466 503 <!-- Dialog used to change the installation directory --> 467 504 <Dialog Id="VBoxBrowseDlg" Width="370" Height="270" Title="[ProductName] !(loc.Setup)" NoMinimize="yes"> 468 <Control Id="PathEdit" Type="PathEdit" X="84" Y="202" Width="261" Height="18" Property="_BrowseProperty" Indirect="yes" /> 469 <Control Id="OK" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_OK)"> 470 <Publish Event="SetTargetPath" Value="[_BrowseProperty]">1</Publish> 471 <Publish Event="EndDialog" Value="Return">1</Publish> 472 </Control> 473 <Control Id="Cancel" Type="PushButton" X="240" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)"> 474 <Publish Event="Reset" Value="0">1</Publish> 475 <Publish Event="EndDialog" Value="Return">1</Publish> 476 </Control> 505 <Control Id="PathEdit" Type="PathEdit" X="84" Y="202" Width="261" Height="18" Property="VBOX_TARGET_DIR" Indirect="yes" /> 506 <Control Id="OK" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.ButtonText_OK)" /> 507 <Control Id="Cancel" Type="PushButton" X="240" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.ButtonText_Cancel)"/> 477 508 <Control Id="ComboLabel" Type="Text" X="25" Y="58" Width="44" Height="10" TabSkip="no" Text="!(loc.BrowseDlg_LookIn)" /> 478 509 <Control Id="DirectoryCombo" Type="DirectoryCombo" X="70" Y="55" Width="220" Height="80" 479 Property=" _BrowseProperty" Indirect="yes" Fixed="yes" Remote="yes">510 Property="VBOX_TARGET_DIR" Indirect="yes" Fixed="yes" Remote="yes"> 480 511 <Subscribe Event="IgnoreChange" Attribute="IgnoreChange" /> 481 512 </Control> … … 488 519 </Control> 489 520 <Control Id="DirectoryList" Type="DirectoryList" X="25" Y="83" Width="320" Height="110" 490 Property=" _BrowseProperty" Sunken="yes" Indirect="yes" TabSkip="no" />521 Property="VBOX_TARGET_DIR" Sunken="yes" Indirect="yes" TabSkip="no" /> 491 522 <Control Id="PathLabel" Type="Text" X="25" Y="205" Width="59" Height="10" TabSkip="no" Text="!(loc.BrowseDlg_FolderName)" /> 492 523 <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="[BannerBitmap]" /> … … 1178 1209 <Publish Dialog="VBoxWrongSerialDlg" Control="Back" Event="NewDialog" Value="VBoxCheckSerialDlg">1</Publish> 1179 1210 1180 <!-- Note: We have to set (1) or unset ({}) the properties first (see order #), as those will be needed for further routing. --> 1181 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Property="VBOX_SHOW_WARN_PYTHONAPI_DLG" Value="1" Order="1"><![CDATA[(&VBoxPython=3) AND (VBOX_PYTHON_DEPS_INSTALLED="0")]]></Publish> 1182 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Property="VBOX_SHOW_WARN_PYTHONAPI_DLG" Value="{}" Order="2"><![CDATA[(&VBoxPython<3)]]></Publish> 1183 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Property="VBOX_SHOW_WARN_DISCONNECTIFACES_DLG" Value="1" Order="3"><![CDATA[&VBoxNetworkFlt=3]]></Publish> 1184 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Property="VBOX_SHOW_WARN_DISCONNECTIFACES_DLG" Value="{}" Order="4"><![CDATA[&VBoxNetworkFlt<3]]></Publish> 1185 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Event="NewDialog" Value="VBoxWarnDisconNetIfacesDlg" Order="10"><![CDATA[VBOX_SHOW_WARN_DISCONNECTIFACES_DLG]]></Publish> 1186 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Event="NewDialog" Value="VBoxWarnPythonDlg" Order="11"><![CDATA[VBOX_SHOW_WARN_PYTHONAPI_DLG AND (NOT VBOX_SHOW_WARN_DISCONNECTIFACES_DLG)]]></Publish> 1187 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Event="NewDialog" Value="VBoxCustomize2Dlg" Order="12"><![CDATA[VBOX_SHOW_CUSTOMIZE2_DLG AND (NOT VBOX_SHOW_WARN_DISCONNECTIFACES_DLG) AND (NOT VBOX_SHOW_WARN_PYTHONAPI_DLG)]]></Publish> 1188 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Event="NewDialog" Value="VBoxVerifyReadyDlg" Order="13"><![CDATA[(NOT VBOX_SHOW_CUSTOMIZE2_DLG) AND (NOT VBOX_SHOW_WARN_DISCONNECTIFACES_DLG) AND (NOT VBOX_SHOW_WARN_PYTHONAPI_DLG)]]></Publish> 1211 <Publish Dialog="VBoxBrowseDlg" Control="OK" Event="SetTargetPath" Value="[VBOX_TARGET_DIR]" Order="1">1</Publish> 1212 <Publish Dialog="VBoxBrowseDlg" Control="OK" Event="EndDialog" Value="Return" Order="2">1</Publish> 1213 <Publish Dialog="VBoxBrowseDlg" Control="Cancel" Event="Reset" Value="0" Order="1">1</Publish> 1214 <Publish Dialog="VBoxBrowseDlg" Control="Cancel" Event="EndDialog" Value="Return" Order="2">1</Publish> 1215 1216 <Publish Dialog="VBoxInvalidTargetDirDlg" Control="Back" Event="NewDialog" Value="VBoxCustomizeDlg">1</Publish> 1217 1218 <!-- Note: We have to set (1) or unset ({}) the properties first (see order #), as those will be needed for further routing. 1219 Note2: I'd love to make this easier to read/follow, but this is how Windows Installer XML works for processing all these events, sigh. --> 1220 1221 <!-- Check if the chosen installation directory turned out to be invalid by calling our installation helper DLL 1222 and performing a custom action. See @bugref{10616} --> 1223 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Event="DoAction" Value="ca_CheckTargetDirPre" Order="1">1</Publish> 1224 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Property="VBOX_SHOW_INVALID_TARGET_DLG" Value="1" Order="2"><![CDATA[VBox_Target_Dir_Is_Valid="0"]]></Publish> 1225 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Property="VBOX_SHOW_WARN_PYTHONAPI_DLG" Value="1" Order="3"><![CDATA[(&VBoxPython=3) AND (VBOX_PYTHON_DEPS_INSTALLED="0")]]></Publish> 1226 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Property="VBOX_SHOW_WARN_PYTHONAPI_DLG" Value="{}" Order="4"><![CDATA[(&VBoxPython<3)]]></Publish> 1227 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Property="VBOX_SHOW_WARN_DISCONNECTIFACES_DLG" Value="1" Order="5"><![CDATA[&VBoxNetworkFlt=3]]></Publish> 1228 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Property="VBOX_SHOW_WARN_DISCONNECTIFACES_DLG" Value="{}" Order="6"><![CDATA[&VBoxNetworkFlt<3]]></Publish> 1229 <!-- Show an error dialog if the chosen installation directory was found to be invalid. See @bugref{10616} --> 1230 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Event="NewDialog" Value="VBoxInvalidTargetDirDlg" Order="10">1</Publish> 1231 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Event="NewDialog" Value="VBoxWarnDisconNetIfacesDlg" Order="11"><![CDATA[VBOX_SHOW_WARN_DISCONNECTIFACES_DLG]]></Publish> 1232 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Event="NewDialog" Value="VBoxWarnPythonDlg" Order="12"><![CDATA[VBOX_SHOW_WARN_PYTHONAPI_DLG AND (NOT VBOX_SHOW_WARN_DISCONNECTIFACES_DLG)]]></Publish> 1233 <!-- Only allow going to the next stage if the chosen installation directory is valid. See @bugref{10616} --> 1234 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Event="NewDialog" Value="VBoxCustomize2Dlg" Order="13"><![CDATA[VBOX_SHOW_CUSTOMIZE2_DLG AND (NOT VBOX_SHOW_WARN_DISCONNECTIFACES_DLG) AND (NOT VBOX_SHOW_WARN_PYTHONAPI_DLG) AND (NOT VBox_Target_Dir_Is_Valid="0")]]></Publish> 1235 <Publish Dialog="VBoxCustomizeDlg" Control="Next" Event="NewDialog" Value="VBoxVerifyReadyDlg" Order="14"><![CDATA[(NOT VBOX_SHOW_CUSTOMIZE2_DLG) AND (NOT VBOX_SHOW_WARN_DISCONNECTIFACES_DLG) AND (NOT VBOX_SHOW_WARN_PYTHONAPI_DLG)]]></Publish> 1189 1236 <Publish Dialog="VBoxCustomizeDlg" Control="Back" Event="NewDialog" Value="VBoxCheckSerialDlg"><![CDATA[VBOX_SHOW_SERIAL_CHECK_DLG]]></Publish> 1190 1237 <Publish Dialog="VBoxCustomizeDlg" Control="Back" Event="NewDialog" Value="VBoxLicenseAgreementDlg"><![CDATA[NOT VBOX_SHOW_SERIAL_CHECK_DLG]]></Publish> … … 1212 1259 <Custom Action="ca_IsMSCRTInstalled" After="AppSearch" /> 1213 1260 <?endif?> 1261 <Custom Action="ca_CheckTargetDirPre" After="AppSearch"/> <!-- Required for launch conditions. See @bugref{10616} --> 1214 1262 <Custom Action="ca_OriginalTargetDir" After="FileCost"><![CDATA[(NOT INSTALLDIR) AND (NOT EXISTINGINSTALLDIR)]]></Custom> 1215 1263 <Custom Action="ca_DefaultTargetDir" After="FileCost"><![CDATA[NOT Installed AND (NOT INSTALLDIR) AND EXISTINGINSTALLDIR]]></Custom> -
trunk/src/VBox/Installer/win/VBoxMergeApp.wxi
r103369 r104162 128 128 Vital="yes"> 129 129 <ServiceDependency Id="RPCSS" /> 130 <ServiceConfig ServiceSid="restricted" OnInstall="yes" OnReinstall="yes" /> 130 131 </ServiceInstall> 131 132 <ServiceControl Id="VBoxSDSControl" Name="VBoxSDS" Stop="both" Remove="uninstall" /> -
trunk/src/VBox/Installer/win/VBoxMergeAppCA.wxi
r98103 r104162 36 36 DllEntry="IsWindows10" Execute="immediate" Return="ignore" Impersonate="no" /> 37 37 38 <!-- Makes sure we check if the chosen target directory is valid before allowing to install. See @bugref{10616} --> 39 <CustomAction Id="ca_CheckTargetDirPre" BinaryKey="VBoxInstallHelper" 40 DllEntry="CheckTargetDir" Execute="immediate" Return="ignore" Impersonate="no" /> 41 <!-- Makes sure that the target directory we installed into still is valid. Rollback if it isn't. See @bugref{10616} --> 42 <CustomAction Id="ca_CheckTargetDirPost" BinaryKey="VBoxInstallHelper" 43 DllEntry="CheckTargetDir" Execute="immediate" Return="check" Impersonate="no" /> 38 44 </Include> 39 45 -
trunk/src/VBox/Installer/win/VBoxMergeAppSeq.wxi
r98103 r104162 31 31 <Custom Action="ca_IsMSCRTInstalled" After="AppSearch">1</Custom> 32 32 <?endif?> 33 <!-- Required for lauch conditions. See @bugref{10616} --> 34 <Custom Action="ca_CheckTargetDirPre" After="AppSearch"/> 35 <!-- Check if the installation directory still fits our security requirements after we finalized installation. 36 See @bugref{10616} --> 37 <Custom Action="ca_CheckTargetDirPost" After="InstallFinalize"><![CDATA[NOT REMOVE]]></Custom> 33 38 34 39 <Custom Action="ca_IsWindows10" After="FileCost">1</Custom> -
trunk/src/VBox/Installer/win/VirtualBox.wxs
r103038 r104162 128 128 </Condition> 129 129 <?endif ?> 130 <!-- Check if the current INSTALLDIR is valid or not, or if VBox already is installed. 131 Thight might be handed-in via command line (MSI properties) or through a customized merge module. See @bugref{10616} --> 132 <Condition Message="!(loc.InvalidTargetDir)"> 133 Installed OR (VBox_Target_Dir_Is_Valid="1") 134 </Condition> 130 135 131 136 <!-- Detect old innotek installation -->
Note:
See TracChangeset
for help on using the changeset viewer.