/*++ 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; }
/*++ 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; }