******************************************************************************

        Microsoft Win32 Software Development Kit for Windows NT 3.5
                                Release Notes

******************************************************************************

------------
0.0 CONTENTS
------------

    1.0 Tools Issues
    2.0 API Issues
    3.0 OLE Issues
    4.0 Win32s Issues
    5.0 Documentation Errata

******************************************************************************

----------------
1.0 Tools Issues
----------------


1.1 Compilers
-------------
There are no compilers, linkers, librarians, or make utilities provided with
this release for x86 or MIPS platforms. You must have Microsoft Visual C++
v2.0 for Windows NT, or a compatible 32-bit compiler. See details below for
information on how to use Microsoft Visual C++ 1.10 with the latest headers 
and libraries.

Do not use the compilers provided with the final release of the Win32 SDK for 
Windows NT 3.1.

Note that the Alpha compiler is now named cl.exe.


1.2 Linker/Librarian
--------------------
If you are building 32-bit applications on Windows NT 3.5 using Microsoft 
Visual C++ version 1.10, please use the patched linker provided in the 
<CD>\SUPPORT\LINKER\32BIT directory.

The linker and librarian have been renamed to LINK.EXE and LIB.EXE, 
respectively. NTWIN32.MAK has been updated to reflect this change, but you 
must make any changes required in your source code.

The new linker can directly link the .RES files produced by the RC compiler. 
You no longer need to run CVTRES before linking so remove this step from 
your build process.

If debug information is requested, the linker will not perform comdat 
elimination. To accomplish this, add -OPT:REF.

WinDebug doesn't support debugging with .PDB files. Make sure you have PDB:NONE
on your link line.

If you get the error unable to find OLDNAMES.LIB, add the /NODEFAULTLIB switch 
to your link line.


1.3 RC/RCPP.EXE
------------
RC.EXE is used to silently ignore duplicate control IDs. It will now warn you
when you are using a duplicate ID other than -1 (0xffff). This is likely to
appear for control IDs of TEXT values, since they tend to be duplicated.

RCPP.EXE has been removed from the Win32 SDK, and its functionality combined 
into RC.EXE. If you require the preprocessor functionality explicitly, 
use CL.EXE with the /EP option.


1.4 Using Microsoft Visual C++ 1.1
----------------------------------
Targeting Windows NT 3.1:
If you are using MSVC 1.1 to target Windows NT 3.1, simply copy LINK.EXE from 
the \SUPPORT\LINKER\32BIT directory into your MSVCNT\BIN directory to ensure 
you are using the new linker. If your executables are all multiples of 2 MB 
in size, this is a sign that the old linker is somewhere in your path ahead 
of the new linker.

Targeting Windows NT 3.5:
If you want to continue using the VC++ 1.1 IDE, but also want to write 
applications for Windows NT 3.5, do the following:
    1.  Ensure that your environment points to \MSTOOLS\BIN, \MSTOOLS\LIB, 
        and \MSTOOLS\H before any of the VC++ tools, headers, or libraries 
        by choosing the Directories command from the Options menu. In 
        particular, it is important to use the latest copy of rc.exe and 
        rcdll.dll with the newest header files.
    2.  Ensure that KERNEL32.LIB is being explicitly linked with your   
        application.
    3.  If you are using MFC, comment out the definition of HTASK in AFXV_NT.H 
        because it has been redefined in the system headers. Add #define
        INC_OLE1 to your build rules. You should also rebuild the MFC 
        libraries using the latest system headers and libraries.
    4.  If you are doing OLE development, you should also add -DWIN32 and 
        -DUNICODE to your command switches. Add OLE32.LIB, UUID.LIB, and 
        OLEAUT32.LIB to your list of libraries.


1.5 Message Compiler (MC.EXE)
-----------------------------
There is a new keyword in the message compiler:  OutputBase = {10|16}. This
allows the radix of the header file output to be either decimal or hex. The
-d command line switch will also set the default output to decimal.

There is a new -e switch to specify the header file extension (e.g. -e hxx to
create a .hxx file instead of a .h file).


1.6 MIDL 2.0
------------
The MIDL compiler shipping with Windows NT 3.5 has significantly changed from 
the version which shipped with Windows NT 3.5.  The are two major issues 
concerning backward compatibilty with MS RPC 1.0 projects.

The /oldnames command line switch.  This switch causes MIDL 2.0 to generate 
MIDL 1.0 interface names which do not contain version numbers.

The MIDL 2.0 compiler no longer generates auxilary stub ( *_X.C
and *_Y.C ) files.  This may require you to modify previously existing
RPC project makefiles.  Also ignore any references to these files in the 
"RPC Programmer's Guide and Reference".

For more information on the new MIDL features, see the "New in this Version 
of RPC" section of the help file.  For a complete listing of the MIDL command 
line switches, run MIDL with the /? switch.


******************************************************************************

--------------
2.0 API Issues
--------------


2.1 32-bit Application Compatibility
------------------------------------
32-bit applications built and tested on Windows NT version 3.1 should 
continue to run unmodified on Windows NT version 3.5. However, the reverse 
is not true: 32-bit applications built and tested on Windows NT 3.5 are not 
supported on Windows NT 3.1.  Similarily, applications built for Win32s 
versions 1.0, 1.1, and 1.15 will continue to run on Win32s version 1.2 and 
Windows NT 3.5 but applications built for Win32s 1.15 and 1.2 will not run 
on Windows NT 3.1 or previous versions of Win32s.

Note:
Win32-based applications built and tested on any beta release of Windows NT 3.5
that uses OLE, or links with WINMM.LIB, must be rebuilt on the final release.

DLLs and services built for Windows NT 3.1 may have problems when they are 
running under Windows NT 3.5. In Windows NT 3.1 all DLL entry points and 
service callbacks had to be declared with the STDCALL calling convention; 
however, there were a number of cases in which the DLLs would still function 
correctly even if the entry points were declared as CDECL. With recent 
optimizations in the way Windows NT is built, this may no longer be the case. 
If the DLL is built incorrectly, a pop-up now warns the user that the DLL
may behave incorrectly. The user can either continue running or exit at this 
point. ISVs are encouraged to verify that their existing applications do not 
exhibit this behavior.


2.2 New APIs
------------
The following APIs are either new or enhanced for Windows NT 3.5. For more 
information, see the Win32 API Help file.
    AreFileApisANSI         FreeEnvironmentStrings      LoadCursorFromFile
    ChoosePixelFormat       FreeLibraryAndExitThread    lstrcpyn
    CommandLineToArgvW      GetBinaryType               NotifyChangeEventLog
    CompareStringA          GetCurrencyFormat           SelectObject
    ConvertDefaultLocale    GetDateFormatA              SetDIBColorTable
    CreateDIBSection        GetDIBColorTable            SetFileApisToANSI
    CreateIoCompletionPort  GetLocaleInfoA              SetErrorMode
    DescribePixelFormat     GetNumberFormat             SetLocaleInfo
    DeviceCapabilitiesEx    GetPixelFormat              SetPixelFormat
    DisableThreadLibraryCalls   GetProcessAffinityMask  SetServiceBits
    EnumCalendarInfo        GetProcessWorkingSetSize    SetSystemCursor
    EnumCalendarInfoProc    GetQueuedCompletionStatus   SetSystemTimeAdjustment
    EnumCodePagesProc       GetShortPathName            SetThreadAffinityMask
    EnumDateFormats         GetStringTypeA              SwapBuffers
    EnumDateFormatsProc     GetStringTypeEx     SystemTimeToTzSpecificLocalTime
    EnumLocalesProc         GetSystemTimeAdjustment     wglCreateContext
    EnumSystemCodePagesW    GetTimeFormatA              wglDeleteContext
    EnumSystemLocales       GetVersionEx                wglGetCurrentContext
    EnumTimeFormats         IsTextUnicode               wglGetCurrentDC
    EnumTimeFormatsProc     IsValidLocale               wglMakeCurrent
    FoldStringA             LCMapStringA                wglUseFontBitmaps


2.3 Headers/Libs
----------------
You are no longer required to use /Zp8 with the system headers.  #pragmas 
have been added to ensure DWORD packing throughout, so you can pack your 
applications in any way required.

If you are doing development for Windows NT 3.5, you must use the new headers 
and libraries provided, along with the new tools. New features, such as 
_declspec(dllimport) and comdat elimination, are now used in the new libraries 
and headers but they are not fully supported by the old tools.

Note
There is no support for building applications that mix libraries built for 
Windows NT 3.5 and those built for Windows NT 3.1. If you rebuild one part 
of your application with the new environment, you should rebuild it all.


2.4 Services
------------
There was a change made in Windows NT 3.5 that prevented services from 
accessing the console directly.  A new interface is being designed to allow 
services to do this. If you are running an existing service which requires
console access, please use the "Allow Service to Interact with the Desktop"
checkbox.

The following functions will attempt to start system services if they are not 
already started.  If you use these functions inside a service initilization 
routine, you should ensure that your service is dependant on the corresponding
system service:

API Function            Service it may attempt to start:
--------------------    --------------------------------------------
RpcNsBindingExport      RPCLOCATOR
RpcNsBindingImport      RPCLOCATOR
RpcEpRegister           RPCSS
RpcEpRegisterNoReplace  RPCSS
NetBios                 NetBios


2.5 OpenGL
----------
When porting OpengGL source from an X-Windows environment, programmers must 
be sure to prototype their callback functions as either APIENTRY or CALLBACK.
The X callback convention is _cdecl, whereas it is _stdcall on Windows NT.


2.6 CreateFile
--------------
DOS does not allow deletes of a ReadOnly file.  In Windows NT 3.1, if
you used the FILE_FLAG_DELETE_ON_CLOSE option to CreateFile, it would delete
the file, even if it was marked as read only.  Windows NT 3.5 is compatible
with DOS, and so you must remove the READ_ONLY attribute before opening a 
file with DELETE_ON_CLOSE.


2.7 Process Detach
------------------
When processing the DLL_PROCESS_DETACH method in your DLLEntry routine, you
should not do process level cleanup when you are called due to ExitProcess -
i.e. the third parameter to the init routine is NON_NULL. Only global state
should be handled in this case. If you are not careful 
you can have multiple active threads at the time you call ExitProcess. 
When this occurs, all threads but the caller are terminated instantly. The 
calling thread then starts calling all of the DLL init routines for 
DLL_PROCESS_DETACH notification. Some of these DLL init routines might try to 
do some work, or use some resources that were in use by one of the terminated 
threads. In some situations, a thread could have been terminated in the middle
of a LocalAlloc call, leaving heap pointers corrupt and the heap possibly
locked.


2.8 WriteFile
-------------
When doing overlapped I/O to a named pipe, Overlapped->{Offset,OffsetHigh} are
ignored. However, the docs state (correctly) that these members MUST be zeroed.
If they aren't zeroed, the API will fail.  This differs from Windows NT 3.1, 
where the WriteFile API would automatically zero this field.


2.9 SetWindowText
-----------------
The documentation states that SetWindowText on an edit control changes the
contents of an edit control. In fact, it changes the title of the edit control.


2.10 BITMAPFILEHEADER
---------------------
The documentation incorrectly states that the bfSize member is the size of the
file in DWORDs. It is actually the size of the file in BYTES.

******************************************************************************

--------------
3.0 OLE Issues
--------------
In this final release of Windows NT 3.5, 32-bit OLE is fully functional 
and usable for developing 32-bit applications using OLE version 2.01-level 
technology. These notes cover topics not included in the OLE Help file 
provided with this release of Windows NT. Besides reading this information, 
you should also look at the OLE Help file, particularly the topic "OLE 
Programming in a 32-Bit Environment."

Important:
Since the last Windows NT 3.5 release candidate, the signatures for the 
32-bit version of CoInitialize and OleInitialize have been changed:

    WINOLEAPI  CoInitialize(LPVOID pvReserved);

    WINOLEAPI OleInitialize(LPVOID pvReserved);


The parameter to these APIs is being changed from IMalloc FAR * 
to LPVOID pvReserved.  The parameter must be NULL.  32-bit OLE does 
not support applications replacing OLE's allocator.  If the parameter 
is not NULL, the APIs will return E_INVALIDARG. See the topic 
"Differences Between 16- and 32-Bit OLE" in the OLE Help file for
more information.
 

Also in the OLE Help file, the reference pages documenting these functions
elaborates on this change and explains its connection to CoGetMalloc.


3.1 Using 32-bit OLE
--------------------
The recommended steps for taking advantage of 32-bit OLE in your 
applications are as follows (when using NTWIN32.MAK):

    1.  Specify #include <WINDOWS.H> in your application.
    2.  For core OLE functionality, use the $(olelibs) macro from the 
        NTWIN32.MAK file. This includes all libraries required by the system.

If you have been developing applications with earlier releases of OLE 
and you used either #define _INC_OLE or #define _RPC_H in order to get 
OLE to work, you should remove these from your code because this obsolete 
mechanism will cause problems. Applications that still call CoBuildVersion 
and/or OleBuildVersion should explicitly include OLE2VER.H, even if you 
use the typical process outlined above. However, since 32-bit OLE is an 
integral part of the Windows NT operating system, these older functions 
have ceased to be useful. It is more appropriate for applications to 
verify the version of the operating system itself if they need this 
information. You can use REGEDIT.EXE to register your OLE registration 
information. This executable is located in %SystemRoot%.


3.2 Registering your OLE app
----------------------------
Important:
User-defined local and in-process servers must be registered using the 
full path to the server, so the OLE service can recognize and start 
(or load) them. 

32-bit OLE uses the following new registry keys:
    LocalServer32       Registers a 32-bit server EXE.
    InProcServer32      Registers a 32-bit in-process server DLL.
    InProcHandler32     Registers a 32-bit handler DLL.
    ProxyStubClsid32    Maps an IID to a CLSID in a 32-bit proxy DLL.

16-bit OLE version 2.01 will continue to use the existing registry keys:
    LocalServer     	Registers a 16-bit server EXE.
    InProcServer        Registers a 16-bit in-process server DLL.
    InProcHandler       Registers a 16-bit handler DLL.
    ProxyStubClsid      Maps an IID to a CLSID in a 16-bit proxy DLL.

