How do I find a non clarion DLL functions parameter types?

,
Tags: #<Tag:0x00007f22502f6268> #<Tag:0x00007f22502f6128>

So I have some windows api calls where I think the datatype I’m using must be incorrect because I’m getting the windows error 87

**ERROR_INVALID_PARAMETER**
87 (0x57)
The parameter is incorrect.

System Error Codes (0-499) (WinError.h) - Win32 apps | Microsoft Docs

So where as with clarion dll functions and procedures I can see what the parameters are in LibMaker, I cant with windows api’s.

So how does everyone else work out what the parameter type (or length) is?

I understand I could dissemble the dll as described here:

|  2 | [ebp + 16] (3rd function argument)
|  5 | [ebp + 12] (2nd argument)
| 10 | [ebp + 8]  (1st argument)
| RA | [ebp + 4]  (return address)
| FP | [ebp]      (old ebp value)
|    | [ebp - 4]  (1st local variable)

x86 Disassembly/Functions and Stack Frames - Wikibooks, open books for an open world

But is there any other way apart from dissembling the dll?

Edit. I know about IDA Pro ( IDA Pro – Hex Rays (hex-rays.com)) , but wondered what the best way is?

What API calls and what Parameters? Details would help.

The main way I know is to read MSDN and/or the .H files. MSDN will sometimes discuss reason for specific errors like 87.

All parameters are 32-bit integers but if if a *LONG is required an you pass a LONG that would be invalid. Or if a certain type of Handle is required Windows will know its invalid when it tries to lookup the handle in a table.

Using dissembled code should only be needed with undocumented functions like calling something in ClaRun.DLL that SV never specified.

Well I was looking at advapi.dll and noticed there are loads of procedures/functions called SystemFunction001 to 041, which piqued my curiosity, but the main reason is
GetSecurityInfo function (aclapi.h) - Win32 apps | Microsoft Docs
in particular what data type the Loc:SE_Object_Type (currently Long) and Loc:SecurityInfo (currently Ulong) should be.

IS_GetSecurityInfo(Long,Long,Ulong,Long,Long,Long,Long,Long),Ulong,Raw,Pascal,Name('GetSecurityInfo')

    Loc:CurrentThreadId         = IS_GetCurrentThreadId()                           !This apps thread identifier
    Loc:hDesk                   = IS_GetThreadDesktop(Loc:CurrentThreadId)          !Handle to the desktop this app is running on
    IF Loc:hDesk = 0
        Message('IS_GetThreadDesktop Failed Error:' & IS_GetLastError() ) 
    Else
        Loc:ReturnValueUlong    = IS_GetSecurityInfo(   Loc:hDesk,|
                                                        Loc:SE_Object_Type,|
                                                        Loc:SecurityInfo,|
                                                        Loc:lplpSidOwner,|
                                                        Loc:lplpSidGroup,|
                                                        Loc:lplpDacl,|
                                                        Loc:lplpSacl,|
                                                        Loc:lplpSecurityDescriptor)
        IF Loc:ReturnValueUlong = Error_Success
            
        Else
            Message('Is_GetSecurityInfo Failed Error:'& Loc:ReturnValueUlong &' GetLastError:'& IS_GetLastError() )
        End

In SE_OBJECT_TYPE (accctrl.h) - Win32 apps | Microsoft Docs

its defined as an ENUM and I dont know what data type this is, same for
SECURITY_INFORMATION (Winnt.h) - Win32 apps | Microsoft Docs
its a set of bit flags, but I dont know if this is a short, long or something else.

ENUM is not something listed in these MS data type webpage links, I linked to here: Clarion Run vs CreateProcessA
Thats why I’m stumped, there are quite a few interpretations online of how these should be defined and handled.

Edit. The last parameters are Long Pointer (lp) containing a memory address to another Long Pointer (lp) which is a bit long winded, but I’ve worked with those before and they are just tedious.

An ENUM is going to be an Integer like BYTE, SHORT or LONG depending on max value. One way to confirm by searching for the .NET / PInvoke declaration. I found this that says its a UINT so 32 bits:

image

https://www.pinvoke.net/default.aspx/Enums/SECURITY_INFORMATION.html

Yeah I got the Ulong for SECURITY_INFORMATION from
SECURITY_INFORMATION (Winnt.h) - Win32 apps | Microsoft Docs

typedef DWORD SECURITY_INFORMATION, *PSECURITY_INFORMATION;

but I’ve not been able to use your method for the SE_OBJECT_TYPE using pinvoke as they dont list a data type.
pinvoke.net: SE_OBJECT_TYPE (Enums)

Thats why I was reluctantly considering a bit of disassembly or trying a number of different data types in the procedure prototype.

Edit: Well I’ve tried Byte, Short & Long as 1,2,4 bytes in the procedure prototype but its still an error 87 so must be something else wrong at this stage, maybe missing an input flag or something.

I think I’ve just found out what it should be. So on here
Desktop Security and Access Rights - Win32 apps | Microsoft Docs

|DESKTOP_CREATEMENU (0x0004L)|Required to create a menu on the desktop.|
|---|---|
|DESKTOP_CREATEWINDOW (0x0002L)|Required to create a window on the desktop.|
|DESKTOP_ENUMERATE (0x0040L)|Required for the desktop to be enumerated.|
|DESKTOP_HOOKCONTROL (0x0008L)|Required to establish any of the window hooks.|
|DESKTOP_JOURNALPLAYBACK (0x0020L)|Required to perform journal playback on a desktop.|
|DESKTOP_JOURNALRECORD (0x0010L)|Required to perform journal recording on a desktop.|
|DESKTOP_READOBJECTS (0x0001L)|Required to read objects on the desktop.|
|DESKTOP_SWITCHDESKTOP (0x0100L)|Required to activate the desktop using the SwitchDesktop function.|
|DESKTOP_WRITEOBJECTS (0x0080L)|Required to write objects on the desktop.|

So a 0x will indicate a it needs to be hex, but the L on the end indicates it needs to be a Long, IIRC.
So in a round about way the MS documentation did/does specify the data type needed.

IS_DESKTOP_CREATEMENU       Equate(0004h)                                       !Required to create a menu on the desktop.
IS_DESKTOP_CREATEWINDOW     Equate(0002h)	                                    !Required to create a window on the desktop.
IS_DESKTOP_ENUMERATE        Equate(0040h)	                                    !Required for the desktop to be enumerated.
IS_DESKTOP_HOOKCONTROL      Equate(0008h)                                       !Required to establish any of the window hooks.
IS_DESKTOP_JOURNALPLAYBACK  Equate(0020h)	                                    !Required to perform journal playback on a desktop.
IS_DESKTOP_JOURNALRECORD    Equate(0010h)                                       !Required to perform journal recording on a desktop.
IS_DESKTOP_READOBJECTS      Equate(0001h)	                                    !Required to read objects on the desktop.
IS_DESKTOP_SWITCHDESKTOP    Equate(0100h)	                                    !Required to activate the desktop using the SwitchDesktop function.
IS_DESKTOP_WRITEOBJECTS     Equate(0080h)	                                    !Required to write objects on the desktop. 

I’ll be back if it doesnt work, but it probably would have paid to have copied over all the equates before hand before posting.

I’m getting

**ERROR_ACCESS_DENIED**  5 (0x5)  Access is denied

which is good, the original clarion prototype was correct ie using a Long, I just needed to tell the api what info I wanted like setting the flags and giving it some addresses for the double long pointers.

    Loc:CurrentThreadId         = IS_GetCurrentThreadId()                           !This apps thread identifier
    Loc:hDesk                   = IS_GetThreadDesktop(Loc:CurrentThreadId)          !Handle to the desktop this app is running on
    IF Loc:hDesk = 0
        Message('IS_GetThreadDesktop Failed Error:' & IS_GetLastError() ) 
    Else
        Loc:SE_Object_Type          = IS_SE_WINDOW_OBJECT
        Loc:SecurityInfo            = IS_OWNER_SECURITY_INFORMATION +|
                                      IS_GROUP_SECURITY_INFORMATION +|
                                      IS_DACL_SECURITY_INFORMATION +|
                                      IS_SACL_SECURITY_INFORMATION

        Loc:lplpSidOwner            = Address(Loc:lpSidOwner)
        Loc:lplpSidGroup            = Address(Loc:lpSidGroup)
        Loc:lplpDacl                = Address(Loc:lpDacl)
        Loc:lplpSacl                = Address(Loc:lpSacl)
        Loc:lplpSecurityDescriptor  = Address(Loc:lpSecurityDescriptor)   

        Loc:ReturnValueUlong    = IS_GetSecurityInfo(   Loc:hDesk,|
                                                        Loc:SE_Object_Type,|
                                                        Loc:SecurityInfo,|
                                                        Loc:lplpSidOwner,|
                                                        Loc:lplpSidGroup,|
                                                        Loc:lplpDacl,|
                                                        Loc:lplpSacl,|
                                                        Loc:lplpSecurityDescriptor)
        IF Loc:ReturnValueUlong = IS_Error_Success
            
        Else
            Message('Is_GetSecurityInfo Failed Error:'& Loc:ReturnValueUlong &' GetLastError:'& IS_GetLastError() )
        End
               
    End

Now I have to go through Desktop Security and Access Rights - Win32 apps | Microsoft Docs

to get the right flags and settings in order to get the callback function EnumDesktopWindows function (winuser.h) - Win32 apps | Microsoft Docs to work! :roll_eyes: