Get the Current Domain Name in Windows

Hello,

I am trying to find out the domain name for the current user.
This is my first endeavor into dl/win32 and I am having no luck getting
the data.

Here is a reference to the function I am trying to call:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netwkstausergetinfo.asp

Here is a reference to the struct where I am trying to extract the data
from:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/wksta_user_info_1_str.asp

Here is my code with the results in the header:

# username:
# logon_domain:
# oth_domains:
# logon_server:

require 'dl/win32'

getUserNameInfo = Win32API.new('Netapi32.dll', 'NetWkstaUserGetInfo',
%w{p l P}, 'i')
bufferFree = Win32API.new('Netapi32.dll', 'NetApiBufferFree', %w{p},
'l')

reserved = "\0" * 4
buf = " " * 4 * 255

begin
  getUserNameInfo.call(reserved, 1, buf)
  username, logon_domain, oth_domains, logon_server = buf.unpack('AAAA')
  puts 'username: ' + username
  puts 'logon_domain: ' + logon_domain
  puts 'oth_domains: ' + oth_domains
  puts 'logon_server: ' + logon_server
ensure
  bufferFree.call(buf)
end

Thank you,
Brian Takita

Brian Takita wrote:
[snip]

reserved = "\0" * 4

Here is the main problem. You need to pass 0 (or nil) for reserved. If you
had checked the return code from the first function call you would see it
was 87 (which is ERROR_INVALID_PARAMETER.)

After changing reserved to 0, I got 0 back for the response (success), but
the result in buffer was unreadable (I assume it is Unicode, but AFAIK
there is no Ruby Unicode library.)

But making the change I suggested above should at least start you moving
forward.

Ryan

Try this for a simple solution:

require 'win32ole'
p ENV['USERDOMAIN']

These extra ENV arguments should work as well. To cite the source, I
Googled and found them in this blog:
http://blogs.officezealot.com/charles/archive/2004/12/10/3574.aspx

ALLUSERSPROFILE
APPDATA
AVENGINE
CLIENTNAME
CommonProgramFiles
COMPUTERNAME
ComSpec
FP_NO_HOST_CHECK
HOMEDRIVE
HOMEPATH
INCLUDE
INOCULAN
LIB
LOGONSERVER
NUMBER_OF_PROCESSORS
OS
Path
PATHEXT
PROCESSOR_ARCHITECTURE
PROCESSOR_IDENTIFIER
PROCESSOR_LEVEL
PROCESSOR_REVISION
ProgramFiles
SESSIONNAME
SystemDrive
SystemRoot
TEMP
TMP
USERDOMAIN
USERNAME
USERPROFILE
VS71COMNTOOLS
WecVersionForRosebud.FF0
windir

···

On 4/25/05, Brian Takita <brian.takita@gmail.com> wrote:

Hello,

I am trying to find out the domain name for the current user.
This is my first endeavor into dl/win32 and I am having no luck getting
the data.

Here is a reference to the function I am trying to call:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netwkstausergetinfo.asp

Here is a reference to the struct where I am trying to extract the data
from:
Technical documentation | Microsoft Learn

Here is my code with the results in the header:

# username:
# logon_domain:
# oth_domains:
# logon_server:

require 'dl/win32'

getUserNameInfo = Win32API.new('Netapi32.dll', 'NetWkstaUserGetInfo',
%w{p l P}, 'i')
bufferFree = Win32API.new('Netapi32.dll', 'NetApiBufferFree', %w{p},
'l')

reserved = "\0" * 4
buf = " " * 4 * 255

begin
        getUserNameInfo.call(reserved, 1, buf)
        username, logon_domain, oth_domains, logon_server = buf.unpack('AAAA')
        puts 'username: ' + username
        puts 'logon_domain: ' + logon_domain
        puts 'oth_domains: ' + oth_domains
        puts 'logon_server: ' + logon_server
ensure
        bufferFree.call(buf)
end

Thank you,
Brian Takita

Thank you for your response Ryan.

This did get me moving forward. I looked at some VB samples in using
the WKSTA_USER_INFO_1 structure and it looks like four of the
parameters are long data types.

http://vbnet.mvps.org/index.html?code/network/netwkstagetinfouserinfo.htm

It seems like they are pointers to the strings. The example uses a
RtlMoveMemory and then extracts the string from the pointer.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/memory/base/movememory.asp

I tried this but still can't get this to work. I can use Dan's solution
to my problem, but would be nice to know how to work with the Windows
API.

Here is my code:
require 'dl/win32'

getUserNameInfo = Win32API.new('Netapi32.dll', 'NetWkstaUserGetInfo',
%w{p l P}, 'i')
bufferFree = Win32API.new('Netapi32.dll', 'NetApiBufferFree', 'p', 'l')
memoryCopy = Win32API.new('kernel32.dll', 'RtlMoveMemory', 'ppl', '')

reserved = 0
buf = ' ' * 4 * 4

begin
  returnCode = getUserNameInfo.call(reserved, 1, buf)
  username_loc, logon_domain_loc, oth_domains_loc, logon_server_loc =
buf.unpack('llll')
  puts 'username: ' + username_loc.to_s
  puts 'logon_domain: ' + logon_domain_loc.to_s
  puts 'oth_domains: ' + oth_domains_loc.to_s
  puts 'logon_server: ' + logon_server_loc.to_s
  puts returnCode

  username = 0
  memoryCopy.call(username, username_loc, 255)
  result = username.unpack('a')
  puts result.to_s
ensure
  bufferFree.call(buf)
  bufferFree.call(username)
end

I am getting the following output:
username: 287528
logon_domain: 538976288
oth_domains: 538976288
logon_server: 538976288
0
c:/program files/ruby/lib/ruby/1.8/dl/win32.rb:20:in `call': 2
arguments are needed (ArgumentError)
        from c:/program files/ruby/lib/ruby/1.8/dl/win32.rb:20:in
`call'
        from test.rb:20

It's strange that I get this error, because the RtlMoveMemory function
calls for three argements.

Awesome!! Thanks Craig.