Unicode
Across
Windows
Michael S. Kaplan
Trigeminal Software, Inc.
Cathy A. Wissink
Microsoft
Unicode on Downlevel Windows (IUC 18)
Why Unicode in your application?





World wide EXE
Decrease localization costs
Superior multilingual support
Better integration with the NT platform
Support for new languages on Windows
2000, Windows XP, and beyond
Unicode on Downlevel Windows (IUC 18)
Why not Unicode in your apps?
(note that none of these are true any more; some were never true!)




One code page at a time is enough,
right?
Every major language has at least
one version of Windows which
supports it
Visual Studio does not support
Unicode
There is no support for Unicode
when you are on Win95/98/ME
Unicode on Downlevel Windows (IUC 18)
The old workarounds

Build two versions of the application




Always do ANSI applications




Multiple code bases or build types to maintain
Larger downloads/setups
Harder to isolate problems in code
No multilingual support
Poorer performance on NT platforms
No support for Unicode only languages
Create your own layer (based on the 4/99 MSJ article
from Microsoft)
http://www.microsoft.com/msj/0499/multilangUnicode/multilangunicode.htm

A lot of work required!
Unicode on Downlevel Windows (IUC 18)
Bumps in the road




Microsoft assumed that the migration to
NT would happen more quickly and that
ISVs would make that happen
Developers needed to support the
consumer applications
Microsoft did not have a consistent
Unicode story for all platforms (and
needed one)
Something had to give....
Unicode on Downlevel Windows (IUC 18)
®
Microsoft
The
Layer
for Unicode™ on
®
Windows 95/98/ME
Systems
Unicode on Downlevel Windows (IUC 18)
What is MSLU?

The MICROSOFT Layer for Unicode on
Windows 95/98/ME Systems


file name: UnicoWS.dll
Allows you to write a single Unicode
application for all platforms
Unicode on Downlevel Windows (IUC 18)
Design goals for MSLU



Cannot slow down Unicode applications on
WinNT/Win2K/WinXP
When possible, provide a consistent, identical
Unicode subset of the Win32 API across all
platforms
Based on the Millennium API set


Supports Win95/98 also
Allow developers to take advantage of the
new languages on Windows 2000 and
Windows XP without abandoning older
platforms
Unicode on Downlevel Windows (IUC 18)
Other design goals

As small as possible:







Dll is ~160kb
Has over 440 API wrappers
Has more than 40 "stub" wrappers
Frugal with resources
No registration required
No dependencies
No special file location requirement


No inherent "DLL hell" issues
Cannot be put in the system directory!
Unicode on Downlevel Windows (IUC 18)
Performance

No slowdown at all on WinNT/2K/XP
No extra DLL load
 Native APIs called directly


Minimal slowdown on Win95/98/ME
Need time to convert strings to ANSI
 For functions with out params, need to
convert strings to Unicode

Unicode on Downlevel Windows (IUC 18)
MSLU's custom loader

No Virginia, you cannot do a true static link





Your application statically links to the loader
The loader works in a similar way to the
/DELAYLOAD functionality in VC++
Should work with other C++ compilers, too
Supports the ability to override any API but
get all the benefits of the loader!
No fear of failure:


DLL not present
Low memory scenarios
Unicode on Downlevel Windows (IUC 18)
Agenda








What is Unicode?
Why Unicode in your application?
Introducing the MS Layer for Unicode
Integration of the layer
Covered APIs and functionality
What the layer is not
What about Visual Studio.Net?
Where to get MSLU
Unicode on Downlevel Windows (IUC 18)
Integration of the layer

Just add UnicoWS.lib to the link list, and you
are done!



1) Add it after static libraries like the CRT
2) Add it before all of the libraries that it uses
(such as kernel32.lib and shell32.lib)
Making sense of the rules:


The linker resolves references Left to Right
When it reaches the end, it wraps around
uafxcw.lib libcmt.lib unicows.lib kernel32.lib gdi32.lib user32.lib
oleaut32.lib oledlg.lib shell32.lib comdlg32.lib advapi32.lib winspool.lib
Unicode on Downlevel Windows (IUC 18)
How the DLL is loaded

Setting an override:
Add a function that you use to load the DLL
 "Set the hook" by adding this line:

extern "C" HMODULE (__stdcall *_PfnLoadUnicows) (void) = &LoadUnicows;

Good place to handle failure

Default behavior: LoadLibrary!

Fallback to the shared location if you
must (not preferred at all)

When all else fails, fail APIs gracefully!
Unicode on Downlevel Windows (IUC 18)
Overriding individual APIs


Add your function (using the same
signature as the Win32 header files
define)
"Set the hook" with this line of code:
extern "C" FARPROC Unicows_<api>W = (FARPROC)&<your function>;


Overriding "stubbed out" APIs
The new PSDK will have notes for every
API -- including any special issues, when
needed
Unicode on Downlevel Windows (IUC 18)
Detecting when APIs are wrapped properly

Current technologies do not support
MSLU:
Dependency Walker (DEPENDS.EXE)
 DUMPBIN.EXE /IMPORTS


Using these methods anyway to
determine what is linked and what is not
Unicode on Downlevel Windows (IUC 18)
Loading your own "unicows.dll"

How LoadLibrary works for loaded DLLs


If DLL of the same name is already loaded,
LoadLibrary uses that DLL
How to stay independent of others
Rename unicows.dll
 Use the loader override to load the DLL

Unicode on Downlevel Windows (IUC 18)
Integration samples


Taking a few samples from the PSDK
Showing off a customer integration or two
Unicode on Downlevel Windows (IUC 18)
Agenda








What is Unicode?
Why Unicode in your application?
Introducing the MS Layer for Unicode
Integration of the layer
Covered APIs and functionality
What the layer is not
What about Visual Studio.Net?
Where to get MSLU
Unicode on Downlevel Windows (IUC 18)
Covered APIs and functionality - 1

Wraps almost every "W" Win32 API



The few that are not wrapped are ones that
already support Unicode, such as the IME APIs
Stubs you can override are present for APIs not
explicitly supported
Wraps several non "W" APIs when needed for
Unicode support



Unicode support (e.g., IsWindowUnicode)
Consistent user messaging (e.g., CallWindowProcA)
Common, known issues (e.g., ExtTextOutW)
Unicode on Downlevel Windows (IUC 18)
Covered APIs and functionality - 2

User messaging support


Similar to NT's user messaging support for
ANSI applications
Threadsafe

Can handle multithreaded applications
properly
Unicode on Downlevel Windows (IUC 18)
Covered APIs and functionality - 3
(Playing well with the other children)

Works properly with the Unicode
versions of MFC, ATL, and the CRT in
both VS 6.0 and VS 7.0

Interoperability with other MSLU clients
in process
 out of process


Interoperability with non-Unicode
applications
Unicode on Downlevel Windows (IUC 18)
Agenda








What is Unicode?
Why Unicode in your application?
Introducing the MS Layer for Unicode
Integration of the layer
Covered APIs and functionality
What the layer is not
What about Visual Studio.Net?
Where to get MSLU
Unicode on Downlevel Windows (IUC 18)
What the layer is not


Not a rewrite of the Win9x platform
No NT-specific functionality added






No
No
No
No
"Unicode-only" language support
supplementary character support
new international support
new functionality added, at all
Not an "NT emulator" for Windows 95!
Not a layer over components that are
still shipping new versions
Unicode on Downlevel Windows (IUC 18)
Other components, other solutions

RichEdit




Windows Common Controls (comctl32.dll)




2.0: Unicode support
3.0: Bidirectional support
4.0: Supplementary character support
5.80: full Unicode support
Uniscribe/GDI+
MLang
Common Language Runtime (CLR)


System.Globalization namespace
System.Text namespace's encoding support
Unicode on Downlevel Windows (IUC 18)
Agenda








What is Unicode?
Why Unicode in your application?
Introducing the MS Layer for Unicode
Integration of the layer
Covered APIs and functionality
What the layer is not
What about Visual Studio.Net?
Where to get MSLU
Unicode on Downlevel Windows (IUC 18)
What about Visual Studio.Net?

VS.NET should include the newest Platform
SDK; unicows.lib is in there!

CLR languages like VB.NET, C#, and MC++
have their own delayload solution



PInvoke does not support calling different libraries
on different platforms
Do not call MSLU on NT platforms!
You will have the same runtime issue with
PInvoke in your MC++ code
Unicode on Downlevel Windows (IUC 18)
using System;
using System.Text;
using System.Runtime.InteropServices;
C#.NET syntax
public class SystemAPI
{
[DllImport("kernel32")]
private static extern uint GetVersion();
[DllImport("kernel32", EntryPoint="GetSystemDirectoryW", CharSet=CharSet.Unicode)]
private static extern uint OsGetSystemDirectoryW(StringBuilder lpBuf, uint uSize);
[DllImport("unicows.dll", EntryPoint="GetSystemDirectoryW", CharSet=CharSet.Unicode)]
private static extern uint MsluGetSystemDirectoryW(StringBuilder lpBuf, uint uSize);
public static uint GetSystemDirectory(StringBuilder lpBuf, uint uSize)
{
if(GetVersion() < 0x80000000)
return(OsGetSystemDirectoryW(lpBuf, uSize));
else
return(MsluGetSystemDirectoryW(lpBuf, uSize));
}
}
class Class1
{
static void Main(string[] args)
{
StringBuilder pSysDir = new StringBuilder(256);
SystemAPI.GetSystemDirectory(pSysDir, 256);
Console.WriteLine(pSysDir);
return;
}
}
Unicode on Downlevel Windows (IUC 18)
Imports System
Imports System.Text
Imports System.Runtime.InteropServices
VB.NET syntax
Public Class SystemAPI
Declare Function GetVersion Lib "kernel32" () As Integer
Declare
(ByVal
Declare
(ByVal
Unicode Function OsGetSystemDirectoryW Lib "kernel32" Alias "GetSystemDirectoryW" _
lpBuf As StringBuilder, ByVal uSize As Integer) As Integer
Unicode Function MsluGetSystemDirectoryW Lib "unicows.dll" Alias "GetSystemDirectoryW" _
lpBuf As StringBuilder, ByVal uSize As Integer) As Integer
Public Function GetSystemDirectory(ByVal lpBuf As StringBuilder, ByVal uSize As Integer) As Integer
If (GetVersion() > &H80000000) Then
GetSystemDirectory = OsGetSystemDirectoryW(lpBuf, uSize)
Else
GetSystemDirectory = MsluGetSystemDirectoryW(lpBuf, uSize)
End If
End Function
End Class
Module Module1
Sub main()
Dim stSysDir As StringBuilder = New StringBuilder(256)
Dim sapi As New SystemAPI()
sapi.GetSystemDirectory(stSysDir, 256)
Console.WriteLine(stSysDir)
End Sub
End Module
Unicode on Downlevel Windows (IUC 18)
Agenda








What is Unicode?
Why Unicode in your application?
Introducing the MS Layer for Unicode
Integration of the layer
Covered APIs and functionality
What the layer is not
What about Visual Studio.Net?
Where to get MSLU
Unicode on Downlevel Windows (IUC 18)
Where to get MSLU

the .LIB ships in the Platform SDK!
http://www.microsoft.com/msdownload/platformsdk/setuplauncher.asp

The DLL is a redistributable component:
http://www.microsoft.com/msdownload/platformsdk/setuplauncher.asp
(it will be somewhere up there, not sure where yet!)
Unicode on Downlevel Windows (IUC 18)
Questions?
Unicode on Downlevel Windows (IUC 18)
Don't Forget Your Evals!
®
Microsoft
The
Layer
for Unicode™ on
®
Windows 95/98/ME
Systems
Unicode on Downlevel Windows (IUC 18)
Descargar

Unicode on Downlevel Windows