GetLocalTime (kernel32.dll) Help

I have the following WS setup:

       01 SYSTEMTIME.
           05 WS-YEAR          PIC  9(4)  USAGE IS COMP-N.
           05 WS-MONTH         PIC  9(4)  USAGE IS COMP-N.
           05 WS-DOW           PIC  9(4)  USAGE IS COMP-N.
           05 WS-DAY           PIC  9(4)  USAGE IS COMP-N.
           05 WS-HOUR          PIC  9(4)  USAGE IS COMP-N.
           05 WS-MINUTE        PIC  9(4)  USAGE IS COMP-N.
           05 WS-SECOND        PIC  9(4)  USAGE IS COMP-N.
           05 WS-MILLISECOND   PIC  9(4)  USAGE IS COMP-N.

and the following Code:

       SET-REFRESH-TIME.
           INITIALIZE SYSTEMTIME.
           SET ENVIRONMENT "DLL-CONVENTION" TO 1.
           CALL "@[DISPLAY]:kernel32.dll".
           CALL "@[DISPLAY]:GetLocalTime" USING
                BY REFERENCE SYSTEMTIME.
           CANCEL "@[DISPLAY]:GetLocalTime".
           CANCEL "@[DISPLAY]:kernel32.dll".

The above logic works perfect in getting me the local machine time when run locally (without @[DISPLAY}:) logic.   Once I add that and compile to the server and run the logic via Thin-Client I get incorrect/strange values.

Does anyone have a clue why the above logic will not work when called using Thin-Client?

  • I believe it is a PATH issue, as the Thin client will only search the local directory for resources.

    The file path for a called DLL is relative to the directory that contains "acuthin.exe". For example, if "acuthin.exe" is located in C:\Program Files\Micro Focus\Acucbl9xx\AcuGT\bin, then the following call:

    CALL "@[DISPLAY]:MYAPP\MYLIB.DLL"

    refers to C:\Program Files\Micro Focus\Acucbl9xx\AcuGT\bin\MYAPP\MYLIB.DLL. Note that the CALL statement ignores CODE_PREFIX when it searches for DLLs on the client. CODE_PREFIX is applied only to actions on the application host.

  • So are you saying I need the full path to the kernel32.dll listed in the CALL?

    CALL "@[DISPLAY}:C:\Windows\System32\kernel32.dll".

    I tried this also with no luck.

  • When I run your original program through thin client, I placed a monitor on ws-year and it change when initialized and when the call occurred

  • I did this with the object file running on a Linux box and the thin client returned the client values.

  • When I attempt this original program the below is what I get...

               INITIALIZE SYSTEMTIME.
               SET ENVIRONMENT "DLL-CONVENTION" TO 1.
               CALL "@[DISPLAY]:kernel32.dll".
               CALL "@[DISPLAY]:GetLocalTime" USING
                    BY REFERENCE SYSTEMTIME.
               CANCEL "@[DISPLAY]:GetLocalTime".
               CANCEL "@[DISPLAY]:kernel32.dll".  
               DISPLAY MESSAGE BOX
                  WS-YEAR
                  "/"
                  WS-MONTH
                  "/"
                  WS-DAY-X
                  " - "
                  WS-HOUR
                  ":"
                  WS-MINUTE.

    YEAR = 56583

    MONTH = 1792

    DAY = 256

    HOUR = 3072

    MINUTE = 6912

    I am running this on AIX Unix called via Thin-Client to a Win7 machine...v 6.2 of Extend.

    Thanks for the help...I am not sure that the difference is an why this will not work correctly for me.

  • When I attempt this original program the below is what I get...

               INITIALIZE SYSTEMTIME.
               SET ENVIRONMENT "DLL-CONVENTION" TO 1.
               CALL "@[DISPLAY]:kernel32.dll".
               CALL "@[DISPLAY]:GetLocalTime" USING
                    BY REFERENCE SYSTEMTIME.
               CANCEL "@[DISPLAY]:GetLocalTime".
               CANCEL "@[DISPLAY]:kernel32.dll".  
               DISPLAY MESSAGE BOX
                  WS-YEAR
                  "/"
                  WS-MONTH
                  "/"
                  WS-DAY-X
                  " - "
                  WS-HOUR
                  ":"
                  WS-MINUTE.

    YEAR = 56583

    MONTH = 1792

    DAY = 256

    HOUR = 3072

    MINUTE = 6912

    I am running this on AIX Unix called via Thin-Client to a Win7 machine...v 6.2 of Extend.

    Thanks for the help...I am not sure that the difference is an why this will not work correctly for me.

  • I'm unsure when the @[DISPLAY] syntax was made available. I tested with a current version.

  • I compiled with -c61 and -z61 and was still able to execute your code ... no idea why we are seeing differences.

  • If you use one of the current versions (9.1 or 9.2) it will work as expected.  Version 6.2 is not supported on Windows 7.

  • Verified Answer

    This is a byte-ordering issue.  The call to GetLocalTime sets the elementary parameters in the so-called "little-endian" byte order, which is the native ordering for Windows running on an Intel cpu.  When the code is run locally on Windows, or remotely (via Thin Client) on a Linux system, the result is interpreted correctly as both Windows and Linux are running on the "little-endian" Intel architecture (x86 or x64).

    When you run it via Thin Client from an AIX host, the result is mis-interpreted because the AIX system (on a PowerPC or its descendants) uses the "big-endian" architecture.

    I'm not sure if there's a more elegant way to deal with this, but here's a somewhat low-level, brute-force method:

    First, determine if you're on a Big-Endian machine:

           01 double-byte          pic x(2) comp-n.
           01 redefines double-byte.
               03 double-byte-b1   pic x comp-x.
               03 double-byte-b2   pic x comp-x.
    ...
               move 1 to double-byte
               if double-byte-b1 = 1
                   continue            *> it's a Little-Endian system
               else
                   perform swap-bytes
               end-if                  *> it's a Big-Endian system
    

    Then, if it's Big-Endian, swap the bytes:

          *  modified SYSTEMTIME structure with some redefines
          *  so we can address individual bytes
          *
           01 SYSTEMTIME.
               05 WS-YEAR               PIC  9(4)  USAGE IS COMP-N.
               05 redefines ws-year.
                   10 ws-year-b1        pic  x     usage is comp-x.
                   10 ws-year-b2        pic  x     usage is comp-x.
               05 WS-MONTH              PIC  9(4)  USAGE IS COMP-N.
               05 redefines ws-month.
                   10 ws-month-b1       pic  x     usage is comp-x.
                   10 ws-month-b2       pic  x     usage is comp-x.
          * ... and so on...
    
          *  add a tmp-byte variable
           01 tmp-byte                  pic  x     usage is comp-x.
    
    
    ...
          * swap the bytes in each element in the SYSTEMTIME structure
    
           swap-bytes.
               move ws-year-b1      to tmp-byte
               move ws-year-b2      to ws-year-b1
               move tmp-byte        to ws-year-b2
    
               move ws-month-b1      to tmp-byte
               move ws-month-b2      to ws-month-b1
               move tmp-byte         to ws-month-b2
    
          *  ... and so on ...