How to dynamically load DLL's, check if your app is manifested properly, track back Access Violations in your app and a brief foray into the windows dll using the clarion debugger disassembler window

Richard, I think ALSO first comment refers to this new technique:
https://clarionsharp.com/blog/new-clarion-language-features/

Clarion 11.13622 Sept. 4, 2020

FEATURE: Reference variables of Procedure types are supported by the compiler, and corresponding support is added to the linker and RTL

Yes, this one: New Clarion language features

Hi ALSO, apologies for the question that is not the subject of this thread but another, although casually mentioned here in message 8, I would like to know your opinion about whether the compiler could issue a Warning when the programmer uses optional parameters with Angles <> with simple variables that are passed on the Stack for prototypes with C and Pascal calling convention. I imagine that using those could be useful for calling Topspeed variants of those languages, but nowadays I think it is mostly used for Windows and other APIs, and those angles if inadvertently misused cause problems and aren’t always caught. Thank you

link to referred message

If omittable parameter is prototyped to be passed by value and it has no one of entity types (WINDOW, FILE, etc.), it is accompanied with additional hidden parameter which tells whether actual parameter has been really omitted. This additional parameter is passing according calling convention for this procedure. For example, if function is prototyped as follows

Func PROCEDURE(<STRING S>, LONG L)

, the string value (empty string if parameter is omitted) is passing on the string stack, the hidden parameter telling whether S has been omitted is passing in the EAX register and value of L is passing in the EBX register.

It’s better to set parameter’s default value in the prototype for parameters passing by value instead of specifying them as omittable. It’s OK to specify entity parameters and parameters passing by reference as omittable if actual value can be NULL.

Thanks, I discovered that some years ago after spending several hours debugging an application that sporadically crashed.

The question was more about if a compiler warning is feasible. Like when you put an exclamation mark before an equal sign IF MYVAR != 1 compiler warns “! introduces a comment” so to say don’t confuse it with not equal, using <> with not entity types and C or Pascal calling convention could post a warning “<> introduces another parameter” or something like that. What do you think?

It happens time to time programmers translates API’s prototypes documentation in other languages to Clarion and tends to use < > for omittable parameters instead of default values and problems appears, or not, which usually is worse.

So I know they are in the same format, I had been using both and its impossible to tell any difference from the output, but the MS docs states CoCreateGuid function (combaseapi.h) - Win32 apps | Microsoft Learn

Use CoCreateGuid when you need an absolutely unique number that you will use as a persistent identifier in a distributed environment.

So reading from both links
UuidCreate function (rpcdce.h) - Win32 apps | Microsoft Learn

The TLDR I get from reading the two links is, UUID is unique to the computer, GUID is unique on this planet. Both same data structure, and same format.

Ok, nothing springs to mind immediately about what I could use them for but thanks for the link, but I’m still using C6 at the moment, I’m not in a position to get C11 working for me unless my circumstances change, highly stressful environments are not suitable for learning.

Edit.
I dont quite get this because I’m already using references to classes in C6.
eg

2. Procedure Reference assignments

RefVar &=
6) the label of a Class method

CType    CLASS,TYPE
M          PROCEDURE (LONG),LONG,PASCAL,VIRTUAL
         END

         MAP
PType     PROCEDURE (*CType, LONG),LONG,PASCAL
         END
R1       &PType
R2       &MESSAGE  ! the MESSAGE - built-in function
RC       &CType
AClass   CType

  CODE

  RC &= AClass  !<--- havent tried this yet
  R1 &= NULL
  R1 &= AClass.M !<--- havent tried this either
  R1 &= RC.M
  R1 &= CType.M
  R2 &= 0 + SYSTEM {PROP:MessageHook} !<--- havent tried this either

So everything else I have working in C6. The only thing the appgen doesnt allow is overloaded procedures in the appgen tree, but thats all.

In fact passing procedures as parameters is in the WinExt class files found in the libsrc, as I’m using this method myself to extend the systray functionality and its what SV have done to add systray functionality themselves.

In the debugger, the class properties from a referenced class are added to the calling class as you would expect so all the reference class methods are recursive in memory, which could make apps walking data structures get stuck in a loop. This is no different to web page spiders following links which take them back to the index page, in effect getting stuck in a loop. I read once, I think it was google had to update their webpage spider to recognise it had already visited the webpage and had to drop out of the list of links which need spidering, as it was getting stuck in loops following url links.

