Пример #1
0
/*++
Function:
    GetComputerNameW

Uses gethostname to get the computer name. See MSDN for functional spec.

--*/
PALIMPORT
BOOL
PALAPI
GetComputerNameW(
    OUT LPWSTR lpBuffer, // address of name buffer
    IN OUT LPDWORD nSize)    // address of size of name buffer
{
    BOOL fRet = FALSE;
    char szHostName[MAXHOSTNAMELEN+1];
    char *pchDot = NULL;
    DWORD cwchLen = 0;
    CPalThread *pPalThread = InternalGetCurrentThread();

    PERF_ENTRY(GetComputerNameW);
    ENTRY("GetComputerNameW(lpBuffer = %p, nSize = %p (%d)\n",
          lpBuffer, nSize, nSize?*nSize:0);

    if (NULL == lpBuffer || NULL == nSize)
    {
        ERROR("lpBuffer == NULL or nSize == NULL");
        pPalThread->SetLastError(ERROR_INVALID_PARAMETER);
        goto done;
    }

    if (0 != gethostname(szHostName, sizeof(szHostName)/sizeof(szHostName[0])))
    {
        ERROR("gethostname failed with error (%d) %s\n", errno, strerror(errno));
        pPalThread->SetLastError(ERROR_INTERNAL_ERROR);
        goto done;
    }

    // Null terminate the string
    szHostName[sizeof(szHostName)/sizeof(szHostName[0])-1] = '\0';

    // some OSes return the hostname with the domain name included.
    // We want to return only the host part of the name (see the spec for
    // more details
    pchDot = strchr(szHostName, '.');
    if (NULL != pchDot)
    {
        *pchDot = '\0'; // remove the domain name info
    }

    // clip the hostname to MAX_COMPUTERNAME_LENGTH
    if (sizeof(szHostName) > MAX_COMPUTERNAME_LENGTH)
    {
        szHostName[MAX_COMPUTERNAME_LENGTH] = '\0';
    }

    // copy the hostname (including NULL character)
    cwchLen = MultiByteToWideChar(CP_ACP, 0, szHostName, -1, lpBuffer, *nSize);
    if (0 == cwchLen) 
    {
        ERROR ("MultiByteToWideChar failed with error %d when trying to convert the hostname "
                "%s to wide char\n", pPalThread->GetLastError(), szHostName);
        if (ERROR_INSUFFICIENT_BUFFER == pPalThread->GetLastError())
        {
            // Find the required size (including NULL)
            cwchLen = MultiByteToWideChar(CP_ACP, 0, szHostName, -1, NULL, 0);
            if (0 == cwchLen)
            {
                ERROR ("MultiByteToWideChar failed with error %d when trying to find the size of "
                       "%s in wide chars\n", pPalThread->GetLastError(), szHostName);
                pPalThread->SetLastError(ERROR_INTERNAL_ERROR);
            }
            else
            {
                // Update the required size
                *nSize = cwchLen - 1; // don't include the NULL
                pPalThread->SetLastError(ERROR_BUFFER_OVERFLOW);
            }
        }
        goto done;
    }

    *nSize = cwchLen - 1; // don't include the NULL
    fRet = TRUE;

done:
    LOGEXIT("GetComputerNameW returning BOOL %d\n", fRet);
    PERF_EXIT(GetComputerNameW);
    return fRet;
}
Пример #2
0
/*++
Function:
    GetUserNameW

Uses getpwuid_r to get the user name and if it's not available uses
getpwuid (with the safety of a critical section). See MSDN for functional spec.

--*/
PALIMPORT
BOOL
PALAPI
GetUserNameW(
    OUT LPWSTR lpBuffer, // address of name buffer
    IN OUT LPDWORD nSize )    // address of size of name buffer
{
    BOOL fRet = FALSE;
    struct passwd *pPasswd = NULL;
    char *szUserName = NULL;
    DWORD cwchLen = 0;
    int iEuid = -1;
    int iRet = -1;
    CPalThread *pPalThread = InternalGetCurrentThread();

#if HAVE_GETPWUID_R
    
    char *pchBuffer = NULL;
    DWORD dwBufLen = 0;
    struct passwd sPasswd;
    
#endif // HAVE_GETPWUID_R

    PERF_ENTRY(GetUserNameW);
    ENTRY("GetUserNameW(lpBuffer = %p, nSize = %p (%d)\n",
          lpBuffer, nSize, nSize?*nSize:0);

    iEuid = geteuid();

    if (NULL == lpBuffer || NULL == nSize)
    {
        ERROR("lpBuffer == NULL or nSize == NULL");
        pPalThread->SetLastError(ERROR_INVALID_PARAMETER);
        goto done;
    }

#if HAVE_GETPWUID_R

    dwBufLen = dwInitialPasswdBufferSize;

    while (NULL == pPasswd)
    {
        pchBuffer = (char*) InternalMalloc(pPalThread, sizeof(pchBuffer[0]) * dwBufLen);
        if (NULL == pchBuffer)
        {
            pPalThread->SetLastError(ERROR_OUTOFMEMORY);
            goto done;
        }

        iRet = InternalGetpwuid_r(pPalThread, iEuid, &sPasswd, pchBuffer, dwBufLen, &pPasswd);
        if (0 != iRet)
        {
            WARN("getpwuid_r(%d) returns %d for a buffer size of %d, error string is %s\n", 
                        iEuid, iRet, dwBufLen, strerror(iRet));

            if (ERANGE == iRet) // need a bigger buffer
            {
                InternalFree(pPalThread, pchBuffer);
                pchBuffer = NULL;
                pPasswd = NULL;
                dwBufLen *= 2; // double the buffer
                continue; // try again
            }

            pPalThread->SetLastError(ERROR_INTERNAL_ERROR);
            goto done;
        }

        // Unfortunately, HPUX returns success and result = NULL even when the buffer size is small
        // (instead of returning ERANGE error). But, since we are using either
        // sysconf(_SC_GETPW_R_SIZE_MAX) or the HP recommended value of 1024, buffer should always
        // be big enough for getpwuid_r.

        if (NULL == pPasswd || NULL == pPasswd->pw_name)
        {
            // No matching entry found! something failed somewhere.
            ERROR("getpwuid_r(%d) returned %p with name NULL!\n", iEuid, pPasswd);
            pPalThread->SetLastError(ERROR_INTERNAL_ERROR);
            goto done;
        }
    }

    szUserName = pPasswd->pw_name;

#else // HAVE_GETPWUID_R

    InternalEnterCriticalSection(pPalThread, &identity_critsec);
    pPasswd = getpwuid(iEuid);

    if ((NULL == pPasswd) || (NULL == pPasswd->pw_name))
    {
        InternalLeaveCriticalSection(pPalThread, &identity_critsec);
        ERROR("getpwuid(%d) returned %p with name NULL! error (%d) is %s\n",
                iEuid, pPasswd, errno, strerror(errno));
        pPalThread->SetLastError(ERROR_INTERNAL_ERROR);
        goto done;
    }

    // make a copy so that we can modify it
    szUserName = InternalStrdup(pPalThread, pPasswd->pw_name);
    if (NULL == szUserName)
    {
        InternalLeaveCriticalSection(pPalThread, &identity_critsec);
        pPalThread->SetLastError(ERROR_OUTOFMEMORY);
        goto done;
    }

    InternalLeaveCriticalSection(pPalThread, &identity_critsec);
#endif // HAVE_GETPWUID_R

    // truncate the user name if it exceeds the maximum allowed limit
    if (strlen(szUserName) > UNLEN)
    {
        szUserName[UNLEN] = '\0';
    }

    // Copy from pPasswd->pw_name
    cwchLen = MultiByteToWideChar(CP_ACP, 0, szUserName, -1, lpBuffer, *nSize);
    if (0 == cwchLen)
    {
        ERROR ("MultiByteToWideChar failed with error %d when trying to convert the username "
               "%s to wide char\n", pPalThread->GetLastError(), szUserName);
        if (ERROR_INSUFFICIENT_BUFFER == pPalThread->GetLastError())
        {
            // Find the required size (including NULL)
            cwchLen = MultiByteToWideChar(CP_ACP, 0, szUserName, -1, NULL, 0);
            if (0 == cwchLen)
            {
                ERROR ("MultiByteToWideChar failed with error %d when trying to find the size of "
                       "%s in wide chars\n", pPalThread->GetLastError(), szUserName);
                pPalThread->SetLastError(ERROR_INTERNAL_ERROR);
            }
            else
            {
                // Update the required size
                *nSize = cwchLen;
                pPalThread->SetLastError(ERROR_MORE_DATA);
            }
        }
        goto done;
    }

    *nSize = cwchLen;
    fRet = TRUE;

done:
#if HAVE_GETPWUID_R
    if (NULL != pchBuffer)
    {
        InternalFree(pPalThread, pchBuffer);
    }
#else // HAVE_GETPWUID_R
    if (NULL != szUserName)
    {
        InternalFree(pPalThread, szUserName);
    }
#endif // HAVE_GETPWUID_R

    LOGEXIT("GetUserNameW returning BOOL %d\n", fRet);
    PERF_EXIT(GetUserNameW);
    return fRet;
}