The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: KSS on April 23, 2006, 09:25:45 PM

Title: Microsoft Layer for Unicode in MASM32
Post by: KSS on April 23, 2006, 09:25:45 PM
How I can write program in TRUE unicode that can run under 9x/Me systems?

  Example:
   Invoke MessageBoxW,0,ADDR MB_Text_string,0,MB_OK
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: hutch-- on April 24, 2006, 07:00:53 AM
KSS,

What you can get out of win9x depends purely on how effective the unicode support is for it and while I don't have the details handy, i gathered it only supplied empty stubs for many of the unicode functions. This is something you would have to look up at Microsoft as I don't personally have any data on unicode support for win9x.
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: Vortex on April 24, 2006, 09:49:14 AM
Platform Software Development Kit Redistributable: Microsoft Layer for Unicode on Windows 95, 98, and Me Systems, 1.1.3790.0 :

http://www.microsoft.com/downloads/details.aspx?FamilyID=73BA7BD7-ED06-4F0D-80A4-2A7EEAEE17E2&displaylang=en

QuoteOverview
The Microsoft Layer for Unicode on Windows 95, 98, and Me systems (MSLU) helps to provide a layer over the Win32 API on Win9x so that you can write a single Unicode version of your application.
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: KSS on April 25, 2006, 08:59:45 AM
Thanks you for answer, but I want load/call "unicows.dll" dynamical. (Such as in GoAsm mslu loader)

I tried load "unicows.dll" with LoadLibraryA() {I read article "Compiling Your Application with the Microsoft Layer for Unicode" in my Platform SDK.}, but it not work. :'(
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: MichaelW on April 25, 2006, 11:09:39 AM
This works for me under Windows 98 SE:

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      hLib  dd 0
      modfn dw 256 dup(0)
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    invoke LoadLibrary, chr$("unicows.dll")
    mov   hLib, eax
    print uhex$(eax),13,10
    invoke GetProcAddress,hLib,chr$("GetModuleFileNameW")
    push  eax
    print uhex$(eax),13,10
    pop   eax
    push  256
    push  OFFSET modfn
    push  0
    call  eax
    print ustr$(eax),13,10
    invoke crt_printf,chr$("single-byte character string:%s%c"),ADDR modfn,10
    invoke crt_printf,chr$("wide-character string:%S%c"),ADDR modfn,10
    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


I think a better solution might be to link with the unicows.lib from the PSDK, but I have no idea how to do that. I'm assuming that unicows.lib is a static library because it's 2.27MB, where the import library I built was only 103KB.

BTW, judging from the module definition file produced by Vortex's Dll2inc tool, unicows.dll contains 507 functions.

Title: Re: Microsoft Layer for Unicode in MASM32
Post by: KSS on April 25, 2006, 04:43:20 PM
MichaelW,
Your method is very hard to use in big app! I don't like it.

Possible, I need load "unicows.dll" and dynamically replace all unicode functions addresses that used in my app (in import table) to functions addresses from "unicows.dll" that have same names? :8)
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: KSS on April 25, 2006, 04:46:24 PM
If some want...
http://msdn.microsoft.com/msdnmag/issues/01/10/MSLU/
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: MichaelW on April 25, 2006, 11:30:01 PM
Linking with the unicows.lib from the PSDK turned out to be easier than I thought it would be. At least most of the necessary prototypes are already in the MASM32 include files, and with unicows.lib included first the linker produced an exe with no unicode functions in the imports.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    includelib unicows.lib
    include \masm32\include\masm32rt.inc
    include \masm32\macros\ucmacros.asm   
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      modfnw  dw 256 dup(0)
      envvarw dw 512 dup(0)
    .code
start:   
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    invoke GetModuleFileNameW,NULL,ADDR modfnw,256
    invoke crt_printf,chr$("%S%c"),ADDR modfnw,10

    invoke GetEnvironmentVariableW,uni$("Path"),ADDR envvarw,512
    invoke crt_printf,chr$("%S%c"),ADDR envvarw,10

    invoke MessageBoxW,0,uni$("MessageBoxW"),uni$("MessageBoxW"),0

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


Here is a listing of the imports from kernel32.dll with unicows.lib included first (as it is in the attachment):

00004000  23C SetLastError
00004004   B3 FreeLibrary
00004008   1E CompareStringA
0000400C  109 GetModuleHandleA
00004010  107 GetModuleFileNameA
00004014  162 GetWindowsDirectoryA
00004018  13C GetSystemDirectoryA
0000401C  1A4 LoadLibraryA
00004020  18F InterlockedExchange
00004024   FD GetLastError
00004028   80 ExitProcess
0000402C  134 GetStdHandle
00004030  29E WriteFile
00004034   A8 FlushConsoleInputBuffer
00004038  260 Sleep

The resulting exe (14KB) runs under Windows 98 SE and produces the same output as it produces under Windows 2000.

Here is the same listing with unicows.lib included last:

00002000   A8 FlushConsoleInputBuffer
00002004  29E WriteFile
00002008   80 ExitProcess
0000200C   ED GetEnvironmentVariableW
00002010  108 GetModuleFileNameW
00002014  134 GetStdHandle
00002018  260 Sleep

The resulting exe (4KB) runs under Windows 98 SE, but the GetModuleFileNameW and GetEnvironmentVariableW calls fail.



[attachment deleted by admin]
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: KSS on April 26, 2006, 09:11:24 AM
MichaelW,
For first — view my attached archive.

   About how to work "unicows.lib" and "unicows.dll"
(When you include "unicows.lib" before kernel32.lib, advapi32.lib, user32.lib, gdi32.lib, shell32.lib, comdlg32.lib, version.lib, mpr.lib, rasapi32.lib, winmm.lib, winspool.lib, vfw32.lib, secur32.lib, oleacc.lib, oledlg.lib, sensapi.lib)
  1. All unicode function are stripped from result exe-file and add they ANSI equivalent. (to work in Win9x/Me)
  2. In code (where placed calls to unicode functions) dispose call to "unicows.*" functions (that determine about what OS they run, and decide what type of function to call)

Because "unicows.lib" work so badly (I think) I don't want use it at the link-time.
So... I looks for method that allow me to use "unicows.dll" only at run-time.

My things about this:
I need load "unicows.dll" and dynamically replace all unicode functions addresses that used in my app (in import table) to functions addresses from "unicows.dll" that have same names.
But I didn't try this. (I shall do it on following week.)


[attachment deleted by admin]
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: KSS on April 26, 2006, 09:27:06 AM
MSLU: reported bugs and known issues:
http://www.trigeminal.com/usenet/usenet035.asp

Wikipedia: Microsoft Layer for Unicode:
http://en.wikipedia.org/wiki/Microsoft_Layer_for_Unicode
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: Mark Jones on April 26, 2006, 03:07:51 PM
Is this what you are wanting to do?

Quote from: Wikipedia: Microsoft Layer for Unicode:
When a wide-character function is called for the first time at runtime, the function stub in UNICOWS.LIB first receives control and decides if it is running on a Windows 95/98/ME system:

    * If so, it dynamically loads the UNICOWS.DLL (if it hasn't been loaded yet) and passes control to the corresponding thunking stub in there. The thunking stub translates the wide-character arguments into ANSI strings and then invokes the native A version from the OS, and then translates any returned strings back into wide-character format.
    * If the OS natively supports the W version (ie: Windows NT/2000/XP/2003), then the function stub updates the in-memory import table so that future calls will directly invoke the native W version without any more overhead.

Because of this technique, when an application is linked against MSLU, only Windows 95/98/ME systems will need the UNICOWS.DLL at runtime, and on all other operating systems there is only a slight performance penalty for the first function call.
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: MichaelW on April 27, 2006, 08:49:28 AM
This is just a quick test to verify that linking with unicows.lib does not (significantly) slow down calls to Unicode functions under Windows 2000.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    includelib unicows.lib
    include \masm32\include\masm32rt.inc
    include \masm32\macros\ucmacros.asm
    .686
    include timers.asm
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      modfnw  dw 256 dup(0)
      envvarw dw 512 dup(0)
    .code
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    LOOP_COUNT equ 5000000
    invoke Sleep,1000

    counter_begin LOOP_COUNT,HIGH_PRIORITY_CLASS
      invoke GetModuleFileNameW,NULL,ADDR modfnw,256
    counter_end
    print ustr$(eax)," cycles",13,10

    counter_begin LOOP_COUNT,HIGH_PRIORITY_CLASS
      invoke GetEnvironmentVariableW,uni$("Path"),ADDR envvarw,512
    counter_end
    print ustr$(eax)," cycles",13,10

    counter_begin LOOP_COUNT,HIGH_PRIORITY_CLASS
      invoke lstrlenW,ADDR envvarw
    counter_end
    print ustr$(eax)," cycles",13,10

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


Result without unicows.lib:

195 cycles
563 cycles
455 cycles


Result with unicows.lib:

198 cycles
563 cycles
455 cycles


The run to run variation was typically plus or minus one cycle, but the call to GetModuleFileNameW consistently took slightly longer with unicows.lib.

Title: Re: Microsoft Layer for Unicode in MASM32
Post by: KSS on May 02, 2006, 05:48:54 PM
Hi, MichaelW!
I make my own loader for "UnicoWS.dll" because:

I have almost written it. (I have some understand trouble with IMAGE_IMPORT_DESCRIPTOR and IMAGE_THUNK_DATA)
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: KSS on May 04, 2006, 08:47:44 PM
I wrote my own loader for "UnicoWS.DLL"  :toothy

If somebody interest this — please test this loader in:


Anybody know that user32.MessageBoxW in WinMe works OK???
I looked in unicows.MessageBoxW and found that it use user32.MessageBoxW :eek

[attachment deleted by admin]
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: Mark Jones on July 13, 2006, 12:00:07 AM
Quote from: MichaelW on April 25, 2006, 11:30:01 PM
Linking with the unicows.lib from the PSDK turned out to be easier than I thought it would be...

I can't get your app to compile properly Michael. It's as if the unicows.lib is not being recognized at all, the build size is always 4kb. I've tried the v7.xx and 6.15 ML and Link with many options to no avail. Does it have to be assembled on a 9x platform or use some other obscure link options? Example attached.

EDIT: corrected makeit.bat.

[attachment deleted by admin]
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: Casper on July 13, 2006, 03:27:14 AM
KSS,
Your test program does not work on Windows ME.  It quietly fails.  It works on my XP machine but not on my daughter's ME and '98 machines.

Paul
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: KSS on July 18, 2006, 12:16:22 AM
Casper,
I ran my test on "Microsoft Virtual PC 2004" with installed "Virtual Machine Addition" and it worked fine. (WinMe)
Now I retest it, all right. And attach compiled EXE.

[attachment deleted by admin]
Title: Re: Microsoft Layer for Unicode in MASM32
Post by: GregL on July 19, 2006, 08:15:36 PM
I was trying the code above, and for what it's worth, I modified StdOut to work with Unicode. I thought someone might find it useful.


StdOutW PROC lpszwText:PTR WORD

    LOCAL hOutPut  :DWORD
    LOCAL bWritten :DWORD
    LOCAL sl       :DWORD

    INVOKE GetStdHandle, STD_OUTPUT_HANDLE
    mov hOutPut, eax

    INVOKE lstrlenW, lpszwText
    mov sl, eax

    INVOKE WriteConsoleW, hOutPut, lpszwText, sl, ADDR bWritten, NULL

    mov eax, bWritten
    ret

StdOutW endp