On the point of R2 &= 0 + SYSTEM {PROP:MessageHook}

In the property.clw there are loads of equates with hex values, below 64k, now I’m thinking I might be able to change those equate values with an address for newer procedures, my own procedures and then enhance some of the {prop:xyz} properties.

I’ve not messed around with that yet, but the thought did cross my mind the other day.

In my opinion, current behavior of the compiler is correct. It can’t raise the error here because there is no violation of the syntax rules if ! begins the comment. On the other hand, it notifies programmers who not switched from C/C++ that Clarion has another syntax.

List of formal parameters tells which parameters must be passed and in which order. The calling convention’s attribute in the function prototype tells how these parameters must be passed (and how to mangle the default external name of this function). “List of…” and “how…” are orthogonal things. Additional data is passing not for omittable parameters only: parameters of *STRING, *CSTRING, *PSTRING, *GROUP, *NamedGroupType and *BLOB types require some extra data besides address.

1 Like

UUID and GUID are declared as synonyms: UUID
If you have an instance of GUID/UUID from any source (created by CoCreateGuid, read from some database, etc.), that stops you from usage of UuidToString to transform it to string?

I’m only going on the MS docs, yes they (UUID & GUID) are both the same datastructure, but the wording for CoCreateGuid and UuidCreate suggests there are differences, namely UUID and UuidCreate is unique to the device and GUID and CoCreateGuid is unique globally. The docs infer there is an additional process which CoCreateGuid applies.

I wouldnt expect the api UuidToString to throw an error converting a Guid to a string, unless there is some sort of GUID tracking taking place based on other api’s, but NotifyIconA does state there is GUID tracking taking place and it works.
NOTIFYICONDATAA (shellapi.h) - Win32 apps | Microsoft Learn

The binary file that contains the icon was moved. The path of the binary file is included in the registration of the icon’s GUID and cannot be changed. Settings associated with the icon are preserved through an upgrade only if the file path and GUID are unchanged. If the path must be changed, the application should remove any GUID information that was added when the existing icon was registered. Once that information is removed, you can move the binary file to a new location and reregister it with a new GUID. Any settings associated with the original GUID registration will be lost.

TLDR
The first use of a GUID and the icon file, which can be an exe, dll or icon file, will register the GUID with that file. It then stops you from moving that exe/dll/icon file to another location.

So far it seems impossible to reregister that GUID unless the exe/dll/icon file has changed.

So there is GUID tracking tacking place, to what extent or how far that reach’s into the OS, I’ve not been able to establish, but it doesnt stop coders from passing a GUID to UuidToString to get a string form.

Then there’s Raymond Chen only refering to GUID’s GUIDs are globally unique, but substrings of GUIDs aren’t - The Old New Thing (microsoft.com)

and then there’s this internet draft which treats UUID’s and GUID’s as one and the same.
www.webdav.org/specs/draft-leach-uuids-guids-01.txt

This specification defines the format of UUIDs (Universally Unique
IDentifier), also known as GUIDs (Globally Unique IDentifier). A UUID
is 128 bits long, and if generated according to the one of the
mechanisms in this document, is either guaranteed to be different
from all other UUIDs/GUIDs generated until 3400 A.D. or extremely
likely to be different (depending on the mechanism chosen). UUIDs
were originally used in the Network Computing System (NCS) [1] and
later in the Open Software Foundation’s (OSF) Distributed Computing
Environment [2].

Now it seems there are 4 versions of a UUID/GUID which may suggest the difference between UuidCreate and CoCreateGuid’s wording.
Universally unique identifier - Wikipedia

Which makes me think, there might be a difference to UuidToString and GuidToString2, but they wont throw an error, because I can a NID 4 structure to Shell_NotifyIcon without the overlaid 4 byte Union

union {
    UINT uTimeout;
    UINT uVersion;
  } DUMMYUNIONNAME;

and the description from szInfoTitle (the systray balloon title) will be minus 4 characters, implying some of these structures are not having their contents validated, which makes life interesting from a clever security perspective.

SO TLDR is I’m using GUID api’s for GUIDS and UUID api’s for UUID’s, which should make it one less step to workout what machine it was generated on.