Changeset 39866 in vbox
- Timestamp:
- Jan 25, 2012 2:36:08 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/process-win.cpp
r39865 r39866 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 52 52 #include <iprt/mem.h> 53 53 #include <iprt/once.h> 54 #include <iprt/path.h> 54 55 #include <iprt/pipe.h> 55 56 #include <iprt/string.h> … … 264 265 265 266 266 RTR3DECL(int) 267 RTR3DECL(int) RTProcCreate(const char *pszExec, const char * const *papszArgs, RTENV Env, unsigned fFlags, PRTPROCESS pProcess) 267 268 { 268 269 return RTProcCreateEx(pszExec, papszArgs, Env, fFlags, … … 280 281 * @param dwError Windows error code to map to IPRT code. 281 282 */ 282 static int rtProc MapErrorCodes(DWORD dwError)283 static int rtProcWinMapErrorCodes(DWORD dwError) 283 284 { 284 285 int rc; … … 306 307 307 308 /** 308 * Get the process token (not the process handle like the name might indicate)309 * of the process indicated by @a dwPID if the @a pSIDmatches.309 * Get the process token of the process indicated by @a dwPID if the @a pSid 310 * matches. 310 311 * 311 312 * @returns IPRT status code. 312 313 * 313 * @param dwP IDThe process identifier.314 * @param pS IDThe secure identifier of the user.315 * @param phToken Where to return the token handle - duplicate,316 * caller closes it on success.317 */ 318 static int rtProc GetProcessHandle(DWORD dwPID, PSID pSID, PHANDLE phToken)319 { 320 AssertPtr(pS ID);314 * @param dwPid The process identifier. 315 * @param pSid The secure identifier of the user. 316 * @param phToken Where to return the a duplicate of the process token 317 * handle on success. (The caller closes it.) 318 */ 319 static int rtProcWinGetProcessTokenHandle(DWORD dwPid, PSID pSid, PHANDLE phToken) 320 { 321 AssertPtr(pSid); 321 322 AssertPtr(phToken); 322 323 323 DWORD dwErr; 324 BOOL fRc; 325 bool fFound = false; 326 HANDLE hProc = OpenProcess(MAXIMUM_ALLOWED, TRUE, dwPID); 324 int rc; 325 HANDLE hProc = OpenProcess(MAXIMUM_ALLOWED, TRUE, dwPid); 327 326 if (hProc != NULL) 328 327 { 329 328 HANDLE hTokenProc; 330 fRc = OpenProcessToken(hProc, 331 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE 332 | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, 333 &hTokenProc); 334 if (fRc) 335 { 336 DWORD dwSize = 0; 337 fRc = GetTokenInformation(hTokenProc, TokenUser, NULL, 0, &dwSize); 338 if (!fRc) 339 dwErr = GetLastError(); 329 if (OpenProcessToken(hProc, 330 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE 331 | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, 332 &hTokenProc)) 333 { 334 SetLastError(NO_ERROR); 335 DWORD dwSize = 0; 336 BOOL fRc = GetTokenInformation(hTokenProc, TokenUser, NULL, 0, &dwSize); 337 DWORD dwErr = GetLastError(); 340 338 if ( !fRc 341 339 && dwErr == ERROR_INSUFFICIENT_BUFFER 342 340 && dwSize > 0) 343 341 { 344 PTOKEN_USER pTokenUser = (PTOKEN_USER)RTMemAlloc(dwSize); 345 AssertPtrReturn(pTokenUser, VERR_NO_MEMORY); /** @todo r=bird: Leaking handles when we're out of memory... */ 346 RT_ZERO(*pTokenUser); 347 if ( GetTokenInformation(hTokenProc, 348 TokenUser, 349 (LPVOID)pTokenUser, 350 dwSize, 351 &dwSize)) 342 PTOKEN_USER pTokenUser = (PTOKEN_USER)RTMemTmpAllocZ(dwSize); 343 if (pTokenUser) 352 344 { 353 if ( IsValidSid(pTokenUser->User.Sid) 354 && EqualSid(pTokenUser->User.Sid, pSID)) 345 if (GetTokenInformation(hTokenProc, 346 TokenUser, 347 pTokenUser, 348 dwSize, 349 &dwSize)) 355 350 { 356 if ( DuplicateTokenEx(hTokenProc, MAXIMUM_ALLOWED,357 NULL, SecurityIdentification, TokenPrimary, phToken))351 if ( IsValidSid(pTokenUser->User.Sid) 352 && EqualSid(pTokenUser->User.Sid, pSid)) 358 353 { 359 /* 360 * So we found the process instance which belongs to the user we want to 361 * to run our new process under. This duplicated token will be used for 362 * the actual CreateProcessAsUserW() call then. 363 */ 364 fFound = true; 354 if (DuplicateTokenEx(hTokenProc, MAXIMUM_ALLOWED, 355 NULL, SecurityIdentification, TokenPrimary, phToken)) 356 { 357 /* 358 * So we found the process instance which belongs to the user we want to 359 * to run our new process under. This duplicated token will be used for 360 * the actual CreateProcessAsUserW() call then. 361 */ 362 rc = VINF_SUCCESS; 363 } 364 else 365 rc = rtProcWinMapErrorCodes(GetLastError()); 365 366 } 366 367 else 367 dwErr = GetLastError();368 rc = VERR_NOT_FOUND; 368 369 } 370 else 371 rc = rtProcWinMapErrorCodes(GetLastError()); 372 RTMemTmpFree(pTokenUser); 369 373 } 370 374 else 371 dwErr = GetLastError(); 372 RTMemFree(pTokenUser); 375 rc = VERR_NO_MEMORY; 373 376 } 377 else if (fRc || dwErr == NO_ERROR) 378 rc = VERR_IPE_UNEXPECTED_STATUS; 374 379 else 375 dwErr = GetLastError();380 rc = rtProcWinMapErrorCodes(dwErr); 376 381 CloseHandle(hTokenProc); 377 382 } 378 383 else 379 dwErr = GetLastError();384 rc = rtProcWinMapErrorCodes(GetLastError()); 380 385 CloseHandle(hProc); 381 386 } 382 387 else 383 dwErr = GetLastError(); 384 if (fFound) 385 return VINF_SUCCESS; 386 if (dwErr != NO_ERROR) 387 return RTErrConvertFromWin32(dwErr); 388 return VERR_NOT_FOUND; /* No error occurred, but we didn't find the right process. */ 389 } 390 391 392 /** 393 * Finds a one of the processes in @a papszNames running with user @a pSID and 394 * returns a duplicate handle to its token. 388 rc = rtProcWinMapErrorCodes(GetLastError()); 389 return rc; 390 } 391 392 393 /** 394 * Fallback method for rtProcWinFindTokenByProcess that uses the older NT4 395 * PSAPI.DLL API. 395 396 * 396 397 * @returns Success indicator. … … 399 400 * @param phToken Where to return the token handle - duplicate, 400 401 * caller closes it on success. 401 */ 402 static bool rtProcFindProcessByName(const char * const *papszNames, PSID pSid, PHANDLE phToken) 402 * 403 * @remarks NT4 needs a copy of "PSAPI.dll" (redistributed by Microsoft and not 404 * part of the OS) in order to get a lookup. If we don't have this DLL 405 * we are not able to get a token and therefore no UI will be visible. 406 */ 407 static bool rtProcWinFindTokenByProcessAndPsApi(const char * const *papszNames, PSID pSid, PHANDLE phToken) 408 { 409 bool fFound = false; 410 411 /* 412 * Load PSAPI.DLL and resolve the two symbols we need. 413 */ 414 RTLDRMOD hPsApi; 415 int rc = RTLdrLoad("PSAPI.dll", &hPsApi); 416 if (RT_FAILURE_NP(rc)) 417 return false; 418 PFNGETMODULEBASENAME pfnGetModuleBaseName; 419 PFNENUMPROCESSES pfnEnumProcesses; 420 rc = RTLdrGetSymbol(hPsApi, "EnumProcesses", (void**)&pfnEnumProcesses); 421 if (RT_SUCCESS(rc)) 422 rc = RTLdrGetSymbol(hPsApi, "GetModuleBaseName", (void**)&pfnGetModuleBaseName); 423 if (RT_SUCCESS(rc)) 424 { 425 /* 426 * Get a list of PID. We retry if it looks like there are more PIDs 427 * to be returned than what we supplied buffer space for. 428 */ 429 DWORD cbPidsAllocated = 4096; 430 DWORD cbPidsReturned = 0; 431 DWORD *paPids; 432 for (;;) 433 { 434 paPids = (DWORD *)RTMemTmpAlloc(cbPidsAllocated); 435 AssertBreakStmt(paPids, rc = VERR_NO_TMP_MEMORY); 436 if (!pfnEnumProcesses(paPids, cbPidsAllocated, &cbPidsReturned)) 437 { 438 rc = RTErrConvertFromWin32(GetLastError()); 439 AssertMsgFailedBreak(("%Rrc\n", rc)); 440 } 441 if ( cbPidsReturned < cbPidsAllocated 442 || cbPidsAllocated >= _512K) 443 break; 444 RTMemTmpFree(paPids); 445 cbPidsAllocated *= 2; 446 } 447 if (RT_SUCCESS(rc)) 448 { 449 /* 450 * Search for the process. 451 * 452 * We ASSUME that the caller won't be specifying any names longer 453 * than RTPATH_MAX. 454 */ 455 DWORD cbProcName = RTPATH_MAX; 456 char *pszProcName = (char *)RTMemTmpAlloc(RTPATH_MAX); 457 if (pszProcName) 458 { 459 for (size_t i = 0; papszNames[i] && !fFound; i++) 460 { 461 const DWORD cPids = cbPidsReturned / sizeof(DWORD); 462 for (DWORD iPid = 0; iPid < cPids && !fFound; iPid++) 463 { 464 HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, paPids[iPid]); 465 if (hProc) 466 { 467 *pszProcName = '\0'; 468 DWORD cbRet = pfnGetModuleBaseName(hProc, 0 /*hModule = exe */, pszProcName, cbProcName); 469 if ( cbRet > 0 470 && _stricmp(pszProcName, papszNames[i]) == 0 471 && RT_SUCCESS(rtProcWinGetProcessTokenHandle(paPids[iPid], pSid, phToken))) 472 fFound = true; 473 CloseHandle(hProc); 474 } 475 } 476 } 477 RTMemTmpFree(pszProcName); 478 } 479 else 480 rc = VERR_NO_TMP_MEMORY; 481 } 482 RTMemTmpFree(paPids); 483 } 484 RTLdrClose(hPsApi); 485 return fFound; 486 } 487 488 489 /** 490 * Finds a one of the processes in @a papszNames running with user @a pSid and 491 * returns a duplicate handle to its token. 492 * 493 * @returns Success indicator. 494 * @param papszNames The process candidates, in prioritized order. 495 * @param pSid The secure identifier of the user. 496 * @param phToken Where to return the token handle - duplicate, 497 * caller closes it on success. 498 */ 499 static bool rtProcWinFindTokenByProcess(const char * const *papszNames, PSID pSid, PHANDLE phToken) 403 500 { 404 501 AssertPtr(papszNames); … … 406 503 AssertPtr(phToken); 407 504 408 DWORD dwErr = NO_ERROR;409 505 bool fFound = false; 410 506 411 507 /* 412 508 * On modern systems (W2K+) try the Toolhelp32 API first; this is more stable 413 * and reliable. Fallback to EnumProcess on NT4.509 * and reliable. Fallback to EnumProcess on NT4. 414 510 */ 415 511 RTLDRMOD hKernel32; … … 418 514 { 419 515 PFNCREATETOOLHELP32SNAPSHOT pfnCreateToolhelp32Snapshot; 420 rc = RTLdrGetSymbol(hKernel32, "CreateToolhelp32Snapshot", (void**)&pfnCreateToolhelp32Snapshot); 516 PFNPROCESS32FIRST pfnProcess32First; 517 PFNPROCESS32NEXT pfnProcess32Next; 518 rc = RTLdrGetSymbol(hKernel32, "CreateToolhelp32Snapshot", (void **)&pfnCreateToolhelp32Snapshot); 421 519 if (RT_SUCCESS(rc)) 422 {423 PFNPROCESS32FIRST pfnProcess32First;424 520 rc = RTLdrGetSymbol(hKernel32, "Process32First", (void**)&pfnProcess32First); 425 if (RT_SUCCESS(rc)) 426 { 427 PFNPROCESS32NEXT pfnProcess32Next; 428 rc = RTLdrGetSymbol(hKernel32, "Process32Next", (void**)&pfnProcess32Next); 429 if (RT_SUCCESS(rc)) 521 if (RT_SUCCESS(rc)) 522 rc = RTLdrGetSymbol(hKernel32, "Process32Next", (void**)&pfnProcess32Next); 523 524 if (RT_SUCCESS(rc)) 525 { 526 HANDLE hSnap = pfnCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 527 if (hSnap != INVALID_HANDLE_VALUE) 528 { 529 for (size_t i = 0; papszNames[i] && !fFound; i++) 430 530 { 431 HANDLE hSnap = pfnCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 432 if (hSnap != INVALID_HANDLE_VALUE) 531 PROCESSENTRY32 procEntry; 532 procEntry.dwSize = sizeof(PROCESSENTRY32); 533 if (pfnProcess32First(hSnap, &procEntry)) 433 534 { 434 for (size_t i = 0; papszNames[i] && !fFound; i++)535 do 435 536 { 436 PROCESSENTRY32 procEntry; 437 procEntry.dwSize = sizeof(PROCESSENTRY32); 438 if (pfnProcess32First(hSnap, &procEntry)) 537 if ( _stricmp(procEntry.szExeFile, papszNames[i]) == 0 538 && RT_SUCCESS(rtProcWinGetProcessTokenHandle(procEntry.th32ProcessID, pSid, phToken))) 439 539 { 440 do 441 { 442 if ( _stricmp(procEntry.szExeFile, papszNames[i]) == 0 443 && RT_SUCCESS(rtProcGetProcessHandle(procEntry.th32ProcessID, pSid, phToken))) 444 { 445 fFound = true; 446 break; 447 } 448 } while (pfnProcess32Next(hSnap, &procEntry)); 540 fFound = true; 541 break; 449 542 } 450 else /* Process32First */ 451 dwErr = GetLastError(); 452 if (FAILED(dwErr)) 453 break; 454 } 455 CloseHandle(hSnap); 543 } while (pfnProcess32Next(hSnap, &procEntry)); 456 544 } 457 else /* hSnap == INVALID_HANDLE_VALUE */ 458 dwErr = GetLastError(); 545 #ifdef RT_STRICT 546 else 547 { 548 DWORD dwErr = GetLastError(); 549 AssertMsgFailed(("dwErr=%u (%x)\n", dwErr, dwErr)); 550 } 551 #endif 459 552 } 553 CloseHandle(hSnap); 460 554 } 461 } 462 else /* CreateToolhelp32Snapshot / Toolhelp32 API not available. */ 463 { 464 /* 465 * NT4 needs a copy of "PSAPI.dll" (redistributed by Microsoft and not 466 * part of the OS) in order to get a lookup. If we don't have this DLL 467 * we are not able to get a token and therefore no UI will be visible. 468 */ 469 RTLDRMOD hPSAPI; 470 int rc = RTLdrLoad("PSAPI.dll", &hPSAPI); 471 if (RT_SUCCESS(rc)) 472 { 473 PFNENUMPROCESSES pfnEnumProcesses; 474 rc = RTLdrGetSymbol(hPSAPI, "EnumProcesses", (void**)&pfnEnumProcesses); 475 if (RT_SUCCESS(rc)) 476 { 477 PFNGETMODULEBASENAME pfnGetModuleBaseName; 478 rc = RTLdrGetSymbol(hPSAPI, "GetModuleBaseName", (void**)&pfnGetModuleBaseName); 479 if (RT_SUCCESS(rc)) 480 { 481 /** @todo Retry if pBytesReturned equals cbBytes! */ 482 DWORD adwPIDs[4096]; /* Should be sufficient for now. */ 483 DWORD cbBytes = 0; 484 if (pfnEnumProcesses(adwPIDs, sizeof(adwPIDs), &cbBytes)) 485 { 486 for (size_t i = 0; papszNames[i] && !fFound; i++) 487 { 488 for (DWORD dwIdx = 0; dwIdx < cbBytes/sizeof(DWORD) && !fFound; dwIdx++) 489 { 490 HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 491 FALSE, adwPIDs[dwIdx]); 492 if (hProc) 493 { 494 char *pszProcName = NULL; 495 DWORD dwSize = 128; 496 do 497 { 498 RTMemRealloc(pszProcName, dwSize); 499 if (pfnGetModuleBaseName(hProc, 0, pszProcName, dwSize) == dwSize) 500 dwSize += 128; 501 if (dwSize > _4K) /* Play safe. */ 502 break; 503 } while (GetLastError() == ERROR_INSUFFICIENT_BUFFER); 504 505 if (pszProcName) 506 { 507 if ( _stricmp(pszProcName, papszNames[i]) == 0 508 && RT_SUCCESS(rtProcGetProcessHandle(adwPIDs[dwIdx], pSid, phToken))) 509 { 510 fFound = true; 511 } 512 } 513 if (pszProcName) 514 RTStrFree(pszProcName); 515 CloseHandle(hProc); 516 } 517 } 518 } 519 } 520 else 521 dwErr = GetLastError(); 522 } 523 } 524 RTLdrClose(hPSAPI); 525 } 555 else /* hSnap == INVALID_HANDLE_VALUE */ 556 rc = RTErrConvertFromWin32(GetLastError()); 526 557 } 527 558 RTLdrClose(hKernel32); 528 559 } 529 Assert(dwErr == NO_ERROR); 560 561 /* If we couldn't take a process snapshot for some reason or another, fall 562 back on the NT4 compatible API. */ 563 if (RT_FAILURE(rc)) 564 return rtProcWinFindTokenByProcessAndPsApi(papszNames, pSid, phToken); 530 565 return fFound; 531 566 } … … 542 577 * @param phToken Pointer to store the logon token. 543 578 */ 544 static int rtProc UserLogon(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain, HANDLE *phToken)579 static int rtProcWinUserLogon(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain, HANDLE *phToken) 545 580 { 546 581 /** @todo Add domain support! */ … … 559 594 phToken); 560 595 if (!fRc) 561 return rtProc MapErrorCodes(GetLastError());596 return rtProcWinMapErrorCodes(GetLastError()); 562 597 return VINF_SUCCESS; 563 598 } … … 569 604 * @param hToken The token (=user) to log off. 570 605 */ 571 static void rtProc UserLogoff(HANDLE hToken)606 static void rtProcWinUserLogoff(HANDLE hToken) 572 607 { 573 608 CloseHandle(hToken); … … 585 620 * @param ppwszBlock Pointer to the final output. 586 621 */ 587 static int rtProcEnvironmentCreateInternal(VOID *pvBlock, RTENV hEnv, PRTUTF16 *ppwszBlock) 588 { 589 int rc = VINF_SUCCESS; 622 static int rtProcWinEnvironmentCreateInternal(VOID *pvBlock, RTENV hEnv, PRTUTF16 *ppwszBlock) 623 { 590 624 RTENV hEnvTemp; 591 rc = RTEnvClone(&hEnvTemp, hEnv);625 int rc = RTEnvClone(&hEnvTemp, hEnv); 592 626 if (RT_SUCCESS(rc)) 593 627 { 594 PRTUTF16 pBlock = (PRTUTF16)pvBlock; 595 while ( pBlock 596 && pBlock != '\0' 628 PCRTUTF16 pwch = (PCRTUTF16)pvBlock; 629 while ( pwch 597 630 && RT_SUCCESS(rc)) 598 631 { 599 char *pszEntry; 600 rc = RTUtf16ToUtf8(pBlock, &pszEntry); 601 if (RT_SUCCESS(rc)) 602 { 603 /* Don't overwrite values which we already have set to a custom value 604 * specified in hEnv ... */ 605 if (!RTEnvExistEx(hEnv, pszEntry)) 606 rc = RTEnvPutEx(hEnvTemp, pszEntry); 607 RTStrFree(pszEntry); 632 if (*pwch) 633 { 634 char *pszEntry; 635 rc = RTUtf16ToUtf8(pwch, &pszEntry); 636 if (RT_SUCCESS(rc)) 637 { 638 /* Don't overwrite values which we already have set to a custom value 639 * specified in hEnv ... */ 640 if (!RTEnvExistEx(hEnv, pszEntry)) 641 rc = RTEnvPutEx(hEnvTemp, pszEntry); 642 RTStrFree(pszEntry); 643 } 608 644 } 609 610 size_t l; 611 /* 32k should be the maximum the environment block can have on Windows. */ 612 if (FAILED(StringCbLengthW((LPCWSTR)pBlock, _32K * sizeof(RTUTF16), &l))) 645 pwch += RTUtf16Len(pwch) + 1; 646 if (*pwch) 613 647 break; 614 pBlock += l / sizeof(RTUTF16);615 if (pBlock[1] == '\0') /* Did we reach the double zero termination (\0\0)? */616 break;617 pBlock++; /* Skip zero termination of current string and advance to next string ... */618 648 } 619 649 … … 627 657 628 658 /** 659 * Creates the environment block using Userenv.dll. 660 * 629 661 * Builds up the environment block for a specified user (identified by a token), 630 662 * whereas hEnv is an additional set of environment variables which overwrite existing 631 663 * values of the user profile. ppwszBlock needs to be destroyed after usage 632 * calling rtProc EnvironmentDestroy().664 * calling rtProcWinDestoryEnv(). 633 665 * 634 666 * @return IPRT status code. … … 638 670 * @param ppwszBlock Pointer to a pointer of the final UTF16 environment block. 639 671 */ 640 static int rtProc EnvironmentCreateFromToken(HANDLE hToken, RTENV hEnv, PRTUTF16 *ppwszBlock)672 static int rtProcWinCreateEnvFromToken(HANDLE hToken, RTENV hEnv, PRTUTF16 *ppwszBlock) 641 673 { 642 674 RTLDRMOD hUserenv; … … 652 684 if (RT_SUCCESS(rc)) 653 685 { 654 LPVOID p EnvBlockProfile = NULL;655 if (pfnCreateEnvironmentBlock(&p EnvBlockProfile, hToken, FALSE /* Don't inherit from parent. */))686 LPVOID pvEnvBlockProfile = NULL; 687 if (pfnCreateEnvironmentBlock(&pvEnvBlockProfile, hToken, FALSE /* Don't inherit from parent. */)) 656 688 { 657 rc = rtProc EnvironmentCreateInternal(pEnvBlockProfile, hEnv, ppwszBlock);658 pfnDestroyEnvironmentBlock(p EnvBlockProfile);689 rc = rtProcWinEnvironmentCreateInternal(pvEnvBlockProfile, hEnv, ppwszBlock); 690 pfnDestroyEnvironmentBlock(pvEnvBlockProfile); 659 691 } 660 692 else … … 664 696 RTLdrClose(hUserenv); 665 697 } 698 666 699 /* If we don't have the Userenv-API for whatever reason or something with the 667 700 * native environment block failed, try to return at least our own environment block. */ … … 676 709 * and domain), whereas hEnv is an additional set of environment variables which overwrite 677 710 * existing values of the user profile. ppwszBlock needs to be destroyed after usage 678 * calling rtProc EnvironmentDestroy().711 * calling rtProcWinDestoryEnv(). 679 712 * 680 713 * @return IPRT status code. … … 686 719 * @param ppwszBlock Pointer to a pointer of the final UTF16 environment block. 687 720 */ 688 static int rtProc EnvironmentCreateFromAccount(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain,721 static int rtProcWinCreateEnvFromAccount(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain, 689 722 RTENV hEnv, PRTUTF16 *ppwszBlock) 690 723 { 691 724 HANDLE hToken; 692 int rc = rtProc UserLogon(pwszUser, pwszPassword, pwszDomain, &hToken);725 int rc = rtProcWinUserLogon(pwszUser, pwszPassword, pwszDomain, &hToken); 693 726 if (RT_SUCCESS(rc)) 694 727 { 695 rc = rtProc EnvironmentCreateFromToken(hToken, hEnv, ppwszBlock);696 rtProc UserLogoff(hToken);728 rc = rtProcWinCreateEnvFromToken(hToken, hEnv, ppwszBlock); 729 rtProcWinUserLogoff(hToken); 697 730 } 698 731 return rc; … … 701 734 702 735 /** 703 * Destroys an environment block formerly created by rtProc EnvironmentCreateInternal(),704 * rtProc EnvironmentCreateFromToken() or rtProcEnvironmentCreateFromAccount().736 * Destroys an environment block formerly created by rtProcWinEnvironmentCreateInternal(), 737 * rtProcWinCreateEnvFromToken() or rtProcWinCreateEnvFromAccount(). 705 738 * 706 739 * @param ppwszBlock Environment block to destroy. 707 740 */ 708 static void rtProc EnvironmentDestroy(PRTUTF16 ppwszBlock)741 static void rtProcWinDestoryEnv(PRTUTF16 ppwszBlock) 709 742 { 710 743 RTEnvFreeUtf16Block(ppwszBlock); … … 712 745 713 746 714 static int rtProc CreateAsUserHlp(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszExec, PRTUTF16 pwszCmdLine,747 static int rtProcWinCreateAsUser(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszExec, PRTUTF16 pwszCmdLine, 715 748 RTENV hEnv, DWORD dwCreationFlags, 716 749 STARTUPINFOW *pStartupInfo, PROCESS_INFORMATION *pProcInfo, uint32_t fFlags) … … 736 769 */ 737 770 PFNCREATEPROCESSWITHLOGON pfnCreateProcessWithLogonW; 738 rc = RTLdrGetSymbol(hAdvAPI32, "CreateProcessWithLogonW", (void **)&pfnCreateProcessWithLogonW);771 rc = RTLdrGetSymbol(hAdvAPI32, "CreateProcessWithLogonW", (void **)&pfnCreateProcessWithLogonW); 739 772 if (RT_SUCCESS(rc)) 740 773 { 741 774 PRTUTF16 pwszzBlock; 742 rc = rtProc EnvironmentCreateFromAccount(pwszUser, pwszPassword, NULL /* Domain */,743 775 rc = rtProcWinCreateEnvFromAccount(pwszUser, pwszPassword, NULL /* Domain */, 776 hEnv, &pwszzBlock); 744 777 if (RT_SUCCESS(rc)) 745 778 { … … 756 789 pProcInfo); 757 790 if (!fRc) 758 rc = rtProc MapErrorCodes(GetLastError());759 rtProc EnvironmentDestroy(pwszzBlock);791 rc = rtProcWinMapErrorCodes(GetLastError()); 792 rtProcWinDestoryEnv(pwszzBlock); 760 793 } 761 794 } … … 799 832 PHANDLE phToken = NULL; 800 833 HANDLE hTokenLogon = INVALID_HANDLE_VALUE; 801 rc = rtProc UserLogon(pwszUser, pwszPassword, NULL /* Domain */, &hTokenLogon);834 rc = rtProcWinUserLogon(pwszUser, pwszPassword, NULL /* Domain */, &hTokenLogon); 802 835 if (RT_SUCCESS(rc)) 803 836 { … … 854 887 NULL 855 888 }; 856 fFound = rtProc FindProcessByName(s_papszProcNames, pSid, &hTokenUserDesktop);889 fFound = rtProcWinFindTokenByProcess(s_papszProcNames, pSid, &hTokenUserDesktop); 857 890 } 858 891 else … … 907 940 { 908 941 PRTUTF16 pwszzBlock; 909 rc = rtProc EnvironmentCreateFromToken(*phToken, hEnv, &pwszzBlock);942 rc = rtProcWinCreateEnvFromToken(*phToken, hEnv, &pwszzBlock); 910 943 if (RT_SUCCESS(rc)) 911 944 { … … 931 964 else 932 965 dwErr = GetLastError(); /* CreateProcessAsUserW() failed. */ 933 rtProc EnvironmentDestroy(pwszzBlock);966 rtProcWinDestoryEnv(pwszzBlock); 934 967 } 935 968 … … 954 987 if (hTokenUserDesktop != INVALID_HANDLE_VALUE) 955 988 CloseHandle(hTokenUserDesktop); 956 rtProc UserLogoff(hTokenLogon);989 rtProcWinUserLogoff(hTokenLogon); 957 990 } 958 991 } … … 960 993 if ( RT_SUCCESS(rc) 961 994 && dwErr != NO_ERROR) 962 rc = rtProc MapErrorCodes(dwErr);995 rc = rtProcWinMapErrorCodes(dwErr); 963 996 964 997 return rc; … … 1107 1140 * Only use the normal CreateProcess stuff if we have no user name 1108 1141 * and we are not running from a (Windows) service. Otherwise use 1109 * the more advanced version in rtProc CreateAsUserHlp().1142 * the more advanced version in rtProcWinCreateAsUser(). 1110 1143 */ 1111 1144 if ( pszAsUser == NULL … … 1140 1173 if (RT_SUCCESS(rc)) 1141 1174 { 1142 rc = rtProc CreateAsUserHlp(pwszUser, pwszPassword,1175 rc = rtProcWinCreateAsUser(pwszUser, pwszPassword, 1143 1176 pwszExec, pwszCmdLine, hEnv, dwCreationFlags, 1144 1177 &StartupInfo, &ProcInfo, fFlags);
Note:
See TracChangeset
for help on using the changeset viewer.