; Listing2-4.asm
;
; A program that demonstrates using strings compiled
; via the resource compiler.

            option  casemap:none
            include    aoaulib.inc   ;AoA library + constants
            includelib aoaulib.lib   ;Link in aoalib library

            
            .const

; Program title (In Unicode):

            align   word
ttlStr      word    utf16("Listing 2-4"), 0


            .data
            
; Handle for the program:

handle      qword   ?
            
; Buffers that will hold the UTF-16 strings read
; from the resource file linked into the executable.

Hello       word    256 dup (?)
World       word    256 dup (?)
utf8Str     word    256 dup (?)
utf8_16Str  word    256 dup (?)
utf16Str    word    256 dup (?)


            .code

; External definitions for Windows API functions
; LoadStringW and GetModuleHandle:

;int LoadStringW(
;  HINSTANCE hInstance,
;  UINT      uID,
;  LPWSTR    lpBuffer,
;  int       cchBufferMax
;);
;
;HMODULE GetModuleHandleW(
;  LPCSTR lpModuleName
;);
;
;int MultiByteToWideChar(
;  UINT                              CodePage,
;  DWORD                             dwFlags,
;  _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr,
;  int                               cbMultiByte,
;  LPWSTR                            lpWideCharStr,
;  int                               cchWideChar
;);
;

            externdef LoadStringW:proc
            externdef LoadStringA:proc
            externdef GetModuleHandleW:proc
            externdef MultiByteToWideChar:proc
        
; Here is the main assembly language function.

            
            public  asmMain
asmMain     proc
            sub     rsp, 56
            
; Upon entry to the program, get the handle associated
; with this execution instance. Achieve this by passing
; a NULL pointer go GetModuleHandleW.

            xor     rcx, rcx
            call    GetModuleHandleW
            mov     handle, rax
            
; Load in the two strings compiled into the resource
; file using IDs 1 & 2:

            mov     rcx, handle
            mov     rdx, 1      ;ID for "Hello, " str
            lea     r8, Hello   ;Address to place str
            mov     r9d, 240    ;Max length for str
            call    LoadStringW
            test    eax, eax    ;Check for error
            jnz     readHello
            call    wprint
            word    utf16("Error reading 'Hello' ")
            word    utf16(" string"), nl, 0
            jmp     allDone
            
readHello:  mov     rcx, handle
            mov     rdx, 2      ;ID for "World!" str
            lea     r8, World   ;Address to place str
            mov     r9d, 240    ;Max length for str
            call    LoadStringW
            test    eax, eax    ;Check for error
            jnz     readWorld
            call    wprint
            word    utf16("Error reading 'World' ")
            word    utf16(" string"), nl, 0
            jmp     allDone
            
readWorld:  mov     rcx, handle
            mov     rdx, 4      ;ID for "UTF8" str
            lea     r8, utf8Str ;Address to place str
            mov     r9d, 240    ;Max length for str
            call    LoadStringA
            test    eax, eax    ;Check for error
            jnz     readUTF8
            call    wprint
            word    utf16("Error reading 'UTF8' ")
            word    utf16(" string"), nl, 0
            jmp     allDone

; Must convert UTF8 string to UTF16:
            
readUTF8:   mov     ecx, 65001      ;UTF-8 code page
            mov     rdx, 8          ;dwFlags = 0
            lea     r8, utf8Str     ;Ptr to source
            mov     r9, -1          ;Zero terminated
            lea     rax, utf8_16Str
            mov     [rsp+32], rax   ;Ptr to dest
            mov     qword ptr [rsp+40], 60
            call    MultiByteToWideChar
            cmp     eax, 0
            jne     converted
            call    wprint
            word    utf16("Error converting UTF-8 ")
            word    utf16("string to UTF-16"), nl, 0
            jmp     allDone
   
converted:  mov     rcx, handle
            mov     rdx, 3      ;ID for "UTF16" str
            lea     r8, utf16Str
            mov     r9d, 240    
            call    LoadStringW
            test    eax, eax    ;Check for error
            jnz     readUTF16
            call    wprint
            word    utf16("Error reading 'UTF16' ")
            word    utf16(" string"), nl, 0
            jmp     allDone
            
readUTF16:  lea     rdx, Hello
            lea     r8, World
            lea     r9, utf16Str
            lea     r10, utf8_16Str
            call    wprint
            word    utf16("Read '%s%s', '%s', and '%s' ")
            word    utf16(" from the resource file\n\0")            

 
allDone:    add     rsp, 56
            ret     ;Returns to caller
        
asmMain     endp
            end