Forums › Forums › SIMPOL Programming › Getting user name
- This topic has 6 replies, 2 voices, and was last updated 14 years, 4 months ago by Jim Locker.
- AuthorPosts
- December 29, 2009 at 12:10 am #134Jim LockerMember
Is there an equivalent of the USERNAME command in SBL? If so, I havent’ found it. Don’t want to directly invoke the Windows API unless I have to because that would force me to deal with various OS’s on a per-OS basis.
December 29, 2009 at 3:30 pm #1686MichaelKeymasterJim wrote:
> Is there an equivalent of the USERNAME command in SBL? If so, I
> havent' found it.
>
> Don't want to directly invoke the Windows API unless I have to
> because that would force me to deal with various OS's on a per-OS
> basis.Currently there is no equivalent. On Windows it was implemented in a
very roundabout fashion as I recall (in fact I think I tweaked this code
at some point), because it has lots of conditions, like getting the user
name, but if you can't get that, get the machine name, allow the
machine= in the ini to override this value, and if there is an
environment variable called MACHINE use that unless overridden by the
ini file.I haven't needed this until now, but would probably add it to a library.
Which one is a good question. It isn't really part of filesyslib.sml,
nor is it appropriate to uisyshelp.sml. It may be worth adding a
netinfo.sml library for this sort of info. It would then have to detect
OS and do different things on each.Ciao, Neil
December 30, 2009 at 9:14 am #1828Jim LockerMemberWell, I'm afraid I am going to need that capability.
My package has a username/password function, and the security system will
break unless at least one user is defined to the system – even if the
security system is completely disabled. If no user is defined the first
time the program is run after installation, the security system will be
permanently disabled and everyone will be locked out of it.I have handled that historically by using USERNAME to get the logged in
user and assigning that name as the default user the first time the
program was run, with a default password that also was USERNAME, unless
the user set up the security system and did other things.This has kept me out of trouble, but if I can't get the username, I'm
going to have to come up with some other mechanism.December 30, 2009 at 4:15 pm #1625MichaelKeymasterJim wrote:
> Well, I'm afraid I am going to need that capability.
>
> My package has a username/password function, and the security system
> will break unless at least one user is defined to the system – even
> if the security system is completely disabled. If no user is defined
> the first time the program is run after installation, the security
> system will be permanently disabled and everyone will be locked out
> of it.
>
> I have handled that historically by using USERNAME to get the logged
> in user and assigning that name as the default user the first time
> the program was run, with a default password that also was USERNAME,
> unless the user set up the security system and did other things.
>
> This has kept me out of trouble, but if I can't get the username, I'm
> going to have to come up with some other mechanism.
>Getting user name isn't that hard, just depends on what you want to
support. You could probably get away with a single call nowadays.http://msdn.microsoft.com/en-us/library/ms724432%28VS.85%29.aspx
This is currently the only function in the new netinfolib.sml that I
created today. I have a minimal test program that works a treat. It
requires the SLIB component and the include directory where the standard
include files are located.// netinfolib.sma
include "errors.sma"
// BOOL WINAPI GetUserName(
// __out LPTSTR lpBuffer,
// __inout LPDWORD lpnSize
// );function getusername(integer error) export
string username
sharedlibrary advapi32
sharedlibraryfunction GetUserName
integer e, bufsizee = 0
advapi32 =@ sharedlibrary.new("ADVAPI32.DLL", error=e)
if advapi32 =@= .nul
error = e
else
GetUserName =@ advapi32.findfunction("GetUserNameW", "GetUserName",
returntype="s32", parameters="p[+t16(128)]p[+s32]", error=e)
if GetUserName =@= .nul
error = e
else
bufsize = 128
username = ' ' * bufsize
e = GetUserName.call(username, bufsize)
if e == 0
error = iERR_STRINGTOOLONG
end if
end if
end if
end function usernameCiao, Neil
December 30, 2009 at 8:42 pm #1829Jim LockerMemberThanks for that, though it does bring up another thing which I probably
should post in a different thread.!execute vs shellexecute.
I tried the !execute function to run the Windows start command, and it
failed with an error number I couldn't track down (200000002 or some
such). I replaced my !execute("start…) with the shellexecute function
you built, and that is doing what I want.Problem is, of course, that now I am directly hitting the Windows API
which will cause problems using this with Linux and with Mac, etc. This
is the same issue as will appear when I deploy this username function you
wrote.I am not sure how much I should worry about that; when I start talking to
spreadsheets and word processors, the interface will be system dependent –
I see no easy way around that – so maybe just having platform-dependent
sections is what I need to do.However, I do wonder why !execute failed. Also, what is the
best/recommended way to have the executable get the OS it is running on?
This pretty much has to be built into simpol since every system is
different. In Linux, for instance, the command "uname" returns "Linux".
In Windows, there is an API call that I don't remember right now. Surely
Mac will have its own way (though uname might work there too).There must be a system independent way to find out, otherwise it will be
necessary to compile the program differently for every supported system.I've actually been thinking that perhaps the easiest way to do the
interface to outside programs is to write a system-independent simpol
interface using sockets, then write C userspace handlers for each OS to
handle the details, talking to simpol on one side and to the specific
program on the other side. That would only be useful, though, if I can
invoke those handlers in an OS-agnostic way.December 31, 2009 at 12:03 pm #1394MichaelKeymasterJim wrote:
> Thanks for that, though it does bring up another thing which I
> probably should post in a different thread.
>
> !execute vs shellexecute.
>
> I tried the !execute function to run the Windows start command, and
> it failed with an error number I couldn't track down (200000002 or
> some such). I replaced my !execute("start…) with the shellexecute
> function you built, and that is doing what I want.Any error starting with 2000000 is a system error. As I recall, error 2
is file not found. It may have been a path problem. If you have access
to winerror.h, any windows level error starting with 2000000 can be
found in there, by looking up whatever the error is after subtracting
2000000 from it.> Problem is, of course, that now I am directly hitting the Windows API
> which will cause problems using this with Linux and with Mac, etc.
> This is the same issue as will appear when I deploy this username
> function you wrote.The user name function can use uisyshelp.sml to detect OS, and then use
appropriate functions to get the user name. I only implemented the
Windows version at this point. If you look in the source of
uisyshelp.sml (projectslibs directory), you will see that the code does
some of that itself to implement things in various ways, depending on
the OS.> I am not sure how much I should worry about that; when I start
> talking to spreadsheets and word processors, the interface will be
> system dependent – I see no easy way around that – so maybe just
> having platform-dependent sections is what I need to do.I have enhanced the library. It now looks like this:
> However, I do wonder why !execute failed. Also, what is the
> best/recommended way to have the executable get the OS it is running
> on? This pretty much has to be built into simpol since every system
> is different. In Linux, for instance, the command "uname" returns
> "Linux". In Windows, there is an API call that I don't remember right
> now. Surely Mac will have its own way (though uname might work there
> too).At the moment, I tend to only detect if I am running Windows. Most
things work the same in Linux and on OS-X, certainly in the area of
libc-style calls.> There must be a system independent way to find out, otherwise it will
> be necessary to compile the program differently for every supported
> system.See the updated version of the code I sent before:
constant LIBRARYNAME "libglib-2.0.so"
// This one is for testing the POSIX calls on Windows
constant LIBCYGWIN "c:cygwinbincygwin1.dll"
constant USECYGWIN .falseinclude "errors.sma"
// BOOL WINAPI GetUserName(
// __out LPTSTR lpBuffer,
// __inout LPDWORD lpnSize
// );function getusername(integer error) export
string usernameif nil_iswindows_os()
username = getusername_win32(error)
else
username = getusername_posix(error)
end if
end function usernamefunction getusername_win32(integer error) export
string username
sharedlibrary advapi32
sharedlibraryfunction GetUserName
integer e, bufsizee = 0
advapi32 =@ sharedlibrary.new("ADVAPI32.DLL", error=e)
if advapi32 =@= .nul
error = e
else
GetUserName =@ advapi32.findfunction("GetUserNameW", "GetUserName",
returntype="s32", parameters="p[+t16(128)]p[+s32]", error=e)
if GetUserName =@= .nul
error = e
else
bufsize = 128
username = ' ' * bufsize
e = GetUserName.call(username, bufsize)
if e == 0
error = iERR_STRINGTOOLONG
end if
end if
end if
end function usernameconstant DEFBUFSIZE 100
function getusername_posix(integer error) export
string username
sharedlibrary glibc
sharedlibraryfunction getenv, strcpy, strlen
integer e, penvstring, bufsizee = 0
if nil_iswindows_os()
glibc =@ sharedlibrary.new(LIBCYGWIN, error=e)
else
glibc =@ sharedlibrary.new(LIBRARYNAME, error=e)
end ifif glibc =@= .nul
error = e
else
getenv =@ glibc.findfunction("getenv", "getenv", returntype="up",
parameters="pt8(" + .tostr(DEFBUFSIZE, 10) + ")", error=e)
if getenv =@= .nul
error = e
else
strcpy =@ glibc.findfunction("strcpy", "strcpy", returntype="up",
parameters="+pt8(" + .tostr(DEFBUFSIZE, 10) + ")up", error=e)
if strcpy =@= .nul
error = e
else
strlen =@ glibc.findfunction("strlen", "strlen",
returntype="u32", parameters="up", error=e)
if strlen =@= .nul
error = e
else
penvstring = getenv.call("LOGNAME")
if penvstring == 0
penvstring = getenv.call("USER")
if penvstring == 0
// This is for Windows
penvstring = getenv.call("USERNAME")
end if
end ifif penvstring == 0
error = iERR_DATANOTFOUND
else
bufsize = strlen.call(penvstring)
if bufsize < DEFBUFSIZE
username = bufsize * ' '
e = strcpy.call(username, penvstring)
end if
end if
end if
end if
end if
end if
end function usernamefunction nil_iswindows_os() information "[simpol::return::boolean]"
UTOSdirectory cd
integer e
boolean retvale = 0
cd =@ UTOSdirectory.new(".", error=e)
if .lstr(cd, 1) != "/"
retval = .true
else
retval = .false
end if
end function retvalThe final function is a copy of the one in uisyslib.sml, but I chose to
copy it and give it a local name (and not export it), since adding
uisyslib.sml would also require wxWidgets, which shouldn't be necessary
for this library. It does now require UTOS as well as SLIB though.> I've actually been thinking that perhaps the easiest way to do the
> interface to outside programs is to write a system-independent simpol
> interface using sockets, then write C userspace handlers for each OS
> to handle the details, talking to simpol on one side and to the
> specific program on the other side. That would only be useful,
> though, if I can invoke those handlers in an OS-agnostic way.A lot depends on what you need to call, of course, but the sockets stuff
is all system-agnostic.Ciao, Neil
January 2, 2010 at 12:22 am #1830Jim LockerMemberNeil Robinson wrote:
> Jim wrote:
>> Thanks for that, though it does bring up another thing which I
>> probably should post in a different thread.
>>
>> !execute vs shellexecute.
>>
>> I tried the !execute function to run the Windows start command, and
>> it failed with an error number I couldn't track down (200000002 or
>> some such). I replaced my !execute("start…) with the shellexecute
>> function you built, and that is doing what I want.> Any error starting with 2000000 is a system error. As I recall, error 2
> is file not found. It may have been a path problem. If you have access
> to winerror.h, any windows level error starting with 2000000 can be
> found in there, by looking up whatever the error is after subtracting
> 2000000 from it.I had pretty much concluded it was a system error, but I didn't recognize
it. I do have Visual Studio here, and sometimes I even use it when I am
forced to (usually for C# which a client wants). For C or C++, I always
try to use the gcc toolkit.>> Problem is, of course, that now I am directly hitting the Windows API
>> which will cause problems using this with Linux and with Mac, etc.
>> This is the same issue as will appear when I deploy this username
>> function you wrote.> The user name function can use uisyshelp.sml to detect OS, and then use
> appropriate functions to get the user name. I only implemented the
> Windows version at this point. If you look in the source of
> uisyshelp.sml (projectslibs directory), you will see that the code does
> some of that itself to implement things in various ways, depending on
> the OS.I will look at that more closely.
>> I am not sure how much I should worry about that; when I start
>> talking to spreadsheets and word processors, the interface will be
>> system dependent – I see no easy way around that – so maybe just
>> having platform-dependent sections is what I need to do.> I have enhanced the library. It now looks like this:
>> However, I do wonder why !execute failed. Also, what is the
>> best/recommended way to have the executable get the OS it is running
>> on? This pretty much has to be built into simpol since every system
>> is different. In Linux, for instance, the command "uname" returns
>> "Linux". In Windows, there is an API call that I don't remember right
>> now. Surely Mac will have its own way (though uname might work there
>> too).> At the moment, I tend to only detect if I am running Windows. Most
> things work the same in Linux and on OS-X, certainly in the area of
> libc-style calls.OK. That seems reasonable. Do it THIS way except on Windows…
>> There must be a system independent way to find out, otherwise it will
>> be necessary to compile the program differently for every supported
>> system.> See the updated version of the code I sent before:
> constant LIBRARYNAME "libglib-2.0.so"
> // This one is for testing the POSIX calls on Windows
> constant LIBCYGWIN "c:cygwinbincygwin1.dll"
> constant USECYGWIN .false> include "errors.sma"
> // BOOL WINAPI GetUserName(
> // __out LPTSTR lpBuffer,
> // __inout LPDWORD lpnSize
> // );> function getusername(integer error) export
> string username> if nil_iswindows_os()
> username = getusername_win32(error)
> else
> username = getusername_posix(error)
> end if
> end function username> function getusername_win32(integer error) export
> string username
> sharedlibrary advapi32
> sharedlibraryfunction GetUserName
> integer e, bufsize> e = 0
> advapi32 =@ sharedlibrary.new("ADVAPI32.DLL", error=e)
> if advapi32 =@= .nul
> error = e
> else
> GetUserName =@ advapi32.findfunction("GetUserNameW", "GetUserName",
> returntype="s32", parameters="p[+t16(128)]p[+s32]", error=e)
> if GetUserName =@= .nul
> error = e
> else
> bufsize = 128
> username = ' ' * bufsize
> e = GetUserName.call(username, bufsize)
> if e == 0
> error = iERR_STRINGTOOLONG
> end if
> end if
> end if
> end function username> constant DEFBUFSIZE 100
> function getusername_posix(integer error) export
> string username
> sharedlibrary glibc
> sharedlibraryfunction getenv, strcpy, strlen
> integer e, penvstring, bufsize> e = 0
> if nil_iswindows_os()
> glibc =@ sharedlibrary.new(LIBCYGWIN, error=e)
> else
> glibc =@ sharedlibrary.new(LIBRARYNAME, error=e)
> end if> if glibc =@= .nul
> error = e
> else
> getenv =@ glibc.findfunction("getenv", "getenv", returntype="up",
> parameters="pt8(" + .tostr(DEFBUFSIZE, 10) + ")", error=e)
> if getenv =@= .nul
> error = e
> else
> strcpy =@ glibc.findfunction("strcpy", "strcpy", returntype="up",
> parameters="+pt8(" + .tostr(DEFBUFSIZE, 10) + ")up", error=e)
> if strcpy =@= .nul
> error = e
> else
> strlen =@ glibc.findfunction("strlen", "strlen",
> returntype="u32", parameters="up", error=e)
> if strlen =@= .nul
> error = e
> else
> penvstring = getenv.call("LOGNAME")
> if penvstring == 0
> penvstring = getenv.call("USER")
> if penvstring == 0
> // This is for Windows
> penvstring = getenv.call("USERNAME")
> end if
> end if> if penvstring == 0
> error = iERR_DATANOTFOUND
> else
> bufsize = strlen.call(penvstring)
> if bufsize < DEFBUFSIZE
> username = bufsize * ' '
> e = strcpy.call(username, penvstring)
> end if
> end if
> end if
> end if
> end if
> end if
> end function username> function nil_iswindows_os() information "[simpol::return::boolean]"
> UTOSdirectory cd
> integer e
> boolean retval> e = 0
> cd =@ UTOSdirectory.new(".", error=e)
> if .lstr(cd, 1) != "/"
> retval = .true
> else
> retval = .false
> end if
> end function retval> The final function is a copy of the one in uisyslib.sml, but I chose to
> copy it and give it a local name (and not export it), since adding
> uisyslib.sml would also require wxWidgets, which shouldn't be necessary
> for this library. It does now require UTOS as well as SLIB though.>> I've actually been thinking that perhaps the easiest way to do the
>> interface to outside programs is to write a system-independent simpol
>> interface using sockets, then write C userspace handlers for each OS
>> to handle the details, talking to simpol on one side and to the
>> specific program on the other side. That would only be useful,
>> though, if I can invoke those handlers in an OS-agnostic way.> A lot depends on what you need to call, of course, but the sockets stuff
> is all system-agnostic.Sure, that is why I would use sockets. But Windows uses OLE (activeX) or
DDE while any *nix uses named pipes, shared memory, and sockets. Talking
to Open Office will be very different than talking to Microsoft Office.
By making a socket-based interface to outside drivers, I can keep all
those differences out of the simpol program, so long as I can invoke those
outside drivers in an OS agnostic way, that is. - AuthorPosts
- You must be logged in to reply to this topic.