assemblywinapistructexternmasm64

How to use a WinAPI struct in UASM without writing it and its members


UASM (a MASM clone) 64 bit Visual Studio 2022 solution with ICC. I want to use the CONSOLE_CURSOR_INFO struct that is defined in the WinAPI. I know how to use it by copying its declaration from the Documentation.

This is a partial UASM program without the main function and it works.

.CODE
USE64
INCLUDELIB Kernel32.lib

EXTERNDEF __imp_SetConsoleCursorInfo :QWORD

.CONST
ALIGN 4
    ; Cursor size.
    CONSOLE_CURSOR_INFO STRUCT
        dwSize DWORD 100 ; Fully filled.
        bVisible BOOL 1 ; Visible. BOOL is defined as DWORD in another file.
    CONSOLE_CURSOR_INFO ENDS

.DATA
ALIGN 4
    MyCursorD CONSOLE_CURSOR_INFO {}

.CODE
        mov rcx, rax ; rax already have handle from GetStdHandle of STD_OUTPUT_HANDLE.
        lea rdx, MyCursorD ; *lpConsoleCursorInfo.
        call __imp_SetConsoleCursorInfo

How can I access the WinAPI CONSOLE_CURSOR_INFO struct without explicitly copying it and its members to my program the same way I used EXTERNDEF to access the WinAPI function? Is there an EXTERN or EXTERNDEF that I can use?

I tried many combinations of EXTERN and EXTERNDEF and even tried Windows 11 Copilot. It always failed with a syntax error of MyCursorD.

Since the struct is defined in the .CONST section and already has the values I need, is there a way to use it as const without creating the MyCursorD variable in the .DATA section?


Solution

  • You're making this more complicated than it needs to be. -> UASM has a built in directive, "INVOKE" which allows you to call procedures, win32 api etc without needing to worry about setting up all the registers for the given calling convention yourself. -> USE64 is, as per the documentation, for use in FLAT binary output. For a Windows executable or DLL you should be setting the assembler options appropriately. -> UASM is supplied with WinInc, which includes assembly language INC files to correspond to the win32 api header files from the SDK.

    Given these points, a minimal example would be:

    option casemap:none
    option frame:auto
    option STACKBASE:RSP
    option win64:15
    
    .nolist
    .nocref
    WIN32_LEAN_AND_MEAN equ 1
    ;UNICODE                EQU 1
    _WIN64                  EQU 1
    include C:\jwasm\wininc\Include\windows.inc
    .list
    .cref
    
    includelib <kernel32.lib>
    
    .DATA
    ALIGN 4
        MyCursorD CONSOLE_CURSOR_INFO {}
    
    .CODE
    
    start:
        ; rax already have handle from GetStdHandle of STD_OUTPUT_HANDLE.
        invoke SetConsoleCursorInfo, rax, ADDR MyCursorD
    
    end start