Welcome Serena Central users! CLICK HERE
The migration of the Serena Central community is currently underway. Be sure to read THIS MESSAGE to get your new login set up to access your account.
kthomp24 Absent Member.
Absent Member.
3645 views

GetLocalTime (kernel32.dll) Help

Jump to solution

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?

0 Likes
1 Solution

Accepted Solutions
Chuck Edgin Absent Member.
Absent Member.

RE: GetLocalTime (kernel32.dll) Help

Jump to solution

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

View solution in original post

0 Likes
9 Replies
Micro Focus Expert
Micro Focus Expert

RE: GetLocalTime (kernel32.dll) Help

Jump to solution

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.

0 Likes
kthomp24 Absent Member.
Absent Member.

RE: GetLocalTime (kernel32.dll) Help

Jump to solution

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.

0 Likes
Micro Focus Expert
Micro Focus Expert

RE: GetLocalTime (kernel32.dll) Help

Jump to solution

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

0 Likes
Micro Focus Expert
Micro Focus Expert

RE: GetLocalTime (kernel32.dll) Help

Jump to solution

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

0 Likes
kthomp24 Absent Member.
Absent Member.

RE: GetLocalTime (kernel32.dll) Help

Jump to solution

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.

0 Likes
Micro Focus Expert
Micro Focus Expert

RE: GetLocalTime (kernel32.dll) Help

Jump to solution

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

0 Likes
Micro Focus Expert
Micro Focus Expert

RE: GetLocalTime (kernel32.dll) Help

Jump to solution

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

0 Likes
DougP Outstanding Contributor.
Outstanding Contributor.

RE: GetLocalTime (kernel32.dll) Help

Jump to solution

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.

0 Likes
Chuck Edgin Absent Member.
Absent Member.

RE: GetLocalTime (kernel32.dll) Help

Jump to solution

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

View solution in original post

0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.