Changeset 32653 in vbox
- Timestamp:
- Sep 21, 2010 7:45:00 AM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 66063
- Location:
- trunk/src/VBox
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/Makefile.kmk
r32635 r32653 121 121 crypt 122 122 endif 123 VBoxService_LIBS.win += \ 124 $(PATH_SDK_$(VBOX_WINDDK)_LIB)/Userenv.lib 123 125 ifdef VBOX_WITH_GUEST_PROPS 124 126 VBoxService_LIBS.win += \ -
trunk/src/VBox/Runtime/Makefile.kmk
r32648 r32653 1080 1080 endif 1081 1081 VBoxRT_LIBS.win = \ 1082 $(PATH_SDK_$(VBOX_WINDDK)_LIB)/Userenv.lib \ 1082 1083 $(PATH_SDK_$(VBOX_WINDDK)_LIB)/vccomsup.lib \ 1083 1084 $(PATH_SDK_$(VBOX_WINDDK)_LIB)/wbemuuid.lib -
trunk/src/VBox/Runtime/r3/win/process-win.cpp
r32292 r32653 36 36 #include <process.h> 37 37 #include <errno.h> 38 #include <Strsafe.h> 38 39 39 40 #include <iprt/process.h> … … 480 481 481 482 483 /** 484 * Logs on a specified user and returns its primary token. 485 * 486 * @return int 487 * 488 * @param pwszUser User name. 489 * @param pwszPassword Password. 490 * @param pwszDomain Domain (not used at the moment). 491 * @param phToken Pointer to store the logon token. 492 */ 493 static int rtProcUserLogon(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain, HANDLE *phToken) 494 { 495 int rc = VINF_SUCCESS; 496 /** @todo Add domain support! */ 497 BOOL fRc = LogonUserW(pwszUser, 498 /* 499 * Because we have to deal with http://support.microsoft.com/kb/245683 500 * for NULL domain names when running on NT4 here, pass an empty string if so. 501 * However, passing FQDNs should work! 502 */ 503 ((DWORD)(LOBYTE(LOWORD(GetVersion()))) < 5) /* < Windows 2000. */ 504 ? L"" /* NT4 and older. */ 505 : NULL, /* Windows 2000 and up. */ 506 pwszPassword, 507 LOGON32_LOGON_INTERACTIVE, 508 LOGON32_PROVIDER_DEFAULT, 509 phToken); 510 if (!fRc) 511 rc = RTErrConvertFromWin32(GetLastError()); 512 return rc; 513 } 514 515 516 /** 517 * Logs off a user, specified by the given tokken. 518 * 519 * @param hToken The token (=user) to log off. 520 */ 521 static void rtProcUserLogoff(HANDLE hToken) 522 { 523 CloseHandle(hToken); 524 } 525 526 527 /** 528 * Creates an environment block out of a handed in Unicode and RTENV block. 529 * The RTENV block can overwrite entries already present in the Unicode block. 530 * 531 * @return IPRT status code. 532 * 533 * @param pvBlock Unicode block (array) of environment entries; name=value 534 * @param hEnv Handle of an existing RTENV block to use. 535 * @param ppwszBlock Pointer to the final output. 536 */ 537 static int rtProcEnvironmentCreateInternal(VOID *pvBlock, RTENV hEnv, PRTUTF16 *ppwszBlock) 538 { 539 int rc = VINF_SUCCESS; 540 RTENV hEnvTemp; 541 rc = RTEnvClone(&hEnvTemp, hEnv); 542 if (RT_SUCCESS(rc)) 543 { 544 PRTUTF16 pBlock = (PRTUTF16)pvBlock; 545 while ( pBlock 546 && pBlock != '\0' 547 && RT_SUCCESS(rc)) 548 { 549 char *pszEntry; 550 rc = RTUtf16ToUtf8(pBlock, &pszEntry); 551 if (RT_SUCCESS(rc)) 552 { 553 /* Don't overwrite values which we already have set to a custom value 554 * specified in hEnv ... */ 555 if (!RTEnvExistEx(hEnv, pszEntry)) 556 rc = RTEnvPutEx(hEnvTemp, pszEntry); 557 RTStrFree(pszEntry); 558 } 559 560 size_t l; 561 /* 32k should be the maximum the environment block can have on Windows. */ 562 if (FAILED(StringCbLengthW((LPCWSTR)pBlock, _32K * sizeof(RTUTF16), &l))) 563 break; 564 pBlock += l / sizeof(RTUTF16); 565 if (pBlock[1] == '\0') /* Did we reach the double zero termination (\0\0)? */ 566 break; 567 pBlock++; /* Skip zero termination of current string and advance to next string ... */ 568 } 569 570 if (RT_SUCCESS(rc)) 571 rc = RTEnvQueryUtf16Block(hEnvTemp, ppwszBlock); 572 RTEnvDestroy(hEnvTemp); 573 } 574 return rc; 575 } 576 577 578 /** 579 * Builds up the environment block for a specified user (identified by a token), 580 * whereas hEnv is an additional set of environment variables which overwrite existing 581 * values of the user profile. ppwszBlock needs to be destroyed after usage 582 * calling rtProcEnvironmentDestroy(). 583 * 584 * @return IPRT status code. 585 * 586 * @param hToken Token of the user to use. 587 * @param hEnv Own environment block to extend/overwrite the profile's data with. 588 * @param ppwszBlock Pointer to a pointer of the final UTF16 environment block. 589 */ 590 static int rtProcEnvironmentCreateFromToken(HANDLE hToken, RTENV hEnv, PRTUTF16 *ppwszBlock) 591 { 592 int rc = VINF_SUCCESS; 593 LPVOID pEnvBlockProfile = NULL; 594 if (CreateEnvironmentBlock(&pEnvBlockProfile, hToken, FALSE /* Don't inherit from parent. */)) 595 { 596 rc = rtProcEnvironmentCreateInternal(pEnvBlockProfile, hEnv, ppwszBlock); 597 DestroyEnvironmentBlock(pEnvBlockProfile); 598 } 599 else 600 rc = RTErrConvertFromWin32(GetLastError()); 601 return rc; 602 } 603 604 605 /** 606 * Builds up the environment block for a specified user (identified by user name, password 607 * and domain), whereas hEnv is an additional set of environment variables which overwrite 608 * existing values of the user profile. ppwszBlock needs to be destroyed after usage 609 * calling rtProcEnvironmentDestroy(). 610 * 611 * @return IPRT status code. 612 * 613 * @param pwszUser User name. 614 * @param pwszPassword Password. 615 * @param pwszDomain Domain. 616 * @param hEnv Own environment block to extend/overwrite the profile's data with. 617 * @param ppwszBlock Pointer to a pointer of the final UTF16 environment block. 618 */ 619 static int rtProcEnvironmentCreateFromAccount(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain, 620 RTENV hEnv, PRTUTF16 *ppwszBlock) 621 { 622 HANDLE hToken; 623 int rc = rtProcUserLogon(pwszUser, pwszPassword, pwszDomain, &hToken); 624 if (RT_SUCCESS(rc)) 625 { 626 rc = rtProcEnvironmentCreateFromToken(hToken, hEnv, ppwszBlock); 627 rtProcUserLogoff(hToken); 628 } 629 return rc; 630 } 631 632 633 /** 634 * Destroys an environment block formerly created by rtProcEnvironmentCreateInternal(), 635 * rtProcEnvironmentCreateFromToken() or rtProcEnvironmentCreateFromAccount(). 636 * 637 * @param ppwszBlock Environment block to destroy. 638 */ 639 static void rtProcEnvironmentDestroy(PRTUTF16 ppwszBlock) 640 { 641 RTEnvFreeUtf16Block(ppwszBlock); 642 } 643 644 482 645 static int rtProcCreateAsUserHlp(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszExec, PRTUTF16 pwszCmdLine, 483 PRTUTF16 pwszzBlock, DWORD dwCreationFlags,646 RTENV hEnv, DWORD dwCreationFlags, 484 647 STARTUPINFOW *pStartupInfo, PROCESS_INFORMATION *pProcInfo, uint32_t fFlags) 485 648 { … … 507 670 if (RT_SUCCESS(rc)) 508 671 { 509 fRc = pfnCreateProcessWithLogonW(pwszUser, 510 NULL, /* lpDomain*/ 511 pwszPassword, 512 1 /*LOGON_WITH_PROFILE*/, /* dwLogonFlags */ 513 pwszExec, 514 pwszCmdLine, 515 dwCreationFlags, 516 pwszzBlock, 517 NULL, /* pCurrentDirectory */ 518 pStartupInfo, 519 pProcInfo); 520 if (!fRc) 521 dwErr = GetLastError(); 672 PRTUTF16 pwszzBlock; 673 rc = rtProcEnvironmentCreateFromAccount(pwszUser, pwszPassword, NULL /* Domain */, 674 hEnv, &pwszzBlock); 675 if (RT_SUCCESS(rc)) 676 { 677 fRc = pfnCreateProcessWithLogonW(pwszUser, 678 NULL, /* lpDomain*/ 679 pwszPassword, 680 1 /*LOGON_WITH_PROFILE*/, /* dwLogonFlags */ 681 pwszExec, 682 pwszCmdLine, 683 dwCreationFlags, 684 pwszzBlock, 685 NULL, /* pCurrentDirectory */ 686 pStartupInfo, 687 pProcInfo); 688 if (!fRc) 689 dwErr = GetLastError(); 690 rtProcEnvironmentDestroy(pwszzBlock); 691 } 522 692 } 523 693 RTLdrClose(hAdvAPI32); … … 560 730 PHANDLE phToken = NULL; 561 731 HANDLE hTokenLogon = INVALID_HANDLE_VALUE; 562 fRc = LogonUserW(pwszUser, 563 /* 564 * Because we have to deal with http://support.microsoft.com/kb/245683 565 * for NULL domain names when running on NT4 here, pass an empty string if so. 566 * However, passing FQDNs should work! 567 */ 568 ((DWORD)(LOBYTE(LOWORD(GetVersion()))) < 5) /* < Windows 2000. */ 569 ? L"" /* NT4 and older. */ 570 : NULL, /* Windows 2000 and up. */ 571 pwszPassword, 572 LOGON32_LOGON_INTERACTIVE, 573 LOGON32_PROVIDER_DEFAULT, 574 &hTokenLogon); 575 576 bool fFound = false; 577 HANDLE hTokenUserDesktop = INVALID_HANDLE_VALUE; 578 if (fRc) 579 { 732 rc = rtProcUserLogon(pwszUser, pwszPassword, NULL /* Domain */, &hTokenLogon); 733 if (RT_SUCCESS(rc)) 734 { 735 bool fFound = false; 736 HANDLE hTokenUserDesktop = INVALID_HANDLE_VALUE; 737 580 738 if (fFlags & RTPROC_FLAGS_SERVICE) 581 739 { … … 649 807 phToken = fFound ? &hTokenUserDesktop : &hTokenLogon; 650 808 651 /* 652 * Useful KB articles: 653 * http://support.microsoft.com/kb/165194/ 654 * http://support.microsoft.com/kb/184802/ 655 * http://support.microsoft.com/kb/327618/ 656 */ 657 fRc = CreateProcessAsUserW(*phToken, 658 pwszExec, 659 pwszCmdLine, 660 NULL, /* pProcessAttributes */ 661 NULL, /* pThreadAttributes */ 662 TRUE, /* fInheritHandles */ 663 dwCreationFlags, 664 pwszzBlock, 665 NULL, /* pCurrentDirectory */ 666 pStartupInfo, 667 pProcInfo); 668 if (fRc) 669 dwErr = NO_ERROR; 809 PROFILEINFOW profileInfo; 810 ZeroMemory(&profileInfo, sizeof(profileInfo)); 811 profileInfo.dwSize = sizeof(profileInfo); 812 profileInfo.lpUserName = pwszUser; 813 profileInfo.dwFlags = PI_NOUI; /* Prevents the display of profile error messages. */ 814 if (LoadUserProfileW(*phToken, &profileInfo)) 815 { 816 PRTUTF16 pwszzBlock; 817 rc = rtProcEnvironmentCreateFromToken(*phToken, hEnv, &pwszzBlock); 818 if (RT_SUCCESS(rc)) 819 { 820 /* 821 * Useful KB articles: 822 * http://support.microsoft.com/kb/165194/ 823 * http://support.microsoft.com/kb/184802/ 824 * http://support.microsoft.com/kb/327618/ 825 */ 826 fRc = CreateProcessAsUserW(*phToken, 827 pwszExec, 828 pwszCmdLine, 829 NULL, /* pProcessAttributes */ 830 NULL, /* pThreadAttributes */ 831 TRUE, /* fInheritHandles */ 832 dwCreationFlags, 833 pwszzBlock, 834 NULL, /* pCurrentDirectory */ 835 pStartupInfo, 836 pProcInfo); 837 if (fRc) 838 dwErr = NO_ERROR; 839 else 840 dwErr = GetLastError(); /* CreateProcessAsUserW() failed. */ 841 rtProcEnvironmentDestroy(pwszzBlock); 842 } 843 else 844 dwErr = rc; 845 UnloadUserProfile(*phToken, profileInfo.hProfile); 846 } 670 847 else 671 dwErr = GetLastError(); /* CreateProcessAsUserW() failed. */ 672 848 dwErr = GetLastError(); /* LoadUserProfileW() failed. */ 673 849 if (hTokenUserDesktop != INVALID_HANDLE_VALUE) 674 850 CloseHandle(hTokenUserDesktop); 675 CloseHandle(hTokenLogon);851 rtProcUserLogoff(hTokenLogon); 676 852 } 677 853 else 678 dwErr = GetLastError(); /* LogonUserW() failed. */854 dwErr = rc; /* rtProcUserLogon() failed. */ 679 855 } 680 856 … … 874 1050 { 875 1051 rc = rtProcCreateAsUserHlp(pwszUser, pwszPassword, 876 pwszExec, pwszCmdLine, pwszzBlock, dwCreationFlags,1052 pwszExec, pwszCmdLine, hEnv, dwCreationFlags, 877 1053 &StartupInfo, &ProcInfo, fFlags); 878 1054
Note:
See TracChangeset
for help on using the changeset viewer.