Generic Thunks

Microsoft® Windows NT® and Windows® 2000 support running 16-bit Windows-based applications using a technology referred to as WOW (Windows on Win32®). Each 16-bit application is run as a thread of a 32-bit process. Microsoft® Windows® 95 and Windows® 98 also support running 16-bit Windows-based applications. They are run as 16-bit processes.

You cannot directly mix 16-bit code and 32-bit code in the same process. You can use IPC mechanisms, such as DDE, RPC, OLE, named pipes, and WM_COPYDATA, to provide communication between 16-bit code and 32-bit code. However, there are occasions when it is necessary to call functions in Win32-based DLLs (including the system DLLs) from a 16-bit application. Generic thunks provide a mechanism for 16-bit applications to call functions in Win32-based DLLs.

  • About Generic Thunks
  • Using Generic Thunks
  • Generic Thunks Reference
Microsoft Platform SDK, February 2001 Edition.
This content last built on Thursday, February 01, 2001.


About Generic Thunks

The generic thunking mechanism provides functions that allow a 16-bit application to load a Win32®-based DLL, get the addresses of its exported functions, call the functions (passing each one up to thirty-two 32-bit arguments), convert 16:16 (WOW) addresses to 0:32 addresses (useful if you need to build up a 32-bit structure that contains pointers and pass a pointer to it), and free the Win32-based DLL. This process is similar to the run-time dynamic linking used between a Win32-based application and a Win32-based DLL.

You may find that other IPC mechanisms are more powerful and portable. Keep this in mind when deciding whether or not to use thunks.

Note Microsoft® Windows® 95 and Windows® 98 provide another thunking mechanism called flat thunks. For more information, see Thunk Compiler.


Process Context

In generic thunking, the Win32-based DLL is run in the context of the process that loaded it, namely the 16-bit Windows-based application.

The GDI, dialog box, message box, and message functions work within 32-bit code loaded in the context of a 16-bit process. However, not all base features are supported in the context of a 16-bit process. In general, 32-bit code loaded by 16-bit processes can use the Win32 heap functions, memory-mapped file functions, file functions, and functions involving the current process and thread. You should avoid using third party Win32-based DLLs, unless you are sure they work safely in a 16 bit-environment.

Windows 95/98/Me: There are a few additional limitations for Win32-based DLLs loaded by a 16-bit application:

  • The DLL uses the stack reserved by the 16-bit application, which is much smaller than the 1MB default stack used by a Win32-based application (generally between 5 and 45K).
  • The DLL cannot create new threads. Certain Win32 functions, such as those supporting the common dialog boxes or those supporting console applications, create threads on behalf of the calling application. Therefore, these functions cannot be used in a Win32-based DLL loaded by a 16-bit process.


Testing Your Generic Thunks

Debugging generic thunks is difficult, because the debuggers do not debug both the 16-bit and 32-bit sides of the thunk and it is difficult to run both a 16-bit and a 32-bit debugger simultaneously. For this reason, it is best to debug each side separately, then test the thunking portion, as follows.

  • Test the Win32-based DLL by calling it from a Win32-based application. Then you will be sure that the functions you will call through the thunk work correctly.
  • Test the 16-bit application by having it call a 16-bit DLL. Then you will be sure that you are calling the functions correctly, with the right data.
  • Test the thunk by having the 16-bit application call functions in the Win32-based DLL. Start with a simple thunk that does not require parameters. After you know that the basic thunk works, try a thunk that requires parameters. This approach helps you separate problems in calling the thunk from problems in passing parameters.

Be sure to test your thunks on all platforms. Because of architectural differences, programs using generic thunks may not be portable. In particular,

  • A Win32 function that can be called in the context of a 16-bit process under Windows NT/Windows 2000 is not guaranteed to work under Windows 95/98, or vice versa. For more information, see Process Context.
  • If more than one 16-bit application loads the same Win32-based DLL, you should not rely on them sharing the DLL data . On Windows NT/Windows 2000, 16-bit applications that share the same address space use the same DLL instance, so they share its data section, while 16-bit applications that run in separate address spaces use separate copies of the DLL. On Windows 95/98, 16-bit applications always use separate copies of the DLL.


Using Generic Thunks

One approach for implementing generic thunks is to isolate thunking code into DLLs. The advantage is that you can easily discard the thunking code when it is no longer needed. You can also create separate DLLs for each platform, to isolate platform-specific differences. Another approach for isolating platform differences is to detect the platform at run time and call the appropriate functions for each platform.

The examples in this overview demonstrate the required steps for a 16-bit Windows-based application named APP16 call the MyPrint routine from the Win32-based DLL named DLL32. These examples also give hints for isolating thunking code into a DLL named DLL16.

  • Declaring the DLL function
  • Loading the Win32-based DLL
  • Getting the address of the DLL function
  • Calling the DLL function
  • Freeing the Win32-based DLL

You can also use generic thunks to call back into the 16-bit side of the thunk from the 32-bit side of the thunk (generic callback). For more information, see WOWCallback16.

Note You can also use generic thunks to translate pointers outside of thunks. For more information, see, Translating 16:16 Pointers.


Declaring the DLL Function

You can declare the functions to be called through generic thunks (target functions) with either the standard-call calling convention (Intel only) or the C calling convention. It is important to call the target function using the correct convention.

The following example shows how to define the target function, MyPrint, in DLL32 as a standard-call function, using the WINAPI modifier:

void WINAPI MyPrint( LPTSTR lpString, HANDLE hWnd )
{
    ...
}

If you are isolating your thunking code into a DLL, create a DLL16 file and define MyPrint in DLL16 as well. Then when you call MyPrint from APP16, you will be calling the version in DLL16 and the version in DLL16 will perform the thunk to DLL32.


Loading the Win32-based DLL

You load the Win32-based DLL, DLL32, from APP16 by using the LoadLibraryEx32W function.

// Load the Win32-based DLL from the 16-bit code
if( NULL == (ghLib = LoadLibraryEx32W( "dll32.dll", NULL, 0 )) )
{
    MessageBox( NULL, "Cannot load DLL32", "App16", MB_OK );
    return 0;
}

If you are isolating your thunking code into DLL16, you can put the call to LoadLibraryEx32W in the LibMain function of the DLL16 code.

The instance handle is stored in the following global variable:

DWORD ghLib;

When linking the 16-bit code, you need to indicate that the generic thunking functions will be imported from the system kernel. For example, using Microsoft Visual C++, you would create an IMPORTS section in the module definition (.DEF) file for APP16, as follows.

IMPORTS
    kernel.LoadLibraryEx32W
    kernel.FreeLibrary32W
    kernel.GetProcAddress32W
    kernel.GetVDMPointer32W
    kernel.CallProcEx32W


Getting the Address of the DLL Function

Before you can call the target function, MyPrint, from the 16-bit code that loaded DLL32, you must get its address using the GetProcAddress32W function. For example:

// Get the address of the MyPrint routine in the Win32-based DLL
typedef void (FAR PASCAL *MYPROC)(LPSTR);
MYPROC hProc;

if( NULL == (hProc = (MYPROC)GetProcAddress32W( ghLib, "MyPrint" )))
{
    MessageBox( hWnd, "Cannot call DLL function", "App16", MB_OK );
    ...
}

If you are isolating your thunking code into DLL16, put the call to GetProcAddress32W in the MyPrint function of the DLL16 code.


Calling the DLL Function

Once you have obtained the address of the target DLL function, you can call it from APP16 using the CallProcEx32W function.

These examples call MyPrint, passing two arguments, a string and a window handle. All parameters must be 32-bit values. Therefore, the string is declared using a FAR pointer, as shown here:

char FAR *TestString = "Hello there";

You must convert the 16-bit window handle to a 32-bit window handle using the WOWHandle32 function, as shown here:

// Convert the window handle.
DWORD hWnd32;
hWnd32 = WOWHandle32(hWnd, WOW_TYPE_HWND);

The following example uses CallProcEx32W.

// Call the MyPrint routine in the Win32-based DLL
CallProcEx32W( 2 | CPEX_DEST_STDCALL,
                                   2,
                               hProc,
                  (DWORD) TestString,
                              hWnd32);

A mask of 2 (0x10) is given because we want to pass TestString by reference and hProc by value. The system translates the pointer for us.

If you are isolating your thunking code into DLL16, put the call to CallProcEx32W in the MyPrint function of the DLL16 code.


Freeing the Win32-based DLL

Be sure to free the Win32-based DLL using the FreeLibrary32W function before exiting the code that loaded the DLL (APP16 or DLL16). In APP16, you would make the following call.

// Free the Win32-based DLL from the 16-bit Windows-based application.
FreeLibrary32W( ghLib );

If you are isolating your thunking code into DLL16, you would put the call in your WEP function, if you put the call to the LoadLibraryEx32W function in your LibMain function.


Translating 16:16 Pointers

You may occasionally need to translate 16:16 pointers to 32-bit pointers. The GetVDMPointer32W and WOWGetVDMPointer functions accomplish this. Call GetVDMPointer32W from 16-bit code and WOWGetVDMPointer from 32-bit code to translate 16:16 pointers to 32-bit pointers. In addition, GlobalFix, GlobalUnfix, GlobalWire, and GlobalUnwire must be called from 16-bit code. For more information about these functions, see the 16-bit Windows SDK documentation.

Windows 95/98/Me:

If you use GetVDMPointer32W or WOWGetVDMPointer and the affected 16:16 pointer represents a movable global memory manager block, it is important that you first call the GlobalFix or GlobalWire function on the segment portion of the pointer. If you do not, the 16-bit global memory manager can move the block while your process is executing 32-bit code. If this happens, the linear address returned by GetVDMPointer32W or WOWGetVDMPointer will become invalid. The debugging version of the system generates warnings about calls to GetVDMPointer32W on unfixed segments.

The WOWGetVDMPointerFix function is similar to WOWGetVDMPointer, but ensures that the memory pointed to will not be moved by the global memory compacter until the WOWGetVDMPointerUnfix function has been called. WOWGetVDMPointerFix performs an implicit GlobalFix operation on the selector, if necessary. If the selector is allocated as a fixed block or if it is not from the global memory manager, no special action is taken. You should use this function instead of calling GlobalFix separately, because it is easier to use and is faster than calling both GlobalFix and WOWGetVDMPointer.

WOWGetVDMPointerUnfix takes a 16:16 address and undoes the effect of WOWGetVDMPointerFix on the segment (the offset portion is ignored). This function should be called once the linear address is no longer needed to avoid fragmentation. It is faster than the GlobalUnfix function and correctly handles (that is, ignores) selectors that are not from the 16-bit global memory manager.

Windows NT/2000 or later:

While you are executing 32-bit code called through a generic thunk, the 16-bit side of the thunk is completely blocked until you return or yield. Therefore, in most cases, you do not need to fix or wire the memory. Therefore, WOWGetVDMPointerFix is identical to WOWGetVDMPointer (it does not call GlobalFix) and WOWGetVDMPointerUnfix has no effect under Windows NT/Windows 2000.

If you are targeting only Windows NT/Windows 2000 and your 32-bit code yields the message system (by calling functions such as SendMessage, BroadcastSystemMessage, GetMessage, PeekMessage, MessageBox, or DialogBox), you should either call GlobalFix or GlobalWire ahead of time on the 16-bit side or refresh your 32-bit pointers after the yielding function call has completed by calling WOWGetVDMPointer.

If you are targeting Windows NT, Windows 2000, Windows 95, and Windows 98, there are two approaches that you can use. The easiest approach is to have the 16-bit side of the thunk first fix all of the segments in memory using GlobalFix or GlobalWire. In the 32-bit code, use WOWGetVDMPointer, rather than WOWGetVDMPointerFix, because the segments are already fixed in memory. After the 32-bit code returns, call GlobalFix or GlobalUnwire in the 16-bit code. This guarantees that your 32-bit pointers remain valid, regardless of the platform, even if the 16-bit global memory manager compacts the global heap. The drawback to this approach is that many segments can be left fixed in memory for extended periods of time, potentially causing out-of-memory conditions due to memory fragmentation.

The most efficient approach that still works on both platforms requires that you use WOWGetVDMPointerFix and WOWGetVDMPointerUnfix. On Windows NT/Windows 2000, the 32-bit pointers can still be affected by 16-bit memory movement if the 32-bit code yields the message system. After each call that might yield the messaging system, discard your 32-bit pointers using WOWGetVDMPointerUnfix. If you continue to use the pointer, repeat the original call to WOWGetVDMPointerFix to refresh the pointer. The drawback to this approach is that it cannot be used if the called function that yields the messaging system uses 32-bit pointers that you provide after yielding the messaging system. If you cannot determine if this will be a problem, the first approach would be a safer choice.


Generic Thunks Reference

The following functions are associated with generic thunks.

  • 16-bit Generic Thunk Functions
  • 32-bit Generic Thunk Functions


16-bit Generic Thunk Functions

The following generic thunk functions can be called by 16-bit Windows-based applications and DLLs.

CallProcEx32W
FreeLibrary32W
GetProcAddress32W
GetVDMPointer32W
LoadLibraryEx32W


CallProcEx32W

Use the CallProcEx32W function in 16-bit code to call an entry-point function in a Win32 DLL.

DWORD FAR CallProcEx32W(
  DWORD nParams,          // number of parameters passed
  DWORD fAddressConvert,  // bit mask
  DWORD lpProcAddress,    // the DLL function to be called
  DWORD param1            // parameter for DLL function
  ...                     // up to 32 function parameters
);

Parameters

nParams
[in] Number of DWORD parameters to be passed to the DLL function (param1 through paramN). For functions that take no parameters, this parameter will be zero. You can also specify the calling convention by using the OR operator to combine this value with one of the following values.
Value | Meaning
CPEX_DEST_STDCALL | The function uses the standard-call calling convention. This is the default.
CPEX_DEST_CDECL | The function uses the C calling convention.

fAddressConvert
[in] 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. The lowest bit in the mask represents the first parameter specified (param1), the second lowest bit represents the second to the last parameter specified (param2), and so on, so that the highest bit in the mask represents paramN.
lpProcAddress
[in] A value corresponding to the procedure to be called, which is returned by the GetProcAddress32W function.
param1 through param32
[in] Parameters for the 32-bit procedure represented by lpProcAddress

Return Values

Returns the return value from the 32-bit entry-point function represented by lpProcAddress. The return value can also be zero under the following conditions:

  • lpProcAddress is zero
  • nParams is greater than 32
  • lpProcAddress returns zero

Remarks

CallProcEx32W does not automatically fix global memory handles that are translated to 0:32 pointers. Therefore, you must call the GlobalFix or GlobalWire function on the handle first and GlobalUnfix and GlobalUnwire afterward.

Windows 95/98/Me: Global compaction can move memory blocks at any time while the current thread is executing 32-bit code. Because of this, not fixing segments before calling the target function works in Windows NT/Windows 2000, but may cause race conditions in Windows 95 or Windows 98.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt16.h.

See Also

Generic Thunks Overview, 16-bit Generic Thunk Functions, GetProcAddress32W


FreeLibrary32W

Use the FreeLibrary32W function in 16-bit code to free a Win32 DLL that it had previously loaded with the LoadLibraryEx32W function.

DWORD FAR PASCAL FreeLibrary32W(
  DWORD hInst  // handle to loaded library module
);

Parameters

hInst
[in] Handle to the loaded library module. Returned by LoadLibraryEx32W.

Return Values

Returns TRUE if successful or FALSE otherwise.

Remarks

The system does not do any cleanup of 32-bit thunk DLLs when the 16-bit application exits. The 16-bit application or DLL must free the 32-bit thunk DLL when it is finished using it.

Windows 95/98/Me: This function releases the Win16Mutex. If this function is called from a 16-bit DLL, it can be reentered as soon as the 32-bit DLL entry-point function is called. This happens when another 32-bit process thunks to the 16-bit DLL or when another 16-bit DLL calls this 16-bit DLL. However, if this function is called in a 16-bit application and the 32-bit DLL entry-point function does not yield, the function is not reentered.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt16.h.

See Also

Generic Thunks Overview, 16-bit Generic Thunk Functions, LoadLibraryEx32W


GetProcAddress32W

Use the GetProcAddress32W in 16-bit code to retrieve a value that represents a function in a Win32 DLL.

DWORD FAR PASCAL GetProcAddress32W(
  DWORD hModule,   // handle to loaded library module
  LPCSTR lpszProc  // name of function
);

Parameters

hModule
[in] Handle to the loaded library module that contains the function. The LoadLibraryEx32W function returns this handle.
lpszProc
[in] Pointer to a null-terminated string containing the function name.

Return Values

Returns a 32-bit value if successful. This value must be passed as a parameter to the CallProcEx32W function rather than being used directly.

Remarks

Windows 95/98/Me: This function releases the Win16Mutex. If this function is called from a 16-bit DLL, it can be reentered as soon as the 32-bit DLL entry-point function is called. This happens when another 32-bit process thunks to the 16-bit DLL or when another 16-bit DLL calls this 16-bit DLL. However, if this function is called in a 16-bit application and the 32-bit DLL entry-point function does not yield, the function is not reentered.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt16.h.

See Also

Generic Thunks Overview, 16-bit Generic Thunk Functions, CallProcEx32W, LoadLibraryEx32W


GetVDMPointer32W

Use GetVDMPointer32W in 16-bit code to translate a 16:16 pointer into a 32-bit pointer.

DWORD FAR PASCAL GetVDMPointer32W(
  LPVOID lpAddress,  // 16:16 address
  UINT fMode         // mode flag
);

Parameters

lpAddress
[in] Valid protected or real mode 16:16 address.
fMode
[in] Specifies the mode. This parameter can be one of the following values.
Value | Description
1 | The address is interpreted as a protected-mode address.
0 | The address is interpreted as a real-mode address.

Return Values

Returns a 32-bit linear address if successful or NULL otherwise.

Remarks

On non-x86 platforms, real mode address 0:0 may not point to linear 0 in memory, so always use GetVDMPointer32W to avoid making assumptions about memory layout.

The memory manager moves segments in linear memory, but keeps the selectors the same. However, if you get the linear address of a block, it may not be valid if the 16-bit global memory manager moves the block the selector points to.

Windows 95/98/Me: You should assume that global compaction can occur any time that a generic thunk is entered, a Win32 function is called, or the current application yields.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt16.h.

See Also

Generic Thunks Overview, 16-bit Generic Thunk Functions


LoadLibraryEx32W

Use the LoadLibraryEx32W function in 16-bit code to load a Win32 DLL.

DWORD FAR PASCAL LoadLibraryEx32W(
  LPCSTR lpszLibFile,  // name of executable module
  DWORD hFile,         // reserved, must be NULL
  DWORD dwFlags        // entry-point execution flag
);

Parameters

lpszLibFile
[in] Pointer to a null-terminated string that names a Win32-based DLL module.
hFile
[in] This parameter is reserved for future use. It must be NULL.
dwFlags
[in] Specifies the action to take when loading the module. This parameter can be one of the following values:

DONT_RESOLVE_DLL_REFERENCES
LOAD_LIBRARY_AS_DATAFILE
LOAD_WITH_ALTERED_SEARCH_PATH

For more information on these values, see LoadLibraryEx.

Return Values

If the function succeeds, the return value is a 32-bit handle to a DLL module. If the function fails, the return value is NULL.

Remarks

After calling this function, the 16-bit thunk DLL can call the GetProcAddress32W function to get the address of the 32-bit entrypoint function(s) and then call the thunk(s) by using the CallProcEx32W function.

Windows 95/98/Me: This function releases the Win16Mutex. If this function is called from a 16-bit DLL, it can be reentered as soon as the 32-bit DLL entry-point function is called. This happens when another 32-bit process thunks to the 16-bit DLL or when another 16-bit DLL calls this 16-bit DLL. However, if this function is called in a 16-bit application and the 32-bit DLL entry-point function does not yield, the function is not reentered.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt16.h.

See Also

Generic Thunks Overview, 16-bit Generic Thunk Functions, CallProcEx32W, GetProcAddress32W


32-bit Generic Thunk Functions

The following generic thunk functions can be called by Win32-based DLLs that were loaded and called by 16-bit code using generic thunks. These functions can only be called in the context of a thunk.

WOWCallback16
WOWCallback16Ex
WOWGetVDMPointer
WOWGetVDMPointerFix
WOWGetVDMPointerUnfix
WOWGlobalAlloc16
WOWGlobalAllocLock16
WOWGlobalFree16
WOWGlobalLock16
WOWGlobalLockSize16
WOWGlobalUnlock16
WOWGlobalUnlockFree16
WOWHandle16
WOWHandle32


WOWCallback16

Use the WOWCallback16 function in 32-bit code called from 16-bit code (through generic thunks) to call back to the 16-bit side (generic callback).

DWORD WINAPI WOWCallback16(
  DWORD vpfn16,  // pointer to callback function
  DWORD dwParam  // parameter for callback function
);

Parameters

vpfn16
[in] A 16:16 pointer to 16-bit callback routine, passed from the 16-bit side.
dwParam
[in] Parameter for the 16-bit callback routine. If this value is a pointer, it can be used as either a 16:16 or 0:32 pointer, as long as both sides agree on the semantics.

Return Values

The return value comes from the callback routine. If the callback routine returns a WORD type instead of a DWORD type, the upper 16 bits of the return value are undefined and should be ignored by using LOWORD(dwRetCode). If the callback routine has no return value, the entire return value of this function is undefined.

Remarks

The 16-bit function to be called must be declared with one of the following types.

DWORD FAR PASCAL CallbackRoutine(DWORD dwParam);

DWORD FAR PASCAL CallbackRoutine(VOID FAR *vp);

The type used is determined by whether the parameter is a pointer.

If you are passing a pointer, you will need to get the pointer by using either the WOWGlobalAlloc16 or WOWGlobalAllocLock16 function.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt32.h.
Library: Included as a resource in Wow32.dll.

See Also

Generic Thunks Overview, 32-bit Generic Thunk Functions, LOWORD, WOWGlobalAlloc16, WOWGlobalAllocLock16


WOWCallback16Ex

Use the WOWCallback16Ex function in 32-bit code called from 16-bit code (through generic thunks) to call back to the 16-bit side (generic callback).

BOOL WINAPI WOWCallback16Ex(
  DWORD vpfn16,      // pointer to callback function
  DWORD dwFlags,     // flags
  DWORD cbArgs,      // byte count of arguments for callback
  PVOID pArgs,       // arguments for callback function
  PDWORD pdwRetCode  // callback function return code
);

Parameters

vpfn16
[in] A 16:16 pointer to 16-bit callback routine, passed from the 16-bit side.
dwFlags
[in] Specifies the calling convention. This parameter can be one of the following values.
Value | Description
WCB16_CDECL | Calls a _cdecl callback routine.
WCB16_PASCAL | Calls a _pascal callback routine (default).

cbArgs
[in] Count of bytes in arguments (used to properly clean the 16-bit stack).
pArgs
[in] Arguments for the callback routine.
pdwRetCode
[out] Receives the return code from the callback routine.

Return Values

If cbArgs is larger than the WCB16_MAX_ARGS bytes that the system supports, the return value is FALSE and the GetLastError function returns the ERROR_INVALID_PARAMETER value. Otherwise, the return value is TRUE and the DWORD pointed to by pdwRetCode contains the return code from the callback routine. If the callback routine returns a WORD type instead of a DWORD type, the upper 16 bits of the return code are undefined and should be ignored by using LOWORD(dwRetCode).

Remarks

WOWCallback16Ex allows any combination of arguments up to WCB16_MAX_CBARGS bytes total to be passed to the 16-bit callback routine. Regardless of the value of cbArgs, WCB16_MAX_CBARGS bytes will always be copied from pArgs to the 16-bit stack. If pArgs is less than WCB16_MAX_CBARGS bytes from the end of a page and the next page is inaccessible, WOWCallback16Ex will incur an access violation.

The arguments pointed to by pArgs must be in the correct order for the callback routine's calling convention. For example, to call a Pascal routine, place the arguments in the pArgs array in reverse order, with the least significant word first for DWORD types and offset first for FAR pointers.

When you call a _cdecl routine, place the arguments in the pArgs array in the order listed in the function prototype with the least significant word first for DWORD types and offset first for FAR pointers.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt32.h.
Library: Included as a resource in Wow32.dll.

See Also

Generic Thunks Overview, 32-bit Generic Thunk Functions, LOWORD


WOWGetVDMPointer

The WOWGetVDMPointer function converts a 16:16 address to the equivalent linear address. This function can only be called in the context of a thunk.

LPVOID WINAPI WOWGetVDMPointer(
  DWORD vp,            // 16:16 address
  DWORD dwBytes,       // size of vp block
  BOOL fProtectedMode  // protected mode flag
);

Parameters

vp
[in] Valid 16:16 address.
dwBytes
[in] Size of the block pointed to by vp.
fProtectedMode
[in] Specifies the mode. This parameter can be one of the following values.
Value | Description
1 | The upper 16 bits are treated as a selector in the local descriptor table (16-bit protected mode pointer).
0 | The upper 16 bits are treated as a real-mode segment value (real-mode 16:16 pointer).

Return Values

Returns a 32-bit address if successful. If the function is invalid, the return value is NULL.

Remarks

Windows NT/2000 or later: Limit checking is performed only in the checked (debugging) build of WOW32.DLL, which will cause NULL to be returned when the limit is exceeded by the supplied offset.

Windows 95/98/Me: This function should never be used on a 16-bit global memory handle selector that has not been previously fixed in memory by using the GlobalFix or GlobalWire function. You should assume that global compaction can occur at any time the Win16Mutex is not owned by the current thread.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt32.h.
Library: Included as a resource in Wow32.dll.

See Also

Generic Thunks Overview, 32-bit Generic Thunk Functions


WOWGetVDMPointerFix

The WOWGetVDMPointerFix function converts a 16:16 address to the equivalent linear address. This function can only be called in the context of a thunk.

Windows 95/98/Me: This function calls the GlobalFix function before returning the linear address so that the 16-bit memory block will not be moved around in the 16-bit global heap.

Windows NT/2000 or later: This function behaves like the WOWGetVDMPointer function. The memory is not fixed.

LPVOID WINAPI WOWGetVDMPointerFix(
  DWORD vp,            // 16:16 address
  DWORD dwBytes,       // size of vp block
  BOOL fProtectedMode  // protected mode flag
);

Parameters

vp
[in] Valid 16:16 address.
dwBytes
[in] Size of the block pointed to by vp.
fProtectedMode
[in] Specifies the mode. This parameter can be one of the following values.
Value | Description
1 | The upper 16 bits are treated as a selector in the local descriptor table (16-bit protected mode pointer).
0 | The upper 16 bits are treated as a real-mode segment value (real-mode 16:16 pointer).

Return Values

Returns a 32-bit address if successful. If the selector is invalid, the return value is NULL.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt32.h.
Library: Included as a resource in Wow32.dll.

See Also

Generic Thunks Overview, 32-bit Generic Thunk Functions, WOWGetVDMPointer


WOWGetVDMPointerUnfix

Windows 95/98/Me: The WOWGetVDMPointerUnfix function uses the GlobalUnfix function to unfix the specified 16-bit memory block. This function can only be called in the context of a thunk.

Windows NT/2000 or later: This function has no effect.

VOID WINAPI WOWGetVDMPointerUnfix(
  DWORD vp  // 16:16 address
);

Parameters

vp
[in] Valid 16:16 address as specified in the WOWGetVDMPointerFix function.

Return Values

This function does not return a value.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt32.h.
Library: Included as a resource in Wow32.dll.

See Also

Generic Thunks Overview, 32-bit Generic Thunk Functions, WOWGetVDMPointerFix


WOWGlobalAlloc16

The WOWGlobalAlloc16 function allocates the specified number of bytes from the 16-bit global heap. This function can only be called in the context of a thunk.

WORD WINAPI WOWGlobalAlloc16(
  WORD wFlags,  // object allocation attributes
  DWORD cb      // number of bytes to allocate
);

Parameters

wFlags
[in] Specifies how to allocate memory. This parameter can be one or more of the following values.
GHND | GMEM_NODISCARD
GMEM_DDESHARE | GMEM_NOT_BANKED
GMEM_DISCARDABLE | GMEM_NOTIFY
GMEM_FIXED | GMEM_SHARE
GMEM_LOWER | GMEM_ZEROINIT
GMEM_MOVEABLE | GPTR
GMEM_NOCOMPACT

cb
[in] Specifies the number of bytes to allocate.

Return Values

Returns the handle of the newly allocated memory object if successful. Otherwise, returns NULL.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt32.h.
Library: Included as a resource in Wow32.dll.

See Also

Generic Thunks Overview, 32-bit Generic Thunk Functions, WOWGlobalLock16


WOWGlobalAllocLock16

The WOWGlobalAllocLock16 function combines the functionality of the WOWGlobalAlloc16 and WOWGlobalLock16 functions. This function can only be called in the context of a thunk.

DWORD WINAPI WOWGlobalAllocLock16(
  WORD wFlags,  // object allocation flags
  DWORD cb,     // number of bytes to allocate
  LPWORD phMem  // handle to global memory object
);

Parameters

wFlags
[in] Specifies how to allocate memory. This parameter can be one or more of the following values.
GHND | GMEM_NODISCARD
GMEM_DDESHARE | GMEM_NOT_BANKED
GMEM_DISCARDABLE | GMEM_NOTIFY
GMEM_FIXED | GMEM_SHARE
GMEM_LOWER | GMEM_ZEROINIT
GMEM_MOVEABLE | GPTR
GMEM_NOCOMPACT

cb
[in] Specifies the number of bytes to allocate.
phMem
[in] Handle to the object in the 16-bit global heap. This value is returned by WOWGlobalAllocLock16.

Return Values

Returns a pointer to the first byte of the memory block if successful. Otherwise, returns NULL.

Remarks

The pointer returned is a 16:16 pointer that cannot be dereferenced directly in 32-bit code. Instead, call the WOWGetVDMPointerFix function.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt32.h.
Library: Included as a resource in Wow32.dll.

See Also

Generic Thunks Overview, 32-bit Generic Thunk Functions, WOWGetVDMPointerFix, WOWGlobalAlloc16, WOWGlobalLock16


WOWGlobalFree16

The WOWGlobalFree16 function frees the specified global memory object. This function can only be called in the context of a thunk.

WORD WINAPI WOWGlobalFree16(
  WORD hMem  // handle to the global memory object
);

Parameters

hMem
[in] Handle to the object in the 16-bit global heap. This value must have been obtained from the WOWGlobalAlloc16 or WOWGlobalAllocLock16 function.

Return Values

Returns NULL if successful.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt32.h.
Library: Included as a resource in Wow32.dll.

See Also

Generic Thunks Overview, 32-bit Generic Thunk Functions, WOWGlobalAlloc16, WOWGlobalAllocLock16


WOWGlobalLock16

The WOWGlobalLock16 function locks a global memory object and returns a pointer to the first byte of the object's memory block. This function can only be called in the context of a thunk.

DWORD WINAPI WOWGlobalLock16(
  WORD hMem  // handle to the global memory object
);

Parameters

hMem
[in] Handle to the object in the 16-bit global heap. This value must have been obtained from the WOWGlobalAlloc16 or WOWGlobalAllocLock16 function.

Return Values

Returns a pointer to the first byte of the object's memory block if successful. Otherwise, returns NULL.

Remarks

The pointer returned is a 16:16 pointer that cannot be dereferenced directly in 32-bit code. Instead, call the WOWGetVDMPointerFix function.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt32.h.
Library: Included as a resource in Wow32.dll.

See Also

Generic Thunks Overview, 32-bit Generic Thunk Functions, WOWGetVDMPointerFix, WOWGlobalAlloc16, WOWGlobalAllocLock16


WOWGlobalLockSize16

The WOWGlobalLockSize16 function combines the functionality of the WOWGlobalLock16 and 16-bit GlobalSize functions. This function can only be called in the context of a thunk.

DWORD WINAPI WOWGlobalLockSize16(
  WORD hMem,  // handle to the global memory object
  PDWORD pcb  // gets size of the global memory object
);

Parameters

hMem
[in] Handle to the object in the 16-bit global heap. This value must have been obtained from the WOWGlobalAlloc16 or WOWGlobalAllocLock16 function.
pcb
Receives the size of the object in the 16-bit global heap.

Return Values

Returns a pointer to the first byte of the memory block if successful. Otherwise, returns NULL.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt32.h.
Library: Included as a resource in Wow32.dll.

See Also

Generic Thunks Overview, 32-bit Generic Thunk Functions, WOWGlobalAlloc16, WOWGlobalAllocLock16, WOWGlobalLock16


WOWGlobalUnlock16

The WOWGlobalUnlock16 function unlocks a global memory object. This function can only be called in the context of a thunk.

BOOL WINAPI WOWGlobalUnlock16(
  WORD hMem  // handle to the global memory object
);

Parameters

hMem
[in] Handle to the object in the 16-bit global heap. This value must have been obtained from the WOWGlobalAlloc16 or WOWGlobalAllocLock16 function.

Return Values

Returns zero if the object's lock count was decremented (decreased by one) to zero. Otherwise, returns a nonzero value.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt32.h.
Library: Included as a resource in Wow32.dll.

See Also

Generic Thunks Overview, 32-bit Generic Thunk Functions, WOWGlobalAlloc16, WOWGlobalAllocLock16


WOWGlobalUnlockFree16

The WOWGlobalUnlockFree16 function combines the functionality of the WOWGlobalUnlock16 and WOWGlobalFree16 functions. This function can only be called in the context of a thunk.

WORD WINAPI WOWGlobalUnlockFree16(
  DWORD vpMem  // address of memory block
);

Parameters

vpMem
[in] Pointer to the memory block returned by the WOWGlobalLock16 or WOWGlobalAllocLock16 function.

Return Values

Returns NULL if successful.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt32.h.
Library: Included as a resource in Wow32.dll.

See Also

Generic Thunks Overview, 32-bit Generic Thunk Functions, WOWGlobalAllocLock16, WOWGlobalFree16, WOWGlobalLock16, WOWGlobalUnlock16


WOWHandle16

The WOWHandle16 function is used to map a 32-bit handle to a 16-bit handle. Because the relationship between a Win16 handle and a Win32 handle may change in the future, use this function to convert handles instead of any knowledge of the relationship between them.

This function can only be called in the context of a thunk.

WORD WINAPI WOWHandle16(
  HANDLE Handle,        // 32-bit handle
  WOW_HANDLE_TYPE Type  // handle type
);

Parameters

Handle
[in] The 32-bit handle to be mapped.
Type
[in] Specifies the type of handle being translated. The accepted values are of the form WOW_TYPE_handle, where handle can be one of the following values.

HWND
HRGN
HMENU
HBITMAP
HDWP
HBRUSH
HDROP
HPALETTE
HDC
HPEN
HFONT
HACCEL
HMETAFILE
HTASK

For example, use WOW_TYPE_HWND to convert an HWND.

Return Values

A 16-bit handle.

Remarks

You can also use supplied macros to map handles. For example, to map a 32-bit HWND to a 16-bit HWND, you would use the HWND_16 macro.

(hWnd16 = HWND_16(hWnd32))

WOWHandle16 with WOW_TYPE_HTASK (and HTASK_16) takes a thread identifier and converts it to a handle to a task if possible.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt32.h.
Library: Included as a resource in Wow32.dll.

See Also

Generic Thunks Overview, 32-bit Generic Thunk Functions, WOWHandle32


WOWHandle32

The WOWHandle32 function is used to map a 16-bit handle to a 32-bit handle. Because the relationship between a Win16 handle and a Win32 handle may change in the future, use this function to convert handles instead of any knowledge of the relationship between them.

This function can only be called in the context of a thunk.

HANDLE WINAPI WOWHandle32(
  WORD Handle,          // 16-bit handle
  WOW_HANDLE_TYPE Type  // handle type
);

Parameters

Handle
[in] The 16-bit handle to be mapped.
Type
[in] Indicates the type of handle being translated.

The accepted values are of the form WOW_TYPE_handle, where handle can be one of the following values.

HWND
HBITMAP
HMENU
HBRUSH
HDWP
HPALETTE
HDROP
HPEN
HDC
HACCEL
HFONT
HTASK
HMETAFILE
FULLHWND
HRGN

For example, use WOW_TYPE_HWND to convert an HWND.

Return Values

A 32-bit handle.

Remarks

You can also use supplied macros to map handles. For example, to map a 16-bit HWND to a 32-bit HWND, you would use the HWND_32 macro.

(hWnd32 = HWND_32(hWnd16))

The type WOW_TYPE_FULLHWND is a window handle that the system passes to a Win32-based application. The type WOW_TYPE_HWND has a different value, but it is recognized by the system and may be passed as a parameter to Win32 functions. If you intend to store the window handle and use it in comparisons with 32-bit window handles received from Win32 functions, use WOW_TYPE_FULLHWND when calling WOWHandle32. Do not make assumptions about the relationship between the 16-bit window handle, the 32-bit window handle, and the full window handle. This relationship has changed in the past (for performance reasons), and it may change again in the future.

When you pass WOWHandle32 type WOW_TYPE_HTASK with a 16-bit task handle, it returns a 32-bit thread identifier. You may compare this value with other thread identifiers, such as those returned by the GetWindowThreadProcessId function.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wownt32.h.
Library: Included as a resource in Wow32.dll.

See Also

Generic Thunks Overview, 32-bit Generic Thunk Functions, WOWHandle16


Large Integers

This overview describes the support for operations on large (64-bit) integers provided by 32-bit Windows. For information on 64-bit integers on 64-bit Windows, see The New Data Types.

Applications can multiply signed or unsigned 32-bit integers, generating 64-bit results, by using the Int32x32To64 and UInt32x32To64 functions. Applications can shift bits in 64-bit values to the left or right by using the Int64ShllMod32, Int64ShraMod32, and Int64ShrlMod32 functions. These functions provide logical and arithmetic shifting.

Applications can also multiply and divide 32-bit values in a single operation by using the MulDiv function. Although the result of the operation is a 32-bit value, the function stores the intermediate result as a 64-bit value, so that information is not lost when large 32-bit values are multiplied and divided.

Note Your C compiler may support 64-bit integers natively. For example, Microsoft® Visual C++® supports the __int64 sized integer type. For more information, see the documentation included with your C compiler.


Large Integer Reference

The following elements are used with large integers.

  • Large Integer Functions
  • Large Integer Structures


Large Integer Functions

The following functions are used with large integers.

Function | Description
Int32x32To64 | Multiplies two signed 32-bit integers.
Int64ShllMod32 | Performs a left logical shift operation on an unsigned 64-bit integer value.
Int64ShraMod32 | Performs a right arithmetic shift operation on a signed 64-bit integer value.
Int64ShrlMod32 | Performs a right logical shift operation on an unsigned 64-bit integer value.
MulDiv | Multiplies two 32-bit values and then divides the 64-bit result by a third 32-bit value.
UInt32x32To64 | Multiplies two unsigned 32-bit integers, returning an unsigned 64-bit integer result.


Int32x32To64

The Int32x32To64 function multiplies two signed 32-bit integers, returning a signed 64-bit integer result. The function performs optimally on all Win32 platforms.

LONGLONG Int32x32To64(
  LONG Multiplier,    // first signed 32-bit integer
  LONG Multiplicand   // second signed 32-bit integer
);

Parameters

Multiplier
[in] Specifies the first signed 32-bit integer for the multiplication.
Multiplicand
[in] Specifies the second signed 32-bit integer for the multiplication.

Return Values

The return value is the signed 64-bit integer result of the multiplication.

Remarks

This function is implemented on all platforms by optimal inline code: a single multiply instruction that returns a 64-bit result.

Please note that the function's return value is a 64-bit value, not a LARGE_INTEGER structure.

For example, see Converting a time_t Value to a File Time.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

UInt32x32To64


Int64ShllMod32

The Int64ShllMod32 function performs a left logical shift operation on an unsigned 64-bit integer value. The function provides improved shifting code for left logical shifts where the shift count is in the range 0 – 31.

ULONGLONG Int64ShllMod32(
  ULONGLONG Value,  // unsigned 64-bit integer
  DWORD ShiftCount  // shift count
);

Parameters

Value
[in] Specifies the unsigned 64-bit integer to be shifted.
ShiftCount
[in] Specifies a shift count in the range 0 – 31.

Return Values

The return value is the unsigned 64-bit integer result of the left logical shift operation.

Remarks

The shift count is the number of bit positions that the value's bits move.

In a left logical shift operation on an unsigned value, the value's bits move to the left, and vacated bits on the right side of the value are set to zero.

A compiler can generate optimal code for a left logical shift operation when the shift count is a constant. However, if the shift count is a variable whose range of values is unknown, the compiler must assume the worst case, leading to non-optimal code: code that calls a subroutine, or code that is inline but branches. By restricting the shift count to the range 0 – 31, the Int64ShllMod32 function lets the compiler generate optimal or near-optimal code.

Please note that the Int64ShllMod32 function's Value parameter and return value are 64-bit values, not LARGE_INTEGER structures.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Int64ShraMod32, Int64ShrlMod32


Int64ShraMod32

The Int64ShraMod32 function performs a right arithmetic shift operation on a signed 64-bit integer value. The function provides improved shifting code for right arithmetic shifts where the shift count is in the range 0 – 31.

LONGLONG Int64ShraMod32(
  LONGLONG Value,    // signed 64-bit integer
  DWORD ShiftCount   // shift count
);

Parameters

Value
[in] Specifies the signed 64-bit integer to be shifted.
ShiftCount
[in] Specifies a shift count in the range 0 – 31.

Return Values

The return value is the signed 64-bit integer result of the right arithmetic shift operation.

Remarks

The shift count is the number of bit positions that the value's bits move.

In a right arithmetic shift operation on a signed value, the value's bits move to the right, and vacated bits on the left side of the value are set to the value of the sign bit.

A compiler can generate optimal code for a right arithmetic shift operation when the shift count is a constant. However, if the shift count is a variable whose range of values is unknown, the compiler must assume the worst case, leading to non-optimal code: code that calls a subroutine, or code that is inline but branches. By restricting the shift count to the range 0 – 31, the Int64ShraMod32 function lets the compiler generate optimal or near-optimal code.

Please note that the Int64ShraMod32 function's Value parameter and return value are 64-bit values, not LARGE_INTEGER structures.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Int64ShllMod32, Int64ShrlMod32


Int64ShrlMod32

The Int64ShrlMod32 function performs a right logical shift operation on an unsigned 64-bit integer value. The function provides improved shifting code for right logical shifts where the shift count is in the range 0 – 31.

ULONGLONG Int64ShrlMod32(
  ULONGLONG Value,  // unsigned 64-bit integer
  DWORD ShiftCount  // shift count
);

Parameters

Value
[in] Specifies the unsigned 64-bit integer to be shifted.
ShiftCount
[in] Specifies a shift count in the range 0 – 31.

Return Values

The return value is the unsigned 64-bit integer result of the right logical shift operation.

Remarks

The shift count is the number of bit positions that the value's bits move.

In a right logical shift operation on an unsigned value, the value's bits move to the right, and vacated bits on the left side of the value are set to zero.

A compiler can generate optimal code for a right logical shift operation when the shift count is a constant. However, if the shift count is a variable whose range of values is unknown, the compiler must assume the worst case, leading to non-optimal code: code that calls a subroutine, or code that is inline but branches. By restricting the shift count to the range 0 – 31, the Int64ShrlMod32 function lets the compiler generate optimal or near-optimal code.

Note The Int64ShrlMod32 function's Value parameter and return value are 64-bit values, not LARGE_INTEGER structures.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Int64ShllMod32, Int64ShraMod32


MulDiv

The MulDiv function multiplies two 32-bit values and then divides the 64-bit result by a third 32-bit value. The return value is rounded up or down to the nearest integer.

int MulDiv(
  int nNumber,       // 32-bit signed multiplicand
  int nNumerator,    // 32-bit signed multiplier
  int nDenominator   // 32-bit signed divisor
);

Parameters

nNumber
[in] Specifies the multiplicand.
nNumerator
[in] Specifies the multiplier.
nDenominator
[in] Specifies the number by which the result of the multiplication (nNumber * nNumerator) is to be divided.

Return Values

If the function succeeds, the return value is the result of the multiplication and division. If either an overflow occurred or nDenominator was 0, the return value is –1.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

Int32x32To64, UInt32x32To64


UInt32x32To64

The UInt32x32To64 function multiplies two unsigned 32-bit integers, returning an unsigned 64-bit integer result. The function performs optimally on all Win32 platforms.

ULONGLONG UInt32x32To64(
  DWORD Multiplier,    // first unsigned 32-bit integer
  DWORD Multiplicand   // second unsigned 32-bit integer
);

Parameters

Multiplier
[in] Specifies the first unsigned 32-bit integer for the multiplication.
Multiplicand
[in] Specifies the second unsigned 32-bit integer for the multiplication.

Return Values

The return value is the unsigned 64-bit integer result of the multiplication.

Remarks

This function is implemented on all platforms by optimal inline code: a single multiply instruction that returns a 64-bit result.

Please note that the function's return value is a 64-bit value, not a LARGE_INTEGER structure.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Int32x32To64


Large Integer Structures

The following structures represent large integers.

LARGE_INTEGER
ULARGE_INTEGER


LARGE_INTEGER

The LARGE_INTEGER structure is used to represent a 64-bit signed integer value.

Note Your C compiler may support 64-bit integers natively. For example, Microsoft® Visual C++® supports the __int64 sized integer type. For more information, see the documentation included with your C compiler.

typedef union _LARGE_INTEGER {
  struct {
      DWORD LowPart;
      LONG  HighPart;
  };
  LONGLONG QuadPart;
} LARGE_INTEGER, *PLARGE_INTEGER;

Members

LowPart
Specifies the low-order 32 bits.
HighPart
Specifies the high-order 32 bits.
QuadPart
Specifies a 64-bit signed integer.

Remarks

The LARGE_INTEGER structure is actually a union. If your compiler has built-in support for 64-bit integers, use the QuadPart member to store the 64-bit integer. Otherwise, use the LowPart and HighPart members to store the 64-bit integer.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

LUID, ULARGE_INTEGER


ULARGE_INTEGER

The ULARGE_INTEGER structure is used to specify a 64-bit unsigned integer value.

Note Your C compiler may support 64-bit integers natively. For example, Microsoft® Visual C++® supports the __int64 sized integer type. For more information, see the documentation included with your C compiler.

typedef union _ULARGE_INTEGER {
  struct {
      DWORD LowPart;
      DWORD HighPart;
  };
  ULONGLONG QuadPart;
} ULARGE_INTEGER, *PULARGE_INTEGER;

Members

LowPart
Specifies the low-order 32 bits.
HighPart
Specifies the high-order 32 bits.
QuadPart
Specifies a 64-bit unsigned integer.

Remarks

The ULARGE_INTEGER structure is actually a union. If your compiler has built-in support for 64-bit integers, use the QuadPart member to store the 64-bit integer. Otherwise, use the LowPart and HighPart members to store the 64-bit integer.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

LARGE_INTEGER


Interlocked Singly Linked Lists

[This is preliminary documentation and subject to change.]

Interlocked singly linked lists (SLists) ease the task of insertion and deletion from a linked list. They are implemented using a nonblocking algorithm to provide atomic synchronization, increase system performance, and avoid problems such as priority inversion and lock convoys.

For more information, see the following topics:

  • About Singly Linked Lists
  • Using Singly Linked Lists
  • SList Reference


About Singly Linked Lists

[This is preliminary documentation and subject to change.]

Singly linked lists (SLists) are straightforward to implement and use in 32-bit code. However, it is challenging to implement them in 64-bit code because the amount of data exchangeable by the native interlocked exchange primitives is not double the address size, as it is in 32-bit code. Therefore, Whistler provides SLists to enable porting high-end scalable algorithms to Windows.

Applications can use SLists by calling the InitializeSListHead function to initialize the head of the list. To insert items into the list, use the InterlockedPushEntrySList function. To delete items from the list, use the InterlockedPopEntrySList function.


Using Singly Linked Lists

[This is preliminary documentation and subject to change.]

The following examples demonstrate the use of singly linked lists:

  • Inserting Items into a Singly Linked List
  • Removing Items from a Singly Linked List


Inserting Items into a Singly Linked List

[This is preliminary documentation and subject to change.]

The following example uses the InitializeSListHead function to initialize an SList and the InterlockedPushEntrySList function to insert 10 items.

#include <windows.h>
#include <malloc.h>

// Structure to be used for a list item. Typically, the first member
// is of type SINGLE_LIST_ENTRY. Additional members are used for data.
// Here, the data is simply a signature for testing purposes.

typedef struct _PROGRAM_ITEM {
    SINGLE_LIST_ENTRY ItemEntry;
    ULONG Signature;
} PROGRAM_ITEM, *PPROGRAM_ITEM;

void main( )
{
    ULONG Count;
    PSINGLE_LIST_ENTRY FirstEntry;
    SLIST_HEADER ListHead;
    PPROGRAM_ITEM ProgramItem;

    // Initialize the list header.
    InitializeSListHead(&ListHead);

    // Insert 10 items into the list.
    for( Count = 1; Count <= 10; Count += 1 )
    {
        ProgramItem = (PPROGRAM_ITEM)malloc(sizeof(*ProgramItem));
        ProgramItem->Signature = Count;
        FirstEntry = InterlockedPushEntrySList(&ListHead,
                       &ProgramItem->ItemEntry);
    }
}


Removing Items from a Singly Linked List

[This is preliminary documentation and subject to change.]

The following code fragment removes items from the SList created in the example Inserting Items into a Singly Linked List. The code uses the InterlockedPopEntrySList function to remove 10 items and the InterlockedFlushSList function to verify that the list is empty.

// Remove 10 items from the list.
for( Count = 10; Count <= 1; Count -= 1 )
{
    ListEntry = InterlockedPopEntrySList(&ListHead);
    ProgramItem=CONTAINING_RECORD(ListEntry, PROGRAM_ITEM, ItemEntry);
}

// Flush the list and verify that the items are gone.
ListEntry = InterlockedFlushSList(&ListHead);
FirstEntry = InterlockedPopEntrySList(&ListHead);
if (FirstEntry != NULL)
{
    // Error - list is not empty.
}


SList Reference

[This is preliminary documentation and subject to change.]

The following elements are used with singly linked lists:

  • SList Functions
  • SList Structures


SList Functions

[This is preliminary documentation and subject to change.]

The following functions are used with singly linked lists.

Function | Description
InitializeSListHead | Initializes the head of a singly linked list.
InterlockedFlushSList | Flushes the entire list of items in a singly linked list.
InterlockedPopEntrySList | Removes an item from the front of a singly linked list.
InterlockedPushEntrySList | Inserts an item at the front of a singly linked list.


InitializeSListHead

[This is preliminary documentation and subject to change.]

The InitializeSListHead function initializes the head of a singly linked list.

VOID InitializeSListHead(
  PSLIST_HEADER ListHead
);

Parameters

ListHead
Pointer to an SLIST_HEADER structure that represents the head of a singly linked list. This structure is for system use only.

Return Values

This function does not return a value.

Remarks

All list items must be aligned on a heap allocation boundary. Unaligned items can cause unpredictable results.

To add items to the list, use the InterlockedPushEntrySList function. To remove items from the list, use the InterlockedPopEntrySList function.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

InterlockedPopEntrySList, InterlockedPushEntrySList


InterlockedFlushSList

[This is preliminary documentation and subject to change.]

The InterlockedFlushSList function flushes all items from a singly linked list. Access to the list is synchronized on a multiprocessor system.

PSINGLE_LIST_ENTRY InterlockedFlushSList(
  PSLIST_HEADER ListHead
);

Parameters

ListHead
Pointer to an SLIST_HEADER structure that represents the head of the singly linked list. This structure is for system use only.

Return Values

The return value is a pointer to the items removed from the list. If the list is empty, the return value is NULL.

Remarks

All list items must be aligned on a heap allocation boundary. Unaligned items can cause unpredictable results.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

SINGLE_LIST_ENTRY


InterlockedPopEntrySList

[This is preliminary documentation and subject to change.]

The InterlockedPopEntrySList function removes an item from the front of a singly linked list. Access to the list is synchronized on a multiprocessor system.

PSINGLE_LIST_ENTRY InterlockedPopEntrySList(
  PSLIST_HEADER ListHead
);

Parameters

ListHead
Pointer to an SLIST_HEADER structure that represents the head of a singly linked list. This structure is for system use only.

Return Values

The return value is a pointer to the item removed from the list. If the list is empty, the return value is NULL.

Remarks

All list items must be aligned on a heap allocation boundary. Unaligned items can cause unpredictable results.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

InterlockedPushEntrySList, SINGLE_LIST_ENTRY


InterlockedPushEntrySList

[This is preliminary documentation and subject to change.]

The InterlockedPushEntrySList function inserts an item at the front of a singly linked list. Access to the list is synchronized on a multiprocessor system.

PSINGLE_LIST_ENTRY InterlockedPushEntrySList(
  PSLIST_HEADER ListHead,
  PSINGLE_LIST_ENTRY ListEntry
);

Parameters

ListHead
Pointer to an SLIST_HEADER structure that represents the head of a singly linked list. This structure is for system use only.
ListEntry
Pointer to a SINGLE_LIST_ENTRY structure that represents an item in a singly linked list.

Return Values

The return value is the previous first item in the list. If the list was previously empty, the return value is NULL.

Remarks

All list items must be aligned on a heap allocation boundary. Unaligned items can cause unpredictable results.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.

See Also

InterlockedPopEntrySList, SINGLE_LIST_ENTRY


SList Structures

[This is preliminary documentation and subject to change.]

The following structure is used with singly linked lists.

SINGLE_LIST_ENTRY


SINGLE_LIST_ENTRY

[This is preliminary documentation and subject to change.]

The SINGLE_LIST_ENTRY structure represents an item in a singly linked list.

typedef struct _SINGLE_LIST_ENTRY {
  struct _SINGLE_LIST_ENTRY *Next;
} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;

Members

Next
Pointer to a SINGLE_LIST_ENTRY structure that represents the next item in a singly linked list.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Winbase.h; include Windows.h.

See Also

InitializeSListHead, InterlockedFlushSList, InterlockedPopEntrySList, InterlockedPushEntrySList


Tool Help Library

The functions provided by the tool help library make it easier for you to obtain information about currently executing Win32®-based applications. These functions are designed to streamline the creation of Win32-hosted tools, specifically debuggers.

  • About Tool Help Functions
  • Using the Tool Help Functions
  • Tool Help Reference


About Tool Help Functions

The following topics are discussed in this article:

  • Snapshots of the system
  • Process walking
  • Thread walking
  • Module walking
  • Heap lists and heap walking


Snapshots of the System

Snapshots are at the core of the tool help functions. A snapshot is a read-only copy of the current state of one or more of the following lists that reside in system memory: processes, threads, modules, and heaps.

Processes that use tool help functions access these lists from snapshots instead of directly from the operating system. The lists in system memory change when processes are started and ended, threads are created and destroyed, executable modules are loaded and unloaded from system memory, and heaps are created and destroyed. The use of information from a snapshot prevents inconsistencies. Otherwise, changes to a list could possibly cause a thread to incorrectly traverse the list or cause an access violation (a GP fault). For example, if an application traverses the thread list while other threads are created or terminated, information that the application is using to traverse the thread list might become outdated and could cause an error for the application traversing the list.

You can take a snapshot of the system memory by using the CreateToolhelp32Snapshot function. You can control the content of a snapshot by specifying one or more of the following values when calling this function:

  • TH32CS_SNAPHEAPLIST
  • TH32CS_SNAPMODULE
  • TH32CS_SNAPPROCESS
  • TH32CS_SNAPTHREAD

The TH32CS_SNAPHEAPLIST and TH32CS_SNAPMODULE values are process specific. When these values are specified, the heap and module lists of the specified process are included in the snapshot. If you specify zero as the process identifier, the current process is used. The TH32CS_SNAPTHREAD value always creates a system-wide snapshot even if a process identifier is passed to CreateToolhelp32Snapshot.

You can enumerate the heap or module state for all processes by specifying the TH32CS_SNAPALL value and the current process. Then, for each process in the snapshot that is not the current process, you can call CreateToolhelp32Snapshot again, specifying the process identifier and the TH32CS_SNAPHEAPLIST or TH32CS_SNAPMODULE value.

You can retrieve an extended error status code for CreateToolhelp32Snapshot by using the GetLastError function.

When your process finishes using a snapshot, you should destroy it by using the CloseHandle function. Not destroying a snapshot causes the process to leak memory until the process exits, at which time the system reclaims the memory.

Note The snapshot handle acts like a file handle and is subject to the same rules regarding which processes and threads it is valid in.


Process Walking

A snapshot that includes the process list contains information about each currently executing process. You can retrieve information for the first process in the list by using the Process32First function. After retrieving the first process in the list, you can traverse the process list for subsequent entries by using the Process32Next function. Process32First and Process32Next fill a PROCESSENTRY32 structure with information about a process in the snapshot.

You can retrieve an extended error status code for Process32First and Process32Next by using the GetLastError function.

You can read the memory in a specific process into a buffer by using the Toolhelp32ReadProcessMemory function (or the VirtualQueryEx function).

Note The contents of the th32ProcessID and th32ParentProcessID members of PROCESSENTRY32 are process identifiers and can be used by Win32 Application Programming Interface (API) elements.


Thread Walking

A snapshot that includes the thread list contains information about each thread of each currently executing process. You can retrieve information for the first thread in the list by using the Thread32First function. After retrieving the first thread in the list, you can retrieve information for subsequent threads by using the Thread32Next function. Thread32First and Thread32Next fill a THREADENTRY32 structure with information about individual threads in the snapshot.

You can enumerate the threads of a specific process by taking a snapshot that includes the threads and then by traversing the thread list, keeping information about the threads that have the same process identifier as the specified process.

You can retrieve an extended error status code for Thread32First and Thread32Next by using the GetLastError function.

Note The contents of the th32ThreadID member of THREADENTRY32 is a thread identifier and can be used by Win32 API elements.


Module Walking

A snapshot that includes the module list for a specified process contains information about each module, executable file, or dynamic-link library (DLL), used by the specified process. You can retrieve information for the first module in the list by using the Module32First function. After retrieving the first module in the list, you can retrieve information for subsequent modules in the list by using the Module32Next function. Module32First and Module32Next fill a MODULEENTRY32 structure with information about the module.

You can retrieve an extended error status code for Module32First and Module32Next by using the GetLastError function.

Note The module identifier, which is specified in the th32ModuleID member of MODULEENTRY32, has meaning only to the tool help functions. It is not a handle, nor is it usable by Win32 API elements.


Heap Lists and Heap Walking

A snapshot that includes the heap list for a specified process contains identification information for each heap associated with the specified process and detailed information about each heap. You can retrieve an identifier for the first heap of the heap list by using the Heap32ListFirst function. After retrieving the first heap in the list, you can traverse the heap list for subsequent heaps associated with the process by using the Heap32ListNext function. Heap32ListFirst and Heap32ListNext fill a HEAPLIST32 structure with the process identifier, the heap identifier, and flags describing the heap.

You can retrieve information about the first block of a heap by using the Heap32First function. After retrieving the first block of a heap, you can retrieve information about subsequent blocks of the same heap by using the Heap32Next function. Heap32First and Heap32Next fill a HEAPENTRY32 structure with information for the appropriate block of a heap.

You can retrieve an extended error status code for Heap32ListFirst, Heap32ListNext, Heap32First, and Heap32Next by using the GetLastError function.

Note The heap identifier, which is specified in the th32HeapID member of the HEAPENTRY32 structure, has meaning only to the tool help functions. It is not a handle, nor is it usable by Win32 API elements.


Using the Tool Help Functions

This section contains examples demonstrating how to perform the following tasks:

  • Taking a snapshot and viewing processes
  • Traversing the thread list
  • Traversing the module list


Taking a Snapshot and Viewing Processes

The following example obtains a list of running processes. First, the GetProcessList function takes a snapshot of the currently executing processes in the system using the CreateToolhelp32Snapshot function, then it walks through the list recorded in the snapshot, using the Process32First and Process32Next functions. For each process, the function calls GetProcessModule, which is defined in Traversing the module list.

#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

BOOL GetProcessList ()
{
    HANDLE         hProcessSnap = NULL;
    BOOL           bRet      = FALSE;
    PROCESSENTRY32 pe32      = {0};

    //  Take a snapshot of all processes in the system.

    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (hProcessSnap == INVALID_HANDLE_VALUE)
        return (FALSE);

    //  Fill in the size of the structure before using it.

    pe32.dwSize = sizeof(PROCESSENTRY32);

    //  Walk the snapshot of the processes, and for each process,
    //  display information.

    if (Process32First(hProcessSnap, &pe32))
    {
        DWORD         dwPriorityClass;
        BOOL          bGotModule = FALSE;
        MODULEENTRY32 me32       = {0};

        do
        {
            bGotModule = GetProcessModule(pe32.th32ProcessID,
                pe32.th32ModuleID, &me32, sizeof(MODULEENTRY32));

            if (bGotModule)
            {
                HANDLE hProcess;

                // Get the actual priority class.
                hProcess = OpenProcess (PROCESS_ALL_ACCESS,
                    FALSE, pe32.th32ProcessID);
                dwPriorityClass = GetPriorityClass (hProcess);
                CloseHandle (hProcess);

                // Print the process's information.
                printf( "\nPriority Class Base\t%d\n",
                    pe32.pcPriClassBase);
                printf( "PID\t\t\t%d\n", pe32.th32ProcessID);
                printf( "Thread Count\t\t%d\n", pe32.cntThreads);
                printf( "Module Name\t\t%s\n", me32.szModule);
                printf( "Full Path\t\t%s\n\n", me32.szExePath);
            }
        }
        while (Process32Next(hProcessSnap, &pe32));
        bRet = TRUE;
    }
    else
        bRet = FALSE;    // could not walk the list of processes

    // Do not forget to clean up the snapshot object.

    CloseHandle (hProcessSnap);
    return (bRet);
}


Traversing the Thread List

The following example obtains a list of running threads for the specified process. First, the RefreshThreadList function takes a snapshot of the currently executing threads in the system using the CreateToolhelp32Snapshot function, then it walks through the list recorded in the snapshot, using the Thread32First and Thread32Next functions. The parameter for RefreshThreadList is the identifier of the process whose threads will be listed.

#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

BOOL RefreshThreadList (DWORD dwOwnerPID)
{
    HANDLE        hThreadSnap = NULL;
    BOOL          bRet        = FALSE;
    THREADENTRY32 te32        = {0};

    // Take a snapshot of all threads currently in the system.

    hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if (hThreadSnap == INVALID_HANDLE_VALUE)
        return (FALSE);

    // Fill in the size of the structure before using it.

    te32.dwSize = sizeof(THREADENTRY32);

    // Walk the thread snapshot to find all threads of the process.
    // If the thread belongs to the process, add its information
    // to the display list.

    if (Thread32First(hThreadSnap, &te32))
    {
        do
        {
            if (te32.th32OwnerProcessID == dwOwnerPID)
            {
                printf( "\nTID\t\t%d\n", te32.th32ThreadID);
                printf( "Owner PID\t%d\n", te32.th32OwnerProcessID);
                printf( "Delta Priority\t%d\n", te32.tpDeltaPri);
                printf( "Base Priority\t%d\n", te32.tpBasePri);
            }
        }
        while (Thread32Next(hThreadSnap, &te32));
        bRet = TRUE;
    }
    else
        bRet = FALSE;          // could not walk the list of threads

    // Do not forget to clean up the snapshot object.

    CloseHandle (hThreadSnap);

    return (bRet);
}


Traversing the Module List

The following example obtains a list of modules for the specified process. First, the GetProcessModule function takes a snapshot of the system using the CreateToolhelp32Snapshot function, then it walks through the list recorded in the snapshot, using the Module32First and Module32Next functions. The parameters for GetProcessModule are as follows:

dwPID
Identifier of the process that owns the module whose information will be retrieved.
dwModuleID
Tool help identifier of the process module.
lpMe32
Structure that receives data about the module.
cbMe32
Size of the buffer pointed to by the lpMe32 parameter.
#include <windows.h>
#include <tlhelp32.h>

BOOL GetProcessModule (DWORD dwPID, DWORD dwModuleID,
     LPMODULEENTRY32 lpMe32, DWORD cbMe32)
{
    BOOL          bRet        = FALSE;
    BOOL          bFound      = FALSE;
    HANDLE        hModuleSnap = NULL;
    MODULEENTRY32 me32        = {0};

    // Take a snapshot of all modules in the specified process.

    hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
    if (hModuleSnap == INVALID_HANDLE_VALUE)
        return (FALSE);

    // Fill the size of the structure before using it.

    me32.dwSize = sizeof(MODULEENTRY32);

    // Walk the module list of the process, and find the module of
    // interest. Then copy the information to the buffer pointed
    // to by lpMe32 so that it can be returned to the caller.

    if (Module32First(hModuleSnap, &me32))
    {
        do
        {
            if (me32.th32ModuleID == dwModuleID)
            {
                CopyMemory (lpMe32, &me32, cbMe32);
                bFound = TRUE;
            }
        }
        while (!bFound && Module32Next(hModuleSnap, &me32));

        bRet = bFound;   // if this sets bRet to FALSE, dwModuleID
                         // no longer exists in specified process
    }
    else
        bRet = FALSE;           // could not walk module list

    // Do not forget to clean up the snapshot object.

    CloseHandle (hModuleSnap);

    return (bRet);
}


Tool Help Reference

The following functions and structures are associated with the tool help library.

  • Tool Help Functions
  • Tool Help Structures


Tool Help Functions

The following functions are used with tool help services:

CreateToolhelp32Snapshot
Heap32First
Heap32ListFirst
Heap32ListNext
Heap32Next
Module32First
Module32Next
Process32First
Process32Next
Thread32First
Thread32Next
Toolhelp32ReadProcessMemory


CreateToolhelp32Snapshot

Takes a snapshot of the processes and the heaps, modules, and threads used by the processes.

HANDLE WINAPI CreateToolhelp32Snapshot(
  DWORD dwFlags,
  DWORD th32ProcessID
);

Parameters

dwFlags
[in] Specifies portions of the system to include in the snapshot. This parameter can be one of the following values.
Value | Meaning
TH32CS_INHERIT | Indicates that the snapshot handle is to be inheritable.
TH32CS_SNAPALL | Equivalent to specifying TH32CS_SNAPHEAPLIST, TH32CS_SNAPMODULE, TH32CS_SNAPPROCESS, and TH32CS_SNAPTHREAD.
TH32CS_SNAPHEAPLIST | Includes the heap list of the specified process in the snapshot.
TH32CS_SNAPMODULE | Includes the module list of the specified process in the snapshot.
TH32CS_SNAPPROCESS | Includes the process list in the snapshot.
TH32CS_SNAPTHREAD | Includes the thread list in the snapshot.

th32ProcessID
[in] Specifies the process identifier. This parameter can be zero to indicate the current process. This parameter is used when the TH32CS_SNAPHEAPLIST or TH32CS_SNAPMODULE value is specified. Otherwise, it is ignored.

Return Values

Returns an open handle to the specified snapshot if successful or INVALID_HANDLE_VALUE otherwise.

Remarks

The snapshot taken by this function is examined by the other tool help functions to provide their results. Access to the snapshot is read only. The snapshot handle acts like an object handle and is subject to the same rules regarding which processes and threads it is valid in.

To retrieve an extended error status code generated by this function, use the GetLastError function.

To destroy the snapshot, use the CloseHandle function.

For an example, see Taking a Snapshot and Viewing Processes.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.
Library: Use Kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions


Heap32First

Retrieves information about the first block of a heap that has been allocated by a process.

BOOL WINAPI Heap32First(
  LPHEAPENTRY32 lphe,
  DWORD th32ProcessID,
  ULONG_PTR th32HeapID
);

Parameters

lphe
[in/out] Pointer to a HEAPENTRY32 structure.
th32ProcessID
[in] Identifier of the process context that owns the heap.
th32HeapID
[in] Identifier of the heap to enumerate.

Return Values

Returns TRUE if information for the first heap block has been copied to the buffer or FALSE otherwise. The ERROR_NO_MORE_FILES error value is returned by the GetLastError function if the heap is invalid or empty.

Remarks

The calling application must set the dwSize member of HEAPENTRY32 to the size, in bytes, of the structure. Heap32First changes dwSize to the number of bytes written to the structure. This will never be greater than the initial value of dwSize, but it may be smaller. If the value is smaller, do not rely on the values of any members whose offsets are greater than this value.

To access subsequent blocks of the same heap, use the Heap32Next function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.
Library: Use Kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions, , Heap32Next, HEAPENTRY32


Heap32ListFirst

Retrieves information about the first heap that has been allocated by a specified process.

BOOL WINAPI Heap32ListFirst(
  HANDLE hSnapshot,
  LPHEAPLIST32 lphl
);

Parameters

hSnapshot
[in] Handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
lphl
[in/out] Pointer to a HEAPLIST32 structure.

Return Values

Returns TRUE if the first entry of the heap list has been copied to the buffer or FALSE otherwise. The ERROR_NO_MORE_FILES error value is returned by the GetLastError function when no heap list exists or the snapshot does not contain heap list information.

Remarks

The calling application must set the dwSize member of HEAPLIST32 to the size, in bytes, of the structure. Heap32ListFirst changes dwSize to the number of bytes written to the structure. This will never be greater than the initial value of dwSize, but it may be smaller. If the value is smaller, do not rely on the values of any members whose offsets are greater than this value.

To retrieve information about other heaps in the heap list, use the Heap32ListNext function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.
Library: Use Kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions, , CreateToolhelp32Snapshot, HEAPLIST32, Heap32ListNext


Heap32ListNext

Retrieves information about the next heap that has been allocated by a process.

BOOL WINAPI Heap32ListNext(
  HANDLE hSnapshot,
  LPHEAPLIST32 lphl
);

Parameters

hSnapshot
[in] Handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
lphl
[out] Pointer to a HEAPLIST32 structure.

Return Values

Returns TRUE if the next entry of the heap list has been copied to the buffer or FALSE otherwise. The ERROR_NO_MORE_FILES error value is returned by the GetLastError function when no more entries in the heap list exist.

Remarks

To retrieve information about the first heap in a heap list, use the Heap32ListFirst function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.
Library: Use Kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions


Heap32Next

Retrieves information about the next block of a heap that has been allocated by a process.

BOOL WINAPI Heap32Next(
  LPHEAPENTRY32 lphe
);

Parameters

lphe
[out] Pointer to a HEAPENTRY32 structure.

Return Values

Returns TRUE if information about the next block in the heap has been copied to the buffer or FALSE otherwise. The GetLastError function returns ERROR_NO_MORE_FILES when no more objects in the heap exist and ERROR_INVALID_DATA if the heap appears to be corrupt or is modified during the walk in such a way that Heap32Next cannot continue.

Remarks

To retrieve information for the first block of a heap, use the Heap32First function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.
Library: Use Kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions


Module32First

Retrieves information about the first module associated with a process.

BOOL WINAPI Module32First(
  HANDLE hSnapshot,
  LPMODULEENTRY32 lpme
);

Parameters

hSnapshot
[in] Handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
lpme
[in/out] Pointer to a MODULEENTRY32 structure.

Return Values

Returns TRUE if the first entry of the module list has been copied to the buffer or FALSE otherwise. The ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no modules exist or the snapshot does not contain module information.

Remarks

The calling application must set the dwSize member of MODULEENTRY32 to the size, in bytes, of the structure. Module32First changes dwSize to the number of bytes written to the structure. This will never be greater than the initial value of dwSize, but it may be smaller. If the value is smaller, do not rely on the values of any members whose offsets are greater than this value.

To retrieve information about other modules associated with the specified process, use the Module32Next function.

For an example, see Traversing the Module List.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.
Library: Use Kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions, , CreateToolhelp32Snapshot, MODULEENTRY32, Module32Next


Module32Next

Retrieves information about the next module associated with a process or thread.

BOOL WINAPI Module32Next(
  HANDLE hSnapshot,
  LPMODULEENTRY32 lpme
);

Parameters

hSnapshot
[in] Handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
lpme
[out] Pointer to a MODULEENTRY32 structure.

Return Values

Returns TRUE if the next entry of the module list has been copied to the buffer or FALSE otherwise. The ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no more modules exist.

Remarks

To retrieve information about first module associated with a process, use the Module32First function.

For an example, see Traversing the Module List.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.
Library: Use Kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions


Process32First

Retrieves information about the first process encountered in a system snapshot.

BOOL WINAPI Process32First(
  HANDLE hSnapshot,
  LPPROCESSENTRY32 lppe
);

Parameters

hSnapshot
[in] Handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
lppe
[in/out] Pointer to a PROCESSENTRY32 structure.

Return Values

Returns TRUE if the first entry of the process list has been copied to the buffer or FALSE otherwise. The ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no processes exist or the snapshot does not contain process information.

Remarks

The calling application must set the dwSize member of PROCESSENTRY32 to the size, in bytes, of the structure. Process32First changes dwSize to the number of bytes written to the structure. This will never be greater than the initial value of dwSize, but it may be smaller. If the value is smaller, do not rely on the values of any members whose offsets are greater than this value.

To retrieve information about other processes recorded in the same snapshot, use the Process32Next function.

For an example, see Taking a Snapshot and Viewing Processes.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.
Library: Use Kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions, , CreateToolhelp32Snapshot, PROCESSENTRY32, Process32Next


Process32Next

Retrieves information about the next process recorded in a system snapshot.

BOOL WINAPI Process32Next(
  HANDLE hSnapshot,
  LPPROCESSENTRY32 lppe
);

Parameters

hSnapshot
[in] Handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
lppe
[out] Pointer to a PROCESSENTRY32 structure.

Return Values

Returns TRUE if the next entry of the process list has been copied to the buffer or FALSE otherwise. The ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no processes exist or the snapshot does not contain process information.

Remarks

To retrieve information about the first process recorded in a snapshot, use the Process32First function.

For an example, see Taking a Snapshot and Viewing Processes.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.
Library: Use Kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions


Thread32First

Retrieves information about the first thread of any process encountered in a system snapshot.

BOOL WINAPI Thread32First(
  HANDLE hSnapshot,
  LPTHREADENTRY32 lpte
);

Parameters

hSnapshot
[in] Handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
lpte
[in/out] Pointer to a THREADENTRY32 structure.

Return Values

Returns TRUE if the first entry of the thread list has been copied to the buffer or FALSE otherwise. The ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no threads exist or the snapshot does not contain thread information.

Remarks

The calling application must set the dwSize member of THREADENTRY32 to the size, in bytes, of the structure. Thread32First changes dwSize to the number of bytes written to the structure. This will never be greater than the initial value of dwSize, but it may be smaller. If the value is smaller, do not rely on the values of any members whose offsets are greater than this value.

To retrieve information about other threads recorded in the same snapshot, use the Thread32Next function.

For an example, see Traversing the Module List.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.
Library: Use Kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions, , CreateToolhelp32Snapshot, THREADENTRY32, Thread32Next


Thread32Next

Retrieves information about the next thread of any process encountered in the system memory snapshot.

BOOL WINAPI Thread32Next(
  HANDLE hSnapshot,
  LPTHREADENTRY32 lpte
);

Parameters

hSnapshot
[in] Handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
lpte
[out] Pointer to a THREADENTRY32 structure.

Return Values

Returns TRUE if the next entry of the thread list has been copied to the buffer or FALSE otherwise. The ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no threads exist or the snapshot does not contain thread information.

Remarks

To retrieve information about the first thread recorded in a snapshot, use the Thread32First function.

For an example, see Traversing the Module List.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.
Library: Use Kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions


Toolhelp32ReadProcessMemory

Copies memory allocated to another process into an application-supplied buffer.

BOOL WINAPI Toolhelp32ReadProcessMemory(
  DWORD th32ProcessID,
  LPCVOID lpBaseAddress,
  LPVOID lpBuffer,
  SIZE_T cbRead,
  SIZE_T lpNumberOfBytesRead
);

Parameters

th32ProcessID
[in] Identifier of the process whose memory is being copied. This parameter can be zero to copy the memory of the current process.
lpBaseAddress
[in] Base address in the specified process to read. Before transferring any data, the system verifies that all data in the base address and memory of the specified size is accessible for read access. If this is the case, the function proceeds. Otherwise, the function fails.
lpBuffer
[out] Pointer to a buffer that receives the contents of the address space of the specified process.
cbRead
[in] Number of bytes to read from the specified process.
lpNumberOfBytesRead
[out] Number of bytes copied to the specified buffer. If this parameter is NULL, it is ignored.

Return Values

Returns TRUE if successful.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.
Library: Use Kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions


Tool Help Structures

The following structures are used with tool help services:

HEAPENTRY32
HEAPLIST32
MODULEENTRY32
PROCESSENTRY32
THREADENTRY32


HEAPENTRY32

Describes one entry (block) of a heap that is being examined.

typedef struct tagHEAPENTRY32 {
  SIZE_T  dwSize;
  HANDLE  hHandle;
  ULONG_PTR  dwAddress;
  SIZE_T  dwBlockSize;
  DWORD   dwFlags;
  DWORD   dwLockCount;
  DWORD   dwResvd;
  DWORD   th32ProcessID;
  ULONG_PTR  th32HeapID;
} HEAPENTRY32;
typedef HEAPENTRY32 *PHEAPENTRY32;

Members

dwSize
Specifies the length, in bytes, of the structure. Before calling the Heap32First function, set this member to sizeof(HEAPENTRY32). If you do not initialize dwSize, Heap32First will fail.
hHandle
Handle to the heap block.
dwAddress
Linear address of the start of the block.
dwBlockSize
Size, in bytes, of the heap block.
dwFlags
Flags. These values are defined:
Value | Meaning
LF32_FIXED | The memory block has a fixed (unmovable) location.
LF32_FREE | The memory block is not used.
LF32_MOVEABLE | The memory block location can be moved.

dwLockCount
Lock count on the memory block. The lock count is incremented each time the GlobalLock or LocalLock function is called on the block either by the application or the DLL that the heap belongs to.
dwResvd
Reserved; do not use.
th32ProcessID
Identifier of the process to examine. The contents of this member can be used by Win32 API elements.
th32HeapID
Heap identifier in the owning process context. The contents of this member has meaning only to the tool help functions. It is not a handle, nor is it usable by Win32 API elements.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.

See Also

Tool Help Library Overview, Tool Help Structures, , Heap32First


HEAPLIST32

Describes an entry from a list that enumerates the heaps used by a specified process.

typedef struct tagHEAPLIST32 {
  SIZE_T dwSize;
  DWORD th32ProcessID;
  ULONG_PTR th32HeapID;
  DWORD dwFlags;
} HEAPLIST32;
typedef HEAPLIST32 *PHEAPLIST32;

Members

dwSize
Specifies the length, in bytes, of the structure. Before calling the Heap32ListFirst function, set this member to sizeof(HEAPLIST32). If you do not initialize dwSize, Heap32First will fail.
th32ProcessID
Identifier of the process to examine. The contents of this member can be used by Win32 API elements.
th32HeapID
Heap identifier in the owning process context. The contents of this member has meaning only to the tool help functions. It is not a handle, nor is it usable by Win32 API elements.
dwFlags
Flags. These values are defined:
Value | Meaning
HF32_DEFAULT | Process's default heap

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.

See Also

Tool Help Library Overview, Tool Help Structures


MODULEENTRY32

Describes an entry from a list that enumerates the modules used by a specified process.

typedef struct tagMODULEENTRY32 {
  DWORD   dwSize;
  DWORD   th32ModuleID;
  DWORD   th32ProcessID;
  DWORD   GlblcntUsage;
  DWORD   ProccntUsage;
  BYTE  * modBaseAddr;
  DWORD   modBaseSize;
  HMODULE hModule;
  TCHAR   szModule[MAX_MODULE_NAME32 + 1];
  TCHAR   szExePath[MAX_PATH];
} MODULEENTRY32;
typedef MODULEENTRY32 *PMODULEENTRY32;

Members

dwSize
Specifies the length, in bytes, of the structure. Before calling the Module32First function, set this member to sizeof(MODULEENTRY32). If you do not initialize dwSize, Module32First will fail.
th32ModuleID
Module identifier in the context of the owning process. The contents of this member has meaning only to the tool help functions. It is not a handle, nor is it usable by Win32 API elements.
th32ProcessID
Identifier of the process being examined. The contents of this member can be used by Win32 API elements.
GlblcntUsage
Global usage count on the module.
ProccntUsage
Module usage count in the context of the owning process.
modBaseAddr
Base address of the module in the context of the owning process.
modBaseSize
Size, in bytes, of the module.
hModule
Handle to the module in the context of the owning process.
szModule
String containing the module name.
szExePath
String containing the location (path) of the module.

Note The modBaseAddr and hModule members are valid only in the context of the process specified by th32ProcessID.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.

See Also

Tool Help Library Overview, Tool Help Structures, , Module32First


PROCESSENTRY32

Describes an entry from a list that enumerates the processes residing in the system address space when a snapshot was taken.

typedef struct tagPROCESSENTRY32 {
  DWORD dwSize;
  DWORD cntUsage;
  DWORD th32ProcessID;
  ULONG_PTR th32DefaultHeapID;
  DWORD th32ModuleID;
  DWORD cntThreads;
  DWORD th32ParentProcessID;
  LONG  pcPriClassBase;
  DWORD dwFlags;
  TCHAR szExeFile[MAX_PATH];
} PROCESSENTRY32;
typedef PROCESSENTRY32 *PPROCESSENTRY32;

Members

dwSize
Specifies the length, in bytes, of the structure. Before calling the Process32First function, set this member to sizeof(PROCESSENTRY32). If you do not initialize dwSize, Process32First will fail.
cntUsage
Number of references to the process. A process exists as long as its usage count is nonzero. As soon as its usage count becomes zero, a process terminates.
th32ProcessID
Identifier of the process. The contents of this member can be used by Win32 API elements.
th32DefaultHeapID
Identifier of the default heap for the process. The contents of this member has meaning only to the tool help functions. It is not a handle, nor is it usable by Win32 API elements.
th32ModuleID
Module identifier of the process. The contents of this member has meaning only to the tool help functions. It is not a handle, nor is it usable by Win32 API elements.
cntThreads
Number of execution threads started by the process.
th32ParentProcessID
Identifier of the process that created the process being examined. The contents of this member can be used by Win32 API elements.
pcPriClassBase
Base priority of any threads created by this process.
dwFlags
Reserved; do not use.
szExeFile
Path and filename of the executable file for the process.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.

See Also

Tool Help Library Overview, Tool Help Structures


THREADENTRY32

Describes an entry from a list that enumerates the threads executing in the system when a snapshot was taken.

typedef struct tagTHREADENTRY32{
  DWORD  dwSize;
  DWORD  cntUsage;
  DWORD  th32ThreadID;
  DWORD  th32OwnerProcessID;
  LONG   tpBasePri;
  LONG   tpDeltaPri;
  DWORD  dwFlags;
} THREADENTRY32;
typedef THREADENTRY32 *PTHREADENTRY32;

Members

dwSize
Specifies the length, in bytes, of the structure. Before calling the Thread32First function, set this member to sizeof(THREADENTRY32). If you do not initialize dwSize, Thread32First will fail.
cntUsage
Number of references to the thread. A thread exists as long as its usage count is nonzero. As soon as its usage count becomes zero, a thread terminates.
th32ThreadID
Identifier of the thread. This identifier is compatible with the thread identifier returned by the CreateProcess function.
th32OwnerProcessID
Identifier of the process that created the thread. The contents of this member can be used by Win32 API elements.
tpBasePri
Initial priority level assigned to a thread. This member can be one of the following values:
Value | Meaning
THREAD_PRIORITY_IDLE | Indicates a base priority level of 1 for IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS processes, and a base priority level of 16 for REALTIME_PRIORITY_CLASS processes.
THREAD_PRIORITY_LOWEST | Indicates 2 points below normal priority for the priority class.
THREAD_PRIORITY_BELOW_NORMAL | Indicates one point below normal priority for the priority class.
THREAD_PRIORITY_NORMAL | Indicates normal priority for the priority class.
THREAD_PRIORITY_ABOVE_NORMAL | Indicates one point above normal priority for the priority class.
THREAD_PRIORITY_HIGHEST | Indicates two points above normal priority for the priority class.
THREAD_PRIORITY_TIME_CRITICAL | Indicates a base priority level of 15 for IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS processes, and a base priority level of 31 for REALTIME_PRIORITY_CLASS processes.

tpDeltaPri
Change in the priority level of a thread. This value is a signed delta from the base priority level assigned to the thread.
dwFlags
Reserved; do not use.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Tlhelp32.h.

See Also

Tool Help Library Overview, Tool Help Structures, , Thread32First


Topic Not Found

No matching topic was found. Some possible reasons and remedies are as follows:

  • The file (.chm) that contains the destination topic is not in the expected location.

    Remedy: Rerun the MSDN Library Setup.

  • The file (.chm) that contains the current topic or destination topic is out-of-date and the link is no longer valid.

    Remedy: Install the latest version of the MSDN Library.

  • The MSDN Library CD is not in the CD-ROM drive.

    Remedy: Insert the MSDN Library CD into the CD-ROM drive.