Skip to main content

[archive] UUID Api Call

  • January 18, 2010
  • 11 replies
  • 0 views

[Migrated content. Thread originally posted on 15 January 2010]

I'm trying to work out how to create a UUID from the windows API and I can't figure out the logic in cobol for how to do it. Can anyone maybe help me with the conversion from this C code?



typedef struct _GUID {
  unsigned long  Data1;
  unsigned short Data2;
  unsigned short Data3;
  unsigned char  Data4[8];
} GUID, UUID;

****UuidCreateSequential Function****

RPC_STATUS RPC_ENTRY UuidCreateSequential(
    UUID __RPC_FAR *Uuid
);


****UuidToString Function****

RPC_STATUS RPC_ENTRY UuidToString(
    UUID __RPC_FAR *Uuid ,
    unsigned char __RPC_FAR * __RPC_FAR *StringUuid
);

11 replies

[Migrated content. Thread originally posted on 15 January 2010]

I'm trying to work out how to create a UUID from the windows API and I can't figure out the logic in cobol for how to do it. Can anyone maybe help me with the conversion from this C code?



typedef struct _GUID {
  unsigned long  Data1;
  unsigned short Data2;
  unsigned short Data3;
  unsigned char  Data4[8];
} GUID, UUID;

****UuidCreateSequential Function****

RPC_STATUS RPC_ENTRY UuidCreateSequential(
    UUID __RPC_FAR *Uuid
);


****UuidToString Function****

RPC_STATUS RPC_ENTRY UuidToString(
    UUID __RPC_FAR *Uuid ,
    unsigned char __RPC_FAR * __RPC_FAR *StringUuid
);

Assuming this to be Win32, I would translate this into:

WORKING-STORAGE SECTION.
01 GUID.
     03 DATA1 PIC X(4) COMP-N.
     03 DATA2 PIC X(2) COMP-N.
     03 DATA3 PIC X(2) COMP-N.
     03 DATA4 PIC X(8).
01 STRING-UUID PIC X(4) COMP-N.
...
PROCEDURE DIVISION.
MAIN SECTION.
| Populate GUID with adequate values
CALL "UuidToStringA" USING
   BY REFERENCE GUID
   BY REFERENCE STRING-UUID
| STRING-UUID is a pointer and will now have the address of a null terminated string.
| I will leave that operation as  a challenge to you on how to copy to a
| COBOL working storage item.

[Migrated content. Thread originally posted on 15 January 2010]

I'm trying to work out how to create a UUID from the windows API and I can't figure out the logic in cobol for how to do it. Can anyone maybe help me with the conversion from this C code?



typedef struct _GUID {
  unsigned long  Data1;
  unsigned short Data2;
  unsigned short Data3;
  unsigned char  Data4[8];
} GUID, UUID;

****UuidCreateSequential Function****

RPC_STATUS RPC_ENTRY UuidCreateSequential(
    UUID __RPC_FAR *Uuid
);


****UuidToString Function****

RPC_STATUS RPC_ENTRY UuidToString(
    UUID __RPC_FAR *Uuid ,
    unsigned char __RPC_FAR * __RPC_FAR *StringUuid
);

Thanks for your input, always so helpful when it comes to the windows API :-)

Here is the completed code that seems to function properly.


       01 WS-GUID.
           03 WS-DATA1 PIC X(4) COMP-N. 
           03 WS-DATA2 PIC X(2) COMP-N.   
           03 WS-DATA3 PIC X(2) COMP-N.
           03 WS-DATA4 PIC X(8).   
       01 WS-UUID-STRING    PIC X(4) COMP-N.
       01 WS-MY-GUID        PIC X(36). 


           SET ENVIRONMENT "DLL_CONVENTION" TO 1.
           CALL "Rpcrt4.dll".

           CALL "UuidCreateSequential" USING
              BY REFERENCE WS-GUID.

           CALL "UuidToStringA" USING
              BY REFERENCE WS-GUID
              BY REFERENCE WS-UUID-STRING.

           CALL    "C$MEMCPY"  USING
                   BY REFERENCE   WS-MY-GUID
                   BY VALUE         WS-UUID-STRING
                   BY VALUE         36.
     
           CANCEL "Rpcrt4.dll".