In addition, there is now a Win32 key for 32-bit type libraries 
(OLE Automation). The Win16 key is still used for 16-bit type libraries.

32-bit Servers must register both 16 and 32-bit entries so that they can
be used by 16-bit containers.

3.3 Unicode
-----------
Because all 32-bit Windows platforms now implement 32-bit OLE as Unicode, 
we have provided a sample set of libraries to make porting easier. The 
directory \MSTOOLS\SAMPLES\OLE\OLEANSI provides ANSI wrappers for all 
of the OLE interfaces. 

Note, however, that Microsoft does not recommend you use these ANSI
wrappers. They are easy to use but will make your OLE applications bigger
and slower and harder to debug than they would otherwise be. We strongly
recommend that you convert ANSI strings using the appropriate Win32 APIs in the
relatively few places where you must pass strings in and out of OLE APIs and
interfaces. This will make your application run better on both Windows NT 3.5
and, in the future, Chicago. See 3.7 below for more information.


3.4 Headers
-----------
The header files for 32-bit OLE application development have been 
redesigned. The following is a list of current OLE header files:

    *  CGUID.H
    *  INITGUID.H
    *  OBJBASE.H
    *  OLEAUTO.H
    *  OLE2.H 
    *  OLE2VER.H
    *  WTYPES.H

As an alternative to using the normal process mentioned in the Getting 
Started help file, if you only make use of compobj and storage technology, 
it is possible to explicitly include only OBJBASE.H (you must explicitly 
include OBJERROR.H, as well). Likewise, if you use features outside of 
compobj/storage, you can explicitly include OLE2.H, which includes OBJBASE.H,
OLEAUTO.H, and types for higher-level functionality.

Several old header files are no longer appropriate as a result of this 
redesign. In cases where an old header file is no longer needed, but 
was often included explicitly by developers, we have created stub headers 
so that source code would not have to be changed. These stub 
headers are:

    *  COMPOBJ.H
    *  DISPATCH.H
    *  STORAGE.H
    *  VARIANT.H

The following header files are no longer needed. We will make stubs 
for these header files available in LIB1 of the WinOBJ forum on 
CompuServe, but they are not included in the SDK. We do not recommend 
the continued use of the following files:

    *  COBJPS.H
    *  COGUID.H
    *  DVOBJ.H
    *  MONIKER.H
    *  OBJERROR.H
    *  OLEGUID.H
    *  OLE2ANAC.H
    *  SCODE.H


Important:
The header files have changed since the first beta release of the 
Win32 SDK. As a result, you must rebuild all of your 32-bit OLE 
applications using these newer OLE header files.


3.5 DISPTEST.EXE
----------------
There are no current plans to provide a 32-bit version of DISPTEST.EXE 
for OLE Automation testing. The 16-bit version of DISPTEST.EXE provides 
this testing functionality. 


3.6 Debugging
-------------
If you need to start an OLE local server under a debugger, you should 
use REGEDT32.EXE to do the following:

    *  Create key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\scm
       and under it create a value:

            Debugger : REG_SZ : ntsd -g

       (or specify whatever debugger and options you want, such as WinDebug).

    *  Create key: HKEY_CLASSES_ROOT\CLSID\{your class guid}\Debug
       and under it create a nameless value:

            : REG_SZ : Y

Y or y means the server will start under the debugger. Any other value 
means it will not start under the debugger. 

Be aware that this debugging mechanism works only for OLE local servers. 
It does not work for OLE in-process servers.


3.7 OLEANSI
-----------
In the \MSTOOLS\SAMPLES\OLE\OLEANSI directory of the Win32 SDK, you will 
find a particularly important body of sample code that can be used to 
simplify porting ANSI applications to 32-bit OLE. 

A fundamental design point of OLE is the ability to direction to connect to
in-process objects via OLE interfaces without any intervening system code.
This allows very high performance for in-process servers.  It requires, however,
that data types conform to a canonical format for a given platform since
the system cannot intervene to do any data conversions.  Unicode is the
canonical string representation for 32-bit OLE on all 32-bit Windows platforms.

