Files
PowerShell/impl/getusername.cpp
T

95 lines
2.5 KiB
C++
Raw Normal View History

2015-06-16 14:02:19 -07:00
#include "getusername.h"
2015-07-01 16:24:36 -07:00
#include <errno.h>
#include <langinfo.h>
#include <locale.h>
2015-06-16 14:02:19 -07:00
#include <unistd.h>
2015-07-01 16:24:36 -07:00
#include <string>
2015-07-22 10:20:50 -07:00
#include <vector>
#include <scxcorelib/scxstrencodingconv.h>
2015-06-16 14:02:19 -07:00
2015-07-01 16:24:36 -07:00
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724432(v=vs.85).aspx
// Sets errno to:
2015-07-22 10:17:47 -07:00
// ERROR_INVALID_PARAMETER - parameter is not valid
2015-07-01 16:24:36 -07:00
// ERROR_BAD_ENVIRONMENT - locale is not UTF-8
// ERROR_TOO_MANY_OPEN_FILES - already have the maximum allowed number of open files
// ERROR_NO_ASSOCIATION - calling process has no controlling terminal
// ERROR_INSUFFICIENT_BUFFER - buffer not large enough to hold username string
// ERROR_NO_SUCH_USER - there was no corresponding entry in the utmp-file
// ERROR_OUTOFMEMORY - insufficient memory to allocate passwd structure
// ERROR_NO_ASSOCIATION - standard input didn't refer to a terminal
// ERROR_INVALID_FUNCTION - getlogin_r() returned an unrecognized error code
2015-07-01 16:24:36 -07:00
//
// Returns:
// 1 - succeeded
// 0 - failed
2015-07-22 10:17:47 -07:00
BOOL GetUserName(WCHAR_T *lpBuffer, LPDWORD lpnSize)
2015-06-16 14:02:19 -07:00
{
2015-07-22 13:43:09 -07:00
static const std::string utf8 = "UTF-8";
2015-07-01 16:24:36 -07:00
errno = 0;
2015-07-22 10:17:47 -07:00
// Check parameters
if (!lpBuffer || !lpnSize) {
errno = ERROR_INVALID_PARAMETER;
return 0;
}
2015-07-01 16:24:36 -07:00
// Select locale from environment
setlocale(LC_ALL, "");
// Check that locale is UTF-8
if (nl_langinfo(CODESET) != utf8) {
errno = ERROR_BAD_ENVIRONMENT;
return 0;
}
// Get username from system in a thread-safe manner
2015-07-22 16:04:11 -07:00
char userName[LOGIN_NAME_MAX];
int err = getlogin_r(userName, LOGIN_NAME_MAX);
// Map errno to Win32 Error Codes
if (err != 0) {
switch (errno) {
case EMFILE:
case ENFILE:
errno = ERROR_TOO_MANY_OPEN_FILES;
break;
case ENXIO:
errno = ERROR_NO_ASSOCIATION;
break;
case ERANGE:
errno = ERROR_INSUFFICIENT_BUFFER;
break;
case ENOENT:
errno = ERROR_NO_SUCH_USER;
break;
case ENOMEM:
errno = ERROR_OUTOFMEMORY;
break;
case ENOTTY:
errno = ERROR_NO_ASSOCIATION;
break;
default:
errno = ERROR_INVALID_FUNCTION;
}
return 0;
}
2015-07-22 10:20:50 -07:00
// Convert to char * to WCHAR_T * (UTF-8 to UTF-16 LE w/o BOM)
2015-07-22 13:45:25 -07:00
std::string input(userName);
std::vector<unsigned char> output;
SCXCoreLib::Utf8ToUtf16le(input, output);
2015-07-22 10:20:50 -07:00
if (output.size()/2 + 1 > *lpnSize) {
errno = ERROR_INSUFFICIENT_BUFFER;
2015-07-22 15:10:44 -07:00
*lpnSize = output.size()/2 + 1;
2015-07-22 10:20:50 -07:00
return 0;
}
2015-07-22 10:20:50 -07:00
// Add two null bytes (because it's UTF-16)
output.push_back('\0');
output.push_back('\0');
2015-07-22 10:20:50 -07:00
memcpy(lpBuffer, &output[0], output.size());
*lpnSize = output.size()/2;
2015-07-01 16:24:36 -07:00
return 1;
2015-06-16 14:02:19 -07:00
}