On a side note, do you think we will have any trouble running this in a thin client environment using the @[DISPLAY]: on all the calls?

[Migrated content. Thread originally posted on 15 January 2010]

I'm trying to work out how to create a UUID from the windows API and I can't figure out the logic in cobol for how to do it. Can anyone maybe help me with the conversion from this C code?



typedef struct _GUID {
  unsigned long  Data1;
  unsigned short Data2;
  unsigned short Data3;
  unsigned char  Data4[8];
} GUID, UUID;

****UuidCreateSequential Function****

RPC_STATUS RPC_ENTRY UuidCreateSequential(
    UUID __RPC_FAR *Uuid
);


****UuidToString Function****

RPC_STATUS RPC_ENTRY UuidToString(
    UUID __RPC_FAR *Uuid ,
    unsigned char __RPC_FAR * __RPC_FAR *StringUuid
);

Thanks for sharing the example, would have been neat if you could tell why you use the function call, for people not familiar with the API to understand what you achieve.

It should work with TC when you apply the @[DISPLAY]: prefix.
:-)

[Migrated content. Thread originally posted on 15 January 2010]

I'm trying to work out how to create a UUID from the windows API and I can't figure out the logic in cobol for how to do it. Can anyone maybe help me with the conversion from this C code?



typedef struct _GUID {
  unsigned long  Data1;
  unsigned short Data2;
  unsigned short Data3;
  unsigned char  Data4[8];
} GUID, UUID;

****UuidCreateSequential Function****

RPC_STATUS RPC_ENTRY UuidCreateSequential(
    UUID __RPC_FAR *Uuid
);


****UuidToString Function****

RPC_STATUS RPC_ENTRY UuidToString(
    UUID __RPC_FAR *Uuid ,
    unsigned char __RPC_FAR * __RPC_FAR *StringUuid
);

Thanks for sharing the example, would have been neat if you could tell why you use the function call, for people not familiar with the API to understand what you achieve.

It should work with TC when you apply the @[DISPLAY]: prefix.
:-)

[Migrated content. Thread originally posted on 15 January 2010]

I'm trying to work out how to create a UUID from the windows API and I can't figure out the logic in cobol for how to do it. Can anyone maybe help me with the conversion from this C code?



typedef struct _GUID {
  unsigned long  Data1;
  unsigned short Data2;
  unsigned short Data3;
  unsigned char  Data4[8];
} GUID, UUID;

****UuidCreateSequential Function****

RPC_STATUS RPC_ENTRY UuidCreateSequential(
    UUID __RPC_FAR *Uuid
);


****UuidToString Function****

RPC_STATUS RPC_ENTRY UuidToString(
    UUID __RPC_FAR *Uuid ,
    unsigned char __RPC_FAR * __RPC_FAR *StringUuid
);

Thanks for sharing the example, would have been neat if you could tell why you use the function call, for people not familiar with the API to understand what you achieve.

It should work with TC when you apply the @[DISPLAY]: prefix.
:-)

[Migrated content. Thread originally posted on 15 January 2010]

I'm trying to work out how to create a UUID from the windows API and I can't figure out the logic in cobol for how to do it. Can anyone maybe help me with the conversion from this C code?



typedef struct _GUID {
  unsigned long  Data1;
  unsigned short Data2;
  unsigned short Data3;
  unsigned char  Data4[8];
} GUID, UUID;

****UuidCreateSequential Function****

RPC_STATUS RPC_ENTRY UuidCreateSequential(
    UUID __RPC_FAR *Uuid
);


****UuidToString Function****

RPC_STATUS RPC_ENTRY UuidToString(
    UUID __RPC_FAR *Uuid ,
    unsigned char __RPC_FAR * __RPC_FAR *StringUuid
);

I got around to trying this with thin client, and I found that unfortunatly the C$MEMCPY doesn't support the @[DISPLAY]: notation so this does not work under thin client (version 8.1.1)... :-(

[Migrated content. Thread originally posted on 15 January 2010]

I'm trying to work out how to create a UUID from the windows API and I can't figure out the logic in cobol for how to do it. Can anyone maybe help me with the conversion from this C code?



typedef struct _GUID {
  unsigned long  Data1;
  unsigned short Data2;
  unsigned short Data3;
  unsigned char  Data4[8];
} GUID, UUID;

****UuidCreateSequential Function****

RPC_STATUS RPC_ENTRY UuidCreateSequential(
    UUID __RPC_FAR *Uuid
);


****UuidToString Function****

RPC_STATUS RPC_ENTRY UuidToString(
    UUID __RPC_FAR *Uuid ,
    unsigned char __RPC_FAR * __RPC_FAR *StringUuid
);

There is no storage in the thin client, there are mirrors of what is on the runtime side.
Have you compiled with -Zm or can you code using WITH MEMORY SIZE?

[Migrated content. Thread originally posted on 15 January 2010]

I'm trying to work out how to create a UUID from the windows API and I can't figure out the logic in cobol for how to do it. Can anyone maybe help me with the conversion from this C code?



typedef struct _GUID {
  unsigned long  Data1;
  unsigned short Data2;
  unsigned short Data3;
  unsigned char  Data4[8];
} GUID, UUID;

****UuidCreateSequential Function****

RPC_STATUS RPC_ENTRY UuidCreateSequential(
    UUID __RPC_FAR *Uuid
);


****UuidToString Function****

RPC_STATUS RPC_ENTRY UuidToString(
    UUID __RPC_FAR *Uuid ,
    unsigned char __RPC_FAR * __RPC_FAR *StringUuid
);

I added the -Zm option to the compiler to see how it would work but I'm thinking I still need to change the code somehow to properly access the pointer when run under thin client...




       01 WS-UUID-STRUCT.
           03 WS-UUID-DATA1 PIC X(4) COMP-N.   | Hex Value
           03 WS-UUID-DATA2 PIC X(2) COMP-N.   | Hex Value
           03 WS-UUID-DATA3 PIC X(2) COMP-N.   | Hex Value
           03 WS-UUID-DATA4 PIC X(8).          | Hex Value
       01 WS-UUID-STRING    PIC X(4) COMP-N.
       01 WS-MY-GUID        PIC X(36).   
       77  FUNCTION-NAME  PIC X(50)  VALUE SPACES.

           IF IS-REMOTE
              CALL "@[DISPLAY]:Rpcrt4.dll@WINAPI"
              MOVE "@[DISPLAY]:UuidCreateSequential" TO FUNCTION-NAME
              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
              END-CALL
              MOVE "@[DISPLAY]:UuidToStringA" TO FUNCTION-NAME

*** This needs to change:
[B]              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
                   BY REFERENCE WS-UUID-STRING
              END-CALL
              CALL "C$MEMCPY" USING
                   BY REFERENCE     WS-MY-GUID
                   BY REFERENCE     WS-UUID-STRING
                   BY VALUE         36
              END-CALL  [/B]

** to something like:
[B]              MOVE NULL TO WS-UUID-STRING
              SET WS-UUID-STRING TO ADDRESS OF WS-MY-GUID
              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
                   BY VALUE WS-UUID-STRING
              END-CALL[/B]

              CANCEL "@[DISPLAY]:Rpcrt4.dll@WINAPI"
           ELSE
              CALL "Rpcrt4.dll@WINAPI"
              MOVE "UuidCreateSequential" TO FUNCTION-NAME
              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
              END-CALL
              MOVE "UuidToStringA" TO FUNCTION-NAME
              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
                   BY REFERENCE WS-UUID-STRING
              END-CALL
              CALL "C$MEMCPY" USING
                   BY REFERENCE     WS-MY-GUID
                   BY VALUE         WS-UUID-STRING
                   BY VALUE         36
              END-CALL
              CANCEL "Rpcrt4.dll@WINAPI"
           END-IF.

           DISPLAY MESSAGE BOX WS-MY-GUID
                   TITLE IS "Unique GUID"
                   ICON IS Mb-Default-Icon
                   TYPE IS MB-OK.

[Migrated content. Thread originally posted on 15 January 2010]

I'm trying to work out how to create a UUID from the windows API and I can't figure out the logic in cobol for how to do it. Can anyone maybe help me with the conversion from this C code?



typedef struct _GUID {
  unsigned long  Data1;
  unsigned short Data2;
  unsigned short Data3;
  unsigned char  Data4[8];
} GUID, UUID;

****UuidCreateSequential Function****

RPC_STATUS RPC_ENTRY UuidCreateSequential(
    UUID __RPC_FAR *Uuid
);


****UuidToString Function****

RPC_STATUS RPC_ENTRY UuidToString(
    UUID __RPC_FAR *Uuid ,
    unsigned char __RPC_FAR * __RPC_FAR *StringUuid
);

I added the -Zm option to the compiler to see how it would work but I'm thinking I still need to change the code somehow to properly access the pointer when run under thin client...




       01 WS-UUID-STRUCT.
           03 WS-UUID-DATA1 PIC X(4) COMP-N.   | Hex Value
           03 WS-UUID-DATA2 PIC X(2) COMP-N.   | Hex Value
           03 WS-UUID-DATA3 PIC X(2) COMP-N.   | Hex Value
           03 WS-UUID-DATA4 PIC X(8).          | Hex Value
       01 WS-UUID-STRING    PIC X(4) COMP-N.
       01 WS-MY-GUID        PIC X(36).   
       77  FUNCTION-NAME  PIC X(50)  VALUE SPACES.

           IF IS-REMOTE
              CALL "@[DISPLAY]:Rpcrt4.dll@WINAPI"
              MOVE "@[DISPLAY]:UuidCreateSequential" TO FUNCTION-NAME
              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
              END-CALL
              MOVE "@[DISPLAY]:UuidToStringA" TO FUNCTION-NAME

*** This needs to change:
[B]              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
                   BY REFERENCE WS-UUID-STRING
              END-CALL
              CALL "C$MEMCPY" USING
                   BY REFERENCE     WS-MY-GUID
                   BY REFERENCE     WS-UUID-STRING
                   BY VALUE         36
              END-CALL  [/B]

** to something like:
[B]              MOVE NULL TO WS-UUID-STRING
              SET WS-UUID-STRING TO ADDRESS OF WS-MY-GUID
              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
                   BY VALUE WS-UUID-STRING
              END-CALL[/B]

              CANCEL "@[DISPLAY]:Rpcrt4.dll@WINAPI"
           ELSE
              CALL "Rpcrt4.dll@WINAPI"
              MOVE "UuidCreateSequential" TO FUNCTION-NAME
              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
              END-CALL
              MOVE "UuidToStringA" TO FUNCTION-NAME
              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
                   BY REFERENCE WS-UUID-STRING
              END-CALL
              CALL "C$MEMCPY" USING
                   BY REFERENCE     WS-MY-GUID
                   BY VALUE         WS-UUID-STRING
                   BY VALUE         36
              END-CALL
              CANCEL "Rpcrt4.dll@WINAPI"
           END-IF.

           DISPLAY MESSAGE BOX WS-MY-GUID
                   TITLE IS "Unique GUID"
                   ICON IS Mb-Default-Icon
                   TYPE IS MB-OK.

[Migrated content. Thread originally posted on 15 January 2010]

I'm trying to work out how to create a UUID from the windows API and I can't figure out the logic in cobol for how to do it. Can anyone maybe help me with the conversion from this C code?



typedef struct _GUID {
  unsigned long  Data1;
  unsigned short Data2;
  unsigned short Data3;
  unsigned char  Data4[8];
} GUID, UUID;

****UuidCreateSequential Function****

RPC_STATUS RPC_ENTRY UuidCreateSequential(
    UUID __RPC_FAR *Uuid
);


****UuidToString Function****

RPC_STATUS RPC_ENTRY UuidToString(
    UUID __RPC_FAR *Uuid ,
    unsigned char __RPC_FAR * __RPC_FAR *StringUuid
);

I added the -Zm option to the compiler to see how it would work but I'm thinking I still need to change the code somehow to properly access the pointer when run under thin client...




       01 WS-UUID-STRUCT.
           03 WS-UUID-DATA1 PIC X(4) COMP-N.   | Hex Value
           03 WS-UUID-DATA2 PIC X(2) COMP-N.   | Hex Value
           03 WS-UUID-DATA3 PIC X(2) COMP-N.   | Hex Value
           03 WS-UUID-DATA4 PIC X(8).          | Hex Value
       01 WS-UUID-STRING    PIC X(4) COMP-N.
       01 WS-MY-GUID        PIC X(36).   
       77  FUNCTION-NAME  PIC X(50)  VALUE SPACES.

           IF IS-REMOTE
              CALL "@[DISPLAY]:Rpcrt4.dll@WINAPI"
              MOVE "@[DISPLAY]:UuidCreateSequential" TO FUNCTION-NAME
              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
              END-CALL
              MOVE "@[DISPLAY]:UuidToStringA" TO FUNCTION-NAME

*** This needs to change:
[B]              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
                   BY REFERENCE WS-UUID-STRING
              END-CALL
              CALL "C$MEMCPY" USING
                   BY REFERENCE     WS-MY-GUID
                   BY REFERENCE     WS-UUID-STRING
                   BY VALUE         36
              END-CALL  [/B]

** to something like:
[B]              MOVE NULL TO WS-UUID-STRING
              SET WS-UUID-STRING TO ADDRESS OF WS-MY-GUID
              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
                   BY VALUE WS-UUID-STRING
              END-CALL[/B]

              CANCEL "@[DISPLAY]:Rpcrt4.dll@WINAPI"
           ELSE
              CALL "Rpcrt4.dll@WINAPI"
              MOVE "UuidCreateSequential" TO FUNCTION-NAME
              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
              END-CALL
              MOVE "UuidToStringA" TO FUNCTION-NAME
              CALL FUNCTION-NAME USING
                   BY REFERENCE WS-UUID-STRUCT
                   BY REFERENCE WS-UUID-STRING
              END-CALL
              CALL "C$MEMCPY" USING
                   BY REFERENCE     WS-MY-GUID
                   BY VALUE         WS-UUID-STRING
                   BY VALUE         36
              END-CALL
              CANCEL "Rpcrt4.dll@WINAPI"
           END-IF.

           DISPLAY MESSAGE BOX WS-MY-GUID
                   TITLE IS "Unique GUID"
                   ICON IS Mb-Default-Icon
                   TYPE IS MB-OK.

[Migrated content. Thread originally posted on 15 January 2010]

I'm trying to work out how to create a UUID from the windows API and I can't figure out the logic in cobol for how to do it. Can anyone maybe help me with the conversion from this C code?



typedef struct _GUID {
  unsigned long  Data1;
  unsigned short Data2;
  unsigned short Data3;
  unsigned char  Data4[8];
} GUID, UUID;

****UuidCreateSequential Function****

RPC_STATUS RPC_ENTRY UuidCreateSequential(
    UUID __RPC_FAR *Uuid
);


****UuidToString Function****

RPC_STATUS RPC_ENTRY UuidToString(
    UUID __RPC_FAR *Uuid ,
    unsigned char __RPC_FAR * __RPC_FAR *StringUuid
);

There is one thing I don't get here, that is why do you change from BY REFERENCE WS-UUID-STRING to BY VALUE WS-UUID-STRING for the call to C$MEMCPY?

It should be BY VALUE in either case.

You use it BY REFERENCE in the call to UuiToStringA, because this function will modify the pointer, but when you want to move the data from WS-UUID-STRING to WS-MY-GUID, you should reference it BY REFERENCE.

Now, having said that, you cannot use C$MEMCPY on this anyway, because the WS-UUID-STRING is allocated by the API, not the runtime, so we don't know anything about it.

I'd suggest you consider using the memcpy function from the msvcrt.dll to copy from WS-UUID-STRING into WS-MY-GUID. This because the API memcpy function (which, at heart is what we use in C$MEMCPY) will understand WS-UUID-STRING and WS-MY-GUID.