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
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.
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.
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. :'(
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.
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)
If some want...
http://msdn.microsoft.com/msdnmag/issues/01/10/MSLU/
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]
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]
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
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.
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.
Hi, MichaelW!
I make my own loader for "UnicoWS.dll" because:
- I need simple debug (Try debug with unicows.lib :toothy)
- With my own loader I can use any similar project (Projects that free)
I have almost written it. (I have some understand trouble with IMAGE_IMPORT_DESCRIPTOR and IMAGE_THUNK_DATA)
I wrote my own loader for "UnicoWS.DLL" :toothy
If somebody interest this — please test this loader in:
- Windows 95
- Windows 98
- Windows Me (I tested it in this OS, but I want be confident that it work normal)
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]
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]
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
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]
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