VirtualBox

Changeset 57916 in vbox


Ignore:
Timestamp:
Sep 27, 2015 8:36:38 PM (9 years ago)
Author:
vboxsync
Message:

IPRT: More windows process creation hacking and cleaning up. Cleaned up RTProcQueryUsername and RTProcQueryUsernameA too (all platforms).

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/process.h

    r57870 r57916  
    392392 * @retval VERR_BUFFER_OVERFLOW if the given buffer size is to small for the username.
    393393 * @param   hProcess     The process handle to query the username for.
     394 *                       NIL_PROCESS is an alias for the current process.
    394395 * @param   pszUser      Where to store the user name on success.
    395396 * @param   cbUser       The size of the user name buffer.
     
    398399 *                       is returned.
    399400 */
    400 RTR3DECL(int)   RTProcQueryUsername(RTPROCESS hProcess, char *pszUser, size_t cbUser,
    401                                     size_t *pcbUser);
     401RTR3DECL(int)   RTProcQueryUsername(RTPROCESS hProcess, char *pszUser, size_t cbUser, size_t *pcbUser);
    402402
    403403/**
  • trunk/src/VBox/Runtime/Makefile.kmk

    r57905 r57916  
    599599        generic/RTPathGetCurrentDrive-generic.cpp \
    600600        generic/RTPathIsSame-generic.cpp \
    601         generic/RTProcessQueryUsernameA-generic.cpp \
    602601        generic/RTTimerLRCreate-generic.cpp \
    603602        generic/mempool-generic.cpp \
  • trunk/src/VBox/Runtime/r3/posix/process-posix.cpp

    r57358 r57916  
    159159
    160160
    161 RTR3DECL(int) RTProcQueryUsername(RTPROCESS hProcess, char *pszUser, size_t cbUser,
    162                                   size_t *pcbUser)
     161RTR3DECL(int) RTProcQueryUsername(RTPROCESS hProcess, char *pszUser, size_t cbUser, size_t *pcbUser)
    163162{
    164163    AssertReturn(   (pszUser && cbUser > 0)
    165164                 || (!pszUser && !cbUser), VERR_INVALID_PARAMETER);
    166 
    167     if (hProcess != RTProcSelf())
    168         return VERR_NOT_SUPPORTED;
    169 
    170     int32_t cbPwdMax = sysconf(_SC_GETPW_R_SIZE_MAX);
    171     if (cbPwdMax == -1)
    172         return RTErrConvertFromErrno(errno);
    173 
    174     char *pbBuf = (char *)RTMemAllocZ(cbPwdMax);
    175     if (!pbBuf)
    176         return VERR_NO_MEMORY;
    177 
    178     struct passwd Pwd, *pPwd;
    179     int rc = getpwuid_r(geteuid(), &Pwd, pbBuf, cbPwdMax, &pPwd);
    180     if (!rc)
    181     {
    182         size_t cbPwdUser = strlen(pPwd->pw_name) + 1;
    183 
    184         if (pcbUser)
    185             *pcbUser = cbPwdUser;
    186 
    187         if (cbPwdUser > cbUser)
    188             rc = VERR_BUFFER_OVERFLOW;
    189         else
     165    AssertReturn(pcbUser || pszUser, VERR_INVALID_PARAMETER);
     166
     167    int rc;
     168    if (   hProcess == NIL_RTPROCESS
     169        || hProcess == RTProcSelf())
     170    {
     171        /*
     172         * Figure a good buffer estimate.
     173         */
     174        int32_t cbPwdMax = sysconf(_SC_GETPW_R_SIZE_MAX);
     175        if (cbPwdMax <= sizeof(_1K))
     176            cbPwdMax = _1K;
     177        else
     178            AssertStmt(cbPwdMax <= 32U*_1M, cbPwdMax = 32U*_1M);
     179        char *pchBuf = (char *)RTMemTmpAllocZ(cbPwdMax);
     180        if (pbBuf)
    190181        {
    191 /** @todo this needs to be UTF-8 checked or converted...   */
    192             memcpy(pszUser, pPwd->pw_name, cbPwdUser);
    193             rc = VINF_SUCCESS;
     182            /*
     183             * Get the password file entry.
     184             */
     185            struct passwd  Pwd;
     186            struct passwd *pPwd = NULL;
     187            rc = getpwuid_r(geteuid(), &Pwd, pchBuf, cbPwdMax, &pPwd);
     188            if (!rc)
     189            {
     190                /*
     191                 * Convert the name to UTF-8, assuming that we're getting it in the local codeset.
     192                 */
     193                /** @todo This isn't exactly optimal... the current codeset/page conversion
     194                 *        stuff never was.  Should optimize that for UTF-8 and ASCII one day.
     195                 *        And also optimize for avoiding heap. */
     196                char *pszTmp = NULL;
     197                rc = RTStrCurrentCPToUtf8(&pszTmp, pPwd->pw_name);
     198                if (RT_SUCCESS(rc))
     199                {
     200                    size_t cbTmp = strlen(pszTmp) + 1;
     201                    if (pcbUser)
     202                        *pcbUser = cbTmp;
     203                    if (cbPwdUser <= cbUser)
     204                    {
     205                        memcpy(pszUser, pszTmp, cbTmp);
     206                        rc = VINF_SUCCESS;
     207                    }
     208                    else
     209                        rc = VERR_BUFFER_OVERFLOW;
     210                    RTStrFree(pszTmp);
     211                }
     212            }
     213            else
     214                rc = RTErrConvertFromErrno(rc);
     215            RTMemFree(pchBuf);
    194216        }
     217        else
     218            rc = VERR_NO_TMP_MEMORY;
    195219    }
    196220    else
    197         rc = RTErrConvertFromErrno(rc);
    198 
    199     RTMemFree(pbBuf);
     221        rc = VERR_NOT_SUPPORTED;
    200222    return rc;
    201223}
    202224
     225
     226RTR3DECL(int) RTProcQueryUsernameA(RTPROCESS hProcess, char **ppszUser)
     227{
     228    AssertPtrReturn(ppszUser, VERR_INVALID_POINTER);
     229
     230    int rc;
     231    if (   hProcess == NIL_RTPROCESS
     232        || hProcess == RTProcSelf())
     233    {
     234        /*
     235         * Figure a good buffer estimate.
     236         */
     237        int32_t cbPwdMax = sysconf(_SC_GETPW_R_SIZE_MAX);
     238        if (cbPwdMax <= sizeof(_1K))
     239            cbPwdMax = _1K;
     240        else
     241            AssertStmt(cbPwdMax <= 32U*_1M, cbPwdMax = 32U*_1M);
     242        char *pchBuf = (char *)RTMemTmpAllocZ(cbPwdMax);
     243        if (pbBuf)
     244        {
     245            /*
     246             * Get the password file entry.
     247             */
     248            struct passwd  Pwd;
     249            struct passwd *pPwd = NULL;
     250            rc = getpwuid_r(geteuid(), &Pwd, pchBuf, cbPwdMax, &pPwd);
     251            if (!rc)
     252            {
     253                /*
     254                 * Convert the name to UTF-8, assuming that we're getting it in the local codeset.
     255                 */
     256                rc = RTStrCurrentCPToUtf8(ppszUser, pPwd->pw_name);
     257            }
     258            else
     259                rc = RTErrConvertFromErrno(rc);
     260            RTMemFree(pchBuf);
     261        }
     262        else
     263            rc = VERR_NO_TMP_MEMORY;
     264    }
     265    else
     266        rc = VERR_NOT_SUPPORTED;
     267    return rc;
     268}
     269
  • trunk/src/VBox/Runtime/r3/win/process-win.cpp

    r57906 r57916  
    360360
    361361/**
    362  * Map some important or much used Windows error codes
    363  * to our error codes.
    364  *
    365  * @return  Mapped IPRT status code.
    366  * @param   dwError                         Windows error code to map to IPRT code.
    367  */
    368 static int rtProcWinMapErrorCodes(DWORD dwError)
    369 {
    370     int rc;
    371     switch (dwError)
    372     {
    373         case ERROR_NOACCESS: /** @todo r=bird: this is a bogus transation.  Used a couple of places in main. */
    374             rc = VERR_PERMISSION_DENIED;
    375             break;
    376 
    377         default:
    378             /* Could trigger a debug assertion! */
    379             rc = RTErrConvertFromWin32(dwError);
    380             break;
    381     }
    382     return rc;
    383 }
    384 
    385 
    386 /**
    387362 * Get the process token of the process indicated by @a dwPID if the @a pSid
    388363 * matches.
     
    420395                if (pTokenUser)
    421396                {
    422                     if (GetTokenInformation(hTokenProc,
    423                                             TokenUser,
    424                                             pTokenUser,
    425                                             dwSize,
    426                                             &dwSize))
     397                    if (GetTokenInformation(hTokenProc, TokenUser, pTokenUser, dwSize, &dwSize))
    427398                    {
    428399                        if (   IsValidSid(pTokenUser->User.Sid)
     
    440411                            }
    441412                            else
    442                                 rc = rtProcWinMapErrorCodes(GetLastError());
     413                                rc = RTErrConvertFromWin32(GetLastError());
    443414                        }
    444415                        else
     
    446417                    }
    447418                    else
    448                         rc = rtProcWinMapErrorCodes(GetLastError());
     419                        rc = RTErrConvertFromWin32(GetLastError());
    449420                    RTMemTmpFree(pTokenUser);
    450421                }
     
    455426                rc = VERR_IPE_UNEXPECTED_STATUS;
    456427            else
    457                 rc = rtProcWinMapErrorCodes(dwErr);
     428                rc = RTErrConvertFromWin32(dwErr);
    458429            CloseHandle(hTokenProc);
    459430        }
    460431        else
    461             rc = rtProcWinMapErrorCodes(GetLastError());
     432            rc = RTErrConvertFromWin32(GetLastError());
    462433        CloseHandle(hProc);
    463434    }
    464435    else
    465         rc = rtProcWinMapErrorCodes(GetLastError());
     436        rc = RTErrConvertFromWin32(GetLastError());
    466437    return rc;
    467438}
     
    661632
    662633    DWORD dwErr = GetLastError();
    663     int rc = dwErr == ERROR_PRIVILEGE_NOT_HELD ? VERR_PROC_TCB_PRIV_NOT_HELD : rtProcWinMapErrorCodes(dwErr);
     634    int rc = dwErr == ERROR_PRIVILEGE_NOT_HELD ? VERR_PROC_TCB_PRIV_NOT_HELD : RTErrConvertFromWin32(dwErr);
    664635    if (rc == VERR_UNRESOLVED_ERROR)
    665636        LogRelFunc(("dwErr=%u (%#x), rc=%Rrc\n", dwErr, dwErr, rc));
     
    793764        AssertFailed();
    794765    return VERR_PRIVILEGE_NOT_HELD;
     766}
     767
     768#if 0 /* debug code */
     769
     770static char *rtProcWinSidToString(char *psz, PSID pSid)
     771{
     772     char *pszRet = psz;
     773
     774     *psz++ = 'S';
     775     *psz++ = '-';
     776     *psz++ = '1';
     777     *psz++ = '-';
     778
     779     PISID pISid = (PISID)pSid;
     780
     781     psz += RTStrFormatU32(psz, 32, RT_MAKE_U32_FROM_U8(pISid->IdentifierAuthority.Value[5],
     782                                                        pISid->IdentifierAuthority.Value[4],
     783                                                        pISid->IdentifierAuthority.Value[3],
     784                                                        pISid->IdentifierAuthority.Value[2]),
     785                           10, 0, 0, 0);
     786     for (unsigned i = 0; i < pISid->SubAuthorityCount; i++)
     787     {
     788          *psz++ = '-';
     789          psz += RTStrFormatU32(psz, 32, pISid->SubAuthority[i], 10, 0, 0, 0);
     790     }
     791     *psz++ = '\0';
     792     return pszRet;
     793}
     794
     795static void rtProcWinLogAcl(PACL pAcl)
     796{
     797    if (!pAcl)
     798        RTAssertMsg2("ACL is NULL\n");
     799    else
     800    {
     801        RTAssertMsg2("AceCount=%d AclSize=%#x AclRevision=%d\n", pAcl->AceCount, pAcl->AclSize, pAcl->AclRevision);
     802        for (uint32_t i = 0; i < pAcl->AceCount; i++)
     803        {
     804            PACE_HEADER pAceHdr = NULL;
     805            if (GetAce(pAcl, i, (PVOID *)&pAceHdr))
     806            {
     807                RTAssertMsg2(" ACE[%u]: Flags=%#x Type=%#x Size=%#x", i, pAceHdr->AceFlags, pAceHdr->AceType, pAceHdr->AceSize);
     808                char szTmp[256];
     809                if (pAceHdr->AceType == ACCESS_ALLOWED_ACE_TYPE)
     810                    RTAssertMsg2(" Mask=%#x %s\n", ((ACCESS_ALLOWED_ACE *)pAceHdr)->Mask,
     811                                 rtProcWinSidToString(szTmp, &((ACCESS_ALLOWED_ACE *)pAceHdr)->SidStart));
     812                else
     813                    RTAssertMsg2(" ACE[%u]: Flags=%#x Type=%#x Size=%#x\n", i, pAceHdr->AceFlags, pAceHdr->AceType, pAceHdr->AceSize);
     814            }
     815        }
     816    }
     817}
     818
     819static bool rtProcWinLogSecAttr(HANDLE hUserObj)
     820{
     821    /*
     822     * Get the security descriptor for the user interface object.
     823     */
     824    uint32_t             cbSecDesc = _64K;
     825    PSECURITY_DESCRIPTOR pSecDesc  = (PSECURITY_DESCRIPTOR)RTMemTmpAlloc(cbSecDesc);
     826    SECURITY_INFORMATION SecInfo   = DACL_SECURITY_INFORMATION;
     827    DWORD                cbNeeded;
     828    AssertReturn(pSecDesc, false);
     829    if (!GetUserObjectSecurity(hUserObj, &SecInfo, pSecDesc, cbSecDesc, &cbNeeded))
     830    {
     831        RTMemTmpFree(pSecDesc);
     832        AssertReturn(GetLastError() == ERROR_INSUFFICIENT_BUFFER, false);
     833        cbSecDesc = cbNeeded + 128;
     834        pSecDesc  = (PSECURITY_DESCRIPTOR)RTMemTmpAlloc(cbSecDesc);
     835        AssertReturn(pSecDesc, false);
     836        if (!GetUserObjectSecurity(hUserObj, &SecInfo, pSecDesc, cbSecDesc, &cbNeeded))
     837        {
     838            RTMemTmpFree(pSecDesc);
     839            AssertFailedReturn(false);
     840        }
     841    }
     842
     843    /*
     844     * Get the discretionary access control list (if we have one).
     845     */
     846    BOOL fDaclDefaulted;
     847    BOOL fDaclPresent;
     848    PACL pDacl;
     849    if (GetSecurityDescriptorDacl(pSecDesc, &fDaclPresent, &pDacl, &fDaclDefaulted))
     850        rtProcWinLogAcl(pDacl);
     851    else
     852        RTAssertMsg2("GetSecurityDescriptorDacl failed\n");
     853
     854    RTMemFree(pSecDesc);
     855    return true;
     856}
     857
     858#endif /* debug */
     859
     860/**
     861 * Get the user SID from a token.
     862 *
     863 * @returns Pointer to the SID on success. Free by calling RTMemFree.
     864 * @param   hToken              The token..
     865 */
     866static PSID rtProcWinGetTokenUserSid(HANDLE hToken)
     867{
     868    /*
     869     * Get the groups associated with the token.  We just try a size first then
     870     * reallocates if it's insufficient.
     871     */
     872    DWORD       cbUser = _1K;
     873    PTOKEN_USER pUser  = (PTOKEN_USER)RTMemTmpAlloc(cbUser);
     874    AssertReturn(pUser, NULL);
     875    DWORD cbNeeded = 0;
     876    if (!GetTokenInformation(hToken, TokenUser, pUser, cbUser, &cbNeeded))
     877    {
     878        RTMemTmpFree(pUser);
     879        AssertReturn(GetLastError() == ERROR_INSUFFICIENT_BUFFER, NULL);
     880        cbUser = cbNeeded + 128;
     881        pUser = (PTOKEN_USER)RTMemTmpAlloc(cbUser);
     882        AssertReturn(pUser, NULL);
     883        if (!GetTokenInformation(hToken, TokenUser, pUser, cbUser, &cbNeeded))
     884        {
     885            RTMemTmpFree(pUser);
     886            AssertFailedReturn(NULL);
     887        }
     888    }
     889
     890    DWORD cbSid = GetLengthSid(pUser->User.Sid);
     891    PSID pSidRet = RTMemDup(pUser->User.Sid, cbSid);
     892    Assert(pSidRet);
     893    RTMemTmpFree(pUser);
     894    return pSidRet;
     895}
     896
     897
     898#if 0 /* not used */
     899/**
     900 * Get the login SID from a token.
     901 *
     902 * @returns Pointer to the SID on success. Free by calling RTMemFree.
     903 * @param   hToken              The token..
     904 */
     905static PSID rtProcWinGetTokenLogonSid(HANDLE hToken)
     906{
     907    /*
     908     * Get the groups associated with the token.  We just try a size first then
     909     * reallocates if it's insufficient.
     910     */
     911    DWORD         cbGroups = _1K;
     912    PTOKEN_GROUPS pGroups = (PTOKEN_GROUPS)RTMemTmpAlloc(cbGroups);
     913    AssertReturn(pGroups, NULL);
     914    DWORD cbNeeded = 0;
     915    if (!GetTokenInformation(hToken, TokenGroups, pGroups, cbGroups, &cbNeeded))
     916    {
     917        RTMemTmpFree(pGroups);
     918        AssertReturn(GetLastError() == ERROR_INSUFFICIENT_BUFFER, NULL);
     919        cbGroups = cbNeeded + 128;
     920        pGroups = (PTOKEN_GROUPS)RTMemTmpAlloc(cbGroups);
     921        AssertReturn(pGroups, NULL);
     922        if (!GetTokenInformation(hToken, TokenGroups, pGroups, cbGroups, &cbNeeded))
     923        {
     924            RTMemTmpFree(pGroups);
     925            AssertFailedReturn(NULL);
     926        }
     927    }
     928
     929    /*
     930     * Locate the logon sid.
     931     */
     932    PSID     pSidRet = NULL;
     933    uint32_t i = pGroups->GroupCount;
     934    while (i-- > 0)
     935        if ((pGroups->Groups[i].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID)
     936        {
     937            DWORD cbSid = GetLengthSid(pGroups->Groups[i].Sid);
     938            pSidRet = RTMemDup(pGroups->Groups[i].Sid, cbSid);
     939            break;
     940        }
     941
     942    RTMemTmpFree(pGroups);
     943    Assert(pSidRet);
     944    return pSidRet;
     945}
     946#endif /* unused */
     947
     948
     949/**
     950 * Retrieves the DACL security descriptor of the give GUI object.
     951 *
     952 * @returns Pointer to the security descriptor.
     953 * @param   hUserObj        The GUI object handle.
     954 * @param   pcbSecDesc      Where to return the size of the security descriptor.
     955 * @param   ppDacl          Where to return the DACL pointer.
     956 * @param   pfDaclPresent   Where to return the DACL-present indicator.
     957 * @param   pDaclSizeInfo   Where to return the DACL size information.
     958 */
     959static PSECURITY_DESCRIPTOR rtProcWinGetUserObjDacl(HANDLE hUserObj, uint32_t *pcbSecDesc, PACL *ppDacl,
     960                                                    BOOL *pfDaclPresent, ACL_SIZE_INFORMATION *pDaclSizeInfo)
     961{
     962    /*
     963     * Get the security descriptor for the user interface object.
     964     */
     965    uint32_t             cbSecDesc = _1K;
     966    PSECURITY_DESCRIPTOR pSecDesc  = (PSECURITY_DESCRIPTOR)RTMemTmpAlloc(cbSecDesc);
     967    SECURITY_INFORMATION SecInfo   = DACL_SECURITY_INFORMATION;
     968    DWORD                cbNeeded;
     969    AssertReturn(pSecDesc, NULL);
     970    if (!GetUserObjectSecurity(hUserObj, &SecInfo, pSecDesc, cbSecDesc, &cbNeeded))
     971    {
     972        RTMemTmpFree(pSecDesc);
     973        AssertReturn(GetLastError() == ERROR_INSUFFICIENT_BUFFER, NULL);
     974        cbSecDesc = cbNeeded + 128;
     975        pSecDesc  = (PSECURITY_DESCRIPTOR)RTMemTmpAlloc(cbSecDesc);
     976        AssertReturn(pSecDesc, NULL);
     977        if (!GetUserObjectSecurity(hUserObj, &SecInfo, pSecDesc, cbSecDesc, &cbNeeded))
     978        {
     979            RTMemTmpFree(pSecDesc);
     980            AssertFailedReturn(NULL);
     981        }
     982    }
     983    *pcbSecDesc = cbNeeded;
     984
     985    /*
     986     * Get the discretionary access control list (if we have one).
     987     */
     988    BOOL fDaclDefaulted;
     989    if (GetSecurityDescriptorDacl(pSecDesc, pfDaclPresent, ppDacl, &fDaclDefaulted))
     990    {
     991        RT_ZERO(*pDaclSizeInfo);
     992        pDaclSizeInfo->AclBytesInUse = sizeof(ACL);
     993        if (   !*ppDacl
     994            || GetAclInformation(*ppDacl, pDaclSizeInfo, sizeof(*pDaclSizeInfo), AclSizeInformation))
     995            return pSecDesc;
     996        AssertFailed();
     997    }
     998    else
     999        AssertFailed();
     1000    RTMemTmpFree(pSecDesc);
     1001    return NULL;
     1002}
     1003
     1004
     1005/**
     1006 * Copy ACEs from one ACL to another.
     1007 *
     1008 * @returns true on success, false on failure.
     1009 * @param   pDst                The destination ACL.
     1010 * @param   pSrc                The source ACL.
     1011 * @param   cAces               The number of ACEs to copy.
     1012 */
     1013static bool rtProcWinCopyAces(PACL pDst, PACL pSrc, uint32_t cAces)
     1014{
     1015    for (uint32_t i = 0; i < cAces; i++)
     1016    {
     1017        PACE_HEADER pAceHdr;
     1018        AssertReturn(GetAce(pSrc, i, (PVOID *)&pAceHdr), false);
     1019        AssertReturn(AddAce(pDst, ACL_REVISION, MAXDWORD, pAceHdr, pAceHdr->AceSize), false);
     1020    }
     1021    return true;
     1022}
     1023
     1024
     1025/**
     1026 * Adds an access-allowed access control entry to an ACL.
     1027 *
     1028 * @returns true on success, false on failure.
     1029 * @param   pDstAcl             The ACL.
     1030 * @param   fAceFlags           The ACE flags.
     1031 * @param   fMask               The ACE access mask.
     1032 * @param   pSid                The SID to go with the ACE.
     1033 * @param   cbSid               The size of the SID.
     1034 */
     1035static bool rtProcWinAddAccessAllowedAce(PACL pDstAcl, uint32_t fAceFlags, uint32_t fMask, PSID pSid, uint32_t cbSid)
     1036{
     1037    struct
     1038    {
     1039        ACCESS_ALLOWED_ACE  Core;
     1040        DWORD               abPadding[128]; /* More than enough, AFAIK. */
     1041    } AceBuf;
     1042    RT_ZERO(AceBuf);
     1043    uint32_t const cbAllowedAce = RT_OFFSETOF(ACCESS_ALLOWED_ACE, SidStart) + cbSid;
     1044    AssertReturn(cbAllowedAce <= sizeof(AceBuf), false);
     1045
     1046    AceBuf.Core.Header.AceSize     = cbAllowedAce;
     1047    AceBuf.Core.Header.AceType     = ACCESS_ALLOWED_ACE_TYPE;
     1048    AceBuf.Core.Header.AceFlags    = fAceFlags;
     1049    AceBuf.Core.Mask               = fMask;
     1050    AssertReturn(CopySid(cbSid, &AceBuf.Core.SidStart, pSid), false);
     1051
     1052    uint32_t i = pDstAcl->AceCount;
     1053    while (i-- > 0)
     1054    {
     1055        PACE_HEADER pAceHdr;
     1056        AssertStmt(GetAce(pDstAcl, i, (PVOID *)&pAceHdr), continue);
     1057        if (   pAceHdr->AceSize == cbAllowedAce
     1058            && memcmp(pAceHdr, &AceBuf.Core, cbAllowedAce) == 0)
     1059            return true;
     1060
     1061    }
     1062    AssertMsgReturn(AddAce(pDstAcl, ACL_REVISION, MAXDWORD, &AceBuf.Core, cbAllowedAce), ("%u\n", GetLastError()), false);
     1063    return true;
     1064}
     1065
     1066
     1067/** All window station rights we know about   */
     1068#define MY_WINSTATION_ALL_RIGHTS (  WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP \
     1069                                  | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | WINSTA_READATTRIBUTES \
     1070                                  | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES | DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER )
     1071/** All desktop rights we know about   */
     1072#define MY_DESKTOP_ALL_RIGHTS    (  DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL \
     1073                                  | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS \
     1074                                  | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS | DELETE | READ_CONTROL | WRITE_DAC \
     1075                                  | WRITE_OWNER )
     1076/** Generic rights. */
     1077#define MY_GENERIC_ALL_RIGHTS    ( GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL )
     1078
     1079
     1080/**
     1081 * Grants the given SID full access to the given window station.
     1082 *
     1083 * @returns true on success, false on failure.
     1084 * @param   hWinStation         The window station.
     1085 * @param   pSid                The SID.
     1086 */
     1087static bool rtProcWinAddSidToWinStation(HWINSTA hWinStation, PSID pSid)
     1088{
     1089    bool fRet = false;
     1090
     1091    /*
     1092     * Get the current DACL.
     1093     */
     1094    uint32_t                cbSecDesc;
     1095    PACL                    pDacl;
     1096    ACL_SIZE_INFORMATION    DaclSizeInfo;
     1097    BOOL                    fDaclPresent;
     1098    PSECURITY_DESCRIPTOR    pSecDesc = rtProcWinGetUserObjDacl(hWinStation, &cbSecDesc, &pDacl, &fDaclPresent, &DaclSizeInfo);
     1099    if (pSecDesc)
     1100    {
     1101        /*
     1102         * Create a new DACL. This will contain two extra ACEs.
     1103         */
     1104        PSECURITY_DESCRIPTOR pNewSecDesc = (PSECURITY_DESCRIPTOR)RTMemTmpAlloc(cbSecDesc);
     1105        if (   pNewSecDesc
     1106            && InitializeSecurityDescriptor(pNewSecDesc, SECURITY_DESCRIPTOR_REVISION))
     1107        {
     1108            uint32_t const cbSid     = GetLengthSid(pSid);
     1109            uint32_t const cbNewDacl = DaclSizeInfo.AclBytesInUse + (sizeof(ACCESS_ALLOWED_ACE) + cbSid) * 2;
     1110            PACL pNewDacl = (PACL)RTMemTmpAlloc(cbNewDacl);
     1111            if (   pNewDacl
     1112                && InitializeAcl(pNewDacl, cbNewDacl, ACL_REVISION)
     1113                && rtProcWinCopyAces(pNewDacl, pDacl, fDaclPresent ? DaclSizeInfo.AceCount : 0))
     1114            {
     1115                /*
     1116                 * Add the two new SID ACEs.
     1117                 */
     1118                if (   rtProcWinAddAccessAllowedAce(pNewDacl, CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE,
     1119                                                    MY_GENERIC_ALL_RIGHTS, pSid, cbSid)
     1120                    && rtProcWinAddAccessAllowedAce(pNewDacl, NO_PROPAGATE_INHERIT_ACE, MY_WINSTATION_ALL_RIGHTS, pSid, cbSid))
     1121                {
     1122                    /*
     1123                     * Now mate the new DECL with the security descriptor and set it.
     1124                     */
     1125                    if (SetSecurityDescriptorDacl(pNewSecDesc, TRUE /*fDaclPresent*/, pNewDacl, FALSE /*fDaclDefaulted*/))
     1126                    {
     1127                        SECURITY_INFORMATION SecInfo = DACL_SECURITY_INFORMATION;
     1128                        if (SetUserObjectSecurity(hWinStation, &SecInfo, pNewSecDesc))
     1129                            fRet = true;
     1130                        else
     1131                            AssertFailed();
     1132                    }
     1133                    else
     1134                        AssertFailed();
     1135                }
     1136                else
     1137                    AssertFailed();
     1138            }
     1139            else
     1140                AssertFailed();
     1141            RTMemTmpFree(pNewDacl);
     1142        }
     1143        else
     1144            AssertFailed();
     1145        RTMemTmpFree(pNewSecDesc);
     1146        RTMemTmpFree(pSecDesc);
     1147    }
     1148    return fRet;
     1149}
     1150
     1151
     1152/**
     1153 * Grants the given SID full access to the given desktop.
     1154 *
     1155 * @returns true on success, false on failure.
     1156 * @param   hWinStation         The window station.
     1157 * @param   pSid                The SID.
     1158 */
     1159static bool rtProcWinAddSidToDesktop(HDESK hDesktop, PSID pSid)
     1160{
     1161    bool fRet = false;
     1162
     1163    /*
     1164     * Get the current DACL.
     1165     */
     1166    uint32_t                cbSecDesc;
     1167    PACL                    pDacl;
     1168    ACL_SIZE_INFORMATION    DaclSizeInfo;
     1169    BOOL                    fDaclPresent;
     1170    PSECURITY_DESCRIPTOR    pSecDesc = rtProcWinGetUserObjDacl(hDesktop, &cbSecDesc, &pDacl, &fDaclPresent, &DaclSizeInfo);
     1171    if (pSecDesc)
     1172    {
     1173        /*
     1174         * Create a new DACL. This will contain one extra ACE.
     1175         */
     1176        PSECURITY_DESCRIPTOR pNewSecDesc = (PSECURITY_DESCRIPTOR)RTMemTmpAlloc(cbSecDesc);
     1177        if (   pNewSecDesc
     1178            && InitializeSecurityDescriptor(pNewSecDesc, SECURITY_DESCRIPTOR_REVISION))
     1179        {
     1180            uint32_t const cbSid     = GetLengthSid(pSid);
     1181            uint32_t const cbNewDacl = DaclSizeInfo.AclBytesInUse + (sizeof(ACCESS_ALLOWED_ACE) + cbSid) * 1;
     1182            PACL pNewDacl = (PACL)RTMemTmpAlloc(cbNewDacl);
     1183            if (   pNewDacl
     1184                && InitializeAcl(pNewDacl, cbNewDacl, ACL_REVISION)
     1185                && rtProcWinCopyAces(pNewDacl, pDacl, fDaclPresent ? DaclSizeInfo.AceCount : 0))
     1186            {
     1187                /*
     1188                 * Add the new SID ACE.
     1189                 */
     1190                if (rtProcWinAddAccessAllowedAce(pNewDacl, 0 /*fAceFlags*/, MY_DESKTOP_ALL_RIGHTS, pSid, cbSid))
     1191                {
     1192                    /*
     1193                     * Now mate the new DECL with the security descriptor and set it.
     1194                     */
     1195                    if (SetSecurityDescriptorDacl(pNewSecDesc, TRUE /*fDaclPresent*/, pNewDacl, FALSE /*fDaclDefaulted*/))
     1196                    {
     1197                        SECURITY_INFORMATION SecInfo = DACL_SECURITY_INFORMATION;
     1198                        if (SetUserObjectSecurity(hDesktop, &SecInfo, pNewSecDesc))
     1199                            fRet = true;
     1200                        else
     1201                            AssertFailed();
     1202                    }
     1203                    else
     1204                        AssertFailed();
     1205                }
     1206                else
     1207                    AssertFailed();
     1208            }
     1209            else
     1210                AssertFailed();
     1211            RTMemTmpFree(pNewDacl);
     1212        }
     1213        else
     1214            AssertFailed();
     1215        RTMemTmpFree(pNewSecDesc);
     1216        RTMemTmpFree(pSecDesc);
     1217    }
     1218    return fRet;
     1219}
     1220
     1221
     1222/**
     1223 * Preps the window station and desktop for the new app.
     1224 *
     1225 * EXPERIMENTAL. Thus no return code.
     1226 *
     1227 * @param   hTokenToUse     The access token of the new process.
     1228 * @param   pStartupInfo    The startup info (we'll change lpDesktop, maybe).
     1229 * @param   phWinStationOld Where to return an window station handle to restore.
     1230 *                          Pass this to SetProcessWindowStation if not NULL.
     1231 */
     1232static void rtProcWinStationPrep(HANDLE hTokenToUse, STARTUPINFOW *pStartupInfo, HWINSTA *phWinStationOld)
     1233{
     1234    /** @todo Always mess with the interactive one? Maybe it's not there...  */
     1235    *phWinStationOld = GetProcessWindowStation();
     1236    HWINSTA hWinStation0 = OpenWindowStationW(L"winsta0", FALSE /*fInherit*/, READ_CONTROL | WRITE_DAC);
     1237    if (hWinStation0)
     1238    {
     1239        if (SetProcessWindowStation(hWinStation0))
     1240        {
     1241            HDESK hDesktop = OpenDesktop("default", 0 /*fFlags*/, FALSE /*fInherit*/,
     1242                                         READ_CONTROL | WRITE_DAC | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS);
     1243            if (hDesktop)
     1244            {
     1245                /*PSID pSid = rtProcWinGetTokenLogonSid(hTokenToUse); - Better to use the user SID. Avoid overflowing the ACL. */
     1246                PSID pSid = rtProcWinGetTokenUserSid(hTokenToUse);
     1247                if (pSid)
     1248                {
     1249                    if (   rtProcWinAddSidToWinStation(hWinStation0, pSid)
     1250                        && rtProcWinAddSidToDesktop(hDesktop, pSid))
     1251                    {
     1252                        pStartupInfo->lpDesktop = L"winsta0\\default";
     1253                    }
     1254                    RTMemFree(pSid);
     1255                }
     1256                CloseDesktop(hDesktop);
     1257            }
     1258            else
     1259                AssertFailed();
     1260        }
     1261        else
     1262            AssertFailed();
     1263        CloseWindowStation(hWinStation0);
     1264    }
     1265    else
     1266        AssertFailed();
    7951267}
    7961268
     
    8391311        HANDLE hTokenUserDesktop = INVALID_HANDLE_VALUE;
    8401312
     1313        /*
     1314         * If the SERVICE flag is specified, we do something rather ugly to
     1315         * make things work at all.  We search for a known desktop process
     1316         * belonging to the user, grab its token and use it for launching
     1317         * the new process.  That way the process will have desktop access.
     1318         */
    8411319        if (fFlags & RTPROC_FLAGS_SERVICE)
    8421320        {
     
    8831361        /* else: !RTPROC_FLAGS_SERVICE: Nothing to do here right now. */
    8841362
    885         /** @todo Hmm, this function already is too big! We need to split
    886          *        it up into several small parts. */
    887 
    888         /* If we got an error due to account lookup/loading above, don't
    889          * continue here. */
     1363#if 0
     1364        /*
     1365         * If we make LogonUserW to return an impersonation token, enable this
     1366         * to convert it into a primary token.
     1367         */
     1368        if (!fFound && detect-impersonation-token)
     1369        {
     1370            HANDLE hNewToken;
     1371            if (DuplicateTokenEx(hTokenLogon, MAXIMUM_ALLOWED, NULL /*SecurityAttribs*/,
     1372                                 SecurityIdentification, TokenPrimary, &hNewToken))
     1373            {
     1374                CloseHandle(hTokenLogon);
     1375                hTokenLogon = hNewToken;
     1376            }
     1377            else
     1378                AssertMsgFailed(("%d\n", GetLastError()));
     1379        }
     1380#endif
     1381
    8901382        if (RT_SUCCESS(rc))
    8911383        {
     
    9301422                            if (RT_SUCCESS(rc))
    9311423                            {
     1424                                HWINSTA hOldWinStation = NULL;
     1425                                if (!fFound && g_enmWinVer <= kRTWinOSType_NT4) /** @todo test newer versions... */
     1426                                    rtProcWinStationPrep(hTokenToUse, pStartupInfo, &hOldWinStation);
     1427
    9321428                                /*
    9331429                                 * Useful KB articles:
     
    9591455                                        rc = RTErrConvertFromWin32(dwErr);
    9601456                                }
     1457
     1458                                if (hOldWinStation)
     1459                                    SetProcessWindowStation(hOldWinStation);
    9611460                            }
    9621461                            RTEnvFreeUtf16Block(pwszzBlock);
     
    10891588     * gets the environment specified by the user profile.
    10901589     */
    1091     int      rc         = VINF_SUCCESS;
     1590    int      rc;
    10921591    PRTUTF16 pwszzBlock = NULL;
    10931592
     
    11101609    else if (   hEnv == RTENV_DEFAULT
    11111610             && !(fFlags & (RTPROC_FLAGS_ENV_CHANGE_RECORD | RTPROC_FLAGS_SEARCH_PATH)))
     1611    {
    11121612        pwszzBlock = NULL;
     1613        rc = VINF_SUCCESS;
     1614    }
    11131615    /*
    11141616     * Otherwise, we need to get the user profile environment.
     
    11211623        if (RT_SUCCESS(rc))
    11221624        {
    1123     /** @todo r=bird: Why didn't we load the environment here?  The
    1124      *       CreateEnvironmentBlock docs indicate that USERPROFILE isn't set
    1125      *       unless we call LoadUserProfile first.  However, experiments here on W10
    1126      *       shows it isn't really needed though. Weird.
    1127      * Update: It works even on W2K. Possible only required for roaming profiles? */
    1128 #if 0
    1129             if (fFlags & RTPROC_FLAGS_PROFILE)
    1130             {
    1131                 PROFILEINFOW ProfileInfo;
    1132                 RT_ZERO(ProfileInfo);
    1133                 ProfileInfo.dwSize     = sizeof(ProfileInfo);
    1134                 ProfileInfo.lpUserName = pwszUser;
    1135                 ProfileInfo.dwFlags    = PI_NOUI; /* Prevents the display of profile error messages. */
    1136 
    1137                 if (g_pfnLoadUserProfileW(hToken, &ProfileInfo))
     1625            /* CreateEnvFromToken docs says we should load the profile, though
     1626               we haven't observed any difference when not doing it.  Maybe it's
     1627               only an issue with roaming profiles or something similar... */
     1628            PROFILEINFOW ProfileInfo;
     1629            RT_ZERO(ProfileInfo);
     1630            ProfileInfo.dwSize     = sizeof(ProfileInfo);
     1631            ProfileInfo.lpUserName = pwszUser;
     1632            ProfileInfo.dwFlags    = PI_NOUI; /* Prevents the display of profile error messages. */
     1633
     1634            if (g_pfnLoadUserProfileW(hToken, &ProfileInfo))
     1635            {
     1636                /*
     1637                 * Do what we need to do.  Don't keep any temp environment object.
     1638                 */
     1639                rc = rtProcWinCreateEnvFromToken(hToken, hEnv, fFlags, &hEnvToUse);
     1640                if (RT_SUCCESS(rc))
    11381641                {
    1139                     rc = rtProcWinCreateEnvFromToken(hToken, hEnv, fFlags, &hEnvToUse);
    1140 
    1141                     if (!g_pfnUnloadUserProfile(hToken, ProfileInfo.hProfile))
    1142                         AssertFailed();
     1642                    rc = rtProcWinFindExe(fFlags, hEnv, pszExec, ppwszExec);
     1643                    if (RT_SUCCESS(rc))
     1644                        rc = RTEnvQueryUtf16Block(hEnvToUse, &pwszzBlock);
     1645                    if (hEnvToUse != hEnv)
     1646                        RTEnvDestroy(hEnvToUse);
    11431647                }
    1144                 else
    1145                     rc = RTErrConvertFromWin32(GetLastError());
     1648
     1649                if (!g_pfnUnloadUserProfile(hToken, ProfileInfo.hProfile))
     1650                    AssertFailed();
    11461651            }
    11471652            else
    1148 #endif
    1149                 rc = rtProcWinCreateEnvFromToken(hToken, hEnv, fFlags, &hEnvToUse);
     1653                rc = RTErrConvertFromWin32(GetLastError());
    11501654            CloseHandle(hToken);
    1151 
    1152             /*
    1153              * Query the environment block and find the executable file,
    1154              * Then destroy any temp env block.
    1155              */
    1156             if (RT_SUCCESS(rc))
    1157             {
    1158                 rc = rtProcWinFindExe(fFlags, hEnv, pszExec, ppwszExec);
    1159                 if (RT_SUCCESS(rc))
    1160                     rc = RTEnvQueryUtf16Block(hEnvToUse, &pwszzBlock);
    1161                 if (hEnvToUse != hEnv)
    1162                     RTEnvDestroy(hEnvToUse);
    1163             }
    11641655        }
    11651656    }
    11661657    if (RT_SUCCESS(rc))
    11671658    {
     1659        /*
     1660         * Create the process.
     1661         */
    11681662        Assert(!(dwCreationFlags & CREATE_SUSPENDED));
    11691663        bool const fCreatedSuspended = g_enmWinVer < kRTWinOSType_XP;
     
    11851679            else
    11861680            {
    1187                 /* Duplicate standard handles into the child process, we ignore failures here as it's
    1188                    legal to have bad standard handle values and we cannot dup console I/O handles. */
     1681                /*
     1682                 * Duplicate standard handles into the child process, we ignore failures here as it's
     1683                 * legal to have bad standard handle values and we cannot dup console I/O handles.*
     1684                 */
    11891685                PVOID pvDstProcParamCache = NULL;
    11901686                rtProcWinDupStdHandleIntoChild(pStartupInfo->hStdInput, pProcInfo->hProcess,
     
    11951691                                               RT_OFFSETOF(RTL_USER_PROCESS_PARAMETERS, StandardError), &pvDstProcParamCache);
    11961692
    1197                 if (ResumeThread(pProcInfo->hThread) == ~(DWORD)0)
     1693                if (ResumeThread(pProcInfo->hThread) != ~(DWORD)0)
     1694                    rc = VINF_SUCCESS;
     1695                else
    11981696                    rc = RTErrConvertFromWin32(GetLastError());
    11991697                if (RT_FAILURE(rc))
     
    12081706        {
    12091707            DWORD dwErr = GetLastError();
    1210             rc = rtProcWinMapErrorCodes(dwErr);
     1708            rc = RTErrConvertFromWin32(dwErr);
    12111709            if (rc == VERR_UNRESOLVED_ERROR)
    12121710                LogRelFunc(("g_pfnCreateProcessWithLogonW (%p) failed: dwErr=%u (%#x), rc=%Rrc\n",
     
    17542252
    17552253
    1756 RTR3DECL(int) RTProcQueryUsername(RTPROCESS hProcess, char *pszUser, size_t cbUser,
    1757                                   size_t *pcbUser)
     2254RTR3DECL(int) RTProcQueryUsername(RTPROCESS hProcess, char *pszUser, size_t cbUser, size_t *pcbUser)
    17582255{
    17592256    AssertReturn(   (pszUser && cbUser > 0)
    17602257                 || (!pszUser && !cbUser), VERR_INVALID_PARAMETER);
    1761 
    1762     if (hProcess != RTProcSelf())
    1763         return VERR_NOT_SUPPORTED;
    1764 
    1765     RTUTF16 awszUserName[UNLEN + 1];
    1766     DWORD   cchUserName = UNLEN + 1;
    1767 
    1768     if (!GetUserNameW(&awszUserName[0], &cchUserName))
    1769         return RTErrConvertFromWin32(GetLastError());
    1770 
    1771     char *pszUserName = NULL;
    1772     int rc = RTUtf16ToUtf8(awszUserName, &pszUserName);
    1773     if (RT_SUCCESS(rc))
    1774     {
    1775         size_t cbUserName = strlen(pszUserName) + 1;
    1776 
    1777         if (pcbUser)
    1778             *pcbUser = cbUserName;
    1779 
    1780         if (cbUserName > cbUser)
    1781             rc = VERR_BUFFER_OVERFLOW;
     2258    AssertReturn(pcbUser || pszUser, VERR_INVALID_PARAMETER);
     2259
     2260    int rc;
     2261    if (   hProcess == NIL_RTPROCESS
     2262        || hProcess == RTProcSelf())
     2263    {
     2264        RTUTF16 wszUsername[UNLEN + 1];
     2265        DWORD   cwcUsername = RT_ELEMENTS(wszUsername);
     2266        if (GetUserNameW(&wszUsername[0], &cwcUsername))
     2267        {
     2268            if (pszUser)
     2269            {
     2270                rc = RTUtf16ToUtf8Ex(wszUsername, cwcUsername, &pszUser, cbUser, pcbUser);
     2271                if (pcbUser)
     2272                    *pcbUser += 1;
     2273            }
     2274            else
     2275            {
     2276                *pcbUser = RTUtf16CalcUtf8Len(wszUsername) + 1;
     2277                rc = VERR_BUFFER_OVERFLOW;
     2278            }
     2279        }
    17822280        else
    1783         {
    1784             memcpy(pszUser, pszUserName, cbUserName);
    1785             rc = VINF_SUCCESS;
    1786         }
    1787 
    1788         RTStrFree(pszUserName);
    1789     }
    1790 
     2281            rc = RTErrConvertFromWin32(GetLastError());
     2282    }
     2283    else
     2284        rc = VERR_NOT_SUPPORTED;
    17912285    return rc;
    17922286}
    17932287
     2288
     2289RTR3DECL(int) RTProcQueryUsernameA(RTPROCESS hProcess, char **ppszUser)
     2290{
     2291    AssertPtrReturn(ppszUser, VERR_INVALID_POINTER);
     2292    int rc;
     2293    if (   hProcess == NIL_RTPROCESS
     2294        || hProcess == RTProcSelf())
     2295    {
     2296        RTUTF16 wszUsername[UNLEN + 1];
     2297        DWORD   cwcUsername = RT_ELEMENTS(wszUsername);
     2298        if (GetUserNameW(&wszUsername[0], &cwcUsername))
     2299            rc = RTUtf16ToUtf8(wszUsername, ppszUser);
     2300        else
     2301            rc = RTErrConvertFromWin32(GetLastError());
     2302    }
     2303    else
     2304        rc = VERR_NOT_SUPPORTED;
     2305    return rc;
     2306}
     2307
  • trunk/src/VBox/Runtime/testcase/tstRTProcQueryUsername.cpp

    r57358 r57916  
    3535#include <iprt/test.h>
    3636
     37
    3738static void tstRTProcQueryUsername(void)
    3839{
    39     char abUser[1024];
    40     size_t cbUser;
    41     char *pszUser = NULL;
    42 
    4340    RTTestISub("Basics");
    4441
    45     memset(abUser, 0, sizeof(abUser));
     42    size_t  cbUser;
     43    char    szUser[1024];
     44    memset(szUser, '-', sizeof(szUser));
     45
     46    /* negative stuff that may assert: */
     47    bool fMayPanic = RTAssertSetMayPanic(false);
     48    bool fQuiet    = RTAssertSetQuiet(true);
     49
    4650    RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), NULL, 8, &cbUser), VERR_INVALID_PARAMETER);
    47     RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), abUser, 0, &cbUser), VERR_INVALID_PARAMETER);
    48     RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), NULL, 0, NULL), VERR_BUFFER_OVERFLOW);
     51    RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), szUser, 0, &cbUser), VERR_INVALID_PARAMETER);
     52    RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), NULL, 0, NULL), VERR_INVALID_PARAMETER);
     53    RTTESTI_CHECK_RC(RTProcQueryUsernameA(RTProcSelf(), NULL), VERR_INVALID_POINTER);
     54
     55    RTAssertSetMayPanic(fMayPanic);
     56    RTAssertSetQuiet(fQuiet);
     57
    4958    RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), NULL, 0, &cbUser), VERR_BUFFER_OVERFLOW);
     59    memset(szUser, '-', sizeof(szUser));
     60    RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), szUser, cbUser - 1, &cbUser), VERR_BUFFER_OVERFLOW);
     61    memset(szUser, '-', sizeof(szUser));
     62    RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), szUser, sizeof(szUser), &cbUser), VINF_SUCCESS);
     63    RTTestPrintf(NULL, RTTESTLVL_ALWAYS, "Username: %s\n", szUser); /* */
    5064
    51     RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), abUser, sizeof(abUser), &cbUser), VINF_SUCCESS);
    52     RTTestPrintf(NULL, RTTESTLVL_ALWAYS, "Username: %s\n", abUser);
    53     RTTESTI_CHECK_RC(RTProcQueryUsername(RTProcSelf(), abUser, cbUser - 1, &cbUser), VERR_BUFFER_OVERFLOW);
    54 
    55     RTTESTI_CHECK_RC(RTProcQueryUsernameA(RTProcSelf(), NULL), VERR_INVALID_POINTER);
     65    char *pszUser = NULL;
    5666    RTTESTI_CHECK_RC(RTProcQueryUsernameA(RTProcSelf(), &pszUser), VINF_SUCCESS);
    5767    RTTestPrintf(NULL, RTTESTLVL_ALWAYS, "Username: %s\n", pszUser);
     68    RTTESTI_CHECK(strcmp(pszUser, szUser) == 0);
    5869    RTStrFree(pszUser);
    5970}
     71
    6072
    6173int main(int argc, char **argv)
  • trunk/src/VBox/Runtime/win/RTErrConvertFromWin32.cpp

    r57906 r57916  
    5050        case ERROR_TOO_MANY_OPEN_FILES:     return VERR_TOO_MANY_OPEN_FILES;
    5151        case ERROR_ACCESS_DENIED:           return VERR_ACCESS_DENIED;
    52         case ERROR_NOACCESS:                return VERR_ACCESS_DENIED;
     52        case ERROR_NOACCESS:                return VERR_INVALID_POINTER; /* (STATUS_ACCESS_VIOLATION, STATUS_DATATYPE_MISALIGNMENT, STATUS_DATATYPE_MISALIGNMENT_ERROR) */
    5353
    5454        case ERROR_INVALID_HANDLE:
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette