Skip to content

Getting user name

Forums Forums SIMPOL Programming Getting user name

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #134
    Jim Locker
    Member

    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.

    #1686
    Michael
    Keymaster

    Jim 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

    #1828
    Jim Locker
    Member

    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.

    #1625
    Michael
    Keymaster

    Jim 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, 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

    Ciao, Neil

    #1829
    Jim Locker
    Member

    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.

    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.

    #1394
    Michael
    Keymaster

    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.

    > 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 .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.

    Ciao, Neil

    #1830
    Jim Locker
    Member

    Neil 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.

Viewing 7 posts - 1 through 7 (of 7 total)
  • You must be logged in to reply to this topic.