|
27 | 27 |
|
28 | 28 | #if TARGET_OS_WIN32
|
29 | 29 | #include <lm.h>
|
| 30 | +#include <sddl.h> |
30 | 31 | #include <shellapi.h>
|
31 | 32 | #include <shlobj.h>
|
| 33 | +#include <shlwapi.h> |
32 | 34 | #include <WinIoCtl.h>
|
33 | 35 | #include <direct.h>
|
34 | 36 | #include <process.h>
|
@@ -582,26 +584,76 @@ CF_EXPORT CFURLRef CFCopyHomeDirectoryURLForUser(CFStringRef uName) {
|
582 | 584 | return CFCopyHomeDirectoryURL();
|
583 | 585 | }
|
584 | 586 |
|
585 |
| - CFIndex ulLength = CFStringGetLength(uName); |
| 587 | + static const wchar_t * const kProfileListPath = |
| 588 | + L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\"; |
| 589 | + static const wchar_t * const kProfileImagePath = L"ProfileImagePath"; |
| 590 | + |
| 591 | + CFURLRef url = NULL; |
586 | 592 |
|
587 |
| - UniChar *buffer = calloc(ulLength + 1, sizeof(UniChar)); |
588 |
| - if (buffer == NULL) |
| 593 | + CFIndex ulLength = CFStringGetLength(uName); |
| 594 | + UniChar *pwszUserName = |
| 595 | + CFAllocatorAllocate(kCFAllocatorSystemDefault, |
| 596 | + (ulLength + 1) * sizeof(UniChar), 0); |
| 597 | + if (pwszUserName == NULL) |
589 | 598 | return NULL;
|
590 |
| - CFStringGetCharacters(uName, CFRangeMake(0, ulLength), buffer); |
591 | 599 |
|
592 |
| - CFURLRef url = NULL; |
593 |
| - LPUSER_INFO_1 lpUI1 = NULL; |
594 |
| - if (NetUserGetInfo(NULL, buffer, 1, (LPBYTE*)&lpUI1) == NERR_Success) { |
595 |
| - CFStringRef path = |
596 |
| - CFStringCreateWithCharacters(kCFAllocatorSystemDefault, |
597 |
| - lpUI1->usri1_home_dir, |
598 |
| - wcslen(lpUI1->usri1_home_dir)); |
599 |
| - url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, path, |
600 |
| - kCFURLWindowsPathStyle, true); |
601 |
| - CFRelease(path); |
602 |
| - NetApiBufferFree(lpUI1); |
603 |
| - } |
604 |
| - free(buffer); |
| 600 | + CFStringGetCharacters(uName, CFRangeMake(0, ulLength), pwszUserName); |
| 601 | + pwszUserName[ulLength] = L'\0'; |
| 602 | + |
| 603 | + DWORD cbSID = 0; |
| 604 | + DWORD cchReferencedDomainName = 0; |
| 605 | + SID_NAME_USE eUse; |
| 606 | + LookupAccountNameW(NULL, pwszUserName, NULL, &cbSID, NULL, |
| 607 | + &cchReferencedDomainName, &eUse); |
| 608 | + |
| 609 | + LPBYTE pSID = CFAllocatorAllocate(kCFAllocatorSystemDefault, cbSID, 0); |
| 610 | + LPWSTR pwszReferencedDomainName = |
| 611 | + CFAllocatorAllocate(kCFAllocatorSystemDefault, |
| 612 | + (cchReferencedDomainName + 1) * sizeof(UniChar), 0); |
| 613 | + |
| 614 | + if (LookupAccountNameW(NULL, pwszUserName, pSID, &cbSID, |
| 615 | + pwszReferencedDomainName, &cchReferencedDomainName, |
| 616 | + &eUse)) { |
| 617 | + LPWSTR pwszSID; |
| 618 | + |
| 619 | + if (ConvertSidToStringSidW(pSID, &pwszSID)) { |
| 620 | + DWORD cchBuffer = wcslen(kProfileListPath) + wcslen(pwszSID) + 1; |
| 621 | + PWSTR pwszKeyPath = |
| 622 | + CFAllocatorAllocate(kCFAllocatorSystemDefault, |
| 623 | + cchBuffer * sizeof(UniChar), 0); |
| 624 | + |
| 625 | + DWORD dwOffset = |
| 626 | + StrCatChainW(pwszKeyPath, cchBuffer, 0, kProfileListPath); |
| 627 | + StrCatChainW(pwszKeyPath, cchBuffer, dwOffset, pwszSID); |
| 628 | + |
| 629 | + DWORD cbData = 0; |
| 630 | + RegGetValueW(HKEY_LOCAL_MACHINE, pwszKeyPath, kProfileImagePath, |
| 631 | + RRF_RT_REG_SZ, NULL, NULL, &cbData); |
| 632 | + |
| 633 | + LPWSTR pwszProfileImagePath = |
| 634 | + CFAllocatorAllocate(kCFAllocatorSystemDefault, cbData, 0); |
| 635 | + RegGetValueW(HKEY_LOCAL_MACHINE, pwszKeyPath, kProfileImagePath, |
| 636 | + RRF_RT_REG_SZ, NULL, pwszProfileImagePath, &cbData); |
| 637 | + |
| 638 | + CFStringRef profile = |
| 639 | + CFStringCreateWithCharacters(kCFAllocatorSystemDefault, |
| 640 | + pwszProfileImagePath, |
| 641 | + cbData / sizeof(wchar_t)); |
| 642 | + |
| 643 | + url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, |
| 644 | + profile, kCFURLWindowsPathStyle, |
| 645 | + true); |
| 646 | + CFRelease(profile); |
| 647 | + CFAllocatorDeallocate(kCFAllocatorSystemDefault, pwszProfileImagePath); |
| 648 | + CFAllocatorDeallocate(kCFAllocatorSystemDefault, pwszKeyPath); |
| 649 | + } |
| 650 | + |
| 651 | + LocalFree(pwszSID); |
| 652 | + } |
| 653 | + |
| 654 | + CFAllocatorDeallocate(kCFAllocatorSystemDefault, pwszReferencedDomainName); |
| 655 | + CFAllocatorDeallocate(kCFAllocatorSystemDefault, pSID); |
| 656 | + CFAllocatorDeallocate(kCFAllocatorSystemDefault, pwszUserName); |
605 | 657 |
|
606 | 658 | return url;
|
607 | 659 | #else
|
|
0 commit comments