DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (b6057e17f856)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsUserInfo.h"

#include "mozilla/ArrayUtils.h" // ArrayLength
#include "nsString.h"
#include "windows.h"
#include "nsCRT.h"
#include "nsXPIDLString.h"

#define SECURITY_WIN32
#include "lm.h"
#include "security.h"

nsUserInfo::nsUserInfo()
{
}

nsUserInfo::~nsUserInfo()
{
}

NS_IMPL_ISUPPORTS(nsUserInfo, nsIUserInfo)

NS_IMETHODIMP
nsUserInfo::GetUsername(char **aUsername)
{
  NS_ENSURE_ARG_POINTER(aUsername);
  *aUsername = nullptr;

  // ULEN is the max username length as defined in lmcons.h
  wchar_t username[UNLEN +1];
  DWORD size = mozilla::ArrayLength(username);
  if (!GetUserNameW(username, &size))
    return NS_ERROR_FAILURE;

  *aUsername = ToNewUTF8String(nsDependentString(username));
  return (*aUsername) ? NS_OK : NS_ERROR_FAILURE;
}

NS_IMETHODIMP
nsUserInfo::GetFullname(char16_t **aFullname)
{
  NS_ENSURE_ARG_POINTER(aFullname);
  *aFullname = nullptr;

  wchar_t fullName[512];
  DWORD size = mozilla::ArrayLength(fullName);

  if (GetUserNameExW(NameDisplay, fullName, &size)) {
    *aFullname = ToNewUnicode(nsDependentString(fullName));
  } else {
    DWORD getUsernameError = GetLastError();

    // Try to use the net APIs regardless of the error because it may be
    // able to obtain the information.
    wchar_t username[UNLEN + 1];
    size = mozilla::ArrayLength(username);
    if (!GetUserNameW(username, &size)) {
      // ERROR_NONE_MAPPED means the user info is not filled out on this computer
      return getUsernameError == ERROR_NONE_MAPPED ?
             NS_ERROR_NOT_AVAILABLE : NS_ERROR_FAILURE;
    }

    const DWORD level = 2;
    LPBYTE info;
    // If the NetUserGetInfo function has no full name info it will return
    // success with an empty string.
    NET_API_STATUS status = NetUserGetInfo(nullptr, username, level, &info);
    if (status != NERR_Success) {
      // We have an error with NetUserGetInfo but we know the info is not
      // filled in because GetUserNameExW returned ERROR_NONE_MAPPED.
      return getUsernameError == ERROR_NONE_MAPPED ?
             NS_ERROR_NOT_AVAILABLE : NS_ERROR_FAILURE;
    }

    nsDependentString fullName =
      nsDependentString(reinterpret_cast<USER_INFO_2 *>(info)->usri2_full_name);

    // NetUserGetInfo returns an empty string if the full name is not filled out
    if (fullName.Length() == 0) {
      NetApiBufferFree(info);
      return NS_ERROR_NOT_AVAILABLE;
    }

    *aFullname = ToNewUnicode(fullName);
    NetApiBufferFree(info);
  }

  return (*aFullname) ? NS_OK : NS_ERROR_FAILURE;
}

NS_IMETHODIMP
nsUserInfo::GetDomain(char **aDomain)
{
  NS_ENSURE_ARG_POINTER(aDomain);
  *aDomain = nullptr;

  const DWORD level = 100;
  LPBYTE info;
  NET_API_STATUS status = NetWkstaGetInfo(nullptr, level, &info);
  if (status == NERR_Success) {
    *aDomain =
      ToNewUTF8String(nsDependentString(reinterpret_cast<WKSTA_INFO_100 *>(info)->
                                        wki100_langroup));
    NetApiBufferFree(info);
  }

  return (*aDomain) ? NS_OK : NS_ERROR_FAILURE;
}

NS_IMETHODIMP
nsUserInfo::GetEmailAddress(char **aEmailAddress)
{
  NS_ENSURE_ARG_POINTER(aEmailAddress);
  *aEmailAddress = nullptr;

  // RFC3696 says max length of an email address is 254
  wchar_t emailAddress[255];
  DWORD size = mozilla::ArrayLength(emailAddress);

  if (!GetUserNameExW(NameUserPrincipal, emailAddress, &size)) {
    DWORD getUsernameError = GetLastError();
    return getUsernameError == ERROR_NONE_MAPPED ?
           NS_ERROR_NOT_AVAILABLE : NS_ERROR_FAILURE;
  }

  *aEmailAddress = ToNewUTF8String(nsDependentString(emailAddress));
  return (*aEmailAddress) ? NS_OK : NS_ERROR_FAILURE;
}