📄 genthunk.txt
字号:
Windows NT Generic Thunk Overview
=================================
Windows NT supports running 16-bit applications using a technology referred
to as WOW (Windows on Windows NT). Each 16-bit application can be run in its
own address space (VDM) or run in a shared address space (the default). The
16-bit Windows API calls are mapped to Win32 APIs in the WOW layer.
Windows NT does not allow mixing 16-bit and 32-bit code in the same process.
WOW supports standard IPC mechanisms such as DDE, RPC, OLE, and named pipes,
but there are occasions when it is necessary to call a routine in a Win32
DLL (including Win32 APIs in the system DLLs) from a 16-bit application. This
functionality is provided by WOW Generic Thunks.
When deciding whether to use existing IPC mechanisms or use Generic Thunks, it
is important to consider that Generic Thunks are unique to Windows NT and code
that uses them will not be portable to other Win32 platforms. Other Win32
platforms support different thunking mechanisms (i.e. Universal Thunks on
Win32s). The best thing to do is to isolate thunking code into DLLs which can
be made platform-specific, or to detect the platform at runtime and call
the appropriate APIs (see the \SCT\Samples\Interop sample for an example).
WOW Application Programming Interfaces
======================================
The following are 16-bit WOW APIs exported by KERNEL for use in Generic Thunks.
The prototypes can be found in wownt16.h.
----------
DWORD FAR PASCAL LoadLibraryEx32W(
LPCSTR lpszLibFile,
DWORD hFile,
DWORD dwFlags);
This API allows a 16-bit thunk DLL to load a 32-bit thunk DLL.
Parameters
This API thunks to the Win32 LoadLibraryEx(). For a complete description of
the parameters, please refer to the Win32 SDK documentation.
Returns
If the call succeeds, the return value is a 32-bit DLL HINSTANCE, otherwise,
it is NULL.
Comments
The 16-bit thunk DLL can then call GetProcAddress32W() to get the address of
the 32-bit entry point(s) and then call the thunk(s) via CallProc32W().
----------
BOOL FAR PASCAL FreeLibrary32W(DWORD hInst);
This API allows a 16-bit thunk DLL to free a 32-bit thunk DLL which it had
previously loaded via LoadLibraryEx32W().
Parameter
This API thunks to the Win32 FreeLibrary(). For a complete description of the
parameter, please refer to the Win32 SDK documentation.
Returns
If the function succeeds, the return value is TRUE, otherwise, it is FALSE.
Comments
Note that WOW does not do any cleanup of 32-bit thunk DLLs when the WOW task
exits. It is up to the 16-bit thunk DLLs to free the 32-bit thunk DLLs as
necessary.
----------
DWORD FAR PASCAL GetProcAddress32W(DWORD hModule, LPCSTR lpszProc);
This API allows a 16-bit thunk DLL to get a value that corresponds to a
32-bit thunk routine.
Parameters
This API thunks to the Win32 GetProcAddress(). For a complete description of
the parameters, please refer to the Win32 SDK documentation.
Returns
If the call succeeds, the return value is a 32-bit value that must be passed
as a parameter to CallProc32W() or CallProcEx32W(), rather than used directly.
----------
DWORD FAR PASCAL GetVDMPointer32W(lpAddress, fMode);
This API allows a 16-bit thunk DLL to translate a 16-bit far pointer into
a 32-bit flat pointer for use by a 32-bit thunk DLL.
Parameters
LPVOID lpAddress Valid 16:16 address, either protect or "real" mode
UNIT fMode 1 - address is interpreted as Protect Mode address
0 - address is interpreted as "Real" Mode Address
Returns
If the call succeeds, the return value is a 32-bit linear address. Otherwise,
the function will return NULL. Note that on non-x86 platforms "real" mode
address 0:0 may not point to linear 0 in memory, so always use this function
and make no assumptions about memory layout.
Comments
The WOW Kernel memory manager moves segments in memory and keeps the selectors
the same. However if you get the linear address, it may not be valid if the
memory manager has moved memory. If you need to keep a flat pointer to
a buffer for a long period (rather than doing the address conversion each time
the pointer is used), then call GlobalWire() to lock the segment in low memory.
On non-x86 platforms, it will not be possible to use this address directly,
but the address can be useful to pass to other 32-bit thunk DLLs or as a part
of a packet of data to be passed to another process.
----------
DWORD FAR PASCAL CallProc32W( DWORD param1, DWORD param2, ... ,
LPVOID lpProcAddress32,
DWORD fAddressConvert, DWORD nParams);
This API is used by a 16-bit thunk DLL to call an entry point in a 32-bit DLL.
Parameters
DWORD param1-param32 Parameters for 32-bit procedure represented by
lpProcAddress32
LPVOID lpProcAddress32 The 32-bit value corresponding to the procedure
to be called, returned by GetProcAddress32().
DWORD fAddressConvert Bit mask representing which parameters will be
treated as 16:16 pointers and translated into
flat linear pointers before being passed to the
32-bit procedure
DWORD nParams Number of DWORD params passed (not counting
fAddressConvert and nParams). For functions
that take no parameters this will be 0.
Returns
The API returns a DWORD which is the return value from the 32-bit entry point
represented by lpProcAddress32. The return value can also be 0 if lpProcAddress
was 0 or if nParams is greater than 32.
Comments
At minimum this routine takes 3 parameters (lpProcAddress32, fAddressConvert
and nParams). It can additionally take a maximum of 32 optional parameters.
These parameters must be DWORDS and must match the type that the 32-bit thunk
DLL is expecting. If the appropriate bit is set in the fAddressConvert mask,
the parameter will be translated from a 16:16 pointer to a 32-bit flat linear
pointer. Note that the lowest bit in the mask represents param1, the second
lowest bit represents param2, and so forth.
Under Windows NT version 3.1, the procedure called must be defined with the
_stdcall calling convention.
WARNING: Be careful when using this API, since there is no compiler check made
on the number and type of parameters, no conversions of types (all parameters
passed a DWORDS and will be passed directly to the function called without
conversion). No checks of 16:16 address are made (limit checks, NULL checks,
correct ring level, and so forth).
Reference
See also CallProcEx32W().
----------
DWORD FAR CallProcEx32W( DWORD nParams, DWORD fAddressConvert,
DWORD lpProcAddress, DWORD param1, ... );
This API is used by a 16-bit thunk DLL to call an entry point in a 32-bit DLL.
This function is new to Windows NT version 3.5.
Parameters
See the parameters for CallProc32W().
Comments
CallProcEx32W() is similar to CallProc32W(), but it uses the C calling
convention to allow easier and more flexible prototyping.
On Windows NT version 3.5, both CallProc32W() and CallProcEx32W() accept a
flag OR'd with the parameter count which indicates the calling convention of
the 32-bit procedure. For example, the call to a _cdecl function that accepts
1 parameter by value would look like this:
dwResult = CallProcEx32W( CPEX_DEST_CDECL | 1, 0, dwfn32, param1 );
while a similar call to a _stdcall function would look like this:
dwResult = CallProcEx32W( CPEX_DEST_STDCALL | 1, 0, dwfn32, param1 );
Reference
See also CallProc32W().
-------------------------------------------------------------------------------
The following are 32-bit WOW APIs exported by WOW32.DLL.
----------
LPVOID WINAPI WOWGetVDMPointer(DWORD vp, DWORD dwBytes, BOOL fProtectedMode);
Convert a 16:16 address to the equivalent flat address.
Parameters
vp Valid 16:16 address
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -