File: /~heha/hsn/UNI-T/

GNUL is Not a Unicode Layer (and NUL alone is a forbidden file name in Windows)

Applies to:
Application software development for Windows (both Win9x/Me and NT/2k/XP/Vista),
preferably in C or C++. Delphi should work too.

After I got some experiences with unicows.dll, I was frustrated
that this DLL does not cover the APIs I needed, EnumPrinters for example.
So, I see these disantvantages:
* Not all APIs are covered
* The executable needs throrougly testing on Win9x/Me systems
* The unicows.dll (or opencows.dll) is not always installed
* The MSLU (Microsoft Layer for Unicode), namely unicows.dll,
  does ANSI<->Unicode conversion that slows down applications
  just on low-end systems typically running Win9x
* A dependency walker does not show up meanigful information,
  except when tracing the application

The GNUL uses another approach to cope with the Win9x/Me built-in but useless
Unicode functions:
At application startup, when Win9x/Me is detected, the GNUL code
changes all imports that end with letter "W" to those with letter "A"!
On NT based systems, the startup code does nothing.
Moreover, imports that end with letter "A" are not affected.
Very simple, yeah!

This concept introduces following ideas:
* The executable must be compiled in Unicode mode
* At startup, the function GnulInit() function must be called,
  at least before any Unicode-specific Windows function is called.
  This applies for DLLs too.
* The startup code is very small! Because it need no additional information
  about entry point names (like code in much bigger libunicows.lib)
* There is a small header file and a small extra .C (or .LIB) file
  with only one worker function!
* Within Win98/Me, all character arrays passed from/to Windows are
  simply used by its half size. The other half is simply wasted.
* Direct access to TCHAR characters without case distinction is not allowed!
  Use sizeofTCHAR or shiftTCHAR macros for case distinction.
* If a real Win9x/Me Unicode function is needed (like ExtTextOutW),
  catch the pointer to a volatile(!!) pointer before you call GnulInit().
* The function IsWindowUnicode() reports ANSI on Win9x/Me.
* No unicows.lib, no opencows.lib is needed!
* No additional ANSI<->Unicode conversions are made by any software layer
  (as the name should imply) on any system!
* The executable and GNUL code can be tested on Windows NT based systems
  by faking Windows 9x/Me on a single decicion point inside GnulInit()
  (using a pre-defined macro). For comparison, unicows.dll compatibility
  testing MUST be done on a Win9x/Me system.
* Constant strings should be avoided. Put them into string resources.
  Or you have to convert them to ANSI if Win9x detected.
  Read <gnul.h> file for details how to do this. It's easy.
* One drawback is that some memory is wasted on Win9x/Me systems
* Functions of run-time library need special precautions, cannot auto-change.
  For those you have to provide a "translation list".
  For more information, read <gnul.h> file.

GNUL is merely intended for small programs with overseeable constant string use.
Life would be much easier when you use string resources!

GNUL is public-domain open source.

void GnulInit(HINSTANCE hInstance, LPCSTR fromto, const LPCWSTR *list);
	Must be called to make effect.
	Performs the following actions when Win9x/Me detected:
	* Auto-changes Win32 API entry points, like CreateFileW, to CreateFileA
	* Changes additional entry points given by <fromto> list
	* Changes constant wide-character strings pointed to by <list> array

BOOL GnulIsAnsi();
	Macro, returns TRUE if Win9x/Me (or 3.x with Win32s) detected.
	Must be called only after GnulInit().

	returns 1 on Win98/Me, 2 otherwise. For use as <sizeof(TCHAR)> replacement.

	returns 0 on Win98/Me, 1 otherwise. For use as second shift operator.

For ease of debugging, if you not define UNICODE for your project, all functions
and macros revert to their expected behaviour.
Moreover, for X64 or other non-IX86 platforms, no code is added, as Win9x/Me never
run onto such systems, and all functions ans macros revert to expected behaviour too.

henni, 090810
Detected encoding: ASCII (7 bit)2