Because 32-bit OLE is Unicode on all 32-bit Windows platforms 
(including Win32s 1.2), developers porting 16-bit OLE 2.01 code to 32-bit
platforms must deal with this issue in one of three ways:

    *   Port your application completely to Unicode. This is an appropriate 
        alternative if your application is targeting Windows NT only, but 
        not if you want your application to run on Win32s (because Win32s 
        does not support the Unicode Win32 API). With this approach there 
        is no need to use the OLEANSI wrappers. This is the fastest model. 
        Depending on the application, it can be easy to write an ANSI/Unicode 
        application through the use of TCHAR that compiles for ANSI under
        Windows and Unicode under Win32. 

    *   Leave your application ANSI internally, and translate ANSI strings 
        to Unicode before calling Unicode OLE. Alternatively, you could 
        port your application to Unicode internally, and translate strings 
        to ANSI before calling ANSI Win32 API. Either of these are appropriate 
        alternatives if your application is targeting both Windows NT and 
        Win32s. You might want to refer to the OLEANSI sources for examples
        of how to do this. Some of the wrapper code can be moved to the 
        application to aid in conversions between ANSI and Unicode. There 
        is no need to build and use an application-specific version of 
        OLE2ANSI.DLL because the required conversion code is embedded into 
        the application. Interfaces are not wrapped, which results in a big 
        savings in overhead. However, this approach does require some 
        source code changes. 

    *   Leave your application ANSI internally, and make use of the OLEANSI 
        sample code to enable your application to use 32-bit Unicode OLE. 
        This is similar in concept and effect to the option previously 
        mentioned. The benefit is a greatly reduced amount of work to get 
        your application ported and running; major applications can be ported 
        without any source changes. Following the instructions in the 
        README.TXT, the OLE2ANSI.DLL becomes a "translation thunk" between 
        the application and the OLE2 subsystem. The drawback is an overall 
        size and performance impact on your application. 

If you choose to use the OLEANSI code by building it as a DLL rather than by 
including it in your source directly, you must rename the DLL to a name 
specific to your application. You should also install the DLL in the same 
directory as your application. Specifically, OLEANSI is not an OLE system 
component and must not be treated as such. Read the README.TXT file in the 
OLEANSI directory for details about using this code. 

Microsoft strongly recommends that you use the second approach for dealing
with ANSI/Unicode issues in any production-quality application that you build.
Our internal experience with OLEANSI is that it is helpful to get
an application up and running but that it can introduce some subtle difficulties
and certainly reduce the speed and increase the size of your OLE application.
Although only a very small numer of OLE interfaces involve passing string
data, OLEANSI must "wrap" the major of OLE interfaces because they have methods 
that can contain interface pointers as in or out parameters and OLEANSI must 
check to see if those interface pointers are among the small set that must be
"wrapped." By doing the string conversions "manually" in a few areas of your
application, you can increase the performance and reduce the size of your 
application.

3.8 OLE2UI
----------
There are two versions of OLE2UI provided with the OUTLINE sample series.  
The OLE2UI provided in the OLE2UI directory uses its own translation routines.
The version of OLE2UI provided in the WRAPUI directory with the OUTLINE sample 
series uses the OLE2ANSI code to enable them to use 32-bit Unicode OLE. As 
with the OLE2ANSI code itself, if you choose to use any version of the OLE2UI 
code by building it as a DLL rather than by including it in your source 
directly, you must rename the DLL to a name specific to your application, and 
you should install the DLL in the same directory as your application. 
Specifically, OLE2UI is not an OLE system component, and must not be treated 
as such.

There is a known problem with the Insert As Icon functionality of the 
Insert Object and Paste Special dialog boxes in this version of OLE2UI. In 
both cases, the dialog box itself will not properly display the icon. In 
addition, the icon will not be properly displayed in the container application 
after closing these dialog boxes until the icon object is activated.


3.9 32-bit OLE Test Tools
-------------------------
In the Win32 SDK, you will find several 32-bit OLE (version 2.01-level) 
applications that may be useful in your testing:

    *  We have included CL32TEST and SR32TEST in this release. These 
       are 32-bit OLE versions of CL2TEST and SR2TEST, which were included 
       in the 16-bit OLE 2.01 SDK. To make use of these test applications, 
       you will first need to register their information by running REGEDIT 
       SR32TEST.REG. These tools are installed automatically into your 
       \MSTOOLS\BIN directory.

Important:
As with any other 32-bit OLE sample or test application, you must ensure 
that the information in these test applications .REG files contains full 
paths to the servers installed locations. You will need to modify the 
contents of SR32TEST.REG to reflect the correct location of these test 
applications before registering them with REGEDIT.


******************************************************************************

-----------------------------
4.0 Win32s Version 1.20 Notes
-----------------------------


4.1 Notes
---------
The 16-bit OLE libraries with Win32s 1.20 are designed to replace existing 
16-bit OLE libraries and are redistributable stand-alone entities, without 
Win32s, for 16-bit OLE applications. These 16-bit OLE libraries have a higher 
version number than previous versions of the OLE libraries that are 
redistributed with 16-bit OLE applications. The new 16-bit OLE libraries have 
version numbers beginning with 2.02.

OLE Custom Interfaces and Custom Marshalling are not supported in Win32s.

Win32s keeps a table of selectors for translation of Linear Address to 
selector:offset. Win32s 1.20 removes the size limitation of this table.

Memory that is passed between processes and marshalled must be allocated with 
globalAlloc(GMEM_MOVEABLE). Memory allocated as GMEM_FIXED will not be 
marshalled correctly for 32-bit OLE applications running under Win32s. 

Support for wide (Unicode) APIs has been removed from Win32s.


4.2 Shipping Win32s with your application
-----------------------------------------
The following list of files must be redistributed with a Win32s application:
CTYPE.NLS       L_INTL.NLS  LOCALE.NLS      SORTKEY.NLS
SORTTBLS.NLS    UNICODE.NLS W32S.386        COMDLG32.DLL
CRTDLL.DLL      LZ32.DLL    MPR.DLL         NETAPI32.DLL
NTMSG.DLL       OLECLI.DLL  OLECLI32.DLL    OLESVR32.DLL
SCK16THK.DLL    SHELL32.DLL VERSION.DLL     W32SCOMB.DLL
W32SKRNL.DLL    W32SYS.DLL  WIN32S16.DLL    WINMM.DLL
WINMM16.DLL     WSOCK32.DLL WINSPOOL.DRV    WIN32S.EXE

You must also ship Natural Language Support files corresponding to the market 
of the Win32s application. For a Win32s application that has an international 
market, you must ship all of the .NLS files found in \MSTOOLS\WIN32S\NLS. For 
instance, a Win32s application that is released only in the United States 
must ship P_437.NLS, P_850.NLS, and P_1252.NLS.

Applications that do not need OLE support are not required to redistribute the
OLE files.  If your application uses OLE 2 functionality, you must redistribute
ALL of the following files in accordance with the installation instructions 
in the Win32s Programmer's Reference and the OLE 2 Programmer's Reference:
COMPOBJ.DLL     OLE2.DLL        OLE2.REG        OLE2CONV.DLL
OLE2DISP.DLL    OLE2NLS.DLL     OLE2PROX.DLL    OLE2THK.DLL
OLE32.DLL       OLEAUT32.DLL    STDOLE.TLB      STDOLE32.TLB
STORAGE.DLL     TYPELIB.DLL     


4.3 Debugging
-------------
The Win32 SDK includes a tool called WinDbg, which can be used to debug 
32-bit applications under Win32s. Note that previously shipped versions of 
WinDbg cannot be used to debug 32-bit applications under Win32s 1.20.


4.4 Setup sources
-----------------
We have included the Setup sources for Win32s as an example of how to install 
Win32s applications. These sources are located in \MSTOOLS\WIN32S\SETUP. For 
information on using these setup utilities, see the Win32s Overview in the 
Win32 API Help File.  Installation of OLE requires several setup steps, which 
are discussed in the Win32s Overview.

Your setup application should instruct the user to exit all active applications.


4.5 Updates to the Win32s Programmers Reference
-----------------------------------------------
Win32s System Requirements: 2.2MB of hard disk space is required for Win32s, 
and another 2MB of hard drive space is required for OLE (for a total of 
4.2MB).

Win32s Dynamic Link Libraries: With respect to _declspec(thread), only the 
DLLs that contain the instance data should be loaded at load time. It is 
still possible to use LoadLibrary() to load libraries that don't have 
static instance data (static data that was declared using _declspec(thread)).

Localized Win32s Files:  The file W32S.386, not WIN32S.386, is localized.  
Nine languages are provided with this release of the Win32 SDK.

Figure 7.a, which depicts Debugger Options, incorrectly shows the process 
to choose options.  Consult the text of the Debugging and Testing section 
for correct information.

The Win32s kernel traps all exceptions that occur during execution of a 32-bit 
process. Some exceptions, however, are also handled by Windows 3.1 kernel; 
for example, calling the 16-bit function IsBadPointer or IsWindow with an 
invalid parameter causes a GP fault, which is trapped by the Windows 3.1 
kernel and handled gracefully. In Win32s Version 1.1 such an exception would 
be trapped by the Win32s SEH mechanism instead of the Windows 3.1 kernel. 

This was a problem for 16-bit code that was called through the Universal Thunk 
(UT) and makes calls to the mentioned APIs. This problem is now fixed in Win32s
Version 1.20. Exceptions in 16-bit that are handled by the Windows 3.1 
kernel are left to the 16-bit fault handler.

MS-DOS does not support UniversalTimeConvention (UTC) translation. Win32s 
always uses local time instead of UTC. The functions FileTimeToLocalFileTime, 
LocalFileTimeToFileTime, FindFirstFile, and FindNextFile all return local time.

Under Win32s, the base address of the flat code and data selectors is not zero.
Applications can use the GetThreadSelectorEntry function to query the base 
address at run time.

Memory for data that is passed to NetBIOS must be allocated by using 
GlobalAlloc. An attempt to pass a pointer to memory allocated by using 
LocalAlloc, VirtualAlloc, or to data on the stack or in a global variable 
will fail. The return error is 0x22 - too many commands outstanding.

A 16-bit DLL can be loaded by Win32s so that GetProcAddress can be called for 
printer driver APIs. Behavior has changed as follows. LoadLibrary now sets 
the last error code to ERROR_BAD_EXE_FORMAT (193) if a 16-bit DLL is 
successfully loaded. This error code can be used to determine whether a loaded 
DLL is 16-bit or 32-bit.


4.6 NLS code pages
------------------
An application that uses the full set of NLS code pages should install the 
code page files at setup on a file-by-file basis, overwriting older files 
which are present on the machine. Win32s applications with full international 
support should install the NLS code pages over older versions of the files; 
other applications that do not need international language support will 
not have installed the full suite.


4.7 _TZSET()
------------
Calling _tzset() on Win32s v120 returns JST-9 as default instead of PST8PDT.


4.8 Detecting running Win32s applications at setup
--------------------------------------------------
The Win32s setup program has added the capability to check whether a Win32s 
application is running on the user's machine.  The interface, which is 
accessed by linking W32SGRA.OBJ into INIUPD.DLL, is as follows:


4.9 Win32sGetRunningApp
-----------------------
/****************************************************************************
* Win32sGetRunningApp
*
* Entry
*     lpszAppName - Pointer to buffer to receive application's file name
*     cMaxAppName - lpszAppName buffer size.
*     lphTask - Pointer to WORD variable that will receive the hTask of the
*               application. This parameter can be set to NULL.
*
* Returns
*     If successful returns number of bytes copied to passed buffer,
*     including the terminating null character. If the buffer size is not
*     large enough, the return value is the required buffer size for a
*     successful operation. If the function fails, the return value is zero.
*
* For just knowing whether or not there is an active Win32s application call:
* fBool = Win32sGetRunnigApp(NULL, 0, NULL) != 0;
*
*
*****************************************************************************/

WORD FAR PASCAL Win32sGetRunningApp(LPSTR lpszAppName, WORD cMaxAppName, LPWORD lphTask);


4.10 OLE2.REG
-------------
OLE2.REG is a localizable file.  Localized versions of this file will be 
provided in an upcoming release of the Win32 SDK.


4.11    Net Connection APIs
---------------------------
WNetGetConnectionA and WNetAddConnectionA are now implemented by thunks
to Windows3.1. These APIs are needed by OLE.


4.12    OLE Limitations
-----------------------
Although OLE is exposed as Unicode APIs and methods, formats put on the
clipboard are always ANSI (for compatibility with 16 bit apps). Therefore, apps
should not put Unicode CF_OBJECTDESCRIPTOR or CF_LINKSOURCEDESCRIPTOR directly 
on the Clipboard (by using the Win32 api SetClipboardData), rather they should 
use the OLE API OleSetClipboard.

The dlls OLEPRX32.DLL and OLECNV32.DLL do not exist on Win32s. The 
functionality in these libraries is implemented by OLE32.DLL. Apps should not 
try to load these dlls explicitly. However, Windows NT registry files that use
oleprx32.dll are valid on Win32s.

When using the default OLE memory allocator (calling OleInitialize(NULL)),
::DidAlloc will always return -1.

::CreateInstance is always called with IID_IUnknown and not with the iid
supplied by the calling application.


4.13    Debugging Aids
----------------------
The following explains debug support for OLE applications using the debug 
version of the OLE dlls.

Default debug allocator- OLE32.DLL has a debug memory allocator which can help 
trace memory leaks. To use it instead of the default allocator add the 
following to system.ini in the [Win32sDbg] section:

    usedballoc=1

If you want to override your own memory allocator with the default allocator, 
add the following to system.ini in the [Win32sDbg] section:

    ForceDbgAlloc=1.

When calling Ole[Co]Uninitialize and releasing the default memory allocator, 
if there are memory leaks then a list of un-freed memory blocks will be 
printed on the debug terminal. Each line in the list includes the blocks 
address, its serial ID and its size. To find where the leak occured, add 
the following to system.ini in the [Win32sDbg] section:

    dballoc=XXX

where XXX is the ID of the unreleased memory block. Now run the same test again.
When OLE allocates block number XXX it will first break to debugger.

******************************************************************************

------------------------
5.0 Documentation Errata
------------------------


5.1 Keyboard Input
------------------
GetAsysncKeyState
    Append the following to the final paragraph in the Remarks section: 
    
    You can determine the system's current mapping of physical mouse 
    buttons to logical mouse buttons by calling GetSystemMetrics(SM_SWAPBUTTON)
    which returns TRUE if the mouse buttons have been swapped.


5.2 Memory Management
---------------------
GetHandleInformation
    The GetHandleInformation function obtains information about certain 
    properties of an object handle. The information is obtained as a set 
    of bit flags. 

    BOOL GetHandleInformation(
        HANDLE  hObject,    // handle to an object
        LPDWORD lpdwFlags   // points to variable to receive flags
    );

    Parameters
    hObject     Specifies a handle to an object. The GetHandleInformation 
                function obtains information about this object handle. 

    lpdwFlags   Points to a variable to receive a set of bit flags that 
                specify properties of the object handle. The following 
                flags are defined: 

    Value                           Meaning
    HANDLE_FLAG_INHERIT             If this flag is set, a child process 
                                    created with the bInheritHandle parameter 
                                    TRUE inherits the object handle.

    HANDLE_FLAG_PROTECT_FROM_CLOSE  If this flag is set, calling the 
                                    CloseHandle function will not close 
                                    the object handle.

    Return Value
    If the function succeeds, the return value is TRUE. If the function fails, 
    the return value is FALSE. To get extended error information, call the 
    GetLastError function.

    See Also
    CloseHandle, SetHandleInformation 

MoveMemory
    This function IS part of Win32s. The Quick Info dialog data is 
    incorrect. The relevant Quick Info entry should be "Win32s    Yes". 

SetHandleInformation
    The SetHandleInformation function sets certain properties of an object 
    handle. The information is specified as a set of bit flags. 

    BOOL SetHandleInformation (
        HANDLE  hObject,     // handle to an object
        DWORD   dwMask,      // specifies flags to change
        DWORD   dwFlags      // specifies new values for flags
    );

    Parameters
    hObject     Specifies a handle to an object. The SetHandleInformation 
                function sets information associated with this object handle. 

    dwMask      A mask that specifies the bit flags to be changed. Use the 
                same flag constants shown in the description of dwFlags. 

    dwFlags     A set of bit flags that specify properties of the object    
                handle. The following flags are defined: 

    Value                           Meaning
    HANDLE_FLAG_INHERIT             If this flag is set, a child process 
                                    created with the bInheritHandle parameter 
                                    TRUE inherits the object handle.

    HANDLE_FLAG_PROTECT_FROM_CLOSE  If this flag is set, calling the 
                                    CloseHandle function will not close 
                                    the object handle.


    Return Value
    If the function succeeds, the return value is TRUE. If the function fails, 
    the return value is FALSE. To get extended error information, call the
    GetLastError function.

    Remarks
    Note that you must set a bit flag in dwMask in order to set or clear the 
    associated bit flag in dwFlags. 

    See Also
    CloseHandle, GetHandleInformation 


5.3 Painting and Drawing
------------------------
GdiFlush
    Insert the following paragraph before the current final paragraph 
    of the Remarks section:

    Call GdiFlush before a thread goes away if there is a possibility 
    that there are pending function calls in the graphics batch queue. 
    The operating system does not execute such batched functions when 
    a thread goes away. 


5.4 Registry and Initialization Files
-------------------------------------
RegEnumValue
    This function IS part of Win32s. The Quick Info dialog data is 
    incorrect. The relevant Quick Info entry should be "Win32s    Yes". 

RegQueryValueEx
    This function IS part of Win32s. The Quick Info dialog data is 
    incorrect. The relevant Quick Info entry should be "Win32s    Yes". 


5.5 System Information
----------------------
IsTask
    This function is deleted. It is NOT part of Windows NT, Chicago, 
    or Win32s. The Quick Info dialog data is incorrect. The relevant 
    Quick Info entries should be "Windows NT    No; Chicago    No; 
    Win32s    No". 


5.6 Multimedia
--------------
waveOutGetPosition
    The waveOutGetPosition function retrieves the current playback 
    position of the specified waveform output device.  

    MMRESULT waveOutGetPosition(
        HWAVEOUT  hWaveOut,     // handle of output device
        LPMMTIME  lpmmt,        // address of structure for current position
        UINT      cbmmt         // size of structure, in bytes
    );

    Parameters
    hWaveOut    Identifies the waveform output device. 
    lpmmt       Points to an MMTIME structure that receives the current 
                playback position. 
    cbmmt       Specifies the size, in bytes, of the MMTIME structure. 

    Return Value
    If the function succeeds, the return value is zero. If the function fails, 
    the return value is an error code, which can be one of the following:  

    Value                   Meaning
    MMSYSERR_INVALHANDLE    The specified device handle is invalid.

    MMSYSERR_HANDLEBUSY     The handle hWaveOut is in use on another thread.

    Remarks
    Before calling waveOutGetPosition, set the wType member of the MMTIME 
    structure to indicate the time format. After calling waveOutGetPosition, 
    check the wType field to determine if the requested time format is 
    supported. If the requested format is not supported, wType will specify 
    an alternative format. The position is set to zero when the device is 
    opened or reset. 

5.7 Networking
--------------
GetUserName
    This function IS part of Chicago. The Quick Info dialog data is 
    incorrect. The relevant Quick Info entry should be "Chicago    Yes". 

