michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsUserInfo.h" michael@0: michael@0: #include "mozilla/ArrayUtils.h" // ArrayLength michael@0: #include "nsString.h" michael@0: #include "windows.h" michael@0: #include "nsCRT.h" michael@0: #include "nsXPIDLString.h" michael@0: michael@0: #define SECURITY_WIN32 michael@0: #include "lm.h" michael@0: #include "security.h" michael@0: michael@0: nsUserInfo::nsUserInfo() michael@0: { michael@0: } michael@0: michael@0: nsUserInfo::~nsUserInfo() michael@0: { michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS(nsUserInfo, nsIUserInfo) michael@0: michael@0: NS_IMETHODIMP michael@0: nsUserInfo::GetUsername(char **aUsername) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aUsername); michael@0: *aUsername = nullptr; michael@0: michael@0: // ULEN is the max username length as defined in lmcons.h michael@0: wchar_t username[UNLEN +1]; michael@0: DWORD size = mozilla::ArrayLength(username); michael@0: if (!GetUserNameW(username, &size)) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: *aUsername = ToNewUTF8String(nsDependentString(username)); michael@0: return (*aUsername) ? NS_OK : NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsUserInfo::GetFullname(char16_t **aFullname) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aFullname); michael@0: *aFullname = nullptr; michael@0: michael@0: wchar_t fullName[512]; michael@0: DWORD size = mozilla::ArrayLength(fullName); michael@0: michael@0: if (GetUserNameExW(NameDisplay, fullName, &size)) { michael@0: *aFullname = ToNewUnicode(nsDependentString(fullName)); michael@0: } else { michael@0: DWORD getUsernameError = GetLastError(); michael@0: michael@0: // Try to use the net APIs regardless of the error because it may be michael@0: // able to obtain the information. michael@0: wchar_t username[UNLEN + 1]; michael@0: size = mozilla::ArrayLength(username); michael@0: if (!GetUserNameW(username, &size)) { michael@0: // ERROR_NONE_MAPPED means the user info is not filled out on this computer michael@0: return getUsernameError == ERROR_NONE_MAPPED ? michael@0: NS_ERROR_NOT_AVAILABLE : NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: const DWORD level = 2; michael@0: LPBYTE info; michael@0: // If the NetUserGetInfo function has no full name info it will return michael@0: // success with an empty string. michael@0: NET_API_STATUS status = NetUserGetInfo(nullptr, username, level, &info); michael@0: if (status != NERR_Success) { michael@0: // We have an error with NetUserGetInfo but we know the info is not michael@0: // filled in because GetUserNameExW returned ERROR_NONE_MAPPED. michael@0: return getUsernameError == ERROR_NONE_MAPPED ? michael@0: NS_ERROR_NOT_AVAILABLE : NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: nsDependentString fullName = michael@0: nsDependentString(reinterpret_cast(info)->usri2_full_name); michael@0: michael@0: // NetUserGetInfo returns an empty string if the full name is not filled out michael@0: if (fullName.Length() == 0) { michael@0: NetApiBufferFree(info); michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: *aFullname = ToNewUnicode(fullName); michael@0: NetApiBufferFree(info); michael@0: } michael@0: michael@0: return (*aFullname) ? NS_OK : NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsUserInfo::GetDomain(char **aDomain) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aDomain); michael@0: *aDomain = nullptr; michael@0: michael@0: const DWORD level = 100; michael@0: LPBYTE info; michael@0: NET_API_STATUS status = NetWkstaGetInfo(nullptr, level, &info); michael@0: if (status == NERR_Success) { michael@0: *aDomain = michael@0: ToNewUTF8String(nsDependentString(reinterpret_cast(info)-> michael@0: wki100_langroup)); michael@0: NetApiBufferFree(info); michael@0: } michael@0: michael@0: return (*aDomain) ? NS_OK : NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsUserInfo::GetEmailAddress(char **aEmailAddress) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aEmailAddress); michael@0: *aEmailAddress = nullptr; michael@0: michael@0: // RFC3696 says max length of an email address is 254 michael@0: wchar_t emailAddress[255]; michael@0: DWORD size = mozilla::ArrayLength(emailAddress); michael@0: michael@0: if (!GetUserNameExW(NameUserPrincipal, emailAddress, &size)) { michael@0: DWORD getUsernameError = GetLastError(); michael@0: return getUsernameError == ERROR_NONE_MAPPED ? michael@0: NS_ERROR_NOT_AVAILABLE : NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: *aEmailAddress = ToNewUTF8String(nsDependentString(emailAddress)); michael@0: return (*aEmailAddress) ? NS_OK : NS_ERROR_FAILURE; michael@0: }