; Listing2-2.asm
;
; A demonstration of the MultibyteToWideChar function call.

            option  casemap:none
            include    aoalib.inc   ;AoA library + constants
            includelib aoalib.lib   ;Link in aoalib library

            
            .const
            
; Sample  UTF-8 String:

UTF8Str     byte    "Ĥéĺĺő Шояļđ", nl, 0

; Program title (In Unicode):

            align   word
ttlStr      byte    "Listing 2-2", 0


            .data
            
; Buffer to hold wide string result:

UTF16Str    word    64 dup (?)

            .code


; Windows GetLastError function:

            externdef GetLastError:proc
            
; MultiByteToWideChar function:        
            
            externdef MultiByteToWideChar:proc
            
;int MultiByteToWideChar(
;  UINT                              CodePage,
;  DWORD                             dwFlags,
;  _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr,
;  int                               cbMultiByte,
;  LPWSTR                            lpWideCharStr,
;  int                               cchWideChar
;);
;
; In assembly (specified by Windows ABI):
;
; CodePage is passed in RCX
; dwFlags is passed in RDX
; lpMultiByteStr (address) is passed in R8
; cbMultiByte is passed in R9
; lpWideCharStr (address) is passed on stack
; cchWideChar is passed on stack    
            
            
            
            
; Here is the main assembly language program.

            
            public  asmMain
asmMain     proc
            push    rbx
            push    rbp
            mov     rbp, rsp
            sub     rsp, 56
               
; Here's a call to the MultibyteToWideChar function
; to demonstrate it's use:


; Note: just setting max number of output characters
; to 60 (being safe, for 63 plus zero terminating word).

            mov     ecx, 65001      ;UTF-8 code page
            mov     rdx, 8          ;dwFlags = 0
            lea     r8, UTF8Str     ;Ptr to source
            mov     r9, lengthof UTF8Str ;Size of source
            lea     rax, UTF16Str
            mov     [rsp+32], rax   ;Ptr to dest
            mov     qword ptr [rsp+40], 60
            call    MultiByteToWideChar
            cmp     eax, 0
            jne     goodOutput
            
; If there was an error in the conversion, display the
; Windows error code:

            call    GetLastError
            mov     rdx, rax
            call    print
            byte    "Error code: %d", nl, 0
            jmp     allDone
            
            
            
goodOutput: mov     rdx, rax
            call    print
            byte    "Number of Chars converted: %d", nl
            byte    "Output: ", 0
            
            lea     rbx, UTF16Str
chLoop:     movzx   edx, word ptr [rbx]
            test    dx, dx
            jz      allDone
            call    print
            byte    "%04x ", 0
            add     rbx, 2
            jmp     chLoop

allDone:    call    print
            byte    nl, 0   

            leave
            pop     rbx
            ret     ;Returns to caller
        
asmMain     endp
            end