Getting username under windows
[1/17] from: th72:dds:nl at: 18-Mar-2007 22:49
Hi List,
I'am trying to get the the current username under windows. After a
little searching I found the the following api call:
BOOL GetUserName(
LPTSTR lpBuffer,
LPDWORD lpnSize
);
In REBOL I tried the following:
lib: load/library %advapi32.dll ; no error
user: make routine! [arg1 [string!] agr2 [integer!] return:
[integer!]] lib "GetUserNameA" ; no error
name: make string! 1000
buffersize: 1000
user name buffersize ; crashes rebol
After hitting <enter> rebol crashes. I tried different values for name
and buffersize. I tried arg2 as string! type. Rebol then stops
crashing but no name or anything else is returnt.
Can someone give me a hint on what I 'am doing wrong? Or maybe is
there some other way to get the current user who is logged in?
Thanks Tim
I have included the official MS info:
Parameters
lpBuffer
[out] A pointer to the buffer to receive the user's logon name.
If this buffer is not large enough to contain the entire user name,
the function fails. A buffer size of (UNLEN + 1) characters will hold
the maximum length user name including the terminating null character.
UNLEN is defined in Lmcons.h.
lpnSize
[in, out] On input, this variable specifies the size of the
lpBuffer buffer, in TCHARs. On output, the variable receives the
number of TCHARs copied to the buffer, including the terminating null
character.
If lpBuffer is too small, the function fails and GetLastError
returns ERROR_INSUFFICIENT_BUFFER. This parameter receives the
required buffer size, including the terminating null character.
If this parameter is greater than 32767, the function fails and
GetLastError returns ERROR_INSUFFICIENT_BUFFER.
Return Value
If the function succeeds, the return value is a nonzero value, and the
variable pointed to by lpnSize contains the number of TCHARs copied to
the buffer specified by lpBuffer, including the terminating null
character.
[2/17] from: chris-ross:gill at: 18-Mar-2007 17:02
> I'am trying to get the the current username under windows.
This works under general conditions:
get-env "USERNAME"
- Chris
[3/17] from: moliad::gmail at: 18-Mar-2007 17:38
here is full working code... I have this library in use in apps and its
fully functional:
the first line was to implement different implementations based on os, but I
never got to it, by lack of need so far.
hope this helps!
-MAx
;-----------------------
rebol []
isWin?: (system/version/4 = 3)
;- OS LIBS
libsysinfo*: context [
libinfo: make library! switch system/version/4 [
; other OSes will have to be filled in by other REBOLERS, as I have
absolutely no idea.
3 [%Advapi32]
]
username: make routine! [
"Get the current logon name of thread which launched REBOL"
buffer [char*]
count [string!]
return: [integer!]
] libinfo "GetUserNameA"
]
;-
;- REBOL ACCESSORS
;- username
username: func [/local buffer count][
buffer: head insert/dup copy "" #"^-" 100 ; this should cover any
username!
;buffer: copy "..............................."
count: third make struct! [val [integer!]] [100]
unless isWin? [to-error "username only implemented for windows at this
point"]
either 0 < libsysinfo*/username buffer count [
return copy/part buffer (to-integer reverse count) - 1
][
to-error "no username or invalid username"
]
none
]
probe username
ask "..."
;--------------------------------
On 3/18/07, th72-dds.nl <th72-dds.nl> wrote:
[4/17] from: moliad::gmail::com at: 18-Mar-2007 17:39
hi,
its also a huge security hole, and is used much to often by many (non
rebolers).
-MAx
On 3/18/07, Christopher Ross-Gill <chris-ross-gill.com> wrote:
[5/17] from: chris-ross:gill at: 18-Mar-2007 19:26
> its also a huge security hole, and is used much to often by many (non
> rebolers).
Seems to work on other platforms, eg. OS X:
get-env "USER"
- Chris
[6/17] from: pwawood::gmail::com at: 19-Mar-2007 10:06
Chris
I think that MAx is pointing out that it is very easy for somebody to
fake the user name using the environment variable.
Regards
Peter
[7/17] from: gabriele:colellachiara at: 19-Mar-2007 10:05
Hi Tim,
On Sunday, March 18, 2007, 10:49:15 PM, you wrote:
tdn> user: make routine! [arg1 [string!] agr2 [integer!] return:
tdn> [integer!]] lib "GetUserNameA" ; no error
The problem is that the second argument should be a pointer to a
integer, not an integer. Just create a struct with an integer in
it and pass it to the function.
Regards,
Gabriele.
--
Gabriele Santilli <gabriele-rebol.com> --- http://www.rebol.com/
Colella Chiara software division --- http://www.colellachiara.com/
[8/17] from: th72:dds:nl at: 19-Mar-2007 14:08
Hi all,
Thanks for the positive feedback from you all. This is great! Tonight
I'am going to try all your suggestions. Thanks!
Tim
Quoting th72-dds.nl:
[9/17] from: moliad::gmail::com at: 19-Mar-2007 8:50
peter,
exactly, its even worse, when techie users know they can hide this within a
script.
in medium-large shops, sometimes its nice to automate the user procedure,
not for explicit login purposes, but for simple tracking of who did what.
in such circumstances, these often become logs and unfortunately they get
used for many purposes... including HR and other depts.
if/when any one in the shop gets to understand that an env var allows him to
ghost his user or act on someone else's behalf... you've got very touchy
consequences... and if its ever understood that the software allowed someone
to get wrongfully accused of something (or worse)... well that person (and
admins) can look to the author, for the focus of his anger (for allowing
this to happen).
obviously depends on work environment, but any nice environment can become
political nightmare in an instant, with but the change of one manager in the
corporate ladder.
-MAx
On 3/18/07, Peter Wood <pwawood-gmail.com> wrote:
[10/17] from: gregg:irwin:gmai:l at: 19-Mar-2007 10:22
Just getting back on the ML after being unsubscribed (it seems).
Wil; this work for you?
--Gregg
REBOL [
file: %WNetGetUser.r
Author: "Gregg Irwin"
EMail: greggirwin-acm.org
]
win-lib: load/library %mpr.dll
integer-struct: make struct! [
value [integer!]
] none
null-buff: func [
{Returns a null-filled string buffer of the specified length.}
len [integer!]
][
head insert/dup make string! len #"^-" len
]
WNetGetUser: make routine! compose/deep [
lpName [integer!] ; change to string if you need to use device name
lpUserName [string!]
lpLength [struct! [(first integer-struct)]]
return: [integer!]
] win-lib "WNetGetUserA"
rtn-name: null-buff 256
; If you wanted to find out exactly how much space you need first,
; you can all with a length of 0 and it will return the amount
; of space you need in the lpLength parameter.
len: make struct! integer-struct reduce [0]
print ["res: " res: WNetGetUser 0 rtn-name len]
print ["len: " len/value]
print ""
len: make struct! integer-struct reduce [length? rtn-name]
print ["res: " res: WNetGetUser 0 rtn-name len]
print ["name: " rtn-name]
print ""
free win-lib
halt
[11/17] from: th72:dds:nl at: 19-Mar-2007 21:57
Hi Greg and others,
Yes this wil work! I try to understand it. Never heard of integer-struct.
What does this mean:
lpLength [struct! [(first integer-struct)]]
Sometimes Rebol leaves me in great mysteries :-)
Tim
Quoting Gregg Irwin <gregg.irwin-gmail.com>:
[12/17] from: th72:dds:nl at: 19-Mar-2007 22:06
Hi List,
get-env "USERNAME" also works here. Yet another rebol-word I learned
today. For my purpose this seems good enough. The external library
interface is still a little bit of a mystery to me. I need some more
practice on it.
Thanks for al the help.
Tim
Quoting th72-dds.nl:
[13/17] from: gregg:irwin::gmail at: 19-Mar-2007 15:56
Hi Tim,
tdn> Yes this wil work! I try to understand it. Never heard of integer-struct.
It's just a struct with one int element in it.
tdn> What does this mean:
tdn> lpLength [struct! [(first integer-struct)]]
Using structs with routines is a bit of a pain. What this does is
define a struct as the param for the routine, and you need to provide
the struct spec when you do that, which is what FIRST does.
>> integer-struct: make struct! [val [integer!]] none
>> first integer-struct
== [val [integer!]]
GET-ENV is much easier though. For some reason I thought that wasn't
in all releases anymore, like the *-REG funcs.
--Gregg
[14/17] from: moliad::gmail::com at: 19-Mar-2007 17:12
hi tim,
btw, on my machine (WinXP) for some reason, the username var was not setup
correctly, when I first tried using the get-env trick.
maybe some software install or whatever.. so Tim, be carefull that you are
sure all your users have the username env when you do the install on other
people's machines.
-MAx
On 3/19/07, Gregg Irwin <gregg.irwin-gmail.com> wrote:
[15/17] from: anton::wilddsl::net::au at: 20-Mar-2007 10:09
To explain what the following means...
> integer-struct: make struct! [
> value [integer!]
> ] none
> WNetGetUser: make routine! compose/deep [
> lpLength [struct! [(first integer-struct)]]
> ] win-lib "WNetGetUserA"
If you type this in the rebol console:
integer-struct: make struct! [value [integer!]] none
first integer-struct
The result is:
== [value [integer!]]
It is the spec block of INTEGER-STRUCT that we just defined.
Now this:
compose/deep [
lpLength [struct! [(first integer-struct)]]
]
COMPOSE/DEEP finds parens at any level of nesting, so the
result is:
== [
lpLength [struct! [value [integer!]]]
]
The INTEGER-STRUCT spec has been composed into the routine spec,
ready to be made into a routine.
It's just a way of reusing structure definitions. In this case,
it didn't save us much, but a structs can have a very long spec,
so then it would save us many lines of code each time it is
referenced.
Regards,
Anton.
[16/17] from: th72:dds:nl at: 20-Mar-2007 9:43
Hi Maxim,
Thanks for the "warning". I tested it also on a XP machine and it's
working fine here. I'll keep it in mind.
Tim
Quoting Maxim Olivier-Adlhoch <moliad-gmail.com>:
[17/17] from: th72::dds::nl at: 20-Mar-2007 9:52
Hi Anton and others,
Thanks for the explanation.
I tried it to understand it in the same way. The problem was that I
could't find a explanation of doing:
first integer-struct.
I now understand that this is simply some lazy (and smart) way to
reduce some typing.
Thanks Tim
Quoting Anton Rolls <anton-wilddsl.net.au>: