Debugging

A debugger is an application that enables a developer to observe and correct programming errors. This overview describes the debugging support provided by the Win32 API.


About Debugging Support

The Win32 API provides several functions that can be used to create a basic, event-driven debugger. Event-driven means that the debugger is notified every time certain events occur in the process being debugged. Notification enables the debugger to take appropriate action in response to the events.

The Debug Support from Process, Thread, and Exception Functions section of this overview describes the debugging-specific features of certain Win32 process, thread, and exception-handling functions.

The Win32 Debugging Functions section of this overview describes the Win32 debugging functions. These functions enable an application to wait for debugging events, cause breakpoint exceptions, transfer execution control to the debugger, and so on.

The Debugging Events section of this overview describes the debug event mechanism. Debugging events cause the kernel to notify the debugger.


Debug Support from Process, Thread, and Exception Functions

Some functions essential to debugging are actually part of the process, thread, or exception-handling architectures. For a description of how to start a process that is going to be debugged, see Process Functions. For information on how to examine and manipulate the context and execution of a thread, see Thread Functions. For a description of how a debugger should handle exceptions, see Exception Handling Functions.


Process Functions for Debugging

The CreateProcess function enables a debugger to start a process and debug it. The fdwCreate parameter of CreateProcess is used to specify the type of debugging operation. If the DEBUG_PROCESS flag is specified for the parameter, a debugger debugs the new process and all of the process's descendants, provided that the descendants are created without the DEBUG_PROCESS flag.

If the DEBUG_PROCESS and DEBUG_ONLY_THIS_PROCESS flags are specified for fdwCreate, a debugger debugs the new process but none of its descendants.

One debugger can debug another by creating a process with the DEBUG_PROCESS flag. The new process (the debugger being debugged) must then create a process with the DEBUG_PROCESS flag.

The OpenProcess function enables a debugger to obtain the identifier of an existing process. (The DebugActiveProcess function uses this identifier to attach the debugger to the process.) Typically, debuggers open a process with the PROCESS_VM_READ and PROCESS_VM_WRITE flags. Using these flags enables the debugger to read from and write to the virtual memory of the process by using the ReadProcessMemory and WriteProcessMemory functions. For more information, see Processes and Threads.


Thread Functions for Debugging

The CreateThread function creates a new thread for a process. Debuggers typically need to examine or change the contents of a thread's registers. To accomplish this, a debugger must obtain a handle to the thread by using the DuplicateHandle function and specifying the appropriate access to the thread (THREAD_GET_CONTEXT, THREAD_SET_CONTEXT, or both).

A process with appropriate access to a thread can examine the thread's registers by using the GetThreadContext function and set the contents of the thread's registers by using the SetThreadContext function.

A process can also obtain THREAD_SUSPEND_RESUME access to a thread. This type of access enables a debugger to control a thread's execution with the SuspendThread and ResumeThread functions. For more information about threads, see Processes and Threads.


Exception Functions for Debugging

Exception Handling Functions for Debugging

When an exception occurs in a process that is being debugged, the kernel notifies the debugger by passing the exception to it. This is known as first-chance notification. The kernel then suspends all threads in the process being debugged.

If the debugger does not handle the exception, the kernel attempts to locate an appropriate exception handler. If the kernel cannot locate an appropriate one, the kernel again notifies the debugger that an exception has occurred. This is known as last-chance notification. If the debugger does not handle the exception after the last-chance notification, the kernel terminates the process being debugged.

For more information, see Debugger Exception Handling.


Win32 Debugging Functions

The Debugging a Running Process section of this overview describes attaching the debugger to a running process. The Writing the Debugger's Main Loop section of this overview describes the functions used in the debugger's main loop of execution. For an example of how to organize the main loop, see Using Debugging Support.

Although most of the Win32 debugging functions are used to create a debugger, several functions are designed for use in the process being debugged. For more information, see Communicating with the Debugger.


Debugging a Running Process

To debug a process that is already running, the debugger should use DebugActiveProcess with the process identifier retrieved by OpenProcess. DebugActiveProcess attaches the debugger to the active process. In this case, only the active process can be debugged; its child processes cannot. The debugger must have appropriate access to the executing process to use DebugActiveProcess. For more information about access rights, see Access Control.

After the debugger has either created or attached itself to the process it intends to debug, the kernel notifies the debugger of all debugging events that occur in the process, and, if specified, in any child processes. For more information about debugging events, see Debugging Events.


Writing the Debugger's Main Loop

The debugger uses the WaitForDebugEvent function at the beginning of its main loop. This function blocks the debugger until a debugging event occurs. When the debugging event occurs, the system suspends all threads in the process being debugged and notifies the debugger of the event. The debugger can call the SetDebugErrorLevel function to set the minimum error level at which the system will pass the debugging event to it.

The debugger can interact with the user, or manipulate the state of the process being debugged, by using the GetThreadContext, GetThreadSelectorEntry, ReadProcessMemory, SetThreadContext, and WriteProcessMemory functions. GetThreadSelectorEntry returns the descriptor table entry for a specified selector and thread. Debuggers use the descriptor table entry to convert a segment-relative address to a linear virtual address. The ReadProcessMemory and WriteProcessMemory functions require linear virtual addresses.

Debuggers frequently read the memory of the process being debugged and write the memory that contains instructions to the instruction cache. After the instructions are written, the debugger calls FlushInstructionCache to execute the cached instructions.

The debugger uses the ContinueDebugEvent function at the end of its main loop. This function allows the process being debugged to continue executing.


Communicating with the Debugger

The OutputDebugString function sends a string from the process being debugged to the debugger by generating an OUTPUT_DEBUG_STRING_EVENT debugging event. A process can detect whether it is being debugged by calling the IsDebuggerPresent function.

The DebugBreak function causes a breakpoint exception in the current process. A breakpoint is a location in a program where execution is stopped to allow the developer to examine the program's code, variables, and register values and, as necessary, to make changes, continue execution, or terminate execution.

The FatalExit function terminates the current process and gives execution control to the debugger, but unlike DebugBreak, it does not generate an exception. This function should only be used as a last resort, because it does not always free the process's memory or close its files.


Debugging Events

A debugging event is an incident in the process being debugged that causes the kernel to notify the debugger. Debugging events include creating a process, creating a thread, loading a dynamic-link library (DLL), unloading a DLL, sending an output string, and generating an exception.

If a debugging event occurs while a debugger is waiting for one, the kernel fills the DEBUG_EVENT structure specified by WaitForDebugEvent with information describing the event.

When the kernel notifies the debugger of a debugging event, it also suspends all threads in the affected process. The threads do not resume execution until the debugger continues the debugging event by using ContinueDebugEvent. The following debugging events may occur while a process is being debugged.

Debugging event Description
CREATE_PROCESS_DEBUG_EVENT
Generated whenever a new process is created in a process being debugged or whenever the debugger begins debugging an already active process. The kernel generates this debugging event before the process begins to execute in user mode and before the kernel generates any other debugging events for the new process.
The DEBUG_EVENT structure contains a CREATE_PROCESS_DEBUG_INFO structure. This structure includes a handle to the new process, a handle to the process's image file, a handle to the process's initial thread, and other information that describes the new process.
The handle to the process has PROCESS_VM_READ and PROCESS_VM_WRITE access. If a debugger has these types of access to a thread, it can read and write to the process's memory by using the ReadProcessMemory and WriteProcessMemory functions.
The handle to the process's image file has GENERIC_READ access and is opened for read-sharing.
The handle to the process's initial thread has THREAD_GET_CONTEXT, THREAD_SET_CONTEXT, and THREAD_SUSPEND_RESUME access to the thread. If a debugger has these types of access to a thread, it can read from and write to the thread's registers by using the GetThreadContext and SetThreadContext functions and can suspend and resume the thread by using the SuspendThread and ResumeThread functions.
CREATE_THREAD_DEBUG_EVENT
Generated whenever a new thread is created in a process being debugged or whenever the debugger begins debugging an already active process. This debugging event is generated before the new thread begins to execute in user mode.
The DEBUG_EVENT structure contains a CREATE_THREAD_DEBUG_INFO structure. This structure includes a handle to the new thread and the thread's starting address. The handle has THREAD_GET_CONTEXT, THREAD_SET_CONTEXT, and THREAD_SUSPEND_RESUME access to the thread. If a debugger has these types of access to a thread, it can read from and write to the thread's registers by using the GetThreadContext and SetThreadContext functions and can suspend and resume the thread by using the SuspendThread and ResumeThread functions.
EXCEPTION_DEBUG_EVENT
Generated whenever an exception occurs in the process being debugged. Possible exceptions include attempting to access inaccessible memory, executing breakpoint instructions, attempting to divide by zero, or any other exception noted in Structured Exception Handling.
The DEBUG_EVENT structure contains an EXCEPTION_DEBUG_INFO structure. This structure describes the exception that caused the debugging event.
Besides the standard exception conditions, an additional exception code can occur during console process debugging. The kernel generates a DBG_CONTROL_C exception code when ctrl+c is input to a console process that handles ctrl+c signals and is being debugged. This exception code is not meant to be handled by applications. An application should never use an exception handler to deal with it. It is raised only for the benefit of the debugger and is only used when a debugger is attached to the console process.
If a process is not being debugged or if the debugger passes on the DBG_CONTROL_C exception unhandled (through the gn command), the application's list of handler functions is searched, as documented for the SetConsoleCtrlHandler function.
If the debugger handles the DBG_CONTROL_C exception (through the gh command), an application will not notice the ctrl+c except in code like this.
while ((inputChar = getchar()) != EOF) ...
while (gets(inputString)) ...
Thus, the debugger cannot be used to stop the read wait in such code from terminating.
EXIT_PROCESS_DEBUG_EVENT
Generated whenever the last thread in a process being debugged exits. This debugging event occurs immediately after the kernel unloads the process's DLLs and updates the process's exit code.
The DEBUG_EVENT structure contains an EXIT_PROCESS_DEBUG_INFO structure that specifies the exit code.
The debugger deallocates any internal structures associated with the process on receipt of this debugging event. The kernel closes the debugger's handle to the exiting process and all of the process's threads.
EXIT_THREAD_DEBUG_EVENT
Generated whenever a thread that is part of a process being debugged exits. The kernel generates this debugging event immediately after it updates the thread's exit code.
The DEBUG_EVENT structure contains an EXIT_THREAD_DEBUG_INFO structure that specifies the exit code.
The debugger deallocates any internal structures associated with the thread on receipt of this debugging event. The system closes the debugger's handle to the exiting thread.
This debugging event does not occur if the exiting thread is the last thread of a process. In this case, the EXIT_PROCESS_DEBUG_EVENT debugging event occurs instead.
LOAD_DLL_DEBUG_EVENT
Generated whenever a process being debugged loads a DLL. This debugging event occurs when the system loader resolves links to a DLL or when the debugged process uses the LoadLibrary function. This debugging event only occurs the first time the kernel attaches a DLL to the virtual address space of a process.
The DEBUG_EVENT structure contains a LOAD_DLL_DEBUG_INFO structure. This structure includes a handle to the newly loaded DLL, the base address of the DLL, and other information that describes the DLL.
Typically, a debugger loads a symbol table associated with the DLL on receipt of this debugging event.
OUTPUT_DEBUG_STRING_EVENT
Generated when a process being debugged uses the OutputDebugString function.
The DEBUG_EVENT structure contains an OUTPUT_DEBUG_STRING_INFO structure. This structure specifies the address, length, and format of the debugging string.
UNLOAD_DLL_DEBUG_EVENT
Generated whenever a process being debugged unloads a DLL by using the FreeLibrary function. This debugging event only occurs the last time a DLL is unloaded from a process's address space (that is, when the DLL's usage count is zero).
The DEBUG_EVENT structure contains an UNLOAD_DLL_DEBUG_INFO structure. This structure specifies the base address of the DLL in the address space of the process that unloads the DLL.
Typically, a debugger unloads a symbol table associated with the DLL upon receiving this debugging event.
When a process exits, the kernel automatically unloads the process's DLLs, but does not generate an UNLOAD_DLL_DEBUG_EVENT debugging event.


Using Debugging Support

The following example uses the WaitForDebugEvent and ContinueDebugEvent functions to illustrate how a simple debugger might be organized.

DEBUG_EVENT DebugEv;                   // debugging event information
DWORD dwContinueStatus = DBG_CONTINUE; // exception continuation

for(;;)
{

// Wait for a debugging event to occur. The second parameter indicates
// that the function does not return until a debugging event occurs.

    WaitForDebugEvent(&DebugEv, INFINITE);

// Process the debugging event code.

    switch (DebugEv.dwDebugEventCode)
    {
        case EXCEPTION_DEBUG_EVENT:
        // Process the exception code. When handling
        // exceptions, remember to set the continuation
        // status parameter (dwContinueStatus). This value
        // is used by the ContinueDebugEvent function.

            switch (DebugEv.u.Exception.ExceptionRecord.ExceptionCode)
            {
                case EXCEPTION_ACCESS_VIOLATION:
                // First chance: Pass this on to the kernel.
                // Last chance: Display an appropriate error.

                case EXCEPTION_BREAKPOINT:
                // First chance: Display the current
                // instruction and register values.

                case EXCEPTION_DATATYPE_MISALIGNMENT:
                // First chance: Pass this on to the kernel.
                // Last chance: Display an appropriate error.

                case EXCEPTION_SINGLE_STEP:
                // First chance: Update the display of the
                // current instruction and register values.

                case DBG_CONTROL_C:
                // First chance: Pass this on to the kernel.
                // Last chance: Display an appropriate error.

                // Handle other exceptions.
            }

        case CREATE_THREAD_DEBUG_EVENT:
        // As needed, examine or change the thread's registers
        // with the GetThreadContext and SetThreadContext functions;
        // and suspend and resume thread execution with the
        // SuspendThread and ResumeThread functions.

        case CREATE_PROCESS_DEBUG_EVENT:
        // As needed, examine or change the registers of the
        // process's initial thread with the GetThreadContext and
        // SetThreadContext functions; read from and write to the
        // process's virtual memory with the ReadProcessMemory and
        // WriteProcessMemory functions; and suspend and resume
        // thread execution with the SuspendThread and ResumeThread
        // functions.

        case EXIT_THREAD_DEBUG_EVENT:
        // Display the thread's exit code.

        case EXIT_PROCESS_DEBUG_EVENT:
        // Display the process's exit code.

        case LOAD_DLL_DEBUG_EVENT:
        // Read the debugging information included in the newly
        // loaded DLL.

        case UNLOAD_DLL_DEBUG_EVENT:
        // Display a message that the DLL has been unloaded.

        case OUTPUT_DEBUG_STRING_EVENT:
        // Display the output debugging string.

    }

// Resume executing the thread that reported the debugging event.

ContinueDebugEvent(DebugEv.dwProcessId,
    DebugEv.dwThreadId, dwContinueStatus);

}


Debugging Reference

The following elements are used with debugging.

  • Debugging Functions
  • Debugging Structures


Debugging Functions

The following functions are used with debugging.

ContinueDebugEvent
DebugActiveProcess
DebugBreak
FatalExit
FlushInstructionCache
GetThreadContext
GetThreadSelectorEntry
IsDebuggerPresent
OutputDebugString
ReadProcessMemory
ReadProcessMemoryVlm
SetDebugErrorLevel
SetThreadContext
WaitForDebugEvent
WriteProcessMemory
WriteProcessMemoryVlm


ContinueDebugEvent

The ContinueDebugEvent function enables a debugger to continue a thread that previously reported a debugging event.

BOOL ContinueDebugEvent(
  DWORD dwProcessId,       // process to continue
  DWORD dwThreadId,        // thread to continue
  DWORD dwContinueStatus   // continuation status
);

Parameters

dwProcessId
Handle to the process to continue.
dwThreadId
Handle to the thread to continue. The combination of process identifier and thread identifier must identify a thread that has previously reported a debugging event.
dwContinueStatus
Specifies how to continue the thread that reported the debugging event.

If the DBG_CONTINUE flag is specified for this parameter and the thread specified by the dwThreadId parameter previously reported an EXCEPTION_DEBUG_EVENT debugging event, the function stops all exception processing and continues the thread. For any other debugging event, this flag simply continues the thread.

If the DBG_EXCEPTION_NOT_HANDLED flag is specified for this parameter and the thread specified by dwThreadId previously reported an EXCEPTION_DEBUG_EVENT debugging event, the function continues exception processing. If this is a first-chance exception event, the search and dispatch logic of the structured exception handler is used; otherwise, the process is terminated. For any other debugging event, this flag simply continues the thread.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Only the thread that created dwProcessId with the CreateProcess function can call ContinueDebugEvent.

After the ContinueDebugEvent function succeeds, the specified thread continues. Depending on the debugging event previously reported by the thread, different actions occur. If the continued thread previously reported an EXIT_THREAD_DEBUG_EVENT debugging event, ContinueDebugEvent closes the handle the debugger has to the thread. If the continued thread previously reported an EXIT_PROCESS_DEBUG_EVENT debugging event, ContinueDebugEvent closes the handles the debugger has to the process and to the thread.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Debugging Overview, Debugging Functions, CreateProcess


DebugActiveProcess

The DebugActiveProcess function allows a debugger to attach to an active process and then debug it. To stop debugging the process, you must exit the process. Exiting the debugger will also exit the process.

BOOL DebugActiveProcess(
  DWORD dwProcessId   // process to be debugged
);

Parameters

dwProcessId
Specifies the identifier for the process to be debugged. The debugger gets debugging access to the process as if it created the process with the DEBUG_ONLY_THIS_PROCESS flag. See the Remarks section for more details.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The debugger must have appropriate access to the target process; it must be able to open the process for PROCESS_ALL_ACCESS access. On Windows 95 and Windows 98, the debugger has appropriate access if the process identifier is valid. However, on Windows NT, DebugActiveProcess can fail if the target process was created with a security descriptor that grants the debugger anything less than full access. Note that if the debugging process has the SE_DEBUG_NAME privilege granted and enabled, it can debug any process.

After the system checks the process identifier and determines that a valid debugging attachment is being made, the function returns TRUE. The debugger is then expected to wait for debugging events by using the WaitForDebugEvent function. The system suspends all threads in the process and sends the debugger events representing the current state of the process.

The system sends the debugger a single CREATE_PROCESS_DEBUG_EVENT debugging event representing the process specified by the dwProcessId parameter. The lpStartAddress member of the CREATE_PROCESS_DEBUG_INFO structure is NULL.

For each thread currently part of the process, the system sends a CREATE_THREAD_DEBUG_EVENT debugging event. The lpStartAddress member of the CREATE_THREAD_DEBUG_INFO structure is NULL.

For each dynamic-link library (DLL) currently loaded into the address space of the target process, the system sends a LOAD_DLL_DEBUG_EVENT debugging event. The system arranges for the first thread in the process to execute a breakpoint instruction after it resumes. Continuing this thread causes it to return to whatever it was doing before the debugger was attached.

After all of this has been done, the system resumes all threads in the process. When the first thread in the process resumes, it executes a breakpoint instruction that causes an EXCEPTION_DEBUG_EVENT debugging event to be sent to the debugger. All future debugging events are sent to the debugger by using the normal mechanism and rules.

Windows CE: After a successful return from DebugActiveProcess, when the debugger is waiting for debug events using the WaitForDebugEvent function, the system sends a CREATE_PROCESS_DEBUG_EVENT debugging event that identifies the primary thread handle that is currently part of the process. The system sends an individual CREATE_THREAD_DEBUG_EVENT debugging event for each of the secondary thread handles that are currently part of the process. All of these handles have permission (that is, access rights) for getting and setting thread contexts using the GetThreadContext and SetThreadContext functions.

For both the CREATE_PROCESS_DEBUG_EVENT and CREATE_THREAD_DEBUG_EVENT debugging events, the lpStartAddress member of the CREATE_PROCESS_DEBUG_INFO structure is NULL.

Close each of these thread handles using the CloseHandle function.

No initial debug breakpoint is set when DebugActiveProcess successfully attaches.

Windows CE version 2.0 provides built in support for Just-In-Time (JIT) debugging. A JIT debugger is registered by placing the name of your debugger in the string registry value JITDebugger located at HKEY_LOCAL_MACHINE\Debug. To enable JIT, you must perform a warm reset on the Windows CE target platform after the above value is added to the registry. When your debugger is invoked by JIT, the process identifier of the debugee is passed on the command line.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Debugging Overview, Debugging Functions, CreateProcess, CREATE_PROCESS_DEBUG_INFO, CREATE_THREAD_DEBUG_INFO, WaitForDebugEvent


DebugBreak

The DebugBreak function causes a breakpoint exception to occur in the current process so that the calling thread can signal the debugger and force it to take some action. If the process is not being debugged, the search logic of a standard exception handler is used. In most cases, this causes the calling process to terminate because of an unhandled breakpoint exception.

VOID DebugBreak(VOID)

Parameters

This function has no parameters.

Return Values

This function does not return a value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Debugging Overview, Debugging Functions, DebugActiveProcess


FatalExit

The FatalExit function transfers execution control to the debugger. The behavior of the debugger thereafter is specific to the type of debugger used.

VOID FatalExit(
  int ExitCode   // error code
);

Parameters

ExitCode
Specifies the error code associated with the exit.

Return Values

This function does not return a value.

Remarks

An application should only use FatalExit for debugging purposes. It should not call the function in a retail version of the application because doing so will terminate the application.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Debugging Overview, Debugging Functions, FatalAppExit


FlushInstructionCache

The FlushInstructionCache function flushes the instruction cache for the specified process. This function is valid only on multiprocessor computers.

BOOL FlushInstructionCache(
  HANDLE hProcess,        // handle to process with cache to flush
  LPCVOID lpBaseAddress,  // pointer to region to flush
  DWORD dwSize            // length of region to flush
);

Parameters

hProcess
Handle to the process that has an instruction cache to flush.
lpBaseAddress
Pointer to the base of the region to be flushed. This parameter can be NULL.
dwSize
Specifies the length of the region to be flushed if the lpBaseAddress parameter is not NULL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Windows 95 and Windows 98: The FlushInstructionCache function always returns TRUE. Windows 95 and Windows 98 support only single-processor computers.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Debugging Overview, Debugging Functions


GetThreadContext

The GetThreadContext function retrieves the context of the specified thread.

BOOL GetThreadContext(
  HANDLE hThread,       // handle to thread with context
  LPCONTEXT lpContext   // address of context structure
);

Parameters

hThread
Handle to the thread whose context is to be retrieved.

Windows NT: The handle must have THREAD_GET_CONTEXT access to the thread.

lpContext
Pointer to the CONTEXT structure that receives the appropriate context of the specified thread. The value of the ContextFlags member of this structure specifies which portions of a thread's context are retrieved. The CONTEXT structure is highly computer specific. Currently, there are CONTEXT structures defined for Intel, MIPS, Alpha, and PowerPC processors. Refer to the header file WINNT.H for definitions of these structures.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The GetThreadContext function is used to retrieve the context of the specified thread. The function allows a selective context to be retrieved based on the value of the ContextFlags member of the CONTEXT structure. The thread handle identified by the hThread parameter is typically being debugged, but the function can also operate when it is not being debugged.

You cannot get a valid context for a running thread. Use the SuspendThread function to suspend the thread before calling GetThreadContext.

Windows CE: Windows CE includes a CONTEXT structure for the SH CPUs when SHx is defined.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Debugging Overview, Debugging Functions, CONTEXT, SetThreadContext, SuspendThread


GetThreadSelectorEntry

The GetThreadSelectorEntry function retrieves a descriptor table entry for the specified selector and thread.

BOOL GetThreadSelectorEntry(
  HANDLE hThread,    // handle to thread that contains selector
  DWORD dwSelector,  // number of selector value to look up
  LPLDT_ENTRY lpSelectorEntry
                     // address of selector entry structure
);

Parameters

hThread
Handle to the thread containing the specified selector.

Windows NT: The handle must have THREAD_QUERY_INFORMATION access.

dwSelector
Specifies the global or local selector value to look up in the thread's descriptor tables.
lpSelectorEntry
Pointer to an LDT_ENTRY structure that receives a copy of the descriptor table entry if the specified selector has an entry in the specified thread's descriptor table. This information can be used to convert a segment-relative address to a linear virtual address.

Return Values

If the function succeeds, the return value is nonzero. In that case, the structure pointed to by the lpSelectorEntry parameter receives a copy of the specified descriptor table entry.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

GetThreadSelectorEntry is only functional on x86-based systems. For systems that are not x86-based, the function returns FALSE.

Debuggers use this function to convert segment-relative addresses to linear virtual addresses. The ReadProcessMemory and WriteProcessMemory functions use linear virtual addresses.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Debugging Overview, Debugging Functions, LDT_ENTRY, ReadProcessMemory, WriteProcessMemory


IsDebuggerPresent

The IsDebuggerPresent function indicates whether the calling process is running under the context of a debugger.

This function is exported from KERNEL32.DLL.

BOOL IsDebuggerPresent(VOID)

Parameters

This function has no parameters.

Return Value

If the current process is running in the context of a debugger, the return value is nonzero.

If the current process is not running in the context of a debugger, the return value is zero.

Remarks

This function allows an application to determine whether or not it is being debugged, so that it can modify its behavior. For example, an application could provide additional information using the OutputDebugString function if it is being debugged.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Debugging Overview, Debugging Functions, OutputDebugString


OutputDebugString

The OutputDebugString function sends a string to the debugger for the current application.

VOID OutputDebugString(
  LPCTSTR lpOutputString   // pointer to string to be displayed
);

Parameters

lpOutputString
Pointer to the null-terminated string to be displayed.

Return Values

This function does not return a value.

Remarks

If the application has no debugger, the system debugger displays the string. If the application has no debugger and the system debugger is not active, OutputDebugString does nothing.

Windows CE: Windows CE supports only the Unicode version of this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Debugging Overview, Debugging Functions


ReadProcessMemory

The ReadProcessMemory function reads memory in a specified process. The entire area to be read must be accessible, or the operation fails.

BOOL ReadProcessMemory(
  HANDLE hProcess,  // handle to the process whose memory is read
  LPCVOID lpBaseAddress,
                    // address to start reading
  LPVOID lpBuffer,  // address of buffer to place read data
  DWORD nSize,      // number of bytes to read
  LPDWORD lpNumberOfBytesRead
                    // address of number of bytes read
);

Parameters

hProcess
Handle to the process whose memory is being read. The handle must have PROCESS_VM_READ access to the process.
lpBaseAddress
Pointer to the base address in the specified process to be read. Before any data transfer occurs, 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
Pointer to a buffer that receives the contents from the address space of the specified process.
nSize
Specifies the requested number of bytes to read from the specified process.
lpNumberOfBytesRead
Pointer to the actual number of bytes transferred into the specified buffer. If lpNumberOfBytesRead is NULL, the parameter is ignored.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

The function fails if the requested read operation crosses into an area of the process that is inaccessible.

Remarks

ReadProcessMemory copies the data in the specified address range from the address space of the specified process into the specified buffer of the current process. Any process that has a handle with PROCESS_VM_READ access can call the function. The process whose address space is read is typically, but not necessarily, being debugged.

The entire area to be read must be accessible. If it is not, the function fails as noted previously.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Debugging Overview, Debugging Functions, WriteProcessMemory, ReadProcessMemoryVlm


SetDebugErrorLevel

The SetDebugErrorLevel function sets the minimum error level at which the system will generate debugging events and pass them to a debugger.

VOID SetDebugErrorLevel(
  DWORD dwLevel   // debugging error level
);

Parameters

dwLevel
Specifies the minimum error level for debugging events. If an error is equal to or above this level, the system generates a debugging event. This parameter must be one of the following values:
Value | Meaning
0 | Does not report any errors. This value is the default error level.
SLE_ERROR | Reports only ERROR level debugging events.
SLE_MINORERROR | Reports only MINORERROR level and ERROR level debugging events.
SLE_WARNING | Reports WARNING level, MINORERROR level, and ERROR level debugging events.

Return Values

This function does not return a value.

Remarks

The debugger calls SetDebugErrorLevel to specify the types of errors that it should be notified about.

If the debugging error level is greater than the error that occurred, the value for the GetLastError function is set, but the kernel does not generate a debugging event.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Debugging Overview, Debugging Functions


SetThreadContext

The SetThreadContext function sets the context in the specified thread.

BOOL SetThreadContext(
  HANDLE hThread,            // handle to thread with context
  CONST CONTEXT *lpContext   // address of context structure
);

Parameters

hThread
Handle to the thread whose context is to be set.

Windows NT: The handle must have the THREAD_SET_CONTEXT access right to the thread.

lpContext
Pointer to the CONTEXT structure that contains the context to be set in the specified thread. The value of the ContextFlags member of this structure specifies which portions of a thread's context to set. Some values in the CONTEXT structure that cannot be specified are silently set to the correct value. This includes bits in the CPU status register that specify the privileged processor mode, global enabling bits in the debugging register, and other states that must be controlled by the operating system.

Return Values

If the context was set, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The function allows the selective context to be set based on the value of the ContextFlags member of the context structure. The thread handle identified by the hThread parameter is typically being debugged, but the function can also operate even when it is not being debugged.

Do not try to set the context for a running thread; the results are unpredictable. Use the SuspendThread function to suspend the thread before calling SetThreadContext.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Debugging Overview, Debugging Functions, CONTEXT, GetThreadContext, SuspendThread


WaitForDebugEvent

The WaitForDebugEvent function waits for a debugging event to occur in a process being debugged.

BOOL WaitForDebugEvent(
  LPDEBUG_EVENT lpDebugEvent,  // pointer to debug event structure
  DWORD dwMilliseconds         // milliseconds to wait for event
);

Parameters

lpDebugEvent
Pointer to a DEBUG_EVENT structure that is filled with information about the debugging event.
dwMilliseconds
Specifies the number of milliseconds to wait for a debugging event. If this parameter is zero, the function tests for a debugging event and returns immediately. If the parameter is INFINITE, the function does not return until a debugging event has occurred.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Only the thread that created the process being debugged can call WaitForDebugEvent.

Warning Do not queue an asynchronous procedure call (APC) to a thread that calls WaitForDebugEvent.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Debugging Overview, Debugging Functions, ContinueDebugEvent, DebugActiveProcess, DebugBreak, DEBUG_EVENT, OutputDebugString


WriteProcessMemory

The WriteProcessMemory function writes memory in a specified process. The entire area to be written to must be accessible, or the operation fails.

BOOL WriteProcessMemory(
  HANDLE hProcess,  // handle to process whose memory is written to
  LPVOID lpBaseAddress,
                    // address to start writing to
  LPVOID lpBuffer,  // pointer to buffer to write data to
  DWORD nSize,      // number of bytes to write
  LPDWORD lpNumberOfBytesWritten
                    // actual number of bytes written
);

Parameters

hProcess
Handle to the process whose memory is to be modified. The handle must have PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process.
lpBaseAddress
Pointer to the base address in the specified process to be written to. Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for write access. If this is the case, the function proceeds; otherwise, the function fails.
lpBuffer
Pointer to the buffer that supplies data to be written into the address space of the specified process.
nSize
Specifies the requested number of bytes to write into the specified process.
lpNumberOfBytesWritten
Pointer to the actual number of bytes transferred into the specified process. This parameter is optional. If lpNumberOfBytesWritten is NULL, the parameter is ignored.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The function will fail if the requested write operation crosses into an area of the process that is inaccessible.

Remarks

WriteProcessMemory copies the data from the specified buffer in the current process to the address range of the specified process. Any process that has a handle with PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process to be written to can call the function. The process whose address space is being written to is typically, but not necessarily, being debugged.

The entire area to be written to must be accessible. If it is not, the function fails as noted previously.

Windows CE: The hProcess parameter is the handle returned from the OpenProcess function that provided full access to the process.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Debugging Overview, Debugging Functions, ReadProcessMemory, WriteProcessMemoryVlm


Debugging Structures

The following structures are used with debugging.

CONTEXT
CREATE_PROCESS_DEBUG_INFO
CREATE_THREAD_DEBUG_INFO
DEBUG_EVENT
EXCEPTION_DEBUG_INFO
EXIT_PROCESS_DEBUG_INFO
EXIT_THREAD_DEBUG_INFO
LDT_ENTRY
LOAD_DLL_DEBUG_INFO
OUTPUT_DEBUG_STRING_INFO
RIP_INFO
UNLOAD_DLL_DEBUG_INFO


CONTEXT

A CONTEXT structure contains processor-specific register data. Windows NT uses CONTEXT structures to perform various internal operations. Currently, there are CONTEXT structures defined for Intel, MIPS, Alpha, and PowerPC, processors. Refer to the header file WinNT.h for definitions of these structures.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Debugging Overview, Debugging Structures


CREATE_PROCESS_DEBUG_INFO

The CREATE_PROCESS_DEBUG_INFO structure contains process creation information that can be used by a debugger.

typedef struct _CREATE_PROCESS_DEBUG_INFO { // cpdi
    HANDLE hFile;
    HANDLE hProcess;
    HANDLE hThread;
    LPVOID lpBaseOfImage;
    DWORD dwDebugInfoFileOffset;
    DWORD nDebugInfoSize;
    LPVOID lpThreadLocalBase;
    LPTHREAD_START_ROUTINE lpStartAddress;
    LPVOID lpImageName;
    WORD fUnicode;
} CREATE_PROCESS_DEBUG_INFO;

Members

hFile
Handle to the process's image file. If this member is NULL, the handle is not valid. Otherwise, the debugger can use the member to read from and write to the image file.
hProcess
Handle to the process. If this member is NULL, the handle is not valid. Otherwise, the debugger can use the member to read from and write to the process's memory.
hThread
Handle to the initial thread of the process identified by the hProcess member. If hThread is NULL, the handle is not valid. Otherwise, the debugger has THREAD_GET_CONTEXT, THREAD_SET_CONTEXT, and THREAD_SUSPEND_RESUME access to the thread, allowing the debugger to read from and write to the registers of the thread and to control execution of the thread.
lpBaseOfImage
Pointer to the base address of the executable image that the process is running.
dwDebugInfoFileOffset
Specifies the offset to the debugging information in the file identified by the hFile member. The kernel expects the debugging information to be in Microsoft® CodeView® version 4.0 format. This format is currently a derivative of COFF (Common Object File Format).
nDebugInfoSize
Specifies the size, in bytes, of the debugging information in the file. If this value is zero, there is no debugging information.
lpThreadLocalBase
Pointer to a block of data. At offset 0x2C into this block is another pointer, called ThreadLocalStoragePointer, that points to an array of per-module thread local storage blocks. This gives a debugger access to per-thread data in the threads of the process being debugged using the same algorithms that a compiler would use.
lpStartAddress
Pointer to the starting address of the thread. This value may only be an approximation of the thread's starting address, because any application with appropriate access to the thread can change the thread's context by using the SetThreadContext function.
lpImageName
Pointer to the filename associated with the hFile parameter. This parameter may be NULL, or it may contain the address of a string pointer in the address space of the process being debugged. That address may, in turn, either be NULL or point to the actual filename. If fUnicode is a nonzero value, the name string is Unicode; otherwise, it is ANSI.

This member is strictly optional. Debuggers must be prepared to handle the case where lpImageName is NULL or *lpImageName (in the address space of the process being debugged) is NULL. Specifically, the system does not provide an image name for a create process event, and will not likely pass an image name for the first DLL event. The system also does not provide this information in the case of debug events that originate from a call to the DebugActiveProcess function.

fUnicode
Indicates whether a file name specified by the lpImageName member is Unicode or ANSI. A nonzero value indicates Unicode; zero indicates ANSI.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Debugging Overview, Debugging Structures, CREATE_THREAD_DEBUG_INFO, DebugActiveProcess, DEBUG_EVENT, LOAD_DLL_DEBUG_INFO, SetThreadContext


CREATE_THREAD_DEBUG_INFO

The CREATE_THREAD_DEBUG_INFO structure contains thread-creation information that can be used by a debugger.

typedef struct _CREATE_THREAD_DEBUG_INFO { // ctdi
    HANDLE hThread;
    LPVOID lpThreadLocalBase;
    LPTHREAD_START_ROUTINE lpStartAddress;
} CREATE_THREAD_DEBUG_INFO;

Members

hThread
Handle to the thread whose creation caused the debugging event. If this member is NULL, the handle is not valid. Otherwise, the debugger has THREAD_GET_CONTEXT, THREAD_SET_CONTEXT, and THREAD_SUSPEND_RESUME access to the thread, allowing the debugger to read from and write to the registers of the thread and control execution of the thread.
lpThreadLocalBase
Pointer to a block of data. At offset 0x2C into this block is another pointer, called ThreadLocalStoragePointer, that points to an array of per-module thread local storage blocks. This gives a debugger access to per-thread data in the threads of the process being debugged using the same algorithms that a compiler would use.
lpStartAddress
Pointer to the starting address of the thread. This value may only be an approximation of the thread's starting address, because any application with appropriate access to the thread can change the thread's context by using the SetThreadContext function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Debugging Overview, Debugging Structures, CREATE_PROCESS_DEBUG_INFO, DEBUG_EVENT, LOAD_DLL_DEBUG_INFO, SetThreadContext


DEBUG_EVENT

The DEBUG_EVENT structure describes a debugging event.

typedef struct _DEBUG_EVENT { // de
    DWORD dwDebugEventCode;
    DWORD dwProcessId;
    DWORD dwThreadId;
    union {
        EXCEPTION_DEBUG_INFO Exception;
        CREATE_THREAD_DEBUG_INFO CreateThread;
        CREATE_PROCESS_DEBUG_INFO CreateProcessInfo;
        EXIT_THREAD_DEBUG_INFO ExitThread;
        EXIT_PROCESS_DEBUG_INFO ExitProcess;
        LOAD_DLL_DEBUG_INFO LoadDll;
        UNLOAD_DLL_DEBUG_INFO UnloadDll;
        OUTPUT_DEBUG_STRING_INFO DebugString;
        RIP_INFO RipInfo;
    } u;
} DEBUG_EVENT;

Members

dwDebugEventCode
Specifies a debugging event code that identifies the type of debugging event. This parameter can be one of the following values:
Value Meaning
EXCEPTION_DEBUG_EVENT
Reports an exception debugging event. The value of u.Exception specifies an EXCEPTION_DEBUG_INFO structure.
CREATE_THREAD_DEBUG_EVENT
Reports a create-thread debugging event. The value of u.CreateThread specifies a CREATE_THREAD_DEBUG_INFO structure.
CREATE_PROCESS_DEBUG_EVENT
Reports a create-process debugging event. The value of u.CreateProcessInfo specifies a CREATE_PROCESS_DEBUG_INFO structure.
EXIT_THREAD_DEBUG_EVENT
Reports an exit-thread debugging event. The value of u.ExitThread specifies an EXIT_THREAD_DEBUG_INFO structure.
EXIT_PROCESS_DEBUG_EVENT
Reports an exit-process debugging event. The value of u.ExitProcess specifies an EXIT_PROCESS_DEBUG_INFO structure.
LOAD_DLL_DEBUG_EVENT
Reports a load-dynamic-link-library (DLL) debugging event. The value of u.LoadDll specifies a LOAD_DLL_DEBUG_INFO structure.
UNLOAD_DLL_DEBUG_EVENT
Reports an unload-DLL debugging event. The value of u.UnloadDll specifies an UNLOAD_DLL_DEBUG_INFO structure.
OUTPUT_DEBUG_STRING_EVENT
Reports an output-debugging-string debugging event. The value of u.DebugString specifies an OUTPUT_DEBUG_STRING_INFO structure.
RIP_EVENT
Reports a RIP-debugging event (system debugging error). The value of u.RipInfo specifies a RIP_INFO structure.

dwProcessId
Specifies the identifier of the process in which the debugging event occurred. A debugger uses this value to locate the debugger's per-process structure. These values are not necessarily small integers that can be used as table indices.
dwThreadId
Specifies the identifier of the thread in which the debugging event occurred. A debugger uses this value to locate the debugger's per-thread structure. These values are not necessarily small integers that can be used as table indices.
u
Specifies additional information relating to the debugging event. This union takes on the type and value appropriate to the type of debugging event, as described in the dwDebugEventCode member.

Remarks

If the WaitForDebugEvent function succeeds, it fills in the members of a DEBUG_EVENT structure.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Debugging Overview, Debugging Structures, CREATE_PROCESS_DEBUG_INFO, CREATE_THREAD_DEBUG_INFO, EXIT_PROCESS_DEBUG_INFO, EXIT_THREAD_DEBUG_INFO, EXCEPTION_DEBUG_INFO, LOAD_DLL_DEBUG_INFO, OUTPUT_DEBUG_STRING_INFO, UNLOAD_DLL_DEBUG_INFO, WaitForDebugEvent


EXCEPTION_DEBUG_INFO

The EXCEPTION_DEBUG_INFO structure contains exception information that can be used by a debugger.

typedef struct _EXCEPTION_DEBUG_INFO { // exdi
    EXCEPTION_RECORD ExceptionRecord;
    DWORD dwFirstChance;
} EXCEPTION_DEBUG_INFO;

Members

ExceptionRecord
Contains an EXCEPTION_RECORD structure with information specific to the exception. This includes the exception code, flags, address, a pointer to a related exception, extra parameters, and so on.
dwFirstChance
Indicates whether the debugger has previously encountered the exception specified by the ExceptionRecord member. If the dwFirstChance member is nonzero, this is the first time the debugger has encountered the exception. Debuggers typically handle breakpoint and single-step exceptions when they are first encountered. If this member is zero, the debugger has previously encountered the exception. This occurs only if, during the search for structured exception handlers, either no handler was found or the exception was continued.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Debugging Overview, Debugging Structures, DEBUG_EVENT, EXCEPTION_RECORD


EXIT_PROCESS_DEBUG_INFO

The EXIT_PROCESS_DEBUG_INFO structure contains an exiting process's exit code.

typedef struct _EXIT_PROCESS_DEBUG_INFO { // epdi
    DWORD dwExitCode;
} EXIT_PROCESS_DEBUG_INFO;

Members

dwExitCode
Specifies the exit code for the process.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Debugging Overview, Debugging Structures, DEBUG_EVENT


EXIT_THREAD_DEBUG_INFO

The EXIT_THREAD_DEBUG_INFO structure contains an exiting thread's exit code.

typedef struct _EXIT_THREAD_DEBUG_INFO { // etdi
    DWORD dwExitCode;
} EXIT_THREAD_DEBUG_INFO;

Members

dwExitCode
Specifies the exit code for the thread.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Debugging Overview, Debugging Structures, DEBUG_EVENT


LDT_ENTRY

The LDT_ENTRY structure describes an entry in the descriptor table. This structure is valid only on x86-based systems.

typedef struct _LDT_ENTRY { // ldte
    WORD LimitLow;
    WORD BaseLow;
    union {
        struct {
            BYTE BaseMid;
            BYTE Flags1;
            BYTE Flags2;
            BYTE BaseHi;
        } Bytes;
        struct {
            DWORD BaseMid : 8;
            DWORD Type : 5;
            DWORD Dpl : 2;
            DWORD Pres : 1;
            DWORD LimitHi : 4;
            DWORD Sys : 1;
            DWORD Reserved_0 : 1;
            DWORD Default_Big : 1;
            DWORD Granularity : 1;
            DWORD BaseHi : 8;
        } Bits;
    } HighWord;
} LDT_ENTRY, *PLDT_ENTRY;

Members

LimitLow
Contains the low 16 bits of the address of the last byte in the segment.
BaseLow
Contains the low 16 bits of the base address of the segment.
HighWord
Contains the high two words of the descriptor. This member may be interpreted as bytes or collections of bits, depending on the level of detail required.

The members of the Bits structure are as follows:
Member | Contents
BaseMid | Middle bits (16–23) of the base address of the segment.
Type | Bitmask that indicates the type of segment. This member can be one of the following values:

Value | Meaning
0 | Read-only data segment
1 | Read-write data segment
2 | Unused segment
3 | Read-write expand-down data segment
4 | Execute-only code segment
5 | Executable-readable code segment
6 | Execute-only "conforming" code segment
7 | Executable-readable "conforming" code segment

Dpl | Privilege level of the descriptor. This member is an integer value in the range 0 (most privileged) through 3 (least privileged).
Pres | Present flag. This member is 1 if the segment is present in physical memory or 0 if it is not.
LimitHi | High bits (16–19) of the address of the last byte in the segment.
Sys | Space that is available to system programmers. This member might be used for marking segments in some system-specific way.
Reserved_0 | Reserved.
Default_Big | Size of segment. If the segment is a data segment, this member contains 1 if the segment is larger than 64 kilobytes (K) or 0 if the segment is smaller than or equal to 64K.
If the segment is a code segment, this member contains 1 if the segment is a code segment and runs with the default (native mode) instruction set. This member contains 0 if the code segment is an 80286 code segment and runs with 16-bit offsets and the 80286-compatible instruction set.
Granularity | Granularity. This member contains 0 if the segment is byte granular, 1 if the segment is page granular.
BaseHi | High bits (24–31) of the base address of the segment.

The members of the Bytes structure are as follows:
Member | Contents
BaseMid | Middle bits (16–23) of the base address of the segment.
Flags1 | Values of the Type, Dpl, and Pres members in the Bits structure.
Flags2 | Values of the LimitHi, Sys, Reserved_0, Default_Big, and Granularity members in the Bits structure.
BaseHi | High bits (24–31) of the base address of the segment.

Remarks

The GetThreadSelectorEntry function fills this structure with information from an entry in the descriptor table. You can use this information to convert a segment-relative address to a linear virtual address.

The base address of a segment is the address of offset 0 in the segment. To calculate this value, combine the BaseLow, BaseMid, and BaseHi members.

The limit of a segment is the address of the last byte that can be addressed in the segment. To calculate this value, combine the LimitLow and LimitHi members.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Debugging Overview, Debugging Structures, GetThreadSelectorEntry


LOAD_DLL_DEBUG_INFO

The LOAD_DLL_DEBUG_INFO structure contains information about a dynamic-link library (DLL) that has just been loaded.

typedef struct _LOAD_DLL_DEBUG_INFO { // lddi
    HANDLE hFile;
    LPVOID lpBaseOfDll;
    DWORD  dwDebugInfoFileOffset;
    DWORD  nDebugInfoSize;
    LPVOID lpImageName;
    WORD fUnicode;
} LOAD_DLL_DEBUG_INFO;

Members

hFile
Handle to the loaded DLL. If this member is NULL, the handle is not valid. Otherwise, the member is opened for reading and read-sharing in the context of the debugger.
lpBaseOfDll
Pointer to the base address of the DLL in the address space of the process loading the DLL.
dwDebugInfoFileOffset
Specifies the offset to the debugging information in the file identified by the hFile member. The kernel expects the debugging information to be in CodeView 4.0 format. This format is currently a derivative of Common Object File Format (COFF).
nDebugInfoSize
Specifies the size, in bytes, of the debugging information in the file. If this value is zero, there is no debugging information.
lpImageName
Pointer to the filename associated with hFile. This member may be NULL, or it may contain the address of a string pointer in the address space of the process being debugged. That address may, in turn, either be NULL or point to the actual filename. If fUnicode is a nonzero value, the name string is Unicode; otherwise, it is ANSI.

This member is strictly optional. Debuggers must be prepared to handle the case where lpImageName is NULL or *lpImageName (in the address space of the process being debugged) is NULL. Specifically, the system will never provide an image name for a create process event, and it will not likely pass an image name for the first DLL event. The system will also never provide this information in the case of debugging events that originate from a call to the DebugActiveProcess function.

fUnicode
Indicates whether a filename specified by lpImageName is Unicode or ANSI. A nonzero value for this member indicates Unicode; zero indicates ANSI.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Debugging Overview, Debugging Structures, CREATE_PROCESS_DEBUG_INFO, CREATE_THREAD_DEBUG_INFO, DebugActiveProcess, DEBUG_EVENT


OUTPUT_DEBUG_STRING_INFO

The OUTPUT_DEBUG_STRING_INFO structure contains the address, format, and length, in bytes, of a debugging string.

typedef struct _OUTPUT_DEBUG_STRING_INFO { // odsi
    LPSTR lpDebugStringData;
    WORD  fUnicode;
    WORD  nDebugStringLength;
} OUTPUT_DEBUG_STRING_INFO;

Members

lpDebugStringData
Pointer to the debugging string in the calling process's address space. The debugger can use the ReadProcessMemory function to retrieve the value of the string.
fUnicode
Specifies the format of the debugging string. If this member is zero, the debugging string is 8-bit ASCII; if it is nonzero, the string is 16-bit Unicode™.
nDebugStringLength
Specifies the length, in bytes, of the debugging string. The length includes the string's terminating null character.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Debugging Overview, Debugging Structures, DEBUG_EVENT, ReadProcessMemory


RIP_INFO

The RIP_INFO structure contains the error and address, format, and length, in bytes, of a debugging string.

typedef struct _RIP_INFO { /* ri */
    DWORD  dwError;
    DWORD  dwType;
} RIP_INFO;

Members

dwError
Specifies the error that caused the RIP debug event. For more information about exception handling, see Errors.
dwType
Specifies additional information about the type of error that caused the RIP debug event. This may be one of the following values:
Value | Meaning
SLE_ERROR | Indicates that invalid data was passed to the function that failed. This caused the application to fail.
SLE_MINORERROR | Indicates that invalid data was passed to the function, but the error probably will not cause the application to fail.
SLE_WARNING | Indicates that potentially invalid data was passed to the function, but the function completed processing.
0 | Indicates that only dwError was set.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Debugging Overview, Debugging Structures, DEBUG_EVENT


UNLOAD_DLL_DEBUG_INFO

The UNLOAD_DLL_DEBUG_INFO structure contains information about a dynamic-link library (DLL) that has just been unloaded.

typedef struct _UNLOAD_DLL_DEBUG_INFO { // uddi
    LPVOID lpBaseOfDll;
} UNLOAD_DLL_DEBUG_INFO;

Members

lpBaseOfDll
Pointer to the base address of the DLL in the address space of the process unloading the DLL.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Debugging Overview, Debugging Structures, DEBUG_EVENT


Errors

Well-written applications include code that allows them to recover gracefully from unexpected errors. When an error occurs, the application may need to request user intervention, or it may be able to recover on its own. In extreme cases, the application may log the user off or shut down the system.


About Errors

Microsoft® Windows® and Microsoft® Windows NT® include a special error-handling mechanism for exceptions, such as divide-by-zero errors. For more information about exception handling, see Structured Exception Handling.


Notifying the User

To notify the user that some kind of error has occurred, many applications simply produce a sound by using the Beep or MessageBeep function or flash the window by using the FlashWindow or FlashWindowEx function. An application can also use these functions to call attention to an error and then display a message box or an error message containing details about the error.


Last-Error Code

When an error occurs, most Win32 functions return an error code, usually FALSE, NULL, 0xFFFFFFFF, or –1. Many functions also set an internal error code called the last-error code. When a function succeeds, the last-error code is not reset. The error code is maintained separately for each running thread; an error in one thread does not overwrite the last-error code in another thread. An application can retrieve the last-error code by using the GetLastError function; the error code may tell more about what actually occurred to make the function fail.

The SetLastError function sets the error code for the current thread. The SetLastErrorEx function also allows the caller to set an error type indicating the severity of the error. These functions are intended primarily for dynamic-link libraries (DLLs), so they can emulate the behavior of the Win32 functions.

The system defines a set of error codes that can be set as last-error codes or be returned by these functions. Error codes are 32-bit values (bit 31 is the most significant bit). Bit 29 is reserved for application-defined error codes; no system error code has this bit set. If you define error codes for your application, set this bit to indicate that the error code has been defined by an application and to ensure that the error codes do not conflict with any system-defined error codes. For more information, see the WINERROR.H header file or Error Codes.


Process Error Mode

Each process has an associated error mode that indicates to the system how the application is going to respond to serious errors. Serious errors include disk failure, drive-not-ready errors, data misalignment, and unhandled exceptions. An application can let the system display a message box informing the user that an error has occurred, or it can handle the errors. To handle these errors without user intervention, use the SetErrorMode function. After calling SetErrorMode and specifying appropriate flags, the system will not display the corresponding error message boxes.


Fatal Application Exit

The FatalAppExit function displays a message box and terminates the application when the user closes the message box. This function should only be used as a last resort, because it may not free the memory or files owned by the application.


Using Errors

  • Notifying the user of errors - example
  • Retrieving the last-error code


Notifying the User of Errors - Example

The following example flashes a window and plays the system exclamation sound.

FlashWindow(hwnd, TRUE); // invert the title bar
Sleep(500);              // wait a bit
FlashWindow(hwnd, TRUE); // invert again

// Play the system exclamation sound.

MessageBeep(MB_ICONEXCLAMATION);


Retrieving the Last-Error Code

When a function in the Win32 API fails, it sets the last-error code. If your application needs more details about an error, it can retrieve the last-error code.

The following example shows an error-handling function.

void error(LPSTR lpszFunction)
{
    CHAR szBuf[80];
    DWORD dw = GetLastError();

    sprintf(szBuf, "%s failed: GetLastError returned %u\n",
        lpszFunction, dw);

    MessageBox(NULL, szBuf, "ERROR", MB_OK);
    ExitProcess(dw);
}


Error Reference

The following elements are used with errors.

  • Error Functions


Error Functions

The following functions are used with errors.

Beep
FatalAppExit
FlashWindow
FlashWindowEx
GetLastError
MessageBeep
SetErrorMode
SetLastError
SetLastErrorEx


Beep

The Beep function generates simple tones on the speaker. The function is synchronous; it does not return control to its caller until the sound finishes.

BOOL Beep(
  DWORD dwFreq,      // sound frequency, in hertz
  DWORD dwDuration   // sound duration, in milliseconds
);

Parameters

dwFreq
Windows NT: Specifies the frequency, in hertz, of the sound. This parameter must be in the range 37 through 32,767 (0x25 through 0x7FFF).
dwDuration
Windows NT: Specifies the duration, in milliseconds, of the sound.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows 95: The Beep function ignores the dwFreq and dwDuration parameters. On computers with a sound card, the function plays the default sound event. On computers without a sound card, the function plays the standard system beep.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Errors Overview, Error Functions, MessageBeep


FatalAppExit

The FatalAppExit function displays a message box and terminates the application when the message box is closed. If the system is running with a kernel debugger, the message box gives the user the opportunity to terminate the application or to cancel the message box and return to the application that called FatalAppExit.

VOID FatalAppExit(
  UINT uAction,  // reserved
  LPCTSTR lpMessageText
                 // pointer to string to display in message box
);

Parameters

uAction
Reserved; must be zero.
lpMessageText
Pointer to a null-terminated string that is displayed in the message box. The message is displayed on a single line. To accommodate low-resolution screens, the string should be no more than 35 characters in length.

Return Values

This function does not return a value.

Remarks

An application calls FatalAppExit only when it is not capable of terminating any other way. FatalAppExit may not always free an application's memory or close its files, and it may cause a general failure of the system. An application that encounters an unexpected error should terminate by freeing all its memory and returning from its main message loop.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Errors Overview, Error Functions, FatalExit


FlashWindow

The FlashWindow function flashes the specified window once, whereas the FlashWindowEx function flashes a specified number of times.

BOOL FlashWindow(
  HWND hWnd,     // handle to window to flash
  BOOL bInvert   // flash status
);

Parameters

hWnd
Handle to the window to be flashed. The window can be either open or minimized (iconic).
bInvert
Specifies whether the window is to be flashed or returned to its original state. The window is flashed from one state to the other if this parameter is TRUE. If it is FALSE, the window is returned to its original state (either active or inactive). When an application is iconic, if this parameter is TRUE, the taskbar window button flashes active/inactive. If it is FALSE, the taskbar window button flashes inactive, meaning that it does not change colors. It flashes, as if it were being redraw, but it does not provide the visual invert clue to the user.

Return Values

The return value specifies the window's state before the call to the FlashWindow function. If the window was active before the call, the return value is nonzero.

If the window was not active before the call, the return value is zero.

Remarks

Flashing a window means changing the appearance of its caption bar as if the window were changing from inactive to active status, or vice versa. (An inactive caption bar changes to an active caption bar; an active caption bar changes to an inactive caption bar.)

Typically, a window is flashed to inform the user that the window requires attention but that it does not currently have the keyboard focus.

The FlashWindow function flashes the window only once; for repeated flashing, the application should create a system timer.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Errors Overview, Error Functions


FlashWindowEx

[This is preliminary documentation and subject to change.]

The FlashWindowEx function flashes the specified window. Using this function, you can specify the number of times the system will flash the window, whereas the FlashWindow function flashes the window only once.

BOOL FlashWindowEx(
  PFLASHWINFO pfwi
);

Parameters

pfwi
Pointer to the FLASHWINFO structure.

Return Values

The return value specifies the window's state before the call to the FlashWindowEx function. If the window was active before the call, the return value is nonzero.

If the window was not active before the call, the return value is zero.

Remarks

Typically, you flash a window to inform the user that the window requires attention but does not currently have the keyboard focus. When a window flashes, it appears to change from inactive to active status. An inactive caption bar changes to an active caption bar; an active caption bar changes to an inactive caption bar.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Errors Overview, Error Functions, FLASHWINFO


GetLastError

The GetLastError function returns the calling thread's last-error code value. The last-error code is maintained on a per-thread basis. Multiple threads do not overwrite each other's last-error code.

DWORD GetLastError(VOID)

Parameters

This function has no parameters.

Return Values

The return value is the calling thread's last-error code value. Functions set this value by calling the SetLastError function. The Return Value section of each reference page notes the conditions under which the function sets the last-error code.

Windows 95 and Windows 98: Because SetLastError is a 32-bit function only, Win32 functions that are actually implemented in 16-bit code do not set the last-error code. You should ignore the last-error code when you call these functions. They include window management functions, GDI functions, and Multimedia functions.

Remarks

You should call the GetLastError function immediately when a function's return value indicates that such a call will return useful data. That is because some functions call SetLastError(0) when they succeed, wiping out the error code set by the most recently failed function.

Most functions in the Win32 API that set the thread's last error code value set it when they fail; a few functions set it when they succeed. Function failure is typically indicated by a return value error code such as FALSE, NULL, 0xFFFFFFFF, or –1. Some functions call SetLastError under conditions of success; those cases are noted in each function's reference page.

Error codes are 32-bit values (bit 31 is the most significant bit). Bit 29 is reserved for application-defined error codes; no system error code has this bit set. If you are defining an error code for your application, set this bit to one. That indicates that the error code has been defined by an application, and ensures that your error code does not conflict with any error codes defined by the system.

To obtain an error string for system error codes, use the FormatMessage function. For a complete list of error codes, see Error Codes or the SDK header file WINERROR.H.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Errors Overview, Error Functions, FormatMessage , SetLastError, SetLastErrorEx


MessageBeep

The MessageBeep function plays a waveform sound. The waveform sound for each sound type is identified by an entry in the [sounds] section of the registry.

BOOL MessageBeep(
  UINT uType   // sound type
);

Parameters

uType
Specifies the sound type, as identified by an entry in the [sounds] section of the registry. This parameter can be one of the following values:
Value | Sound
0xFFFFFFFF | Standard beep using the computer speaker
MB_ICONASTERISK | SystemAsterisk
MB_ICONEXCLAMATION | SystemExclamation
MB_ICONHAND | SystemHand
MB_ICONQUESTION | SystemQuestion
MB_OK | SystemDefault

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

After queuing the sound, the MessageBeep function returns control to the calling function and plays the sound asynchronously.

If it cannot play the specified alert sound, MessageBeep attempts to play the system default sound. If it cannot play the system default sound, the function produces a standard beep sound through the computer speaker.

The user can disable the warning beep by using the Sound Control Panel application.

Windows CE: Passing 0xFFFFFFFF will cause the SystemDefault waveform to be played.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Errors Overview, Error Functions, FlashWindow, MessageBox


SetErrorMode

The SetErrorMode function controls whether the system will handle the specified types of serious errors, or whether the process will handle them.

UINT SetErrorMode(
  UINT uMode   // bit flags specifying the process error mode
);

Parameters

uMode
A set of bit flags that specify the process error mode. This parameter can be one or more of the following error mode constants:
Value | Action
SEM_FAILCRITICALERRORS | The system does not display the critical-error-handler message box. Instead, the system sends the error to the calling process.
SEM_NOALIGNMENTFAULTEXCEPT RISC only: The system automatically fixes memory alignment faults and makes them invisible to the application. It does this for the calling process and any descendant processes.

This flag has no effect on x86 processors.
SEM_NOGPFAULTERRORBOX | The system does not display the general-protection-fault message box. This flag should only be set by debugging applications that handle general protection (GP) faults themselves with an exception handler.
SEM_NOOPENFILEERRORBOX | The system does not display a message box when it fails to find a file. Instead, the error is returned to the calling process.

Return Values

The return value is the previous state of the error-mode bit flags.

Remarks

Each process has an associated error mode that indicates to the system how the application is going to respond to serious errors. A child process inherits the error mode of its parent process.

RISC only: On some non-x86 processors misaligned memory references cause an alignment fault exception. The SEM_NOALIGNMENTFAULTEXCEPT flag lets you control whether the system automatically fixes such alignment faults, or makes them visible to an application.

MIPS only: On a MIPS computer, an application must explicitly call SetErrorMode with the SEM_NOALIGNMENTFAULTEXCEPT flag to have the system automatically fix alignment faults. The default setting is for the system to make alignment faults visible to an application.

Alpha only: On an ALPHA computer, you control the alignment fault behavior by setting the EnableAlignmentFaultExceptions value in the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager registry key as follows:

Value | Meaning
0 | Automatically fix alignment faults. This is the default.
1 | Make alignment faults visible to the application. You must call SetErrorMode with SEM_NOALIGNMENTFAULTEXCEPT to have the system automatically fix alignment faults.
2 | Windows NT 5.0 and later: Alignment faults are visible only when the process is running under the debugger.

x86 only: On an x86 computer, the system does not make alignment faults visible to an application. Therefore, specifying the SEM_NOALIGNMENTFAULTEXCEPT flag on an x86 computer is not an error, but the system is free to silently ignore and not properly preserve the flag. This means that code sequences such as the following are not always valid on x86 computers:

SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT);
    fuOldErrorMode = SetErrorMode(0);
    ASSERT(fuOldErrorMode == SEM_NOALIGNMENTFAULTEXCEPT);

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Errors Overview, Error Functions


SetLastError

The SetLastError function sets the last-error code for the calling thread.

VOID SetLastError(
  DWORD dwErrCode   // per-thread error code
);

Parameters

dwErrCode
Specifies the last-error code for the thread.

Remarks

Error codes are 32-bit values (bit 31 is the most significant bit). Bit 29 is reserved for application-defined error codes; no system error code has this bit set. If you are defining an error code for your application, set this bit to indicate that the error code has been defined by your application and to ensure that your error code does not conflict with any system-defined error codes.

This function is intended primarily for dynamic-link libraries (DLLs). Calling this function after an error occurs lets the DLL emulate the behavior of a Win32 function.

Most Win32 functions call SetLastError when they fail. Function failure is typically indicated by a return value error code such as FALSE, NULL, 0xFFFFFFFF, or –1. Some functions call SetLastError under conditions of success; those cases are noted in each function's reference page.

Applications can retrieve the value saved by this function by using the GetLastError function. The use of GetLastError is optional; an application can call it to find out the specific reason for a function failure.

The last-error code is kept in thread local storage so that multiple threads do not overwrite each other's values.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Errors Overview, Error Functions, GetLastError, SetLastErrorEx, TlsGetValue


SetLastErrorEx

The SetLastErrorEx function sets the last-error code. In Windows 95 and in Windows NT, this function is identical to the SetLastError function. The second parameter is not implemented.

VOID SetLastErrorEx(
  DWORD dwErrCode,  // per-thread error code
  DWORD dwType      // error type
);

Parameters

dwErrCode
Specifies the last-error code for the thread.
dwType
Specifies the error type. If this process is being controlled by a debugging process, the debugger may take action based on the error type. This parameter can have one of the following values:
Value | Meaning
SLE_ERROR | Invalid data was passed to the function, and complete failure has occurred.
SLE_MINORERROR | Invalid data was passed to the function, but the function has recovered.
SLE_WARNING | Potentially invalid data was passed to the function, but the function has recovered.
0 | The last-error code is set without reporting anything to the debugger. Specifying this value is equivalent to using the SetLastError function.

Remarks

Error codes are 32-bit values (bit 31 is the most significant bit). Bit 29 is reserved for application-defined error codes; no Win32 API error code has this bit set. If you are defining an error code for your application, set this bit to indicate that the error code has been defined by the application and to ensure that your error code does not conflict with any system-defined error codes.

This function is intended primarily for dynamic-link libraries (DLLs). Calling this function after an error occurs allows the DLL to emulate the behavior of the Win32 API.

Most Win32 functions call SetLastError when they fail. Function failure is typically indicated by a return value error code such as FALSE, NULL, 0xFFFFFFFF, or –1. Some functions call SetLastError under conditions of success; those cases are noted in each function's reference page.

Applications can retrieve the value saved by this function by using the GetLastError function.

The last-error code is kept in thread local storage so that multiple threads do not overwrite each other's values.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Errors Overview, Error Functions, GetLastError, SetLastError


Error Structures

The following structures are used with errors.

FLASHWINFO


FLASHWINFO

[This is preliminary documentation and subject to change.]

The FLASHWINFO structure contains the flash status for a window and the number of times the system should flash the window.

typedef struct {
    UINT  cbSize;
    HWND  hwnd;
    DWORD dwFlags;
    UINT  uCount;
    DWORD dwTimeout;
} FLASHWINFO, *PFLASHWINFO;

Members

cbSize
Specifies the size of the structure.
hwnd
Handle to the window to be flashed. The window can be either opened or minimized.
dwFlags
Specifies the flash status. This parameter can be one or more of the following flags.
Flag | Meaning
FLASHW_STOP | Stop flashing. The system restores the window to its original state.
FLASHW_CAPTION | Flash the window caption.
FLASHW_TRAY | Flash the taskbar button.
FLASHW_ALL | Flash both the window caption and taskbar button. This is equivalent to setting the FLASHW_CAPTION | FLASHW_TRAY flags.
FLASHW_TIMER | Flash continuously, until the FLASHW_STOP flag is set.
FLASHW_TIMERNOFG | Flash continuously until the window comes to the foreground.

uCount
Specifies the number of times to flash the window.
dwTimeout
Specifies the rate, in milliseconds, at which the window will be flashed. If dwTimeout is zero, the function uses the default cursor blink rate.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Errors Overview, Error Structures, FlashWindowEx


Event Logging

Many applications record errors and events in various proprietary error logs. These proprietary error logs have different formats and display different user interfaces. Moreover, you cannot merge the data to provide a complete report. Therefore, you need to check a variety of sources to diagnose problems. Event logging in Microsoft® Windows NT® provides a standard, centralized way for applications (and the operating system) to record important software and hardware events. The event-logging service stores events from various sources in a single collection called an event log. Windows NT also supplies Event Viewer for viewing the logs, and a programming interface for examining the logs.

This overview contains the following topics, which discuss the programming interface for writing to and examining event logs.

  • Event types
  • Logging guidelines
  • Event logging elements
  • Event logging operations
  • Event logging model
  • Event logging security


About Event Logging

When an error occurs, the system administrator or support technicians must determine what caused the error, attempt to recover any lost data, and prevent the error from recurring. It is helpful if applications, the operating system, and other system services record important events such as low-memory conditions or excessive attempts to access a disk. Then the system administrator can use the event log to help determine what conditions caused the error and the context in which it occurred. By periodically viewing the event log, the system administrator may be able to identify problems (such as a failing hard drive) before they cause damage.


Event Types

Windows NT defines five types of events that can be logged. All event classifications have well-defined common data and can optionally include event-specific data. The application indicates the event type when it reports an event. Each event must be of a single type. The Event Viewer uses this type to determine which icon to display in the list view of the log.

The following table describes the event types used in event logging.

Event type | Description
Information | Information events indicate infrequent but significant successful operations. For example, when Microsoft® SQL Server™ successfully loads, it may be appropriate to log an information event stating that "SQL Server has started." Note that while this is appropriate behavior for major server services, it is generally inappropriate for a desktop application (Microsoft® Excel, for example) to log an event each time it starts.
Warning | Warning events indicate problems that are not immediately significant, but that may indicate conditions that could cause future problems. Resource consumption is a good candidate for a warning event. For example, an application can log a warning event if disk space is low. If an application can recover from an event without loss of functionality or data, it can generally classify the event as a warning event.
Error | Error events indicate significant problems that the user should know about. Error events usually indicate a loss of functionality or data. For example, if a service cannot be loaded as the system boots, it can log an error event.
Success audit | Success audit events are security events that occur when an audited access attempt is successful. For example, a successful logon attempt is a success audit event.
Failure audit | Failure audit events are security events that occur when an audited access attempt fails. For example, a failed attempt to open a file is a failure audit event.

Selected activities of users on can be tracked by auditing security events and then placing entries in a computer's security log. To determine the types of security events that will be logged for the computer, use the Windows NT User Manager. For more information, look up "auditing" in the online help provided with the Windows NT User Manager.


Logging Guidelines

Event logs store records of significant events on behalf of Windows NT and applications running on Windows NT. Because the logging functions are general purpose, you must decide what information is appropriate to log. Generally, you should log only information that could be useful in diagnosing a hardware or software problem. Event logging is not intended to be used as a tracing tool.

The following are examples of cases in which event logging can be helpful.

  • Resource problems. If an application gets into a low-memory situation (caused by a code bug or inadequate memory) that degrades performance, logging a warning event when memory allocation fails might provide a clue about what went wrong.
  • Hardware problems. If a device driver encounters a disk controller time-out, a power failure in a parallel port, or a data error from a network or serial card, logging information about these events can help the system administrator diagnose hardware problems. The device driver logs the error.
  • Bad sectors. If a disk driver encounters a bad sector, it may be able to read from or write to the sector after retrying the operation, but the sector will go bad eventually. Therefore, if the disk driver can proceed, it should log a warning; otherwise, it should log an error event. If a file system driver finds a large number of bad sectors, fixes them, and logs warning events, logging information of this type might indicate that the disk is about to fail.
  • Information events. A server application (such as a database server) records a user logging on, opening a database, or starting a file transfer. The server can also log error events it encounters (cannot access file, host process disconnected, and so on), a corruption in the database, or whether a file transfer was successful.

Event logging consumes resources such as disk space and processor time. The amount of disk space that an event log requires and the overhead for an application that logs events depend on how much information you choose to log. This is why it is important to log only essential information. It is also good to place event logging calls in an error path in the code rather than in the main code path, which would reduce performance.

The amount of disk space required per event log record includes the members of the EVENTLOGRECORD structure. This is a variable length structure; strings and binary data are stored following the structure.


Event Logging Elements

The following are the major elements used in event logging:

  • Logfiles
  • Event sources
  • Event categories
  • Event identifiers
  • Message files
  • Event data


Logfiles

The event-logging service uses the information stored in the EventLog registry key. The EventLog key (shown in the following example) contains several subkeys, called logfiles. Logfile registry information is used to locate resources that the event logging service needs when an application writes to and reads from the event log. The default logfiles are Application, Security, and System. The structure is as follows:

HKEY_LOCAL_MACHINE
SYSTEM
CurrentControlSet
Services
EventLog
Application
Security
System

Applications and services use the Application logfile. Device drivers use the System logfile. Windows NT will generate success and failure audit events in the Security log when auditing is turned on. For more information about auditing security events, see the documentation for the Windows NT User Manager.


Event Sources

Each logfile can contain subkeys called event sources. The event source is the name of the software that logs the event. It is often the name of the application, or the name of a subcomponent of the application, if the application is large. Applications and services should add their names to the Application logfile. Device drivers should add their names to the System logfile. The structure is as follows:

HKEY_LOCAL_MACHINE
SYSTEM
CurrentControlSet
Services
EventLog
Application
AppName
Security
System
DriverName

The application provides its name when it opens the event log using the RegisterEventSource function. You cannot use a source name that has already been used as a logfile name. In addition, source names cannot be hierarchical (that is, you cannot use the backslash character [\]).

Each event source contains information specific to the software that will be logging the events, such as the message files, as shown in the following table.

Registry Value | Description
EventMessageFile | Specifies the path for the event message file. You can list multiple files, separated by semicolons. An event message file contains language-dependent strings that describe the events. This value has the type REG_EXPAND_SZ.
CategoryMessageFile | Specifies the path for the category message file. You can list multiple files, separated by semicolons. A category message file contains language-dependent strings that describe the categories. This value has the type REG_EXPAND_SZ.
ParameterMessageFile | Specifies the path for the parameter message file. You can list multiple files, separated by semicolons. A parameter message file contains language-independent strings that are to be inserted into the event description strings. This value has the type REG_EXPAND_SZ.
CategoryCount | Specifies the number of event categories supported. This value has the type REG_DWORD.
TypesSupported | Specifies a bitmask of supported types. This value has the type REG_DWORD. It can be one or more of the following values: EVENTLOG_ERROR_TYPE EVENTLOG_WARNING_TYPE EVENTLOG_INFORMATION_TYPE EVENTLOG_AUDIT_SUCCESS EVENTLOG_AUDIT_FAILURE

When an application uses the RegisterEventSource or OpenEventLog function to get a handle to an event log, the event-logging service searches for the specified event source in the registry. For example, the Application logfile might contain event sources for Microsoft SQL Server and Microsoft Excel. If an application uses RegisterEventSource or OpenEventLog with a source name of Application, SQL, or Excel, the event-logging service returns a handle to the Application logfile.

An application can use the Application event log without adding a new event source to the registry. If the application calls RegisterEventSource, passing a source name that cannot be found in the registry, the event-logging service uses the Application logfile by default. However, because there are no message files, the Event Viewer cannot map any event identifiers or event categories to a description string, and will display an error. For this reason, you should add a unique event source to the registry for your application and specify a message file.


Event Categories

Categories help you organize events so Event Viewer can filter them. Each event source can define its own numbered categories and the text strings to which they are mapped. The categories must be numbered consecutively beginning with the number 1. For example, the security system uses the following categories:

  • Logon/logoff
  • File system access
  • Privileged actions
  • Change in security policy


Event Identifiers

Event identifiers uniquely identify a particular event. Each event source can define its own numbered events and the description strings to which they are mapped. Event viewers can present these strings to the user. They should help the user understand what went wrong and suggest what actions to take. Direct the description at users solving their own problems, not at administrators or support technicians. Make the description clear and concise and avoid culture-specific phrases.

The following sections discuss these description strings, and the insertion strings that serve as placeholders in the description strings.

Description Strings

The description strings in the event message file are indexed by event identifier, enabling Event Viewer to display event-specific text for any event based on the event identifier. All descriptions are localized and language dependent. The description strings may contain insertion string placeholders, of the form %n, where %1 indicates the first insertion string, and so on. For example, the following is a sample entry in the .MC file:

MessageId=0x4
Severity=Error
Facility=System
SymbolicName=MSG_CMD_DELETE
Language=English
File %1 contains %2, which is in error.

In this case, the buffer returned by ReadEventLog contains insertion strings. The NumStrings member of the EVENTLOGRECORD structure indicates the number of insertion strings. The StringOffset member of the EVENTLOGRECORD structure indicates the location of the first insertion string in the buffer.

The description string can also contain placeholders for parameter strings from the parameter message file. The placeholders are of the form %%n, where %%1 is replaced by the parameter string with the identifier of 1, and so on. In this case, the event viewer uses LoadLibraryEx and FormatMessage to retrieve the insertion string from the file indicated by the source's ParameterMessageFile registry value.

Insertion Strings

Insertion strings are optional language-independent strings used to fill in values for placeholders in description strings. Because the strings are not localized, it is critical that these placeholders be used only to represent language-independent strings such as numeric values, file names, user names, and so on. The string length must not exceed 32 kilobytes – 1 characters.

It is not acceptable to use several strings to create a larger description. The insertion string should be treated as data, not text. For example, the following example is not recommended:

LPSTR pszString1 = "successfully";
LPSTR pszString2 = "not";
LPSTR pszDescription = "The user was %1 added to the database.";

It is not acceptable to use pszString1 and pszString2 to form the strings "The user was successfully added to the database." and "The user was not added to the database." There are three reasons this substitution is not effective:

  • The strings "successfully" and "not" should be localized.
  • Even if the description strings are obtained from language-dependent message files, this is done when the event is logged, not when it is viewed. When the event is viewed, the language may be wrong.
  • Such substitutions of adverbs and adjectives will not work in many other languages. The preceding example should use two separate events, each with its own description string.

In the following example, it is appropriate to use either pszString1 or pszString2 for the insertion string in pszDescription.

LPSTR pszString1 = "c:\\testapp1.c";
LPSTR pszString2 = "c:\\testapp2.c";
LPSTR pszDescription = "Access denied. Attempted to open the file %1."


Message Files

Each event sources should register message files that contain description strings for each event identifier, event category, and parameter. Register these files in the EventMessageFile, CategoryMessageFile, and ParameterMessageFile registry values for the event source. You can create one message file that contains descriptions for the event identifiers, categories, and parameters, or create three separate message files. Several applications can share the same message file.

You should typically create message files as dynamic-link libraries (DLL). Use the following procedure to create these DLLs.

To create a message file
  1. Do not include exported functions in the .C file; include only a stub for the DllMain function. The stub should simply return TRUE.
  2. Use the following command to compile the .C file:
    cl options -fo filename.obj filename.c.
  3. Create an .MC file to define the message resource table. For more information, see Message Compiler Source Files.
  4. Use the message compiler to create .RC and .BIN files from the .MC file. Use the following command: mc filename.mc.
  5. Use the resource compiler to create a .RES file. Use the following command: rc -r -fo filename.res filename.rc.
  6. Use the linker to create a .DLL file. Use the following command line: link -dll -out:filename.dll filename.obj filename.res.

To make it easier for the application to use your message file, create a header file that lists each event. For example, suppose you have defined the following message in your .MC file:

MessageId=0x4
Severity=Error
Facility=System
SymbolicName=MSG_CMD_DELETE
Language=English
File %1 contains %2, which is in error.

Your header file should contain the following code:

//
// MessageId: MSG_CMD_DELETE
// MessageText:
//  File %1 contains %2, which is in error.
//
#define MSG_CMD_DELETE                     ((DWORD)0xC0000004L)

Now the event-viewing application can use the following procedure to gain access to the description strings in the message file.

To obtain description strings
  1. Use the RegOpenKey function to open the event source.
  2. Use the RegQueryValueEx function to obtain the EventMessageFile value for the event source, which is the name of the event message DLL.
  3. Use the LoadLibraryEx function to load the event message DLL.
  4. Use the FormatMessage function to obtain the description from the DLL and add the insertion strings.


Event Data

Each event can have event-specific data associated with it. The Event Viewer does not interpret this data; it displays extra data only in a combined hexadecimal and text format. Use event-specific data sparingly, including it only if you are sure it will be useful to someone debugging the problem. For example, many network-related events include network control blocks (NCBs) as event-specific data.

When you use event-specific data, the last part of its description string should provide a note about the information provided as event-specific data. For example, the network software could provide a note such as: "(The NCB is the event data)." As a convention, use parentheses around such remarks, as indicated in this example.

You can also use event-specific data to store information the application can process independently of the Event Viewer. For example, you could write a viewer specifically for your events, or write a program that scans the logfile and makes reports that include information from the event-specific data.


Event Logging Operations

The OpenEventLog, OpenBackupEventLog, RegisterEventSource, DeregisterEventSource, and CloseEventLog functions open and close event log handles. Accessing the object through its handle provides an object-oriented model for the event-logging functions, as well as some performance gain when requesting multiple operations on the logs.

The following table shows the operations that can be performed on an open event log, and the corresponding function for each operation.

Operation | Function
Backup | BackupEventLog
Clear | ClearEventLog
Monitor | NotifyChangeEventLog
Query | GetOldestEventLogRecord, GetNumberOfEventLogRecords
Read | ReadEventLog
Write | ReportEvent

The OpenEventLog and ReportEvent functions take an optional server name as a parameter so the operations can be performed on the remote server. Use OpenEventLog for reading or performing administrative operations (backup, clear, monitor, and query) on the log, and use RegisterEventSource for writing to the log.

Each call to an event logging function is an atomic operation. When you read from the event log, only whole event records are returned. When you write to the event log, each event record is guaranteed to be written sequentially as a complete record in the log. The following list describes how the event-logging service handles special conditions:

  • The event-logging service receives a read operation and a write operation at the same time. If the read position is at the end of the file, either the read operation fails with an "end-of-file" status (if the write operation has not been completed), or it returns the new record (if the write operation has been completed).
  • The event-logging service completes a clear operation before receiving a read operation. The read operation fails with "end-of-file" status.
  • The event-logging service completes a clear operation before receiving a write operation. The clear operation truncates the log, then the write operation adds the new record at the beginning of the log.


Event Logging Model

The following sections describe the processes that form the event-logging model.

  • Writing to the Event Log
  • Reading from the Event Log
  • Viewing the Event Log


Writing to the Event Log

When an application calls the ReportEvent function to write an entry to the log, Windows NT passes the parameters to the event-logging service. The event-logging service uses the information to write an EVENTLOGRECORD structure to the event log. The following diagram illustrates this process.


Reading from the Event Log

An event viewer application uses the OpenEventLog function to open the event log for an event source. The event viewer can then use the ReadEventLog function to read event records from the log. ReadEventLog returns a buffer containing an EVENTLOGRECORD structure and additional information that describes a logged event. The following diagram illustrates this process.


Viewing the Event Log

When the user starts Event Viewer to view the event log entries, it calls the ReadEventLog function to obtain the EVENTLOGRECORD structures. The Event Viewer uses the event source and event identifier to get message text for each event from the registered message file (indicated by the EventMessageFile registry value for the source). The Event Viewer uses the LoadLibraryEx function to load the message file. The Event Viewer then uses the FormatMessage function to retrieve the description string from the loaded module.

The following illustration shows how the Event Viewer presents this information.

If the user double-clicks on an event log entry, the Event Viewer displays more information, as shown in the following illustration.


Event Logging Security

Access to the event logs is determined by the account under which the application is running. The LocalSystem account is a special account that Windows NT services can use. The Administrator account consists of the administrators for the system. The Server Operator account (ServerOp) consists of the administrators of the domain server. The World account includes all users on all systems.

The following table shows which accounts are granted read, write, and clear access to each log.

Log | Account | Access |  |
Application | LocalSystem | Read | Write | Clear
 | Adminstrator | Read | Write | Clear
 | ServerOp | Read | Write | Clear
 | World | Read | Write |
Security | LocalSystem | Read | Write | Clear
 | Adminstrator | Read |  | Clear
 | World | Read |  | Clear
System | LocalSystem | Read | Write | Clear
 | Adminstrator | Read | Write | Clear
 | ServerOp | Read |  | Clear
 | World | Read |  |

In addition, users can read and clear the Security log if they have been granted one of the following:

  • The "manage auditing and security log" user right. Use the Windows NT User Manager. Click the Policies menu, then click User Rights.
  • The SE_AUDIT_NAME privilege. For more information, see Windows NT Privileges.

The following table shows which types of access are required for each event logging function:

Function | Access Required
OpenEventLog | Read
OpenBackupEventLog | Read
RegisterEventSource | Write
ClearEventLog | Clear

As an example, OpenEventLog requires read access. A member of the ServerOp account can call OpenEventLog for the Application event log and the System event log, because ServerOp has read access for both of these logs. However, a member of the ServerOp account cannot call OpenEventLog for the Security log, because it does not have read access for this log.


Using Event Logging

You can use the Windows NT Registry Editor (REGEDT32.EXE) to view the event log registry keys, and you can use the Windows NT Event Viewer to view the event logs. To create event log entries, use the event logging functions as shown in the following topics.

  • Adding a source to the registry
  • Reporting an event
  • Querying the event log
  • Reading the event log
  • Displaying the user for an event
  • Displaying the local time for an event


Adding a Source to the Registry

You can use the default Application event log without adding an event source to the registry. However, Event Viewer will not be able to map your event identifier codes to message strings unless you register your event source and provide a message file.

You can add a new source name to the registry by opening a new registry subkey under the Application key using the RegCreateKey function, and adding registry values to the new subkey using the RegSetValueEx function. The following example opens a new source name called SamplApp and adds a message-file name and a bitmask of supported types.

void AddEventSource()
{
    HKEY hk;
    DWORD dwData;
    UCHAR szBuf[80];

    // Add your source name as a subkey under the Application
    // key in the EventLog registry key.

    if (RegCreateKey(HKEY_LOCAL_MACHINE,
            "SYSTEM\\CurrentControlSet\\Services\
            \\EventLog\\Application\\SamplApp", &hk))
        ErrorExit("Could not create the registry key.");

    // Set the name of the message file.

    strcpy(szBuf, "%SystemRoot%\\System\\SamplApp.dll");

    // Add the name to the EventMessageFile subkey.

    if (RegSetValueEx(hk,             // subkey handle
            "EventMessageFile",       // value name
            0,                        // must be zero
            REG_EXPAND_SZ,            // value type
            (LPBYTE) szBuf,           // pointer to value data
            strlen(szBuf) + 1))       // length of value data
        ErrorExit("Could not set the event message file.");

    // Set the supported event types in the TypesSupported subkey.

    dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
        EVENTLOG_INFORMATION_TYPE;

    if (RegSetValueEx(hk,      // subkey handle
            "TypesSupported",  // value name
            0,                 // must be zero
            REG_DWORD,         // value type
            (LPBYTE) &dwData,  // pointer to value data
            sizeof(DWORD)))    // length of value data
        ErrorExit("Could not set the supported types.");

    RegCloseKey(hk);
}


Reporting an Event

After you have added a source name to the registry, use the RegisterEventSource function to get a handle to the Application event log. The following example obtains the handle and then adds an event to the log using the ReportEvent function.

void MyReportEvent(LPSTR szMsg)
{
    HANDLE h;

    h = RegisterEventSource(NULL,  // uses local computer
             "SamplApp");          // source name
    if (h == NULL)
        ErrorExit("Could not register the event source.");

    if (!ReportEvent(h,           // event log handle
            EVENTLOG_ERROR_TYPE,  // event type
            0,                    // category zero
            MSG_ERR_EXIST,        // event identifier
            NULL,                 // no user security identifier
            1,                    // one substitution string
            0,                    // no data
            (LPTSTR *) szMsg,     // pointer to string array
            NULL))                // pointer to data
        ErrorExit("Could not report the event.");

    DeregisterEventSource(h);
}

Recall that your header file contains the event identifiers. For this example, the following event identifier was used:

//
// MessageId: MSG_ERR_EXIST
// MessageText:
//  File %1 does not exist.
//
#define MSG_ERR_EXIST                         ((DWORD)0xC0000004L)


Querying the Event Log

If you want to find out how many event records are in the event log, use the GetNumberOfEventLogRecords function. The following example displays the number of event records in the Application event log and the System event log. It opens the logs using the OpenEventLog function and obtains the number of records using GetNumberOfEventLogRecords.

void DisplayEventCount()
{
    HANDLE h;
    DWORD cRecords;

    // Open the System log.

    h = OpenEventLog(NULL,  // uses local computer
             "System");     // source name
    if (h == NULL)
        ErrorExit("Could not open the System event log.");

    // Get the number of records in the System event log.

    if (!GetNumberOfEventLogRecords(h, &cRecords))
        ErrorExit("Could not get the number of records.");

    printf("There are %d records in the System event log.\n",
        cRecords);

    CloseEventLog(h);

    // Open the Application log.

    h = OpenEventLog(NULL,    // uses local computer
             "Application");  // source name
    if (h == NULL)
        ErrorExit("Could not open the Application event log.");

    // Get the number of records in the Application event log.

    if (!GetNumberOfEventLogRecords(h, &cRecords))
        ErrorExit("Could not get number of records.");

    printf("There are %d records in the Application event log.\n",
        cRecords);

    CloseEventLog(h);
}


Reading the Event Log

The following example reads all the records in the Application log file and displays the event identifier, event type, and event source for each event log entry.

void DisplayEntries( )
{
    HANDLE h;
    EVENTLOGRECORD *pevlr;
    BYTE bBuffer[BUFFER_SIZE];
    DWORD dwRead, dwNeeded, cRecords, dwThisRecord = 0;

    // Open the Application event log.

    h = OpenEventLog( NULL,             // use local computer
             "Application");   // source name
    if (h == NULL)
        ErrorExit("Could not open the Application event log.");

    pevlr = (EVENTLOGRECORD *) &bBuffer;

    // Opening the event log positions the file pointer for this
    // handle at the beginning of the log. Read the records
    // sequentially until there are no more.

    while (ReadEventLog(h,                // event log handle
                EVENTLOG_FORWARDS_READ |  // reads forward
                EVENTLOG_SEQUENTIAL_READ, // sequential read
                0,            // ignored for sequential reads
                pevlr,        // pointer to buffer
                BUFFER_SIZE,  // size of buffer
                &dwRead,      // number of bytes read
                &dwNeeded))   // bytes in next record
    {
        while (dwRead > 0)
        {
            // Print the event identifier, type, and source name.
            // The source name is just past the end of the
            // formal structure.

            printf("%02d  Event ID: 0x%08X ",
                dwThisRecord++, pevlr->EventID);
            printf("EventType: %d Source: %s\n",
                pevlr->EventType, (LPSTR) ((LPBYTE) pevlr +
                sizeof(EVENTLOGRECORD)));

            dwRead -= pevlr->Length;
            pevlr = (EVENTLOGRECORD *)
                ((LPBYTE) pevlr + pevlr->Length);
        }

        pevlr = (EVENTLOGRECORD *) &bBuffer;
    }

    CloseEventLog(h);
}


Displaying the User For the Event

Displaying the User for an Event

The following example retrieves the name of the user for an event. The function parameters are a pointer to the EVENTLOGRECORD structure, a pointer to a buffer to receive the user name, and a pointer to the size of the allocated buffer. If the function succeeds, it returns TRUE; otherwise, it returns FALSE. To get extended error information, call GetLastError.

BOOL
GetEventUserName(EVENTLOGRECORD *pelr, LPSTR pszUser, LPDWORD pcbUser)
{
    PSID lpSid;
    char szName[256];
    char szDomain[256];
    SID_NAME_USE snu;
    DWORD dwLen;
    DWORD cbName = 256;
    DWORD cbDomain = 256;

    // Point to the SID.
    lpSid = (PSID)((LPBYTE) pelr + pelr->UserSidOffset);

    if (LookupAccountSid(NULL, lpSid, szName, &cbName, szDomain,
         &cbDomain, &snu))
    {
        // Determine whether the buffer is large enough.
        dwLen = lstrlen(lpszUser) + 1;

        if (dwLen > *lpcbUser)
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            *lpcbUser = dwLen;
            return FALSE;
        }

        // Return the user's name.
        lstrcpy( lpszUser, szName );

    }
    else
    {
        // Use the error status from LookupAccountSid.
        return FALSE;
   }

    SetLastError(0);
    return TRUE;
}


Displaying the Local Time For the Event

Displaying the Local Time for an Event

The following example displays the time information for an event. The function parameter is a pointer to the EVENTLOGRECORD structure. The function has no return value.

void PrintTimeGenerated(EVENTLOGRECORD *pevlr)
{
    FILETIME FileTime, LocalFileTime;
    SYSTEMTIME SysTime;
    __int64 lgTemp;
    __int64 SecsTo1970 = 116444736000000000;

    lgTemp = Int32x32To64(pevlr->TimeGenerated,10000000) + SecsTo1970;

    FileTime.dwLowDateTime = (DWORD) lgTemp;
    FileTime.dwHighDateTime = (DWORD)(lgTemp >> 32);

    FileTimeToLocalFileTime(&FileTime, &LocalFileTime);
    FileTimeToSystemTime(&LocalFileTime, &SysTime);

    printf("Time Generated: %02d/%02d/%02d   %02d:%02d:%02d\n",
        SysTime.wMonth,
        SysTime.wDay,
        SysTime.wYear,
        SysTime.wHour,
        SysTime.wMinute,
        SysTime.wSecond);
}


Event Logging Reference

The following elements are used with event logging.

  • Event Logging Functions
  • Event Logging Structures


Event Logging Functions

The following functions are used with event logging.

BackupEventLog
ClearEventLog
CloseEventLog
DeregisterEventSource
GetNumberOfEventLogRecords
GetOldestEventLogRecord
NotifyChangeEventLog
OpenBackupEventLog
OpenEventLog
ReadEventLog
RegisterEventSource
ReportEvent


BackupEventLog

The BackupEventLog function saves the specified event log to a backup file. The function does not clear the event log.

BOOL BackupEventLog(
  HANDLE hEventLog,          // handle to event log
  LPCTSTR lpBackupFileName   // name of backup file
);

Parameters

hEventLog
Handle to the open event log. This handle is returned by the OpenEventLog or OpenBackupEventLog function.
lpBackupFileName
Pointer to a null-terminated string that names the backup file.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The backup file cannot be written to a remote server because this function is implemented by a service running in the LocalSystem account, which does not have credentials on the remote machine. However, it is possible to write the file to a remote machine using a null session.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Event Logging Overview, Event Logging Functions, OpenBackupEventLog, OpenEventLog


ClearEventLog

The ClearEventLog function clears the specified event log, and optionally saves the current copy of the logfile to a backup file.

BOOL ClearEventLog(
  HANDLE hEventLog,          // handle to event log
  LPCTSTR lpBackupFileName   // name of backup file
);

Parameters

hEventLog
Handle to the event log to be cleared. This handle is returned by the OpenEventLog function.
lpBackupFileName
Pointer to the null-terminated string specifying the name of a file in which a current copy of the event logfile will be placed. If this file already exists, the function fails.

If the lpBackupFileName parameter is NULL, the current event logfile is not backed up.

Return Values

If the function succeeds, the return value is nonzero. The specified event log has been backed up (if lpBackupFileName is not NULL) and then cleared.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The ClearEventLog function fails if the event log is empty or a file already exists with the same name as lpBackupFileName.

Remarks

After this function returns, any handles that reference the cleared event log cannot be used to read the log.

The ClearEventLog function is used to optionally back up an existing logfile of the module represented by hEventLog. The function backs up the logfile to another file, and then clears the existing logfile. The caller must have write permission for the path specified, and must also have permission to clear the current logfile.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Event Logging Overview, Event Logging Functions, OpenEventLog


CloseEventLog

The CloseEventLog function closes the specified event log.

BOOL CloseEventLog(
  HANDLE hEventLog   // handle to event log
);

Parameters

hEventLog
Handle to the event log to be closed. This handle is returned by the OpenEventLog function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Event Logging Overview, Event Logging Functions, OpenEventLog


DeregisterEventSource

The DeregisterEventSource function closes a handle to the specified event log.

BOOL DeregisterEventSource(
  HANDLE hEventLog   // handle to event log
);

Parameters

hEventLog
Handle to the event log. This handle is returned by the RegisterEventSource function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Event Logging Overview, Event Logging Functions, RegisterEventSource


GetNumberOfEventLogRecords

The GetNumberOfEventLogRecords function retrieves the number of records in the specified event log.

BOOL GetNumberOfEventLogRecords(
  HANDLE hEventLog,        // handle to event log
  PDWORD NumberOfRecords   // buffer for number of records
);

Parameters

hEventLog
Handle to the open event log. This handle is returned by the OpenEventLog or OpenBackupEventLog function.
NumberOfRecords
Pointer to the buffer that receives the number of records in the specified event log.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Event Logging Overview, Event Logging Functions, GetOldestEventLogRecord, OpenBackupEventLog, OpenEventLog


GetOldestEventLogRecord

The GetOldestEventLogRecord function retrieves the absolute record number of the oldest record in the specified event log.

BOOL GetOldestEventLogRecord(
  HANDLE hEventLog,     // handle to event log
  PDWORD OldestRecord   // buffer for number of oldest record
);

Parameters

hEventLog
Handle to the open event log. This handle is returned by the OpenEventLog or OpenBackupEventLog function.
OldestRecord
Pointer to the buffer that receives the absolute record number of the oldest record in the specified event log.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Event Logging Overview, Event Logging Functions, GetNumberOfEventLogRecords, OpenBackupEventLog, OpenEventLog


NotifyChangeEventLog

The NotifyChangeEventLog function enables an application to receive notification when an event is written to the specified event log file. When the event is written to the event log file, the specified event object is set to the signaled state.

BOOL NotifyChangeEventLog(
  HANDLE hEventLog,  // handle to an event log
  HANDLE hEvent      // handle to an event object
);

Parameters

hEventLog
Handle to an event log file. This handle is returned by the OpenEventLog or OpenBackupEventLog function.
hEvent
Handle to an event object. Use the CreateEvent function to create the event object.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The NotifyChangeEventLog function does not work with remote handles. If the hEventLog parameter is the handle to an event log on a remote computer, NotifiyChangeEventLog returns zero, and GetLastError returns ERROR_INVALID_HANDLE.

When an event is written to the log file specified by hEventLog, the event specified by the hEvent parameter is set to the signaled state.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Event Logging Overview, Event Logging Functions, CreateEvent, OpenBackupEventLog, OpenEventLog


OpenBackupEventLog

The OpenBackupEventLog function opens a handle to a backup event log. This handle can be used with the BackupEventLog function.

HANDLE OpenBackupEventLog(
  LPCTSTR lpUNCServerName,  // backup file server name
  LPCTSTR lpFileName        // backup filename
);

Parameters

lpUNCServerName
Pointer to a null-terminated string that specifies the Universal Naming Convention (UNC) name of the server on which this operation is to be performed.
lpFileName
Pointer to a null-terminated string that specifies the name of the backup file.

Return Values

If the function succeeds, the return value is a handle to the backup event log.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The backup file cannot be written to a remote server because this function is implemented by a service running in the LocalSystem account, which does not have credentials on the remote machine. However, it is possible to write the file to a remote machine using a null session.

If the backup filename specifies a remote server, lpUNCServerName must be NULL.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Event Logging Overview, Event Logging Functions, BackupEventLog


OpenEventLog

The OpenEventLog function opens a handle to an event log.

HANDLE OpenEventLog(
  LPCTSTR lpUNCServerName,  // pointer to server name
  LPCTSTR lpSourceName   // pointer to source name
);

Parameters

lpUNCServerName
Pointer to a null-terminated string that specifies the Universal Naming Convention (UNC) name of the server on which the event log is to be opened.
lpSourceName
Pointer to a null-terminated string that specifies the name of the logfile that the returned handle will reference. This can be the Application, Security, or System logfile, or a custom registered logfile. If a custom registered logfile name cannot be found, the event logging service opens the Application logfile, however, there will be no associated message or category string file.

Return Values

If the function succeeds, the return value is the handle to an event log.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Event Logging Overview, Event Logging Functions, ClearEventLog, CloseEventLog, GetNumberOfEventLogRecords, GetOldestEventLogRecord, ReadEventLog, ReportEvent


ReadEventLog

The ReadEventLog function reads a whole number of entries from the specified event log. The function can be used to read log entries in forward or reverse chronological order.

BOOL ReadEventLog(
  HANDLE hEventLog,            // handle to event log
  DWORD dwReadFlags,           // specifies how to read log
  DWORD dwRecordOffset,        // number of first record
  LPVOID lpBuffer,             // address of buffer for read data
  DWORD nNumberOfBytesToRead,  // number of bytes to read
  DWORD *pnBytesRead,          // number of bytes read
  DWORD *pnMinNumberOfBytesNeeded
                               // number of bytes required for next
                               // record
);

Parameters

hEventLog
Handle to the event log to read. This handle is returned by the OpenEventLog function.
dwReadFlags
Specifies how the read operation is to proceed. This parameter can be any combination of the following values:
Value | Meaning
EVENTLOG_FORWARDS_READ | The log is read in forward chronological order.
EVENTLOG_BACKWARDS_READ | The log is read in reverse chronological order.
EVENTLOG_SEEK_READ | The read operation proceeds from the record specified by the dwRecordOffset parameter. If this flag is used, dwReadFlags must also specify EVENTLOG_FORWARDS_READ or EVENTLOG_BACKWARDS_READ. If the buffer is large enough, more than one record can be read at the specified seek position; the additional flag indicates the direction for successive read operations.
EVENTLOG_SEQUENTIAL_READ | The read operation proceeds sequentially from the last call to the ReadEventLog function using this handle.

dwRecordOffset
Specifies the log-entry record number at which the read operation should start. This parameter is ignored unless the dwReadFlags parameter includes the EVENTLOG_SEEK_READ flag.
lpBuffer
Pointer to a buffer for the data read from the event log. This parameter cannot be NULL, even if the nNumberOfBytesToRead parameter is zero.

The buffer will be filled with an EVENTLOGRECORD structure.

nNumberOfBytesToRead
Specifies the size, in bytes, of the buffer. This function will read as many whole log entries as will fit in the buffer; the function will not return partial entries, even if there is room in the buffer.
pnBytesRead
Pointer to a variable that receives the number of bytes read by the function.
pnMinNumberOfBytesNeeded
Pointer to a variable that receives the number of bytes required for the next log entry. This count is valid only if ReadEventLog returns zero and GetLastError returns ERROR_INSUFFICIENT_BUFFER.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

When this function returns successfully, the read position in the error log is adjusted by the number of records read. Only a whole number of event log records will be returned.

Note The configured filename for this source may also be the configured filename for other sources (several sources can exist as subkeys under a single logfile). Therefore, this function may return events that were logged by more than one source.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Event Logging Overview, Event Logging Functions, ClearEventLog, CloseEventLog, EVENTLOGRECORD, OpenEventLog, ReportEvent


RegisterEventSource

The RegisterEventSource function returns a registered handle to an event log.

HANDLE RegisterEventSource(
  LPCTSTR lpUNCServerName,  // server name for source
  LPCTSTR lpSourceName   // source name for registered handle
);

Parameters

lpUNCServerName
Pointer to a null-terminated string that specifies the Universal Naming Convention (UNC) name of the server on which this operation is to be performed. If this parameter is NULL, the operation is performed on the local computer.
lpSourceName
Pointer to a null-terminated string that specifies the name of the source referenced by the returned handle. The source name must be a subkey of a logfile entry under the EventLog key in the registry. For example, WinApp is a valid source name if the registry has the following key:
HKEY_LOCAL_MACHINE
  System
    CurrentControlSet
      Services
        EventLog
          Application
            WinApp
          Security
          System

Return Values

If the function succeeds, the return value is a handle that can be used with the ReportEvent function.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

If the source name cannot be found, the event logging service uses the Application logfile; it does not create a new source. Events are reported for the source, however, there are no message and category message files specified for looking up descriptions of the event identifiers for the source.

To close the handle to the event log, call the DeregisterEventSource function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Event Logging Overview, Event Logging Functions, DeregisterEventSource, ReportEvent


ReportEvent

The ReportEvent function writes an entry at the end of the specified event log.

BOOL ReportEvent(
  HANDLE hEventLog,    // handle returned by RegisterEventSource
  WORD wType,          // event type to log
  WORD wCategory,      // event category
  DWORD dwEventID,     // event identifier
  PSID lpUserSid,      // user security identifier (optional)
  WORD wNumStrings,    // number of strings to merge with message
  DWORD dwDataSize,    // size of binary data, in bytes
  LPCTSTR *lpStrings,  // array of strings to merge with message
  LPVOID lpRawData     // address of binary data
);

Parameters

hEventLog
Handle to the event log. This handle is returned by the RegisterEventSource function.
wType
Specifies the type of event being logged. This parameter can be one of the following values:
Value | Meaning
EVENTLOG_ERROR_TYPE | Error event
EVENTLOG_WARNING_TYPE | Warning event
EVENTLOG_INFORMATION_TYPE | Information event
EVENTLOG_AUDIT_SUCCESS | Success Audit event
EVENTLOG_AUDIT_FAILURE | Failure Audit event

For more information about event types, see Event Types.

wCategory
Specifies the event category. This is source-specific information; the category can have any value.
dwEventID
Specifies the event. The event identifier specifies the message that goes with this event as an entry in the message file associated with the event source.
lpUserSid
Pointer to the current user's security identifier. This parameter can be NULL if the security identifier is not required.
wNumStrings
Specifies the number of strings in the array pointed to by the lpStrings parameter. A value of zero indicates that no strings are present.
dwDataSize
Specifies the number of bytes of event-specific raw (binary) data to write to the log. If this parameter is zero, no event-specific data is present.
lpStrings
Pointer to a buffer containing an array of null-terminated strings that are merged into the message from the message file before Event Viewer displays the string to the user. This parameter must be a valid pointer (or NULL), even if wNumStrings is zero. Each string has a limit of 32K bytes.
lpRawData
Pointer to the buffer containing the binary data. This parameter must be a valid pointer (or NULL), even if the dwDataSize parameter is zero.

Return Values

If the function succeeds, the return value is nonzero, indicating that the entry was written to the log.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

This function is used to log an event. The entry is written to the end of the configured logfile for the source identified by the hEventLog parameter. The ReportEvent function adds the time, the entry's length, and the offsets before storing the entry in the log. To enable the function to add the username, you must supply the user's SID in the lpUserSid parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Event Logging Overview, Event Logging Functions, ClearEventLog, CloseEventLog, OpenEventLog, ReadEventLog, RegisterEventSource


Event Logging Structures

The following structure is used with event logging.

EVENTLOGRECORD


EVENTLOGRECORD

The EVENTLOGRECORD structure contains information about an event record returned by the ReadEventLog function.

typedef struct _EVENTLOGRECORD {
    DWORD  Length;
    DWORD  Reserved;
    DWORD  RecordNumber;
    DWORD  TimeGenerated;
    DWORD  TimeWritten;
    DWORD  EventID;
    WORD   EventType;
    WORD   NumStrings;
    WORD   EventCategory;
    WORD   ReservedFlags;
    DWORD  ClosingRecordNumber;
    DWORD  StringOffset;
    DWORD  UserSidLength;
    DWORD  UserSidOffset;
    DWORD  DataLength;
    DWORD  DataOffset;
    //
    // Then follow:
    //
    // TCHAR SourceName[]
    // TCHAR Computername[]
    // SID   UserSid
    // TCHAR Strings[]
    // BYTE  Data[]
    // CHAR  Pad[]
    // DWORD Length;
    //
} EVENTLOGRECORD;

Members

Length
Specifies the length, in bytes, of this event record. Note that this value is stored at both ends of the entry to ease moving forward or backward through the log. The length includes any pad bytes inserted at the end of the record for DWORD alignment.
Reserved
Reserved.
RecordNumber
Contains a record number that can be used with the EVENTLOG_SEEK_READ flag passed in a call to the ReadEventLog function to begin reading at a specified record.
TimeGenerated
The time at which this entry was submitted. This time is measured in the number of seconds elapsed since 00:00:00 January 1, 1970, Universal Coordinated Time.
TimeWritten
Specifies the time at which this entry was received by the service to be written to the logfile. This time is measured in the number of seconds elapsed since 00:00:00 January 1, 1970, Universal Coordinated Time.
EventID
Specifies the event. This is specific to the source that generated the event log entry, and is used, together with SourceName, to identify a message in a message file that is presented to the user while viewing the log.
EventType
Specifies the type of event. This member can be one of the following values:
Value | Meaning
EVENTLOG_ERROR_TYPE | Error event
EVENTLOG_WARNING_TYPE | Warning event
EVENTLOG_INFORMATION_TYPE | Information event
EVENTLOG_AUDIT_SUCCESS | Success Audit event
EVENTLOG_AUDIT_FAILURE | Failure Audit event

For more information about event types, see Event Logging.

NumStrings
Specifies the number of strings present in the log (at the position indicated by StringOffset). These strings are merged into the message before it is displayed to the user.
EventCategory
Specifies a subcategory for this event. This subcategory is source specific.
ReservedFlags
Reserved.
ClosingRecordNumber
Reserved.
StringOffset
Specifies the offset of the strings within this event log entry.
UserSidLength
Specifies the length, in bytes, of the UserSid member. This value can be zero if no security identifier was provided.
UserSidOffset
Specifies the offset of the security identifier (SID) within this event record. To obtain the user name for this SID, use the LookupAccountSid function.
DataLength
Specifies the length, in bytes, of the event-specific data (at the position indicated by DataOffset).
DataOffset
Specifies the offset of the event-specific information within this event record. This information could be something specific (a disk driver might log the number of retries, for example), followed by binary information specific to the event being logged and to the source that generated the entry.
SourceName
Contains the variable-length null-terminated string specifying the name of the source (application, service, driver, subsystem) that generated the entry. This is the name used to retrieve from the registry the name of the file containing the message strings for this source. It is used, together with the event identifier, to get the message string that describes this event.
Computername
Contains the variable-length null-terminated string specifying the name of the computer that generated this event. There may also be some pad bytes after this field to ensure that the UserSid is aligned on a DWORD boundary.
UserSid
Specifies the security identifier of the active user at the time this event was logged. This member may be empty if the UserSidLength member is zero.

The defined members are followed by the replacement strings for the message identified by the event identifier, the binary information, some pad bytes to make sure the full entry is on a DWORD boundary, and finally the length of the log entry again. Because the strings and the binary information can be of any length, no structure members are defined to reference them.

The event identifier together with SourceName and a language identifier identify a message string that describes the event in more detail. The strings are used as replacement strings and are merged into the message string to make a complete message. The message strings are contained in a message file specified in the source entry in the registry. To obtain the appropriate message string from the message file, load the message file with the LoadLibrary function and use the FormatMessage function.

The binary information is information that is specific to the event. It could be the contents of the processor registers when a device driver got an error, a dump of an invalid packet that was received from the network, a dump of all the structures in a program (when the data area was detected to be corrupt), and so on. This information should be useful to the writer of the device driver or the application in tracking down bugs or unauthorized breaks into the application.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Event Logging Overview, Event Logging Structures, LookupAccountSid, ReadEventLog


Structured Exception Handling

An exception is an event that occurs during the execution of a program, and requires the execution of code outside the normal flow of control. There are two kinds of exceptions: hardware exceptions and software exceptions. Hardware exceptions are initiated by the CPU. They can result from the execution of certain instruction sequences, such as division by zero or an attempt to access an invalid memory address. Software exceptions are initiated explicitly by applications or the operating system. For example, the system can detect when an invalid parameter value is specified.

Structured exception handling is a mechanism for handling both hardware and software exceptions. Therefore, your code will handle hardware and software exceptions identically. Structured exception handling enables you to have complete control over the handling of exceptions, provides support for debuggers, and is usable across all programming languages and machines.

The system also supports termination handling, which enables you to ensure that whenever a guarded body of code is executed, a specified block of termination code is also executed. The termination code is executed regardless of how the flow of control leaves the guarded body. For example, a termination handler can guarantee that clean-up tasks are performed even if an exception or some other error occurs while the guarded body of code is being executed.


About Structured Exception Handling

The structured exception handling and termination handling mechanisms are integral parts of the system; they enable the system to be robust. You can use these mechanisms to create consistently robust and reliable applications.

Structured exception handling is made available primarily through compiler support. For example, the Microsoft® 32-bit C/C++ Optimizing Compiler supports the try keyword that identifies a guarded body of code, the except keyword that identifies an exception handler, and the finally keyword that identifies a termination handler. Although this overview uses examples specific to the Microsoft C/C++ compiler, other compilers provide this support as well.


Exception Handling

Exceptions can be initiated by hardware or software, and can occur in kernel-mode as well as user-mode code. Structured exception handling provides a single mechanism for the handling of kernel-mode and user-mode exceptions.

The execution of certain instruction sequences can result in exceptions that are initiated by hardware. For example, an access violation is generated by the hardware when a process attempts to read from or write to a virtual address to which it does not have the appropriate access.

Events that require exception handling may also occur during execution of a software routine (for example, when an invalid parameter value is specified). When this happens, a thread can initiate an exception explicitly by calling the RaiseException function. This function enables the calling thread to specify information that describes the exception.

An exception can be continuable or noncontinuable. A noncontinuable exception arises when the event is not continuable in the hardware, or if continuation makes no sense. A noncontinuable exception does not terminate the application. Therefore, an application may be able to catch the exception and run. However, a noncontinuable exception typically arises as a result of a corrupted stack or other serious problem, making it difficult to recover from the exception.


Exception Dispatching

When a hardware or software exception occurs, the processor stops execution at the point at which the exception occurred and transfers control to the system. First, the system saves both the machine state of the current thread and information that describes the exception. The system then attempts to find an exception handler to handle the exception.

The machine state of the thread in which the exception occurred is saved in a CONTEXT structure. This information (called the context record) enables the system to continue execution at the point of the exception if the exception is successfully handled. The description of the exception (called the exception record) is saved in an EXCEPTION_RECORD structure. Because it stores the machine-dependent information of the context record separately from the machine-independent information of the exception record, the exception-handling mechanism is portable to different platforms.

The information in both the context and exception records is available by means of the GetExceptionInformation function, and can be made available to any exception handlers that are executed as a result of the exception. The exception record includes the following information.

  • An exception code that identifies the type of exception.
  • Flags indicating whether the exception is continuable. Any attempt to continue execution after a noncontinuable exception generates another exception.
  • A pointer to another exception record. This facilitates creation of a linked list of exceptions if nested exceptions occur.
  • The address at which the exception occurred.
  • An array of 32-bit arguments that provide additional information about the exception.

When an exception occurs in user-mode code, the system goes uses the following search order to find an exception handler:

  1. If the process is being debugged, the system notifies the debugger. For more information, see Debugger Exception Handling.
  2. If the process is not being debugged, or if the associated debugger does not handle the exception, the system attempts to locate a frame-based exception handler by searching the stack frames of the thread in which the exception occurred. The system searches the current stack frame first, then searches through preceding stack frames in reverse order.
  3. If no frame-based handler can be found, or no frame-based handler handles the exception, but the process is being debugged, the system notifies the debugger a second time.
  4. If the process is not being debugged, or if the associated debugger does not handle the exception, the system provides default handling based on the exception type. For most exceptions, the default action is to call the ExitProcess function.

When an exception occurs in kernel-mode code, the system searches the stack frames of the kernel stack in an attempt to locate an exception handler. If a handler cannot be located or no handler handles the exception, the system is shut down as if the ExitWindows function had been called.


Debugger Exception Handling

The system's handling of user-mode exceptions provides support for sophisticated debuggers. If the process in which an exception occurs is being debugged, the system generates a debug event. If the debugger is using the WaitForDebugEvent function, the debug event causes that function to return with a pointer to a DEBUG_EVENT structure. This structure contains the process and thread identifiers the debugger can use to access the thread's context record. The structure also contains an EXCEPTION_DEBUG_INFO structure that includes a copy of the exception record.

When the system is searching for an exception handler, it makes two attempts to notify a process's debugger. The first notification attempt provides the debugger with an opportunity to handle breakpoint or single-step exceptions. This is known as first-chance notification. The user can then issue debugger commands to manipulate the process's environment before any exception handlers are executed. The second attempt to notify the debugger occurs only if the system is unable to find a frame-based exception handler that handles the exception. This is known as last-chance notification. If the debugger does not handle the exception after the last-chance notification, the system terminates the process being debugged.

At each notification attempt, the debugger uses the ContinueDebugEvent function to return control to the system. Before returning control, the debugger can handle the exception and modify the thread state as appropriate, or it can choose not to handle the exception. Using ContinueDebugEvent, the debugger can indicate that it has handled the exception, in which case the machine state is restored and thread execution is continued at the point at which the exception occurred. The debugger can also indicate that it did not handle the exception, which causes the system to continue its search for an exception handler.


Floating-Point Exceptions

By default, the system has all FP exceptions turned off. Therefore, computations result in NAN or INFINITY, rather than an exception. Before you can trap floating-point (FP) exceptions using structured exception handling, you must call the _controlfp C run-time library function as follows:

// Get the default control word

int cw = _controlfp( 0, 0 );

// Set the exception masks off, turn exceptions on

cw &=~(EM_OVERFLOW | EM_UNDERFLOW | EM_INEXACT | EM_ZERODIVIDE | EM_DENORMAL

// Set the control word

_controlfp( cw, MCW_EM );

This turns on all possible FP exceptions To trap only particular exceptions, use only the flags that correspond to the exceptions to be trapped. Note that any handler for FP errors should call _clearfp as its first FP instruction. This function clears floating-point exceptions.


Frame-based Exception Handling

A frame-based exception handler allows you to deal with the possibility that an exception may occur in a certain sequence of code. A frame-based exception handler consists of the following elements.

  • A guarded body of code
  • A filter expression
  • An exception-handler block

Frame-based exception handlers are declared in language-specific syntax. For example, in the Microsoft C/C++ Optimizing Compiler, they are implemented by the try-except statement. For more information, see Handler Syntax.

The guarded body of code is a set of one or more statements for which the filter expression and the exception-handler block provide exception-handling protection. The guarded body can be a block of code, a set of nested blocks, or an entire procedure or function. Using the Microsoft C/C++ Optimizing Compiler, a guarded body is enclosed by braces ({}) following the try keyword.

The filter expression of a frame-based exception handler is an expression that is evaluated by the system when an exception occurs within the guarded body. This evaluation results in one of the following actions by the system.

  • The system stops its search for an exception handler, restores the machine state, and continues thread execution at the point at which the exception occurred.
  • The system continues its search for an exception handler.
  • The system transfers control to the exception handler, and thread execution continues sequentially in the stack frame in which the exception handler is found. If the handler is not in the stack frame in which the exception occurred, the system unwinds the stack, leaving the current stack frame and any other stack frames until it is back to the exception handler's stack frame. Before an exception handler is executed, termination handlers are executed for any guarded bodies of code that terminated as a result of the transfer of control to the exception handler. For more information about termination handlers, refer to Termination Handling.

The filter expression can be a simple expression, or it can invoke a filter function that attempts to handle the exception. You can call the GetExceptionCode and GetExceptionInformation functions from within a filter expression to get information about the exception being filtered. GetExceptionCode returns a code that identifies the type of exception, and GetExceptionInformation returns a pointer to an EXCEPTION_POINTERS structure that contains pointers to CONTEXT and EXCEPTION_RECORD structures.

These functions cannot be called from within a filter function, but their return values can be passed as parameters to a filter function. GetExceptionCode can be used within the exception-handler block, but GetExceptionInformation cannot because the information it points to is typically on the stack and is destroyed when control is transferred to an exception handler. However, an application can copy the information to safe storage to make it available to the exception handler.

The advantage of a filter function is that it can handle an exception and return a value that causes the system to continue execution from the point at which the exception occurred. With an exception-handler block, in contrast, execution continues sequentially from the exception handler rather than from the point of the exception.

Handling an exception may be as simple as noting an error and setting a flag that will be examined later, printing a warning or error message, or taking some other limited action. If execution can be continued, it may also be necessary to change the machine state by modifying the context record. For an example of a filter function that handles a page fault exception, see Using the Virtual Memory Functions.

The UnhandledExceptionFilter function can be used as a filter function in a filter expression. It returns EXCEPTION_EXECUTE_HANDLER unless the process is being debugged, in which case it returns EXCEPTION_CONTINUE_SEARCH.


Termination Handling

A termination handler ensures that a specific block of code is executed whenever flow of control leaves a particular guarded body of code. A termination handler consists of the following elements.

  • A guarded body of code
  • A block of termination code to be executed when the flow of control leaves the guarded body

Termination handlers are declared in language-specific syntax. Using the Microsoft C/C++ Optimizing Compiler, they are implemented by the try-finally statement. For more information, see Handler Syntax.

The guarded body of code can be a block of code, a set of nested blocks, or an entire procedure or function. Whenever the guarded body is executed, the block of termination code will be executed. The only exception to this is when the thread terminates during execution of the guarded body (for example, if the ExitThread or ExitProcess function is called from within the guarded body).

The termination block is executed when the flow of control leaves the guarded body, regardless of whether the guarded body terminated normally or abnormally. The guarded body is considered to have terminated normally when the last statement in the block is executed and control proceeds sequentially into the termination block. Abnormal termination occurs when the flow of control leaves the guarded body due to an exception, or due to a control statement such as return, goto, break, or continue. The AbnormalTermination function can be called from within the termination block to determine whether the guarded body terminated normally.


Handler Syntax

This section describes the syntax and usage of structured exception handling as implemented in the Microsoft C/C++ Optimizing Compiler. The following keywords are interpreted by the compiler as part of the structured exception-handling mechanism.

Keyword | Description
try | Begins a guarded body of code. Used with the except keyword to construct an exception handler, or with the finally keyword to construct a termination handler.
except | Begins a block of code that is executed only when an exception occurs within its associated try block.
finally | Begins a block of code that is executed whenever the flow of control leaves its associated try block.

The compiler also interprets the GetExceptionCode, GetExceptionInformation, and AbnormalTermination functions as keywords, and their use outside the appropriate exception-handling syntax generates a compiler error. The following are brief descriptions of these functions.

Function | Description
GetExceptionCode | Returns a code that identifies the type of exception. This function can be called only from within the filter expression or exception-handler block of a try-except exception handler.
GetExceptionInformation | Returns a pointer to an EXCEPTION_POINTERS structure containing pointers to the context record and the exception record. This function can be called only from within the filter expression of a try-except exception handler.
AbnormalTermination | Indicates whether the flow of control left the associated try block sequentially after executing the last statement in the block. This function can be called only from within the finally block of a try-finally termination handler.


Exception-Handler Syntax

The try and except keywords are used to construct a frame-based exception handler. The following example shows the structure of a try-except exception handler.

try
{
    // guarded body of code

}
except (filter-expression)
{
    // exception-handler block

}

Note that the try block and the exception-handler block require braces ({}). Using a goto statement to jump into the body of a try block or into an exception-handler block is not permitted. This rule applies to both try-except and try-finally statements.

The try block contains the guarded body of code that the exception handler protects. A function can have any number of try-except statements, and these exception-handling statements can be nested within the same function or in different functions. If an exception occurs within the try block, the system takes control and begins the search for an exception handler. For a detailed description of this search, see Exception Handling.

The exception handler receives only exceptions that occur within a single thread. This means that if a try block contains a call to the CreateProcess or CreateThread function, exceptions that occur within the new process or thread are not dispatched to this handler.

The system evaluates the filter expression of each exception handler guarding the code in which the exception occurred until either the exception is handled or there are no more handlers. A filter expression must be evaluated as one of the three following values.

Value | Meaning
EXCEPTION_EXECUTE_HANDLER | The system transfers control to the exception handler, and execution continues in the stack frame in which the handler is found.
EXCEPTION_CONTINUE_SEARCH | The system continues to search for a handler.
EXCEPTION_CONTINUE_EXECUTION | The system stops its search for a handler and returns control to the point at which the exception occurred. If the exception is noncontinuable, this results in a EXCEPTION_NONCONTINUABLE_EXCEPTION exception.

The filter expression is evaluated in the context of the function in which the try-except statement is located, even though the exception may have occurred in a different function. This means that the filter expression can access the function's local variables. Similarly, the exception-handler block can access the local variables of the function in which it is located.

For more information about filter expressions and filter functions, see Frame-based Exception Handling.


Termination-Handler Syntax

The try and finally keywords are used to construct a termination handler. The following example shows the structure of a try-finally termination handler.

try
{
    // guarded body of code

}
finally
{
    // finally block

}

As with the try-except statement, both the try block and the finally block require braces ({}), and using a goto statement to jump into either block is not permitted.

The try block contains the guarded body of code that is protected by the termination handler. A function can have any number of try-finally statements, and these termination handling structures can be nested within the same function or in different functions.

The finally block is executed whenever the flow of control leaves the try block. However, the finally block is not executed if you call any of the following functions within the try block: ExitProcess, ExitThread, or abort.

The finally block is executed in the context of the function in which the try-finally statement is located. This means that the finally block can access that function's local variables. Execution of the finally block can terminate by any of the following means.

  • Execution of the last statement in the block and continuation to the next instruction
  • Use of a control statement (return, break, continue, or goto)
  • Use of longjmp or a jump to an exception handler

If execution of the try block terminates because of an exception that invokes the exception-handling block of a frame-based exception handler, the finally block is executed before the exception-handling block is executed. Similarly, a call to the longjmp C run-time library function from the try block causes execution of the finally block before execution resumes at the target of the longjmp operation. If try block execution terminates due to a control statement (return, break, continue, or goto), the finally block is executed.

The AbnormalTermination function can be used within the finally block to determine whether the try block terminated sequentially — that is, whether it reached the closing brace (}). Leaving the try block because of a call to longjmp, a jump to an exception handler, or a return, break, continue, or goto statement, is considered an abnormal termination. Note that failure to terminate sequentially causes the system to search through all stack frames in reverse order to determine whether any termination handlers must be called. This can result in performance degradation due to the execution of hundreds of instructions.

To avoid abnormal termination of the try-finally block, execution should continue to the end of the block. You can also execute the leave statement. The leave statement allows for immediate termination of the try block without causing abnormal termination and its performance penalty. Check your compiler documentation to determine if the leave statement is supported.

If execution of the finally block terminates because of the return control statement, it is equivalent to a goto to the closing brace in the enclosing function. Therefore, the enclosing function will return.


Using Structured Exception Handling

The following samples demonstrate how to use structured exception handling in your code.

  • Using an exception handler
  • Using a termination handler


Using an Exception Handler

The following example shows a version of the strcpy C run-time library function that can handle an invalid pointer and return NULL if one is encountered.

Note This exception handler is intended to handle an access-violation exception, but is inappropriate if some other type of exception occurs. Therefore, the filter expression in the example uses the GetExceptionCode function to check the exception type before executing the handler. This enables the system to continue its search for an appropriate handler if some other type of exception occurs.

Also that there is no problem with using a return statement in the try block of a try-except statement. This differs from the use of return in the try block of a try-finally statement, which causes an abnormal termination of the try block.

LPTSTR SafeStrcpy(LPTSTR lpszString1, LPTSTR lpszString2)
{
    try
    {
        return strcpy(string1, string2);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
                EXCEPTION_EXECUTE_HANDLER :
                EXCEPTION_CONTINUE_SEARCH )
    {
        return NULL;
    }
}

The following example shows the interaction of nested try-finally and try-except statements. The RaiseException function causes an exception in the guarded body of a try-finally termination handler that is inside the guarded body of a try-except exception handler. The exception causes the system to evaluate the FilterFunction function, whose return value in turn causes the exception handler to be invoked. However, before the exception-handler block is executed, the finally block of the termination handler is executed because the flow of control has left the try block of the termination handler.

DWORD FilterFunction()
{
    printf("1 ");                     // printed first
    return EXCEPTION_EXECUTE_HANDLER;
}

VOID main(VOID)
{
    try
    {
        try
        {
            RaiseException(1,         // exception code
                0,                    // continuable exception
                0, NULL);             // no arguments
        }
        finally
        {
            printf("2 ")              // this is printed second
        }
    }
    except ( FilterFunction() )
    {
        printf("3\n");                // this is printed last
    }
}


Using a Termination Handler

The following example shows how a try-finally statement is used to ensure that resources are released when execution of a guarded body of code terminates. In this case, a thread uses the EnterCriticalSection function to wait for ownership of a critical section object. When the thread is finished executing the code that is protected by the critical section, it must call the LeaveCriticalSection function to make the critical section object available to other threads. Using a try-finally statement guarantees that this will happen.

For more information, see critical section objects.

LPTSTR lpBuffer = NULL;
CRITICAL_SECTION csCriticalSection;

try
{
    // EnterCriticalSection synchronizes code with other threads.

    EnterCriticalSection(&CriticalSection);

    // Perform a task that may cause an exception.

    lpBuffer = (LPTSTR) LocalAlloc(LPTR, 10);
    strcpy(lpBuffer,"Hello");  // possible access violation
    printf("%s\n",lpBuffer);
    LocalFree(lpBuffer);
}

// LeaveCriticalSection is called even if an exception occurred.

finally
{
    LeaveCriticalSection(&CriticalSection);
}


Structured Exception Handling Reference

The following elements are used with structured exception handling.

  • Structured Exception Handling Functions
  • Structured Exception Handling Structures


Structured Exception Handling Functions

The following functions are used in structured exception handling.

AbnormalTermination
GetExceptionCode
GetExceptionInformation
RaiseException
SetUnhandledExceptionFilter
UnhandledExceptionFilter


AbnormalTermination

The AbnormalTermination function indicates whether the try block of a try-finally statement terminated normally. The function can be called only from within the finally block of a try-finally statement.

Note The Microsoft C/C++ Optimizing Compiler interprets this function as a keyword, and its use outside the appropriate exception-handling syntax generates a compiler error.

BOOL AbnormalTermination(VOID)

Parameters

This function has no parameters.

Return Values

If the try block of the try-finally statement terminated abnormally, the return value is nonzero.

If the try block of the try-finally statement terminated normally, the return value is zero.

Remarks

The try block terminates normally only if execution leaves the block sequentially after executing the last statement in the block. Statements (such as return, goto, continue, or break) that cause execution to leave the try block result in abnormal termination of the block. This is the case even if such a statement is the last statement in the try block.

Abnormal termination of a try block causes the system to search backward through all stack frames to determine whether any termination handlers must be called. This can result in the execution of hundreds of instructions, so it is important to avoid abnormal termination of a try block due to a return, goto, continue, or break statement. Note that these statements do not generate an exception, even though the termination is abnormal.

To avoid abnormal termination of the try-finally block, execution should continue to the end of the block. You can also execute the leave statement. The leave statement allows for immediate termination of the try block without causing abnormal termination and its performance penalty. Check your compiler documentation to determine if the leave statement is supported.

Windows CE: The Excpt.h file has to be explicitly included in order to use this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.

See Also

Structured Exception Handling Overview, Structured Exception Handling Functions


GetExceptionCode

The GetExceptionCode function retrieves a code that identifies the type of exception that occurred. The function can be called only from within the filter expression or exception-handler block of a try-except exception handler.

Note The Microsoft C/C++ Optimizing Compiler interprets this function as a keyword, and its use outside the appropriate exception-handling syntax generates a compiler error.

DWORD GetExceptionCode(VOID)

Parameters

This function has no parameters.

Return Values

The return value identifies the type of exception. Following are the exception codes likely to occur due to common programming errors:

Value | Meaning
EXCEPTION_ACCESS_VIOLATION
 | The thread attempted to read from or write to a virtual address for which it does not have the appropriate access.
EXCEPTION_BREAKPOINT
 | A breakpoint was encountered.
EXCEPTION_DATATYPE_MISALIGNMENT
 | The thread attempted to read or write data that is misaligned on hardware that does not provide alignment. For example, 16-bit values must be aligned on 2-byte boundaries, 32-bit values on 4-byte boundaries, and so on.
EXCEPTION_SINGLE_STEP
 | A trace trap or other single-instruction mechanism signaled that one instruction has been executed.
EXCEPTION_ARRAY_BOUNDS_EXCEEDED
 | The thread attempted to access an array element that is out of bounds, and the underlying hardware supports bounds checking.
EXCEPTION_FLT_DENORMAL_OPERAND
 | One of the operands in a floating-point operation is denormal. A denormal value is one that is too small to represent as a standard floating-point value.
EXCEPTION_FLT_DIVIDE_BY_ZERO
 | The thread attempted to divide a floating-point value by a floating-point divisor of zero.
EXCEPTION_FLT_INEXACT_RESULT
 | The result of a floating-point operation cannot be represented exactly as a decimal fraction.
EXCEPTION_FLT_INVALID_OPERATION
 | This exception represents any floating-point exception not included in this list.
EXCEPTION_FLT_OVERFLOW
 | The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type.
EXCEPTION_FLT_STACK_CHECK
 | The stack overflowed or underflowed as the result of a floating-point operation.
EXCEPTION_FLT_UNDERFLOW
 | The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type.
EXCEPTION_INT_DIVIDE_BY_ZERO
 | The thread attempted to divide an integer value by an integer divisor of zero.
EXCEPTION_INT_OVERFLOW
 | The result of an integer operation caused a carry out of the most significant bit of the result.
EXCEPTION_PRIV_INSTRUCTION
 | The thread attempted to execute an instruction whose operation is not allowed in the current machine mode.
EXCEPTION_NONCONTINUABLE_EXCEPTION
 | The thread attempted to continue execution after a noncontinuable exception occurred.

Remarks

The GetExceptionCode function can be called only from within the filter expression or exception-handler block of a try-except statement. The filter expression is evaluated if an exception occurs during execution of the try block, and it determines whether the except block is executed.

The filter expression can invoke a filter function. The filter function cannot call GetExceptionCode. However, the return value of GetExceptionCode can be passed as a parameter to a filter function. The return value of the GetExceptionInformation function can also be passed as a parameter to a filter function. GetExceptionInformation returns a pointer to a structure that includes the exception-code information.

The following example shows the structure of a try-except statement.

try
{

    // try block

}
except ( FilterFunction(GetExceptionCode() )
{

    // exception handler block

}

In the case of nested try-except statements, each statement's filter expression is evaluated until one is evaluated as EXCEPTION_EXECUTE_HANDLER or EXCEPTION_CONTINUE_EXECUTION. Each filter expression can invoke GetExceptionCode to get the exception code.

The exception code returned is the code generated by a hardware exception, or the code specified in the RaiseException function for a software-generated exception.

When handling the breakpoint exception, it is important to increment the instruction pointer in the context record to continue from this exception.

Windows CE: The Excpt.h file has to be explicitly included in order to use GetExceptionCode.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.

See Also

Structured Exception Handling Overview, Structured Exception Handling Functions, GetExceptionInformation, RaiseException


GetExceptionInformation

The GetExceptionInformation function retrieves a machine-independent description of an exception, and information about the machine state that existed for the thread when the exception occurred. This function can be called only from within the filter expression of a try-except exception handler.

Note The Microsoft C/C++ Optimizing Compiler interprets this function as a keyword, and its use outside the appropriate exception-handling syntax generates a compiler error.

LPEXCEPTION_POINTERS GetExceptionInformation(VOID)

Parameters

This function has no parameters.

Return Values

The return value is a pointer to an EXCEPTION_POINTERS structure that contains pointers to two other structures: an EXCEPTION_RECORD structure containing a description of the exception, and a CONTEXT structure containing the machine-state information.

Remarks

The filter expression (from which the function is called) is evaluated if an exception occurs during execution of the try block, and it determines whether the except block is executed.

The following example shows the structure of a try-except statement.

try
{

    // try block

}
except ( FilterFunction(GetExceptionInformation() )
{

    // exception handler block

}

The filter expression can invoke a filter function. The filter function cannot call GetExceptionInformation. However, the return value of GetExceptionInformation can be passed as a parameter to a filter function.

To pass the EXCEPTION_POINTERS information to the exception-handler block, the filter expression or filter function must copy the pointer or the data to safe storage that the handler can later access.

In the case of nested try-except statements, each statement's filter expression is evaluated until one is evaluated as EXCEPTION_EXECUTE_HANDLER or EXCEPTION_CONTINUE_EXECUTION. Each filter expression can invoke GetExceptionInformation to get exception information.

Windows CE: The Excpt.h file must be explicitly included in order to use GetExceptionInformation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.

See Also

Structured Exception Handling Overview, Structured Exception Handling Functions, CONTEXT, EXCEPTION_POINTERS, EXCEPTION_RECORD, GetExceptionCode


RaiseException

The RaiseException function raises an exception in the calling thread.

VOID RaiseException(
  DWORD dwExceptionCode,  // exception code
  DWORD dwExceptionFlags,  // continuable exception flag
  DWORD nNumberOfArguments,  // number of arguments in array
  CONST DWORD *lpArguments   // address of array of arguments
);

Parameters

dwExceptionCode
Specifies the application-defined exception code of the exception being raised. The filter expression and exception-handler block of an exception handler can use the GetExceptionCode function to retrieve this value.

Note that the system will clear bit 28 of dwExceptionCode. This bit is a reserved exception bit, used by the system for its own purposes. For example, after calling the RaiseException function with a dwExceptionCode value of 0xFFFFFFFF, the system displays a message indicating that the exception number is 0xEFFFFFFF.

dwExceptionFlags
Specifies the exception flags. This can be either zero to indicate a continuable exception, or EXCEPTION_NONCONTINUABLE to indicate a noncontinuable exception. Any attempt to continue execution after a noncontinuable exception causes the EXCEPTION_NONCONTINUABLE_EXCEPTION exception.
nNumberOfArguments
Specifies the number of arguments in the lpArguments array. This value must not exceed EXCEPTION_MAXIMUM_PARAMETERS. This parameter is ignored if lpArguments is NULL.
lpArguments
Pointer to an array of 32-bit arguments. This parameter can be NULL. These arguments can contain any application-defined data that needs to be passed to the filter expression of the exception handler.

Return Values

This function does not return a value.

Remarks

The RaiseException function enables a process to use structured exception handling to handle private, software-generated, application-defined exceptions.

Raising an exception causes the exception dispatcher to go through the following search for an exception handler:

  1. The system first attempts to notify the process's debugger, if any.
  2. If the process is not being debugged, or if the associated debugger does not handle the exception, the system attempts to locate a frame-based exception handler by searching the stack frames of the thread in which the exception occurred. The system searches the current stack frame first, then proceeds backward through preceding stack frames.
  3. If no frame-based handler can be found, or no frame-based handler handles the exception, the system makes a second attempt to notify the process's debugger.
  4. If the process is not being debugged, or if the associated debugger does not handle the exception, the system provides default handling based on the exception type. For most exceptions, the default action is to call the ExitProcess function.

The values specified in the dwExceptionCode, dwExceptionFlags, nNumberOfArguments, and lpArguments parameters can be retrieved in the filter expression of a try-except frame-based exception handler by calling the GetExceptionInformation function. A debugger can retrieve these values by calling the WaitForDebugEvent function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Structured Exception Handling Overview, Structured Exception Handling Functions, ExitProcess, GetExceptionCode, GetExceptionInformation, WaitForDebugEvent


SetUnhandledExceptionFilter

The SetUnhandledExceptionFilter function lets an application supersede the top-level exception handler that Win32 places at the top of each thread and process.

After calling this function, if an exception occurs in a process that is not being debugged, and the exception makes it to the Win32 unhandled exception filter, that filter will call the exception filter function specified by the lpTopLevelExceptionFilter parameter.

LPTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter(
  LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
                                   // exception filter function
);

Parameters

lpTopLevelExceptionFilter
Pointer to a top-level exception filter function that will be called whenever the UnhandledExceptionFilter function gets control, and the process is not being debugged. A value of NULL for this parameter specifies default handling within UnhandledExceptionFilter.

The filter function has syntax congruent to that of UnhandledExceptionFilter: It takes a single parameter of type LPEXCEPTION_POINTERS, and returns a value of type LONG. The filter function should return one of the following values:
Value | Meaning
EXCEPTION_EXECUTE_HANDLER | Return from UnhandledExceptionFilter and execute the associated exception handler. This usually results in process termination.
EXCEPTION_CONTINUE_EXECUTION | Return from UnhandledExceptionFilter and continue execution from the point of the exception. Note that the filter function is free to modify the continuation state by modifying the exception information supplied through its LPEXCEPTION_POINTERS parameter.
EXCEPTION_CONTINUE_SEARCH | Proceed with normal execution of UnhandledExceptionFilter. That means obeying the SetErrorMode flags, or invoking the Application Error pop-up message box.

Return Values

The SetUnhandledExceptionFilter function returns the address of the previous exception filter established with the function. A NULL return value means that there is no current top-level exception handler.

Remarks

Issuing SetUnhandledExceptionFilter replaces the existing top-level exception filter for all existing and all future threads in the calling process.

The exception handler specified by lpTopLevelExceptionFilter is executed in the context of the thread that caused the fault. This can affect the exception handler's ability to recover from certain exceptions, such as an invalid stack.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Structured Exception Handling Overview, Structured Exception Handling Functions, UnhandledExceptionFilter


UnhandledExceptionFilter

The UnhandledExceptionFilter function passes unhandled exceptions to the debugger, if the process is being debugged. Otherwise, it optionally displays an Application Error message box and causes the exception handler to be executed. This function can be called only from within the filter expression of a try-except exception handler.

LONG UnhandledExceptionFilter(
  STRUCT _EXCEPTION_POINTERS *ExceptionInfo   // address of
                                              // exception info
);

Parameters

ExceptionInfo
Pointer to an EXCEPTION_POINTERS structure containing a description of the exception and the processor context at the time of the exception. This pointer is the return value of a call to the GetExceptionInformation function.

Return Values

The function returns one of the following values:

Value | Meaning
EXCEPTION_CONTINUE_SEARCH | The process is being debugged, so the exception should be passed (as second chance) to the application's debugger.
EXCEPTION_EXECUTE_HANDLER | If the SEM_NOGPFAULTERRORBOX flag was specified in a previous call to SetErrorMode, no Application Error message box is displayed. The function returns control to the exception handler, which is free to take any appropriate action.

Remarks

If the process is not being debugged, the function displays an Application Error message box, depending on the current error mode. The default behavior is to display the dialog box, but this can be disabled by specifying SEM_NOGPFAULTERRORBOX in a call to the SetErrorMode function.

The system uses UnhandledExceptionFilter internally to handle exceptions that occur during process and thread creation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Structured Exception Handling Overview, Structured Exception Handling Functions, EXCEPTION_POINTERS, GetExceptionInformation, SetErrorMode, SetUnhandledExceptionFilter, UnhandledExceptionFilter


Structured Exception Handling Structures

The following structures are used with structured exception handling.

EXCEPTION_POINTERS
EXCEPTION_RECORD


EXCEPTION_POINTERS

The EXCEPTION_POINTERS structure contains an exception record with a machine-independent description of an exception and a context record with a machine-dependent description of the processor context at the time of the exception.

typedef struct _EXCEPTION_POINTERS { // exp
    PEXCEPTION_RECORD ExceptionRecord;
    PCONTEXT ContextRecord;
} EXCEPTION_POINTERS;

Members

ExceptionRecord
Pointer to an EXCEPTION_RECORD structure that contains a machine-independent description of the exception.
ContextRecord
Pointer to a CONTEXT structure that contains a processor-specific description of the state of the processor at the time of the exception.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnt.h.

See Also

Structured Exception Handling Overview, Structured Exception Handling Structures, GetExceptionInformation, CONTEXT, EXCEPTION_RECORD


EXCEPTION_RECORD

The EXCEPTION_RECORD structure describes an exception.

typedef struct _EXCEPTION_RECORD { // exr
    DWORD ExceptionCode;
    DWORD ExceptionFlags;
    struct _EXCEPTION_RECORD *ExceptionRecord;
    PVOID ExceptionAddress;
    DWORD NumberParameters;
    DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD;

Members

ExceptionCode
Specifies the reason the exception occurred. This is the code generated by a hardware exception, or the code specified in the RaiseException function for a software-generated exception. Following are the exception codes likely to occur due to common programming errors:
Value Meaning
EXCEPTION_ACCESS_VIOLATION
The thread tried to read from or write to a virtual address for which it does not have the appropriate access.
EXCEPTION_ARRAY_BOUNDS_EXCEEDED
The thread tried to access an array element that is out of bounds and the underlying hardware supports bounds checking.
EXCEPTION_BREAKPOINT
A breakpoint was encountered.
EXCEPTION_DATATYPE_MISALIGNMENT
The thread tried to read or write data that is misaligned on hardware that does not provide alignment. For example, 16-bit values must be aligned on 2-byte boundaries; 32-bit values on 4-byte boundaries, and so on.
EXCEPTION_FLT_DENORMAL_OPERAND
One of the operands in a floating-point operation is denormal. A denormal value is one that is too small to represent as a standard floating-point value.
EXCEPTION_FLT_DIVIDE_BY_ZERO
The thread tried to divide a floating-point value by a floating-point divisor of zero.
EXCEPTION_FLT_INEXACT_RESULT
The result of a floating-point operation cannot be represented exactly as a decimal fraction.
EXCEPTION_FLT_INVALID_OPERATION
This exception represents any floating-point exception not included in this list.
EXCEPTION_FLT_OVERFLOW
The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type.
EXCEPTION_FLT_STACK_CHECK
The stack overflowed or underflowed as the result of a floating-point operation.
EXCEPTION_FLT_UNDERFLOW
The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type.
EXCEPTION_ILLEGAL_INSTRUCTION
The thread tried to execute an invalid instruction.
EXCEPTION_IN_PAGE_ERROR
The thread tried to access a page that was not present, and the system was unable to load the page. For example, this exception might occur if a network connection is lost while running a program over the network.
EXCEPTION_INT_DIVIDE_BY_ZERO
The thread tried to divide an integer value by an integer divisor of zero.
EXCEPTION_INT_OVERFLOW
The result of an integer operation caused a carry out of the most significant bit of the result.
EXCEPTION_INVALID_DISPOSITION
An exception handler returned an invalid disposition to the exception dispatcher. Programmers using a high-level language such as C should never encounter this exception.
EXCEPTION_NONCONTINUABLE_EXCEPTION
The thread tried to continue execution after a noncontinuable exception occurred.
EXCEPTION_PRIV_INSTRUCTION
The thread tried to execute an instruction whose operation is not allowed in the current machine mode.
EXCEPTION_SINGLE_STEP
A trace trap or other single-instruction mechanism signaled that one instruction has been executed.
EXCEPTION_STACK_OVERFLOW
The thread used up its stack.

Another exception code is likely to occur when debugging console processes. It does not arise because of a programming error. The DBG_CONTROL_C exception code occurs when ctrl+c is input to a console process that handles ctrl+c signals and is being debugged. This exception code is not meant to be handled by applications. It is raised only for the benefit of the debugger, and is raised only when a debugger is attached to the console process.

ExceptionFlags
Specifies the exception flags. This member can be either zero, indicating a continuable exception, or EXCEPTION_NONCONTINUABLE indicating a noncontinuable exception. Any attempt to continue execution after a noncontinuable exception causes the EXCEPTION_NONCONTINUABLE_EXCEPTION exception.
ExceptionRecord
Pointer to an associated EXCEPTION_RECORD structure. Exception records can be chained together to provide additional information when nested exceptions occur.
ExceptionAddress
Specifies the address where the exception occurred.
NumberParameters
Specifies the number of parameters associated with the exception. This is the number of defined elements in the ExceptionInformation array.
ExceptionInformation
Specifies an array of additional 32-bit arguments that describe the exception. The RaiseException function can specify this array of arguments. For most exception codes, the array elements are undefined. For the following exception code, the array elements are defined as follows:
Exception code Array contents
EXCEPTION_ACCESS_VIOLATION
The first element of the array contains a read-write flag that indicates the type of operation that caused the access violation. If this value is zero, the thread attempted to read the inaccessible data. If this value is 1, the thread attempted to write to an inaccessible address.
The second array element specifies the virtual address of the inaccessible data.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnt.h.

See Also

Structured Exception Handling Overview, Structured Exception Handling Structures, EXCEPTION_DEBUG_INFO, EXCEPTION_POINTERS, GetExceptionInformation, RaiseException, UnhandledExceptionFilter


Error Codes

This appendix lists the system error codes returned by the GetLastError function for many of the Win32 functions and the network error codes returned by the Net functions. These errors are listed in the following topics:

  • System Errors - Alphabetical Order
  • System Errors - Numerical Order
  • Net Errors - Alphabetical Order
  • Net Errors - Numerical Order


System Errors - Alphabetical Order

The following table provides a list of system error codes.

Name | Description | Code
EPT_S_CANT_CREATE | The endpoint mapper database entry could not be created. | 1899
EPT_S_CANT_PERFORM_OP | The server endpoint cannot perform the operation. | 1752
EPT_S_INVALID_ENTRY | The entry is invalid. | 1751
EPT_S_NOT_REGISTERED | There are no more endpoints available from the endpoint mapper. | 1753
ERROR_ACCESS_DENIED | Access is denied. | 5
ERROR_ACCOUNT_DISABLED | Logon failure: account currently disabled. | 1331
ERROR_ACCOUNT_EXPIRED | The user's account has expired. | 1793
ERROR_ACCOUNT_LOCKED_OUT | The referenced account is currently locked out and may not be logged on to. | 1909
ERROR_ACCOUNT_RESTRICTION | Logon failure: user account restriction. | 1327
ERROR_ACTIVE_CONNECTIONS | Active connections still exist. | 2402
ERROR_ADAP_HDW_ERR | A network adapter hardware error occurred. | 57
ERROR_ADDRESS_ALREADY_ASSOCIATED | The network transport endpoint already has an address associated with it. | 1227
ERROR_ADDRESS_NOT_ASSOCIATED | An address has not yet been associated with the network endpoint. | 1228
ERROR_ALIAS_EXISTS | The specified local group already exists. | 1379
ERROR_ALLOTTED_SPACE_EXCEEDED | No more memory is available for security information updates. | 1344
ERROR_ALREADY_ASSIGNED | The local device name is already in use. | 85
ERROR_ALREADY_EXISTS | Cannot create a file when that file already exists. | 183
ERROR_ALREADY_INITIALIZED | An attempt was made to perform an initialization operation when initialization has already been completed. | 1247
ERROR_ALREADY_REGISTERED | The service is already registered. | 1242
ERROR_ALREADY_RUNNING_LKG | The system is currently running with the last-known-good configuration. | 1074
ERROR_ALREADY_WAITING | The specified printer handle is already being waited on | 1904
ERROR_APP_WRONG_OS | The specified program is not a Windows or MS-DOS program. | 1151
ERROR_ARENA_TRASHED | The storage control blocks were destroyed. | 7
ERROR_ARITHMETIC_OVERFLOW | Arithmetic result exceeded 32 bits. | 534
ERROR_ATOMIC_LOCKS_NOT_SUPPORTED | The file system does not support atomic changes to the lock type. | 174
ERROR_AUTODATASEG_EXCEEDS_64k | The operating system cannot run this application program. | 199
ERROR_BAD_ARGUMENTS | The argument string passed to DosExecPgm is not correct. | 160
ERROR_BAD_COMMAND | The device does not recognize the command. | 22
ERROR_BAD_CONFIGURATION | Configuration data corrupt. | 1610
ERROR_BAD_DATABASE_VERSION | Database version unsupported. | 1613
ERROR_BAD_DESCRIPTOR_FORMAT | A security descriptor is not in the right format (absolute or self-relative). | 1361
ERROR_BAD_DEV_TYPE | The network resource type is not correct. | 66
ERROR_BAD_DEVICE | The specified device name is invalid. | 1200
ERROR_BAD_DRIVER | The specified driver is invalid. | 2001
ERROR_BAD_DRIVER_LEVEL | The system does not support the command requested. | 119
ERROR_BAD_ENVIRONMENT | The environment is incorrect. | 10
ERROR_BAD_EXE_FORMAT | is not a valid Win32 application. | 193
ERROR_BAD_FORMAT | An attempt was made to load a program with an incorrect format. | 11
ERROR_BAD_IMPERSONATION_LEVEL | Either a required impersonation level was not provided, or the provided impersonation level is invalid. | 1346
ERROR_BAD_INHERITANCE_ACL | The inherited access control list (ACL) or access control entry (ACE) could not be built. | 1340
ERROR_BAD_LENGTH | The program issued a command but the command length is incorrect. | 24
ERROR_BAD_LOGON_SESSION_STATE | The logon session is not in a state that is consistent with the requested operation. | 1365
ERROR_BAD_NET_NAME | The network name cannot be found. | 67
ERROR_BAD_NET_RESP | The specified server cannot perform the requested operation. | 58
ERROR_BAD_NETPATH | The network path was not found. | 53
ERROR_BAD_PATHNAME | The specified path is invalid. | 161
ERROR_BAD_PIPE | The pipe state is invalid. | 230
ERROR_BAD_PROFILE | The network connection profile is corrupted. | 1206
ERROR_BAD_PROVIDER | The specified network provider name is invalid. | 1204
ERROR_BAD_QUERY_SYNTAX | SQL query syntax invalid or unsupported. | 1615
ERROR_BAD_REM_ADAP | The remote adapter is not compatible. | 60
ERROR_BAD_THREADID_ADDR | The address for the thread ID is not correct. | 159
ERROR_BAD_TOKEN_TYPE | The type of the token is inappropriate for its attempted use. | 1349
ERROR_BAD_UNIT | The system cannot find the device specified. | 20
ERROR_BAD_USERNAME | The specified username is invalid. | 2202
ERROR_BAD_VALIDATION_CLASS | The validation information class requested was invalid. | 1348
ERROR_BADDB | The configuration registry database is corrupt. | 1009
ERROR_BADKEY | The configuration registry key is invalid. | 1010
ERROR_BEGINNING_OF_MEDIA | The beginning of the tape or a partition was encountered. | 1102
ERROR_BOOT_ALREADY_ACCEPTED | The current boot has already been accepted for use as the last-known-good control set. | 1076
ERROR_BROKEN_PIPE | The pipe has been ended. | 109
ERROR_BUFFER_OVERFLOW | The file name is too long. | 111
ERROR_BUS_RESET | The I/O bus was reset. | 1111
ERROR_BUSY | The requested resource is in use. | 170
ERROR_BUSY_DRIVE | The system cannot perform a JOIN or SUBST at this time. | 142
ERROR_CALL_NOT_IMPLEMENTED | This function is not supported on this system. | 120
ERROR_CAN_NOT_COMPLETE | Cannot complete this function. | 1003
ERROR_CAN_NOT_DEL_LOCAL_WINS | The local WINS can not be deleted. | 4001
ERROR_CANCEL_VIOLATION | A lock request was not outstanding for the supplied cancel region. | 173
ERROR_CANCELLED | The operation was canceled by the user. | 1223
ERROR_CANNOT_COPY | The copy functions cannot be used. | 266
ERROR_CANNOT_DETECT_DRIVER_FAILURE | Failure actions can only be set for Win32 services, not for drivers. | 1080
ERROR_CANNOT_DETECT_PROCESS_ABORT | This service runs in the same process as the service control manager. Therefore, the service control manager cannot take action if this service's process terminates unexpectedly. | 1081
ERROR_CANNOT_FIND_WND_CLASS | Cannot find window class. | 1407
ERROR_CANNOT_IMPERSONATE | Unable to impersonate using a named pipe until data has been read from that pipe. | 1368
ERROR_CANNOT_MAKE | The directory or file cannot be created. | 82
ERROR_CANNOT_OPEN_PROFILE | Unable to open the network connection profile. | 1205
ERROR_CANT_ACCESS_DOMAIN_INFO | Indicates a Windows NT Server could not be contacted or that objects within the domain are protected such that necessary information could not be retrieved. | 1351
ERROR_CANT_ACCESS_FILE | The file can not be accessed by the system. | 1920
ERROR_CANT_DISABLE_MANDATORY | The group may not be disabled. | 1310
ERROR_CANT_EVICT_ACTIVE_NODE | A cluster node cannot be evicted from the cluster while it is online. | 5009
ERROR_CANT_OPEN_ANONYMOUS | Cannot open an anonymous level security token. | 1347
ERROR_CANT_RESOLVE_FILENAME | The name of the file cannot be resolved by the system. | 1921
ERROR_CANTOPEN | The configuration registry key could not be opened. | 1011
ERROR_CANTREAD | The configuration registry key could not be read. | 1012
ERROR_CANTWRITE | The configuration registry key could not be written. | 1013
ERROR_CHILD_MUST_BE_VOLATILE | Cannot create a stable subkey under a volatile parent key. | 1021
ERROR_CHILD_NOT_COMPLETE | The %1 application cannot be run in Win32 mode. | 129
ERROR_CHILD_WINDOW_MENU | Child windows cannot have menus. | 1436
ERROR_CIRCULAR_DEPENDENCY | Circular service dependency was specified. | 1059
ERROR_CLASS_ALREADY_EXISTS | Class already exists. | 1410
ERROR_CLASS_DOES_NOT_EXIST | Class does not exist. | 1411
ERROR_CLASS_HAS_WINDOWS | Class still has open windows. | 1412
ERROR_CLIPBOARD_NOT_OPEN | Thread does not have a clipboard open. | 1418
ERROR_CLIPPING_NOT_SUPPORTED | The requested clipping operation is not supported. | 2005
ERROR_CLUSTER_SHUTTING_DOWN | The cluster software is shutting down. | 5022
ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND | No checkpoint record was found in the cluster log. | 5032
ERROR_CLUSTERLOG_CORRUPT | The cluster log is corrupt. | 5029
ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE | The cluster log exceeds its maximum size. | 5031
ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE | The minimum required disk space needed for logging is not available. | 5033
ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE | The record could not be written to the cluster log since it exceeds the maximum size. | 5030
ERROR_COMMITMENT_LIMIT | The paging file is too small for this operation to complete. | 1455
ERROR_CONNECTED_OTHER_PASSWORD | The network connection was made successfully, but the user had to be prompted for a password other than the one originally specified. | 2108
ERROR_CONNECTION_ABORTED | The network connection was aborted by the local system. | 1236
ERROR_CONNECTION_ACTIVE | An invalid operation was attempted on an active network connection. | 1230
ERROR_CONNECTION_COUNT_LIMIT | A connection to the server could not be made because the limit on the number of concurrent connections for this account has been reached. | 1238
ERROR_CONNECTION_INVALID | An operation was attempted on a nonexistent network connection. | 1229
ERROR_CONNECTION_REFUSED | The remote system refused the network connection. | 1225
ERROR_CONNECTION_UNAVAIL | The device is not currently connected but it is a remembered connection. | 1201
ERROR_CONTINUE | Continue with work in progress. | 1246
ERROR_CONTROL_ID_NOT_FOUND | Control ID not found. | 1421
ERROR_CORE_RESOURCE | The cluster resource could not be deleted since it is a core resource. | 5026
ERROR_COUNTER_TIMEOUT | A serial I/O operation completed because the timeout period expired. The IOCTL_SERIAL_XOFF_COUNTER did not reach zero.) | 1121
ERROR_CRC | Data error (cyclic redundancy check). | 23
ERROR_CURRENT_DIRECTORY | The directory cannot be removed. | 16
ERROR_DATABASE_DOES_NOT_EXIST | The database specified does not exist. | 1065
ERROR_DATABASE_FAILURE | Unable to read from or write to the database. | 4313
ERROR_DATABASE_FULL | The database is full. | 4314
ERROR_DC_NOT_FOUND | Invalid device context (DC) handle. | 1425
ERROR_DDE_FAIL | An error occurred in sending the command to the application. | 1156
ERROR_DECRYPTION_FAILED | The specified file could not be decrypted. | 6001
ERROR_DELETING_ICM_XFORM | There was an error while deleting the color transform. | 2309
ERROR_DEPENDENCY_ALREADY_EXISTS | The cluster resource cannot be made dependent on the specified resource because it is already dependent. | 5003
ERROR_DEPENDENCY_NOT_FOUND | The cluster resource dependency cannot be found. | 5002
ERROR_DEPENDENT_RESOURCE_EXISTS | The cluster resource cannot be moved to another group because other resources are dependent on it. | 5001
ERROR_DEPENDENT_SERVICES_RUNNING | A stop control has been sent to a service that other running services are dependent on. | 1051
ERROR_DESTINATION_ELEMENT_FULL | The indicated destination element already contains media. | 1161
ERROR_DESTROY_OBJECT_OF_OTHER_THREAD | Cannot destroy object created by another thread. | 1435
ERROR_DEV_NOT_EXIST | The specified network resource or device is no longer available. | 55
ERROR_DEVICE_ALREADY_REMEMBERED | An attempt was made to remember a device that had previously been remembered. | 1202
ERROR_DEVICE_DOOR_OPEN | The device has indicated that its door is open. | 1166
ERROR_DEVICE_IN_USE | The device is in use by an active process and cannot be disconnected. | 2404
ERROR_DEVICE_NOT_AVAILABLE | The device is not ready for use. | 4319
ERROR_DEVICE_NOT_CONNECTED | The device is not connected. | 1167
ERROR_DEVICE_NOT_PARTITIONED | Tape partition information could not be found when loading a tape. | 1107
ERROR_DEVICE_REINITIALIZATION_NEEDED | The indicated device requires reinitialization due to hardware errors. | 1164
ERROR_DEVICE_REQUIRES_CLEANING | The device has indicated that cleaning is required before further operations are attempted. | 1165
ERROR_DHCP_ADDRESS_CONFLICT | The DHCP client has obtained an IP address that is already in use on the network. The local interface will be disabled until the DHCP client can obtain a new address. | 4100
ERROR_DIFFERENT_SERVICE_ACCOUNT | The account specified for this service is different from the account specified for other services running in the same process. | 1079
ERROR_DIR_NOT_EMPTY | The directory is not empty. | 145
ERROR_DIR_NOT_ROOT | The directory is not a subdirectory of the root directory. | 144
ERROR_DIRECT_ACCESS_HANDLE | Attempt to use a file handle to an open disk partition for an operation other than raw disk I/O. | 130
ERROR_DIRECTORY | The directory name is invalid. | 267
ERROR_DISCARDED | The segment is already discarded and cannot be locked. | 157
ERROR_DISK_CHANGE | The program stopped because an alternate diskette was not inserted. | 107
ERROR_DISK_CORRUPT | The disk structure is corrupted and unreadable. | 1393
ERROR_DISK_FULL | There is not enough space on the disk. | 112
ERROR_DISK_OPERATION_FAILED | While accessing the hard disk, a disk operation failed even after retries. | 1127
ERROR_DISK_RECALIBRATE_FAILED | While accessing the hard disk, a recalibrate operation failed, even after retries. | 1126
ERROR_DISK_RESET_FAILED | While accessing the hard disk, a disk controller reset was needed, but even that failed. | 1128
ERROR_DLL_INIT_FAILED | A dynamic link library (DLL) initialization routine failed. | 1114
ERROR_DLL_NOT_FOUND | One of the library files needed to run this application cannot be found. | 1157
ERROR_DOMAIN_CONTROLLER_EXISTS | A domain controller with the specified name already exists. | 1250
ERROR_DOMAIN_CONTROLLER_NOT_FOUND | Could not find the domain controller for this domain. | 1908
ERROR_DOMAIN_EXISTS | The specified domain already exists. | 1356
ERROR_DOMAIN_LIMIT_EXCEEDED | An attempt was made to exceed the limit on the number of domains per server. | 1357
ERROR_DOMAIN_TRUST_INCONSISTENT | The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain. | 1810
ERROR_DRIVE_LOCKED | The disk is in use or locked by another process. | 108
ERROR_DRIVE_MEDIA_MISMATCH | The drive and medium are not compatible or exist in different libraries. | 4303
ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS | The specified directory service attribute or value already exists. | 1926
ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED | The attribute type specified to the directory service is not defined. | 1925
ERROR_DS_BUSY | The directory service is busy. | 1927
ERROR_DS_CANT_MOD_OBJ_CLASS | The directory service detected an attempt to modify the object class of an object. | 1936
ERROR_DS_CANT_ON_NON_LEAF | The directory service can perform the requested operation only on a leaf object. | 1934
ERROR_DS_CANT_ON_RDN | The directory service cannot perform the requested operation on the RDN attribute of an object. | 1935
ERROR_DS_CROSS_DOM_MOVE_ERROR | The requested cross domain move operation could not be performed. | 1937
ERROR_DS_GC_NOT_AVAILABLE | Unable to contact the global catalog server. | 1938
ERROR_DS_INCORRECT_ROLE_OWNER | The requested operation could not be performed because the directory service is not the master for that type of operation. | 1931
ERROR_DS_INVALID_ATTRIBUTE_SYNTAX | The attribute syntax specified to the directory service is invalid. | 1924
ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY | The directory service evaluated group memberships locally. | 1922
ERROR_DS_NO_ATTRIBUTE_OR_VALUE | The specified directory service attribute or value does not exist. | 1923
ERROR_DS_NO_MORE_RIDS | The directory service has exhausted the pool of relative identifiers. | 1930
ERROR_DS_NO_RIDS_ALLOCATED | The directory service was unable to allocate a relative identifier. | 1929
ERROR_DS_NOT_INSTALLED | An error occurred while installing the Windows NT directory service. Please view the event log for more information. | 1251
ERROR_DS_OBJ_CLASS_VIOLATION | The requested operation did not satisfy one or more constraints associated with the class of the object. | 1933
ERROR_DS_RIDMGR_INIT_ERROR | The directory service was unable to initialize the subsystem that allocates relative identifiers. | 1932
ERROR_DS_UNAVAILABLE | The directory service is unavailable. | 1928
ERROR_DUP_DOMAINNAME | The workgroup or domain name is already in use by another computer on the network. | 1221
ERROR_DUP_NAME | A duplicate name exists on the network. | 52
ERROR_DUPLICATE_SERVICE_NAME | The name is already in use as either a service name or a service display name. | 1078
ERROR_DUPLICATE_TAG | The specified tag is already present. | 2304
ERROR_DYNLINK_FROM_INVALID_RING | The operating system cannot run this application program. | 196
ERROR_EA_ACCESS_DENIED | Access to the extended attribute was denied. | 994
ERROR_EA_FILE_CORRUPT | The extended attribute file on the mounted file system is corrupt. | 276
ERROR_EA_LIST_INCONSISTENT | The extended attributes are inconsistent. | 255
ERROR_EA_TABLE_FULL | The extended attribute table file is full. | 277
ERROR_EAS_DIDNT_FIT | The extended attributes did not fit in the buffer. | 275
ERROR_EAS_NOT_SUPPORTED | The mounted file system does not support extended attributes. | 282
ERROR_EMPTY | The library, drive, or media pool is empty. | 4306
ERROR_ENCRYPTION_FAILED | The specified file could not be encrypted. | 6000
ERROR_END_OF_MEDIA | The physical end of the tape has been reached. | 1100
ERROR_ENVVAR_NOT_FOUND | The system could not find the environment option that was entered. | 203
ERROR_EOM_OVERFLOW | Physical end of tape encountered. | 1129
ERROR_EVENTLOG_CANT_START | No event log file could be opened, so the event logging service did not start. | 1501
ERROR_EVENTLOG_FILE_CHANGED | The event log file has changed between read operations. | 1503
ERROR_EVENTLOG_FILE_CORRUPT | The event log file is corrupted. | 1500
ERROR_EXCEPTION_IN_SERVICE | An exception occurred in the service when handling the control request. | 1064
ERROR_EXCL_SEM_ALREADY_OWNED | The exclusive semaphore is owned by another process. | 101
ERROR_EXE_MACHINE_TYPE_MISMATCH | The image file %1 is valid, but is for a machine type other than the current machine. | 216
ERROR_EXE_MARKED_INVALID | The operating system cannot run %1. | 192
ERROR_EXTENDED_ERROR | An extended error has occurred. | 1208
ERROR_FAIL_I24 | Fail on INT 24. | 83
ERROR_FAILED_SERVICE_CONTROLLER_CONNECT | The service process could not connect to the service controller. | 1063
ERROR_FILE_CORRUPT | The file or directory is corrupted and unreadable. | 1392
ERROR_FILE_ENCRYPTED | The specified file is encrypted and the user does not have the ability to decrypt it. | 6002
ERROR_FILE_EXISTS | The file exists. | 80
ERROR_FILE_INVALID | The volume for a file has been externally altered so that the opened file is no longer valid. | 1006
ERROR_FILE_NOT_ENCRYPTED | The specified file is not encrypted. | 6007
ERROR_FILE_NOT_FOUND | The system cannot find the file specified. | 2
ERROR_FILE_OFFLINE | The remote storage service was not able to recall the file. | 4350
ERROR_FILEMARK_DETECTED | A tape access reached a filemark. | 1101
ERROR_FILENAME_EXCED_RANGE | The filename or extension is too long. | 206
ERROR_FLOPPY_BAD_REGISTERS | The floppy disk controller returned inconsistent results in its registers. | 1125
ERROR_FLOPPY_ID_MARK_NOT_FOUND | No ID address mark was found on the floppy disk. | 1122
ERROR_FLOPPY_UNKNOWN_ERROR | The floppy disk controller reported an error that is not recognized by the floppy disk driver. | 1124
ERROR_FLOPPY_WRONG_CYLINDER | Mismatch between the floppy disk sector ID field and the floppy disk controller track address. | 1123
ERROR_FULL_BACKUP | The backup failed. Check the directory to which you are backing the database. | 4004
ERROR_FULLSCREEN_MODE | The requested operation cannot be performed in full-screen mode. | 1007
ERROR_GEN_FAILURE | A device attached to the system is not functioning. | 31
ERROR_GENERIC_NOT_MAPPED | Generic access types were contained in an access mask which should already be mapped to nongeneric types. | 1360
ERROR_GLOBAL_ONLY_HOOK | This hook procedure can only be set globally. | 1429
ERROR_GRACEFUL_DISCONNECT | The network connection was gracefully closed. | 1226
ERROR_GROUP_EXISTS | The specified group already exists. | 1318
ERROR_GROUP_NOT_AVAILABLE | The cluster group is not available for any new requests. | 5012
ERROR_GROUP_NOT_FOUND | The cluster group could not be found. | 5013
ERROR_GROUP_NOT_ONLINE | The operation could not be completed because the cluster group is not online. | 5014
ERROR_HANDLE_DISK_FULL | The disk is full. | 39
ERROR_HANDLE_EOF | Reached the end of the file. | 38
ERROR_HOOK_NEEDS_HMOD | Cannot set nonlocal hook without a module handle. | 1428
ERROR_HOOK_NOT_INSTALLED | The hook procedure is not installed. | 1431
ERROR_HOOK_TYPE_NOT_ALLOWED | Hook type not allowed. | 1458
ERROR_HOST_NODE_NOT_AVAILABLE | A cluster node is not available for this operation. | 5005
ERROR_HOST_NODE_NOT_GROUP_OWNER | The cluster node is not the owner of the group. | 5016
ERROR_HOST_NODE_NOT_RESOURCE_OWNER | The cluster node is not the owner of the resource. | 5015
ERROR_HOST_UNREACHABLE | The remote system is not reachable by the transport. | 1232
ERROR_HOTKEY_ALREADY_REGISTERED | Hot key is already registered. | 1409
ERROR_HOTKEY_NOT_REGISTERED | Hot key is not registered. | 1419
ERROR_HWNDS_HAVE_DIFF_PARENT | All handles to windows in a multiple-window position structure must have the same parent. | 1441
ERROR_ICM_NOT_ENABLED | Image Color Management is not enabled. | 2308
ERROR_ILL_FORMED_PASSWORD | Unable to update the password. The value provided for the new password contains values that are not allowed in passwords. | 1324
ERROR_ILLEGAL_ELEMENT_ADDRESS | The indicated element does not exist. | 1162
ERROR_INC_BACKUP | The backup failed. Was a full backup done before? | 4003
ERROR_INCORRECT_ADDRESS | The network address could not be used for the operation requested. | 1241
ERROR_INDEX_ABSENT | Language not available. | 1611
ERROR_INFLOOP_IN_RELOC_CHAIN | The operating system cannot run %1. | 202
ERROR_INSTALL_FAILURE | Fatal error during installation. | 1603
ERROR_INSTALL_SERVICE | Failure accessing install service. | 1601
ERROR_INSTALL_SOURCE_ABSENT | Install source unavailable. | 1612
ERROR_INSTALL_SUSPEND | Installation suspended, incomplete. | 1604
ERROR_INSTALL_USEREXIT | The user canceled the installation. | 1602
ERROR_INSUFFICIENT_BUFFER | The data area passed to a system call is too small. | 122
ERROR_INTERNAL_DB_CORRUPTION | Unable to complete the requested operation because of either a catastrophic media failure or a data structure corruption on the disk. | 1358
ERROR_INTERNAL_DB_ERROR | The local security authority database contains an internal inconsistency. | 1383
ERROR_INTERNAL_ERROR | The security account database contains an internal inconsistency. | 1359
ERROR_INVALID_ACCEL_HANDLE | Invalid accelerator table handle. | 1403
ERROR_INVALID_ACCESS | The access code is invalid. | 12
ERROR_INVALID_ACCOUNT_NAME | The name provided is not a properly formed account name. | 1315
ERROR_INVALID_ACL | The access control list (ACL) structure is invalid. | 1336
ERROR_INVALID_ADDRESS | Attempt to access invalid address. | 487
ERROR_INVALID_AT_INTERRUPT_TIME | Cannot request exclusive semaphores at interrupt time. | 104
ERROR_INVALID_BLOCK | The storage control block address is invalid. | 9
ERROR_INVALID_BLOCK_LENGTH | When accessing a new tape of a multivolume partition, the current blocksize is incorrect. | 1106
ERROR_INVALID_CATEGORY | The IOCTL call made by the application program is not correct. | 117
ERROR_INVALID_CLEANER | The media identifier does not represent a valid cleaner. | 4310
ERROR_INVALID_CMM | The specified color management module is invalid. | 2300
ERROR_INVALID_COLORSPACE | The specified color space is invalid. | 2307
ERROR_INVALID_COMBOBOX_MESSAGE | Invalid message for a combo box because it does not have an edit control. | 1422
ERROR_INVALID_COMPUTERNAME | The format of the specified computer name is invalid. | 1210
ERROR_INVALID_CURSOR_HANDLE | Invalid cursor handle. | 1402
ERROR_INVALID_DATA | The data is invalid. | 13
ERROR_INVALID_DATATYPE | The specified datatype is invalid. | 1804
ERROR_INVALID_DLL | One of the library files needed to run this application is damaged. | 1154
ERROR_INVALID_DOMAIN_ROLE | This operation is only allowed for the Primary Domain Controller of the domain. | 1354
ERROR_INVALID_DOMAIN_STATE | The domain was in the wrong state to perform the security operation. | 1353
ERROR_INVALID_DOMAINNAME | The format of the specified domain name is invalid. | 1212
ERROR_INVALID_DRIVE | The system cannot find the drive specified. | 15
ERROR_INVALID_DWP_HANDLE | Invalid handle to a multiple-window position structure. | 1405
ERROR_INVALID_EA_HANDLE | The specified extended attribute handle is invalid. | 278
ERROR_INVALID_EA_NAME | The specified extended attribute name was invalid. | 254
ERROR_INVALID_EDIT_HEIGHT | Height must be less than 256. | 1424
ERROR_INVALID_ENVIRONMENT | The environment specified is invalid. | 1805
ERROR_INVALID_EVENT_COUNT | The number of specified semaphore events for DosMuxSemWait is not correct. | 151
ERROR_INVALID_EVENTNAME | The format of the specified event name is invalid. | 1211
ERROR_INVALID_EXE_SIGNATURE | Cannot run %1 in Win32 mode. | 191
ERROR_INVALID_FIELD | Record field does not exist. | 1616
ERROR_INVALID_FILTER_PROC | Invalid hook procedure. | 1427
ERROR_INVALID_FLAG_NUMBER | The flag passed is not correct. | 186
ERROR_INVALID_FLAGS | Invalid flags. | 1004
ERROR_INVALID_FORM_NAME | The specified form name is invalid. | 1902
ERROR_INVALID_FORM_SIZE | The specified form size is invalid. | 1903
ERROR_INVALID_FUNCTION | Incorrect function. | 1
ERROR_INVALID_GROUP_ATTRIBUTES | The specified attributes are invalid, or incompatible with the attributes for the group as a whole. | 1345
ERROR_INVALID_GROUPNAME | The format of the specified group name is invalid. | 1209
ERROR_INVALID_GW_COMMAND | Invalid GW_* command. | 1443
ERROR_INVALID_HANDLE | The handle is invalid. | 6
ERROR_INVALID_HANDLE_STATE | Handle is in an invalid state. | 1609
ERROR_INVALID_HOOK_FILTER | Invalid hook procedure type. | 1426
ERROR_INVALID_HOOK_HANDLE | Invalid hook handle. | 1404
ERROR_INVALID_ICON_HANDLE | Invalid icon handle. | 1414
ERROR_INVALID_ID_AUTHORITY | The value provided was an invalid value for an identifier authority. | 1343
ERROR_INVALID_INDEX | Invalid index. | 1413
ERROR_INVALID_KEYBOARD_HANDLE | Invalid keyboard layout handle. | 1457
ERROR_INVALID_LB_MESSAGE | Invalid message for single-selection list box. | 1432
ERROR_INVALID_LEVEL | The system call level is not correct. | 124
ERROR_INVALID_LIBRARY | The library identifier does not represent a valid library. | 4301
ERROR_INVALID_LIST_FORMAT | The DosMuxSemWait list is not correct. | 153
ERROR_INVALID_LOGON_HOURS | Logon failure: account logon time restriction violation. | 1328
ERROR_INVALID_LOGON_TYPE | A logon request contained an invalid logon type value. | 1367
ERROR_INVALID_MEDIA | The media identifier does not represent a valid medium. | 4300
ERROR_INVALID_MEDIA_POOL | The media pool identifier does not represent a valid media pool. | 4302
ERROR_INVALID_MEMBER | A new member could not be added to a local group because the member has the wrong account type. | 1388
ERROR_INVALID_MENU_HANDLE | Invalid menu handle. | 1401
ERROR_INVALID_MESSAGE | The window cannot act on the sent message. | 1002
ERROR_INVALID_MESSAGEDEST | The format of the specified message destination is invalid. | 1218
ERROR_INVALID_MESSAGENAME | The format of the specified message name is invalid. | 1217
ERROR_INVALID_MINALLOCSIZE | The operating system cannot run %1. | 195
ERROR_INVALID_MODULETYPE | The operating system cannot run %1. | 190
ERROR_INVALID_MONITOR_HANDLE | Invalid monitor handle. | 1461
ERROR_INVALID_MSGBOX_STYLE | Invalid message box style. | 1438
ERROR_INVALID_NAME | The filename, directory name, or volume label syntax is incorrect. | 123
ERROR_INVALID_NETNAME | The format of the specified network name is invalid. | 1214
ERROR_INVALID_OPERATION | The operation identifier is not valid. | 4317
ERROR_INVALID_OPLOCK_PROTOCOL | An invalid oplock acknowledgment was received by the system. | 301
ERROR_INVALID_ORDINAL | The operating system cannot run %1. | 182
ERROR_INVALID_OWNER | This security ID may not be assigned as the owner of this object. | 1307
ERROR_INVALID_PARAMETER | The parameter is incorrect. | 87
ERROR_INVALID_PASSWORD | The specified network password is not correct. | 86
ERROR_INVALID_PASSWORDNAME | The format of the specified password is invalid. | 1216
ERROR_INVALID_PIXEL_FORMAT | The pixel format is invalid. | 2000
ERROR_INVALID_PRIMARY_GROUP | This security ID may not be assigned as the primary group of an object. | 1308
ERROR_INVALID_PRINT_MONITOR | The specified print monitor does not have the required functions. | 3007
ERROR_INVALID_PRINTER_COMMAND | The printer command is invalid. | 1803
ERROR_INVALID_PRINTER_NAME | The printer name is invalid. | 1801
ERROR_INVALID_PRINTER_STATE | The state of the printer is invalid. | 1906
ERROR_INVALID_PRIORITY | The specified priority is invalid. | 1800
ERROR_INVALID_PROFILE | The specified color profile is invalid. | 2301
ERROR_INVALID_SCROLLBAR_RANGE | Scroll bar range cannot be greater than 0x7FFF. | 1448
ERROR_INVALID_SECURITY_DESCR | The security descriptor structure is invalid. | 1338
ERROR_INVALID_SEGDPL | The operating system cannot run %1. | 198
ERROR_INVALID_SEGMENT_NUMBER | The system detected a segment number that was not correct. | 180
ERROR_INVALID_SEPARATOR_FILE | The specified separator file is invalid. | 1799
ERROR_INVALID_SERVER_STATE | The security account manager (SAM) or local security authority (LSA) server was in the wrong state to perform the security operation. | 1352
ERROR_INVALID_SERVICE_ACCOUNT | The account name is invalid or does not exist. | 1057
ERROR_INVALID_SERVICE_CONTROL | The requested control is not valid for this service. | 1052
ERROR_INVALID_SERVICE_LOCK | The specified service database lock is invalid. | 1071
ERROR_INVALID_SERVICENAME | The format of the specified service name is invalid. | 1213
ERROR_INVALID_SHARENAME | The format of the specified share name is invalid. | 1215
ERROR_INVALID_SHOWWIN_COMMAND | Cannot show or remove the window in the way specified. | 1449
ERROR_INVALID_SID | The security ID structure is invalid. | 1337
ERROR_INVALID_SIGNAL_NUMBER | The signal being posted is not correct. | 209
ERROR_INVALID_SPI_VALUE | Invalid system-wide (SPI_*) parameter. | 1439
ERROR_INVALID_STACKSEG | The operating system cannot run %1. | 189
ERROR_INVALID_STARTING_CODESEG | The operating system cannot run %1. | 188
ERROR_INVALID_STATE | The group or resource is not in the correct state to perform the requested operation. | 5023
ERROR_INVALID_SUB_AUTHORITY | The subauthority part of a security ID is invalid for this particular use. | 1335
ERROR_INVALID_TARGET_HANDLE | The target internal file identifier is incorrect. | 114
ERROR_INVALID_THREAD_ID | Invalid thread identifier. | 1444
ERROR_INVALID_TIME | The specified time is invalid. | 1901
ERROR_INVALID_TRANSFORM | The specified color transform is invalid. | 2310
ERROR_INVALID_USER_BUFFER | The supplied user buffer is not valid for the requested operation. | 1784
ERROR_INVALID_VERIFY_SWITCH | The verify-on-write switch parameter value is not correct. | 118
ERROR_INVALID_WINDOW_HANDLE | Invalid window handle. | 1400
ERROR_INVALID_WINDOW_STYLE | The window style or class attribute is invalid for this operation. | 2002
ERROR_INVALID_WORKSTATION | Logon failure: user not allowed to log on to this computer. | 1329
ERROR_IO_DEVICE | The request could not be performed because of an I/O device error. | 1117
ERROR_IO_INCOMPLETE | Overlapped I/O event is not in a signaled state. | 996
ERROR_IO_PENDING | Overlapped I/O operation is in progress. | 997
ERROR_IOPL_NOT_ENABLED | The operating system is not presently configured to run this application. | 197
ERROR_IRQ_BUSY | Unable to open a device that was sharing an interrupt request (IRQ) with other devices. At least one other device that uses that IRQ was already opened. | 1119
ERROR_IS_JOIN_PATH | Not enough resources are available to process this command. | 147
ERROR_IS_JOIN_TARGET | A JOIN or SUBST command cannot be used for a drive that contains previously joined drives. | 133
ERROR_IS_JOINED | An attempt was made to use a JOIN or SUBST command on a drive that has already been joined. | 134
ERROR_IS_SUBST_PATH | The path specified is being used in a substitute. | 146
ERROR_IS_SUBST_TARGET | An attempt was made to join or substitute a drive for which a directory on the drive is the target of a previous substitute. | 149
ERROR_IS_SUBSTED | An attempt was made to use a JOIN or SUBST command on a drive that has already been substituted. | 135
ERROR_ITERATED_DATA_EXCEEDS_64k | The operating system cannot run %1. | 194
ERROR_JOIN_TO_JOIN | The system tried to join a drive to a directory on a joined drive. | 138
ERROR_JOIN_TO_SUBST | The system tried to join a drive to a directory on a substituted drive. | 140
ERROR_JOURNAL_HOOK_SET | The journal hook procedure is already installed. | 1430
ERROR_KEY_DELETED | Illegal operation attempted on a registry key that has been marked for deletion. | 1018
ERROR_KEY_HAS_CHILDREN | Cannot create a symbolic link in a registry key that already has subkeys or values. | 1020
ERROR_LABEL_TOO_LONG | The volume label you entered exceeds the label character limit of the target file system. | 154
ERROR_LAST_ADMIN | The last remaining administration account cannot be disabled or deleted. | 1322
ERROR_LB_WITHOUT_TABSTOPS | This list box does not support tab stops. | 1434
ERROR_LIBRARY_OFFLINE | The operation cannot be performed on an offline library. | 4305
ERROR_LICENSE_QUOTA_EXCEEDED | The service being accessed is licensed for a particular number of connections. No more connections can be made to the service at this time because there are already as many connections as the service can accept. | 1395
ERROR_LISTBOX_ID_NOT_FOUND | The list box identifier was not found. | 1416
ERROR_LM_CROSS_ENCRYPTION_REQUIRED | A cross-encrypted password is necessary to change this user password. | 1390
ERROR_LOCAL_USER_SESSION_KEY | No encryption key is available. A well-known encryption key was returned. | 1303
ERROR_LOCK_FAILED | Unable to lock a region of a file. | 167
ERROR_LOCK_VIOLATION | The process cannot access the file because another process has locked a portion of the file. | 33
ERROR_LOCKED | The segment is locked and cannot be reallocated. | 212
ERROR_LOG_FILE_FULL | The event log file is full. | 1502
ERROR_LOGIN_TIME_RESTRICTION | Attempting to log in during an unauthorized time of day for this account. | 1239
ERROR_LOGIN_WKSTA_RESTRICTION | The account is not authorized to log in from this station. | 1240
ERROR_LOGON_FAILURE | Logon failure: unknown user name or bad password. | 1326
ERROR_LOGON_NOT_GRANTED | Logon failure: the user has not been granted the requested logon type at this computer. | 1380
ERROR_LOGON_SESSION_COLLISION | The logon session ID is already in use. | 1366
ERROR_LOGON_SESSION_EXISTS | Cannot start a new logon session with an ID that is already in use. | 1363
ERROR_LOGON_TYPE_NOT_GRANTED | Logon failure: the user has not been granted the requested logon type at this computer. | 1385
ERROR_LUIDS_EXHAUSTED | No more local user identifiers (LUIDs) are available. | 1334
ERROR_MAGAZINE_NOT_PRESENT | The indicated element is part of a magazine that is not present. | 1163
ERROR_MAPPED_ALIGNMENT | The base address or the file offset specified does not have the proper alignment. | 1132
ERROR_MAX_THRDS_REACHED | No more threads can be created in the system. | 164
ERROR_MEDIA_CHANGED | The media in the drive may have changed. | 1110
ERROR_MEDIA_INCOMPATIBLE | The medium is not compatible with the device or media pool. | 4315
ERROR_MEDIA_NOT_AVAILABLE | The media is not mounted or ready for use. | 4318
ERROR_MEDIA_OFFLINE | The medium currently exists in an offline library and must be online to perform this operation. | 4304
ERROR_MEDIA_UNAVAILABLE | No media is currently available in this media pool or library. | 4308
ERROR_MEMBER_IN_ALIAS | The specified account name is already a member of the local group. | 1378
ERROR_MEMBER_IN_GROUP | Either the specified user account is already a member of the specified group, or the specified group cannot be deleted because it contains a member. | 1320
ERROR_MEMBER_NOT_IN_ALIAS | The specified account name is not a member of the local group. | 1377
ERROR_MEMBER_NOT_IN_GROUP | The specified user account is not a member of the specified group account. | 1321
ERROR_MEMBERS_PRIMARY_GROUP | The user cannot be removed from a group because the group is currently the user's primary group. | 1374
ERROR_MENU_ITEM_NOT_FOUND | A menu item was not found. | 1456
ERROR_MESSAGE_SYNC_ONLY | The message can be used only with synchronous operations. | 1159
ERROR_META_EXPANSION_TOO_LONG | The global filename characters, * or ?, are entered incorrectly or too many global filename characters are specified. | 208
ERROR_METAFILE_NOT_SUPPORTED | The requested metafile operation is not supported. | 2003
ERROR_MOD_NOT_FOUND | The specified module could not be found. | 126
ERROR_MORE_DATA | More data is available. | 234
ERROR_MORE_WRITES | A serial I/O operation was completed by another write to the serial port. The IOCTL_SERIAL_XOFF_COUNTER reached zero.) | 1120
ERROR_MR_MID_NOT_FOUND | The system cannot find message text for message number 0x%1 in the message file for %2. | 317
ERROR_NEGATIVE_SEEK | An attempt was made to move the file pointer before the beginning of the file. | 131
ERROR_NESTING_NOT_ALLOWED | Can't nest calls to LoadModule. | 215
ERROR_NET_WRITE_FAULT | A write fault occurred on the network. | 88
ERROR_NETLOGON_NOT_STARTED | An attempt was made to logon, but the network logon service was not started. | 1792
ERROR_NETNAME_DELETED | The specified network name is no longer available. | 64
ERROR_NETWORK_ACCESS_DENIED | Network access is denied. | 65
ERROR_NETWORK_BUSY | The network is busy. | 54
ERROR_NETWORK_UNREACHABLE | The remote network is not reachable by the transport. | 1231
ERROR_NO_ASSOCIATION | No application is associated with the specified file for this operation. | 1155
ERROR_NO_BROWSER_SERVERS_FOUND | The list of servers for this workgroup is not currently available | 6118
ERROR_NO_DATA | The pipe is being closed. | 232
ERROR_NO_DATA_DETECTED | No more data is on the tape. | 1104
ERROR_NO_EFS | The required encryption driver is not loaded for this system. | 6004
ERROR_NO_IMPERSONATION_TOKEN | An attempt has been made to operate on an impersonation token by a thread that is not currently impersonating a client. | 1309
ERROR_NO_INHERITANCE | Indicates an ACL contains no inheritable components. | 1391
ERROR_NO_LOG_SPACE | System could not allocate the required space in a registry log. | 1019
ERROR_NO_LOGON_SERVERS | There are currently no logon servers available to service the logon request. | 1311
ERROR_NO_MATCH | There was no match for the specified key in the index. | 1169
ERROR_NO_MEDIA_IN_DRIVE | No media in drive. | 1112
ERROR_NO_MORE_DEVICES | No more local devices. | 1248
ERROR_NO_MORE_FILES | There are no more files. | 18
ERROR_NO_MORE_ITEMS | No more data is available. | 259
ERROR_NO_MORE_SEARCH_HANDLES | No more internal file identifiers available. | 113
ERROR_NO_MORE_USER_HANDLES | The current process has used all of its system allowance of handles for Window Manager objects. | 1158
ERROR_NO_NET_OR_BAD_PATH | No network provider accepted the given network path. | 1203
ERROR_NO_NETWORK | The network is not present or not started. | 1222
ERROR_NO_PROC_SLOTS | The system cannot start another process at this time. | 89
ERROR_NO_QUOTAS_FOR_ACCOUNT | No system quota limits are specifically set for this account. | 1302
ERROR_NO_RECOVERY_POLICY | There is no encryption recovery policy configured for this system. | 6003
ERROR_NO_RECOVERY_PROGRAM | No recovery program has been configured for this service. | 1082
ERROR_NO_SCROLLBARS | The window does not have scroll bars. | 1447
ERROR_NO_SECURITY_ON_OBJECT | Unable to perform a security operation on an object that has no associated security. | 1350
ERROR_NO_SHUTDOWN_IN_PROGRESS | Unable to abort the system shutdown because no shutdown was in progress. | 1116
ERROR_NO_SIGNAL_SENT | No process in the command subtree has a signal handler. | 205
ERROR_NO_SITENAME | No site name is available for this machine. | 1919
ERROR_NO_SPOOL_SPACE | Space to store the file waiting to be printed is not available on the server. | 62
ERROR_NO_SUCH_ALIAS | The specified local group does not exist. | 1376
ERROR_NO_SUCH_DOMAIN | The specified domain did not exist. | 1355
ERROR_NO_SUCH_GROUP | The specified group does not exist. | 1319
ERROR_NO_SUCH_LOGON_SESSION | A specified logon session does not exist. It may already have been terminated. | 1312
ERROR_NO_SUCH_MEMBER | A new member could not be added to a local group because the member does not exist. | 1387
ERROR_NO_SUCH_PACKAGE | A specified authentication package is unknown. | 1364
ERROR_NO_SUCH_PRIVILEGE | A specified privilege does not exist. | 1313
ERROR_NO_SUCH_SITE | The specified site does not exist. | 1249
ERROR_NO_SUCH_USER | The specified user does not exist. | 1317
ERROR_NO_SYSTEM_MENU | The window does not have a system menu. | 1437
ERROR_NO_SYSTEM_RESOURCES | Insufficient system resources exist to complete the requested service. | 1450
ERROR_NO_TOKEN | An attempt was made to reference a token that does not exist. | 1008
ERROR_NO_TRACKING_SERVICE | The tracking (workstation) service is not running. | 1172
ERROR_NO_TRUST_LSA_SECRET | The workstation does not have a trust secret. | 1786
ERROR_NO_TRUST_SAM_ACCOUNT | The SAM database on the Windows NT Server does not have a computer account for this workstation trust relationship. | 1787
ERROR_NO_UNICODE_TRANSLATION | No mapping for the Unicode character exists in the target multi-byte code page. | 1113
ERROR_NO_USER_KEYS | There are no EFS keys defined for the user. | 6006
ERROR_NO_USER_SESSION_KEY | There is no user session key for the specified logon session. | 1394
ERROR_NO_VOLUME_ID | The Volume ID could not be found. | 1173
ERROR_NO_VOLUME_LABEL | The disk has no volume label. | 125
ERROR_NO_WILDCARD_CHARACTERS | No wildcards were found. | 1417
ERROR_NOACCESS | Invalid access to memory location. | 998
ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT | The account used is an interdomain trust account. Use your global user account or local user account to access this server. | 1807
ERROR_NOLOGON_SERVER_TRUST_ACCOUNT | The account used is a server trust account. Use your global user account or local user account to access this server. | 1809
ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT | The account used is a computer account. Use your global user account or local user account to access this server. | 1808
ERROR_NON_MDICHILD_WINDOW | Cannot process a message from a window that is not a multiple document interface (MDI) window. | 1445
ERROR_NONE_MAPPED | No mapping between account names and security IDs was done. | 1332
ERROR_NONPAGED_SYSTEM_RESOURCES | Insufficient system resources exist to complete the requested service. | 1451
ERROR_NOT_A_REPARSE_POINT | The file or directory is not a reparse point. | 4390
ERROR_NOT_ALL_ASSIGNED | Not all privileges referenced are assigned to the caller. | 1300
ERROR_NOT_AUTHENTICATED | The operation being requested was not performed because the user has not been authenticated. | 1244
ERROR_NOT_CHILD_WINDOW | The window is not a child window. | 1442
ERROR_NOT_CONNECTED | This network connection does not exist. | 2250
ERROR_NOT_CONTAINER | Cannot enumerate a noncontainer. | 1207
ERROR_NOT_DOS_DISK | The specified disk or diskette cannot be accessed. | 26
ERROR_NOT_EMPTY | The library, drive, or media pool must be empty to perform this operation. | 4307
ERROR_NOT_ENOUGH_MEMORY | Not enough storage is available to process this command. | 8
ERROR_NOT_ENOUGH_QUOTA | Not enough quota is available to process this command. | 1816
ERROR_NOT_ENOUGH_SERVER_MEMORY | Not enough server storage is available to process this command. | 1130
ERROR_NOT_EXPORT_FORMAT | The specified file is not in the defined EFS export format. | 6008
ERROR_NOT_FOUND | Element not found. | 1168
ERROR_NOT_JOINED | The system tried to delete the JOIN of a drive that is not joined. | 136
ERROR_NOT_LOCKED | The segment is already unlocked. | 158
ERROR_NOT_LOGGED_ON | The operation being requested was not performed because the user has not logged on to the network. The specified service does not exist. | 1245
ERROR_NOT_LOGON_PROCESS | The requested action is restricted for use by logon processes only. The calling process has not registered as a logon process. | 1362
ERROR_NOT_OWNER | Attempt to release mutex not owned by caller. | 288
ERROR_NOT_QUORUM_CAPABLE | The cluster could not make the specified resource a quorum resource because it is not capable of being a quorum resource. | 5021
ERROR_NOT_QUORUM_CLASS | The cluster could not make the specified resource a quorum resource because it does not belong to a shared storage class. | 5025
ERROR_NOT_READY | The device is not ready. | 21
ERROR_NOT_REGISTRY_FILE | The system has attempted to load or restore a file into the registry, but the specified file is not in a registry file format. | 1017
ERROR_NOT_SAME_DEVICE | The system cannot move the file to a different disk drive. | 17
ERROR_NOT_SUBSTED | The system tried to delete the substitution of a drive that is not substituted. | 137
ERROR_NOT_SUPPORTED | The network request is not supported. | 50
ERROR_NOTIFY_ENUM_DIR | A notify change request is being completed and the information is not being returned in the caller's buffer. The caller now needs to enumerate the files to find the changes. | 1022
ERROR_NT_CROSS_ENCRYPTION_REQUIRED | A cross-encrypted password is necessary to change a user password. | 1386
ERROR_NULL_LM_PASSWORD | The Windows NT password is too complex to be converted to a LAN Manager password. The LAN Manager password returned is a NULL string. | 1304
ERROR_OBJECT_ALREADY_EXISTS | The object already exists. | 5010
ERROR_OBJECT_IN_LIST | The object is already in the list. | 5011
ERROR_OBJECT_NOT_FOUND | The object identifier does not represent a valid object. | 4312
ERROR_OLD_WIN_VERSION | The specified program requires a newer version of Windows. | 1150
ERROR_OPEN_FAILED | The system cannot open the device or file specified. | 110
ERROR_OPEN_FILES | This network connection has files open or requests pending. | 2401
ERROR_OPERATION_ABORTED | The I/O operation has been aborted because of either a thread exit or an application request. | 995
ERROR_OPLOCK_NOT_GRANTED | The oplock request is denied. | 300
ERROR_OUT_OF_PAPER | The printer is out of paper. | 28
ERROR_OUT_OF_STRUCTURES | Storage to process this request is not available. | 84
ERROR_OUTOFMEMORY | Not enough storage is available to complete this operation. | 14
ERROR_PAGED_SYSTEM_RESOURCES | Insufficient system resources exist to complete the requested service. | 1452
ERROR_PAGEFILE_QUOTA | Insufficient quota to complete the requested service. | 1454
ERROR_PARTIAL_COPY | Only part of a ReadProcessMemoty or WriteProcessMemory request was completed. | 299
ERROR_PARTITION_FAILURE | Tape could not be partitioned. | 1105
ERROR_PASSWORD_EXPIRED | Logon failure: the specified account password has expired. | 1330
ERROR_PASSWORD_MUST_CHANGE | The user must change his password before he logs on the first time. | 1907
ERROR_PASSWORD_RESTRICTION | Unable to update the password because a password update rule has been violated. | 1325
ERROR_PATH_BUSY | The path specified cannot be used at this time. | 148
ERROR_PATH_NOT_FOUND | The system cannot find the path specified. | 3
ERROR_PIPE_BUSY | All pipe instances are busy. | 231
ERROR_PIPE_CONNECTED | There is a process on other end of the pipe. | 535
ERROR_PIPE_LISTENING | Waiting for a process to open the other end of the pipe. | 536
ERROR_PIPE_NOT_CONNECTED | No process is on the other end of the pipe. | 233
ERROR_POINT_NOT_FOUND | The point passed to GetMouseMovePoints is not in the buffer. | 1171
ERROR_POPUP_ALREADY_ACTIVE | Popup menu already active. | 1446
ERROR_PORT_UNREACHABLE | No service is operating at the destination network endpoint on the remote system. | 1234
ERROR_POSSIBLE_DEADLOCK | A potential deadlock condition has been detected. | 1131
ERROR_PRINT_CANCELLED | Your file waiting to be printed was deleted. | 63
ERROR_PRINT_MONITOR_ALREADY_INSTALLED | The specified print monitor has already been installed. | 3006
ERROR_PRINT_MONITOR_IN_USE | The specified print monitor is currently in use. | 3008
ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED | The specified print processor has already been installed. | 3005
ERROR_PRINTER_ALREADY_EXISTS | The printer already exists. | 1802
ERROR_PRINTER_DELETED | The specified printer has been deleted. | 1905
ERROR_PRINTER_DRIVER_ALREADY_INSTALLED | The specified printer driver is already installed. | 1795
ERROR_PRINTER_DRIVER_IN_USE | The specified printer driver is currently in use. | 3001
ERROR_PRINTER_HAS_JOBS_QUEUED | The requested operation is not allowed when there are jobs queued to the printer. | 3009
ERROR_PRINTQ_FULL | The printer queue is full. | 61
ERROR_PRIVATE_DIALOG_INDEX | Using private DIALOG window words. | 1415
ERROR_PRIVILEGE_NOT_HELD | A required privilege is not held by the client. | 1314
ERROR_PROC_NOT_FOUND | The specified procedure could not be found. | 127
ERROR_PROCESS_ABORTED | The process terminated unexpectedly. | 1067
ERROR_PRODUCT_UNINSTALLED | Product is uninstalled. | 1614
ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE | The specified color profile is not associated with any device. | 2305
ERROR_PROFILE_NOT_FOUND | The specified color profile was not found. | 2306
ERROR_PROTOCOL_UNREACHABLE | The remote system does not support the transport protocol. | 1233
ERROR_QUORUM_RESOURCE | The cluster resource could not be deleted or brought offline because it is the quorum resource. | 5020
ERROR_QUORUM_RESOURCE_ONLINE_FAILED | The quorum resource failed to come online. | 5027
ERROR_QUORUMLOG_OPEN_FAILED | The quorum log could not be created or mounted successfully. | 5028
ERROR_READ_FAULT | The system cannot read from the specified device. | 30
ERROR_REC_NON_EXISTENT | The name does not exist in the WINS database. | 4005
ERROR_REDIR_PAUSED | The specified printer or disk device has been paused. | 72
ERROR_REDIRECTOR_HAS_OPEN_HANDLES | The redirector is in use and cannot be unloaded. | 1794
ERROR_REGISTRY_CORRUPT | The registry is corrupted. The structure of one of the files that contains registry data is corrupted, or the system's image of the file in memory is corrupted, or the file could not be recovered because the alternate copy or log was absent or corrupted. | 1015
ERROR_REGISTRY_IO_FAILED | An I/O operation initiated by the registry failed unrecoverably. The registry could not read in, or write out, or flush, one of the files that contain the system's image of the registry. | 1016
ERROR_REGISTRY_RECOVERED | One of the files in the registry database had to be recovered by use of a log or alternate copy. The recovery was successful. | 1014
ERROR_RELOC_CHAIN_XEEDS_SEGLIM | The operating system cannot run %1. | 201
ERROR_REM_NOT_LIST | The remote computer is not available. | 51
ERROR_REMOTE_SESSION_LIMIT_EXCEEDED | An attempt was made to establish a session to a network server, but there are already too many sessions established to that server. | 1220
ERROR_REMOTE_STORAGE_MEDIA_ERROR | The remote storage service encountered a media error. | 4352
ERROR_REMOTE_STORAGE_NOT_ACTIVE | The remote storage service is not operational at this time. | 4351
ERROR_REPARSE_ATTRIBUTE_CONFLICT | The reparse point attribute cannot be set because it conflicts with an existing attribute. | 4391
ERROR_REQ_NOT_ACCEP | No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept. | 71
ERROR_REQUEST_ABORTED | The request was aborted. | 1235
ERROR_REQUEST_REFUSED | The operator or administrator has refused the request. | 4320
ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION | This operation requires an interactive window station. | 1459
ERROR_RESMON_CREATE_FAILED | The cluster resource could not be created in the specified resource monitor. | 5017
ERROR_RESMON_ONLINE_FAILED | The cluster resource could not be brought online by the resource monitor. | 5018
ERROR_RESOURCE_DATA_NOT_FOUND | The specified image file did not contain a resource section. | 1812
ERROR_RESOURCE_DISABLED | A resource required for this operation is disabled. | 4309
ERROR_RESOURCE_LANG_NOT_FOUND | The specified resource language ID cannot be found in the image file. | 1815
ERROR_RESOURCE_NAME_NOT_FOUND | The specified resource name cannot be found in the image file. | 1814
ERROR_RESOURCE_NOT_AVAILABLE | The cluster resource is not available. | 5006
ERROR_RESOURCE_NOT_FOUND | The cluster resource could not be found. | 5007
ERROR_RESOURCE_NOT_ONLINE | The cluster resource is not online. | 5004
ERROR_RESOURCE_NOT_PRESENT | The resource required for this operation does not exist. | 4316
ERROR_RESOURCE_ONLINE | The operation could not be completed because the cluster resource is online. | 5019
ERROR_RESOURCE_PROPERTIES_STORED | The properties were stored but not all changes will take effect until the next time the resource is brought online. | 5024
ERROR_RESOURCE_TYPE_NOT_FOUND | The specified resource type cannot be found in the image file. | 1813
ERROR_RETRY | The operation could not be completed. A retry should be performed. | 1237
ERROR_REVISION_MISMATCH | Indicates two revision levels are incompatible. | 1306
ERROR_RING2_STACK_IN_USE | The ring 2 stack is in use. | 207
ERROR_RING2SEG_MUST_BE_MOVABLE | The code segment cannot be greater than or equal to 64K. | 200
ERROR_RMODE_APP | The specified program was written for an earlier version of Windows. | 1153
ERROR_RPL_NOT_ALLOWED | Replication with a nonconfigured partner is not allowed. | 4006
ERROR_RXACT_COMMIT_FAILURE | An internal security database corruption has been encountered. | 1370
ERROR_RXACT_INVALID_STATE | The transaction state of a registry subtree is incompatible with the requested operation. | 1369
ERROR_SAME_DRIVE | The system cannot join or substitute a drive to or for a directory on the same drive. | 143
ERROR_SCREEN_ALREADY_LOCKED | Screen already locked. | 1440
ERROR_SECRET_TOO_LONG | The length of a secret exceeds the maximum length allowed. | 1382
ERROR_SECTOR_NOT_FOUND | The drive cannot find the sector requested. | 27
ERROR_SEEK | The drive cannot locate a specific area or track on the disk. | 25
ERROR_SEEK_ON_DEVICE | The file pointer cannot be set on the specified device or file. | 132
ERROR_SEM_IS_SET | The semaphore is set and cannot be closed. | 102
ERROR_SEM_NOT_FOUND | The specified system semaphore name was not found. | 187
ERROR_SEM_OWNER_DIED | The previous ownership of this semaphore has ended. | 105
ERROR_SEM_TIMEOUT | The semaphore timeout period has expired. | 121
ERROR_SEM_USER_LIMIT | Insert the diskette for drive %1. | 106
ERROR_SERIAL_NO_DEVICE | No serial device was successfully initialized. The serial driver will unload. | 1118
ERROR_SERVER_DISABLED | The server is currently disabled. | 1341
ERROR_SERVER_HAS_OPEN_HANDLES | The server is in use and cannot be unloaded. | 1811
ERROR_SERVER_NOT_DISABLED | The server is currently enabled. | 1342
ERROR_SERVICE_ALREADY_RUNNING | An instance of the service is already running. | 1056
ERROR_SERVICE_CANNOT_ACCEPT_CTRL | The service cannot accept control messages at this time. | 1061
ERROR_SERVICE_DATABASE_LOCKED | The service database is locked. | 1055
ERROR_SERVICE_DEPENDENCY_DELETED | The dependency service does not exist or has been marked for deletion. | 1075
ERROR_SERVICE_DEPENDENCY_FAIL | The dependency service or group failed to start. | 1068
ERROR_SERVICE_DISABLED | The service cannot be started, either because it is disabled or because it has no enabled devices associated with it. | 1058
ERROR_SERVICE_DOES_NOT_EXIST | The specified service does not exist as an installed service. | 1060
ERROR_SERVICE_EXISTS | The specified service already exists. | 1073
ERROR_SERVICE_LOGON_FAILED | The service did not start due to a logon failure. | 1069
ERROR_SERVICE_MARKED_FOR_DELETE | The specified service has been marked for deletion. | 1072
ERROR_SERVICE_NEVER_STARTED | No attempts to start the service have been made since the last boot. | 1077
ERROR_SERVICE_NO_THREAD | A thread could not be created for the service. | 1054
ERROR_SERVICE_NOT_ACTIVE | The service has not been started. | 1062
ERROR_SERVICE_NOT_FOUND | The specified service does not exist. | 1243
ERROR_SERVICE_REQUEST_TIMEOUT | The service did not respond to the start or control request in a timely fashion. | 1053
ERROR_SERVICE_SPECIFIC_ERROR | The service has returned a service-specific error code. | 1066
ERROR_SERVICE_START_HANG | After starting, the service hung in a start-pending state. | 1070
ERROR_SESSION_CREDENTIAL_CONFLICT | The credentials supplied conflict with an existing set of credentials. | 1219
ERROR_SET_NOT_FOUND | The property set specified does not exist on the object. | 1170
ERROR_SET_POWER_STATE_FAILED | The system BIOS failed an attempt to change the system power state. | 1141
ERROR_SET_POWER_STATE_VETOED | An attempt to change the system power state was vetoed by another application or driver. | 1140
ERROR_SETCOUNT_ON_BAD_LB | LB_SETCOUNT sent to non-lazy list box. | 1433
ERROR_SETMARK_DETECTED | A tape access reached the end of a set of files. | 1103
ERROR_SHARING_BUFFER_EXCEEDED | Too many files opened for sharing. | 36
ERROR_SHARING_PAUSED | The remote server has been paused or is in the process of being started. | 70
ERROR_SHARING_VIOLATION | The process cannot access the file because it is being used by another process. | 32
ERROR_SHUTDOWN_CLUSTER | The cluster is being shut down. | 5008
ERROR_SHUTDOWN_IN_PROGRESS | A system shutdown is in progress. | 1115
ERROR_SIGNAL_PENDING | A signal is already pending. | 162
ERROR_SIGNAL_REFUSED | The recipient process has refused the signal. | 156
ERROR_SINGLE_INSTANCE_APP | Cannot start more than one instance of the specified program. | 1152
ERROR_SOME_NOT_MAPPED | Some mapping between account names and security IDs was not done. | 1301
ERROR_SOURCE_ELEMENT_EMPTY | The indicated source element has no media. | 1160
ERROR_SPECIAL_ACCOUNT | Cannot perform this operation on built-in accounts. | 1371
ERROR_SPECIAL_GROUP | Cannot perform this operation on this built-in special group. | 1372
ERROR_SPECIAL_USER | Cannot perform this operation on this built-in special user. | 1373
ERROR_SPL_NO_ADDJOB | An AddJob call was not issued. | 3004
ERROR_SPL_NO_STARTDOC | A StartDocPrinter call was not issued. | 3003
ERROR_SPOOL_FILE_NOT_FOUND | The spool file was not found. | 3002
ERROR_STACK_OVERFLOW | Recursion too deep; the stack overflowed. | 1001
ERROR_STATIC_INIT | The importation from the file failed. | 4002
ERROR_SUBST_TO_JOIN | The system tried to SUBST a drive to a directory on a joined drive. | 141
ERROR_SUBST_TO_SUBST | The system tried to substitute a drive to a directory on a substituted drive. | 139
ERROR_SUCCESS | The operation completed successfully. | 0
ERROR_SUCCESS_REBOOT_REQUIRED | The requested operation is successful. Changes will not be effective until the system is rebooted. | 3010
ERROR_SUCCESS_RESTART_REQUIRED | The requested operation is successful. Changes will not be effective until the service is restarted. | 3011
ERROR_SWAPERROR | Error performing inpage operation. | 999
ERROR_SYSTEM_TRACE | System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed. | 150
ERROR_TAG_NOT_FOUND | The specified tag was not found. | 2302
ERROR_TAG_NOT_PRESENT | A required tag is not present. | 2303
ERROR_THREAD_1_INACTIVE | The signal handler cannot be set. | 210
ERROR_TIMEOUT | This operation returned because the timeout period expired. | 1460
ERROR_TLW_WITH_WSCHILD | Cannot create a top-level child window. | 1406
ERROR_TOKEN_ALREADY_IN_USE | The token is already in use as a primary token. | 1375
ERROR_TOO_MANY_CMDS | The network BIOS command limit has been reached. | 56
ERROR_TOO_MANY_CONTEXT_IDS | During a logon attempt, the user's security context accumulated too many security IDs. | 1384
ERROR_TOO_MANY_LINKS | An attempt was made to create more links on a file than the file system supports. | 1142
ERROR_TOO_MANY_LUIDS_REQUESTED | Too many local user identifiers (LUIDs) were requested at one time. | 1333
ERROR_TOO_MANY_MODULES | Too many dynamic-link modules are attached to this program or dynamic-link module. | 214
ERROR_TOO_MANY_MUXWAITERS | DosMuxSemWait did not execute; too many semaphores are already set. | 152
ERROR_TOO_MANY_NAMES | The name limit for the local computer network adapter card was exceeded. | 68
ERROR_TOO_MANY_OPEN_FILES | The system cannot open the file. | 4
ERROR_TOO_MANY_POSTS | Too many posts were made to a semaphore. | 298
ERROR_TOO_MANY_SECRETS | The maximum number of secrets that may be stored in a single system has been exceeded. | 1381
ERROR_TOO_MANY_SEM_REQUESTS | The semaphore cannot be set again. | 103
ERROR_TOO_MANY_SEMAPHORES | Cannot create another system semaphore. | 100
ERROR_TOO_MANY_SESS | The network BIOS session limit was exceeded. | 69
ERROR_TOO_MANY_SIDS | Too many security IDs have been specified. | 1389
ERROR_TOO_MANY_TCBS | Cannot create another thread. | 155
ERROR_TRANSFORM_NOT_SUPPORTED | The requested transformation operation is not supported. | 2004
ERROR_TRUST_FAILURE | The network logon failed. | 1790
ERROR_TRUSTED_DOMAIN_FAILURE | The trust relationship between the primary domain and the trusted domain failed. | 1788
ERROR_TRUSTED_RELATIONSHIP_FAILURE | The trust relationship between this workstation and the primary domain failed. | 1789
ERROR_UNABLE_TO_CLEAN | The drive cannot be cleaned or does not support cleaning. | 4311
ERROR_UNABLE_TO_LOCK_MEDIA | Unable to lock the media eject mechanism. | 1108
ERROR_UNABLE_TO_UNLOAD_MEDIA | Unable to unload the media. | 1109
ERROR_UNEXP_NET_ERR | An unexpected network error occurred. | 59
ERROR_UNKNOWN_COMPONENT | Component ID not registered. | 1607
ERROR_UNKNOWN_FEATURE | Feature ID not registered. | 1606
ERROR_UNKNOWN_PORT | The specified port is unknown. | 1796
ERROR_UNKNOWN_PRINT_MONITOR | The specified print monitor is unknown. | 3000
ERROR_UNKNOWN_PRINTER_DRIVER | The printer driver is unknown. | 1797
ERROR_UNKNOWN_PRINTPROCESSOR | The print processor is unknown. | 1798
ERROR_UNKNOWN_PRODUCT | Product code not registered. | 1605
ERROR_UNKNOWN_PROPERTY | Unknown property. | 1608
ERROR_UNKNOWN_REVISION | The revision level is unknown. | 1305
ERROR_UNRECOGNIZED_MEDIA | The disk media is not recognized. It may not be formatted. | 1785
ERROR_UNRECOGNIZED_VOLUME | The volume does not contain a recognized file system. Please make sure that all required file system drivers are loaded and that the volume is not corrupted. | 1005
ERROR_USER_EXISTS | The specified user already exists. | 1316
ERROR_USER_MAPPED_FILE | The requested operation cannot be performed on a file with a user-mapped section open. | 1224
ERROR_VC_DISCONNECTED | The session was canceled. | 240
ERROR_WAIT_NO_CHILDREN | There are no child processes to wait for. | 128
ERROR_WINDOW_NOT_COMBOBOX | The window is not a combo box. | 1423
ERROR_WINDOW_NOT_DIALOG | The window is not a valid dialog window. | 1420
ERROR_WINDOW_OF_OTHER_THREAD | Invalid window; it belongs to other thread. | 1408
ERROR_WINS_INTERNAL | WINS encountered an error while processing the command. | 4000
ERROR_WMI_ALREADY_ENABLED | The WMI data block or event notification has already been enabled. | 4206
ERROR_WMI_DP_FAILED | The WMI data provider failed to carry out the request. | 4209
ERROR_WMI_DP_NOT_FOUND | The WMI data provider could not be located. | 4204
ERROR_WMI_GUID_DISCONNECTED | The WMI data block is no longer available. | 4207
ERROR_WMI_GUID_NOT_FOUND | The GUID passed was not recognized as valid by a WMI data provider. | 4200
ERROR_WMI_INSTANCE_NOT_FOUND | The instance name passed was not recognized as valid by a WMI data provider. | 4201
ERROR_WMI_INVALID_MOF | The WMI MOF information is not valid. | 4210
ERROR_WMI_INVALID_REGINFO | The WMI registration information is not valid. | 4211
ERROR_WMI_ITEMID_NOT_FOUND | The data item ID passed was not recognized as valid by a WMI data provider. | 4202
ERROR_WMI_SERVER_UNAVAILABLE | The WMI data service is not available. | 4208
ERROR_WMI_TRY_AGAIN | The WMI request could not be completed and should be retried. | 4203
ERROR_WMI_UNRESOLVED_INSTANCE_REF | The WMI data provider references an instance set that has not been registered. | 4205
ERROR_WORKING_SET_QUOTA | Insufficient quota to complete the requested service. | 1453
ERROR_WRITE_FAULT | The system cannot write to the specified device. | 29
ERROR_WRITE_PROTECT | The media is write protected. | 19
ERROR_WRONG_DISK | The wrong diskette is in the drive. Insert %2 (Volume Serial Number: %3) into drive %1. | 34
ERROR_WRONG_EFS | The file was encrypted with a different encryption driver than is currently loaded. | 6005
ERROR_WRONG_PASSWORD | Unable to update the password. The value provided as the current password is incorrect. | 1323
OR_INVALID_OID | The object specified was not found. | 1911
OR_INVALID_OXID | The object exporter specified was not found. | 1910
OR_INVALID_SET | The object resolver set specified was not found. | 1912
RPC_S_ADDRESS_ERROR | An addressing error occurred in the RPC server. | 1768
RPC_S_ALREADY_LISTENING | The RPC server is already listening. | 1713
RPC_S_ALREADY_REGISTERED | The object universal unique identifier (UUID) has already been registered. | 1711
RPC_S_BINDING_HAS_NO_AUTH | The binding does not contain any authentication information. | 1746
RPC_S_BINDING_INCOMPLETE | The binding handle does not contain all required information. | 1819
RPC_S_CALL_CANCELLED | The remote procedure call was cancelled. | 1818
RPC_S_CALL_FAILED | The remote procedure call failed. | 1726
RPC_S_CALL_FAILED_DNE | The remote procedure call failed and did not execute. | 1727
RPC_S_CALL_IN_PROGRESS | A remote procedure call is already in progress for this thread. | 1791
RPC_S_CANNOT_SUPPORT | The requested operation is not supported. | 1764
RPC_S_CANT_CREATE_ENDPOINT | The endpoint cannot be created. | 1720
RPC_S_COMM_FAILURE | A communications failure occurred during a remote procedure call. | 1820
RPC_S_DUPLICATE_ENDPOINT | The endpoint is a duplicate. | 1740
RPC_S_ENTRY_ALREADY_EXISTS | The entry already exists. | 1760
RPC_S_ENTRY_NOT_FOUND | The entry is not found. | 1761
RPC_S_FP_DIV_ZERO | A floating-point operation at the RPC server caused a division by zero. | 1769
RPC_S_FP_OVERFLOW | A floating-point overflow occurred at the RPC server. | 1771
RPC_S_FP_UNDERFLOW | A floating-point underflow occurred at the RPC server. | 1770
RPC_S_GROUP_MEMBER_NOT_FOUND | The group member was not found. | 1898
RPC_S_INCOMPLETE_NAME | The entry name is incomplete. | 1755
RPC_S_INTERFACE_NOT_FOUND | The interface was not found. | 1759
RPC_S_INTERNAL_ERROR | An internal error occurred in a remote procedure call (RPC). | 1766
RPC_S_INVALID_ASYNC_CALL | Invalid asynchronous RPC call handle for this operation. | 1915
RPC_S_INVALID_ASYNC_HANDLE | Invalid asynchronous remote procedure call handle. | 1914
RPC_S_INVALID_AUTH_IDENTITY | The security context is invalid. | 1749
RPC_S_INVALID_BINDING | The binding handle is invalid. | 1702
RPC_S_INVALID_BOUND | The array bounds are invalid. | 1734
RPC_S_INVALID_ENDPOINT_FORMAT | The endpoint format is invalid. | 1706
RPC_S_INVALID_NAF_ID | The network address family is invalid. | 1763
RPC_S_INVALID_NAME_SYNTAX | The name syntax is invalid. | 1736
RPC_S_INVALID_NET_ADDR | The network address is invalid. | 1707
RPC_S_INVALID_NETWORK_OPTIONS | The network options are invalid. | 1724
RPC_S_INVALID_OBJECT | The object universal unique identifier (UUID) is the nil UUID. | 1900
RPC_S_INVALID_RPC_PROTSEQ | The RPC protocol sequence is invalid. | 1704
RPC_S_INVALID_STRING_BINDING | The string binding is invalid. | 1700
RPC_S_INVALID_STRING_UUID | The string universal unique identifier (UUID) is invalid. | 1705
RPC_S_INVALID_TAG | The tag is invalid. | 1733
RPC_S_INVALID_TIMEOUT | The timeout value is invalid. | 1709
RPC_S_INVALID_VERS_OPTION | The version option is invalid. | 1756
RPC_S_MAX_CALLS_TOO_SMALL | The maximum number of calls is too small. | 1742
RPC_S_NAME_SERVICE_UNAVAILABLE | The name service is unavailable. | 1762
RPC_S_NO_BINDINGS | There are no bindings. | 1718
RPC_S_NO_CALL_ACTIVE | There are no remote procedure calls active on this thread. | 1725
RPC_S_NO_CONTEXT_AVAILABLE | No security context is available to allow impersonation. | 1765
RPC_S_NO_ENDPOINT_FOUND | No endpoint was found. | 1708
RPC_S_NO_ENTRY_NAME | The binding does not contain an entry name. | 1735
RPC_S_NO_INTERFACES | No interfaces have been registered. | 1817
RPC_S_NO_MORE_BINDINGS | There are no more bindings. | 1806
RPC_S_NO_MORE_MEMBERS | There are no more members. | 1757
RPC_S_NO_PRINC_NAME | No principal name registered. | 1822
RPC_S_NO_PROTSEQS | There are no protocol sequences. | 1719
RPC_S_NO_PROTSEQS_REGISTERED | No protocol sequences have been registered. | 1714
RPC_S_NOT_ALL_OBJS_UNEXPORTED | There is nothing to unexport. | 1758
RPC_S_NOT_CANCELLED | Thread is not canceled. | 1826
RPC_S_NOT_LISTENING | The RPC server is not listening. | 1715
RPC_S_NOT_RPC_ERROR | The error specified is not a valid Windows RPC error code. | 1823
RPC_S_NOTHING_TO_EXPORT | No interfaces have been exported. | 1754
RPC_S_OBJECT_NOT_FOUND | The object universal unique identifier (UUID) was not found. | 1710
RPC_S_OUT_OF_RESOURCES | Not enough resources are available to complete this operation. | 1721
RPC_S_PROCNUM_OUT_OF_RANGE | The procedure number is out of range. | 1745
RPC_S_PROTOCOL_ERROR | A remote procedure call (RPC) protocol error occurred. | 1728
RPC_S_PROTSEQ_NOT_FOUND | The RPC protocol sequence was not found. | 1744
RPC_S_PROTSEQ_NOT_SUPPORTED | The RPC protocol sequence is not supported. | 1703
RPC_S_SEC_PKG_ERROR | A security package specific error occurred. | 1825
RPC_S_SEND_INCOMPLETE | Some data remains to be sent in the request buffer. | 1913
RPC_S_SERVER_TOO_BUSY | The RPC server is too busy to complete this operation. | 1723
RPC_S_SERVER_UNAVAILABLE | The RPC server is unavailable. | 1722
RPC_S_STRING_TOO_LONG | The string is too long. | 1743
RPC_S_TYPE_ALREADY_REGISTERED | The type universal unique identifier (UUID) has already been registered. | 1712
RPC_S_UNKNOWN_AUTHN_LEVEL | The authentication level is unknown. | 1748
RPC_S_UNKNOWN_AUTHN_SERVICE | The authentication service is unknown. | 1747
RPC_S_UNKNOWN_AUTHN_TYPE | The authentication type is unknown. | 1741
RPC_S_UNKNOWN_AUTHZ_SERVICE | The authorization service is unknown. | 1750
RPC_S_UNKNOWN_IF | The interface is unknown. | 1717
RPC_S_UNKNOWN_MGR_TYPE | The manager type is unknown. | 1716
RPC_S_UNSUPPORTED_AUTHN_LEVEL | The requested authentication level is not supported. | 1821
RPC_S_UNSUPPORTED_NAME_SYNTAX | The name syntax is not supported. | 1737
RPC_S_UNSUPPORTED_TRANS_SYN | The transfer syntax is not supported by the RPC server. | 1730
RPC_S_UNSUPPORTED_TYPE | The universal unique identifier (UUID) type is not supported. | 1732
RPC_S_UUID_LOCAL_ONLY | A UUID that is valid only on this computer has been allocated. | 1824
RPC_S_UUID_NO_ADDRESS | No network address is available to use to construct a universal unique identifier (UUID). | 1739
RPC_S_WRONG_KIND_OF_BINDING | The binding handle is not the correct type. | 1701
RPC_S_ZERO_DIVIDE | The RPC server attempted an integer division by zero. | 1767
RPC_X_BAD_STUB_DATA | The stub received bad data. | 1783
RPC_X_BYTE_COUNT_TOO_SMALL | The byte count is too small. | 1782
RPC_X_ENUM_VALUE_OUT_OF_RANGE | The enumeration value is out of range. | 1781
RPC_X_INVALID_ES_ACTION | Invalid operation on the encoding/decoding handle. | 1827
RPC_X_INVALID_PIPE_OBJECT | The RPC pipe object is invalid or corrupted. | 1830
RPC_X_NO_MORE_ENTRIES | The list of RPC servers available for the binding of auto handles has been exhausted. | 1772
RPC_X_NULL_REF_POINTER | A null reference pointer was passed to the stub. | 1780
RPC_X_PIPE_CLOSED | The RPC pipe object has already been closed. | 1916
RPC_X_PIPE_DISCIPLINE_ERROR | The RPC call completed before all pipes were processed. | 1917
RPC_X_PIPE_EMPTY | No more data is available from the RPC pipe. | 1918
RPC_X_SS_CANNOT_GET_CALL_HANDLE | The stub is unable to get the remote procedure call handle. | 1779
RPC_X_SS_CHAR_TRANS_OPEN_FAIL | Unable to open the character translation table file. | 1773
RPC_X_SS_CHAR_TRANS_SHORT_FILE | The file containing the character translation table has fewer than bytes. | 1774
RPC_X_SS_CONTEXT_DAMAGED | The context handle changed during a remote procedure call. | 1777
RPC_X_SS_HANDLES_MISMATCH | The binding handles passed to a remote procedure call do not match. | 1778
RPC_X_SS_IN_NULL_CONTEXT | A null context handle was passed from the client to the host during a remote procedure call. | 1775
RPC_X_WRONG_ES_VERSION | Incompatible version of the serializing package. | 1828
RPC_X_WRONG_PIPE_ORDER | An invalid operation was attempted on an RPC pipe object. | 1831
RPC_X_WRONG_PIPE_VERSION | Unsupported RPC pipe version. | 1832
RPC_X_WRONG_STUB_VERSION | Incompatible version of the RPC stub. | 1829


System Errors - Numerical Order

The following table provides a list of system error codes.

Code | Description | Name
0 | The operation completed successfully. | ERROR_SUCCESS
1 | Incorrect function. | ERROR_INVALID_FUNCTION
2 | The system cannot find the file specified. | ERROR_FILE_NOT_FOUND
3 | The system cannot find the path specified. | ERROR_PATH_NOT_FOUND
4 | The system cannot open the file. | ERROR_TOO_MANY_OPEN_FILES
5 | Access is denied. | ERROR_ACCESS_DENIED
6 | The handle is invalid. | ERROR_INVALID_HANDLE
7 | The storage control blocks were destroyed. | ERROR_ARENA_TRASHED
8 | Not enough storage is available to process this command. | ERROR_NOT_ENOUGH_MEMORY
9 | The storage control block address is invalid. | ERROR_INVALID_BLOCK
10 | The environment is incorrect. | ERROR_BAD_ENVIRONMENT
11 | An attempt was made to load a program with an incorrect format. | ERROR_BAD_FORMAT
12 | The access code is invalid. | ERROR_INVALID_ACCESS
13 | The data is invalid. | ERROR_INVALID_DATA
14 | Not enough storage is available to complete this operation. | ERROR_OUTOFMEMORY
15 | The system cannot find the drive specified. | ERROR_INVALID_DRIVE
16 | The directory cannot be removed. | ERROR_CURRENT_DIRECTORY
17 | The system cannot move the file to a different disk drive. | ERROR_NOT_SAME_DEVICE
18 | There are no more files. | ERROR_NO_MORE_FILES
19 | The media is write protected. | ERROR_WRITE_PROTECT
20 | The system cannot find the device specified. | ERROR_BAD_UNIT
21 | The device is not ready. | ERROR_NOT_READY
22 | The device does not recognize the command. | ERROR_BAD_COMMAND
23 | Data error (cyclic redundancy check). | ERROR_CRC
24 | The program issued a command but the command length is incorrect. | ERROR_BAD_LENGTH
25 | The drive cannot locate a specific area or track on the disk. | ERROR_SEEK
26 | The specified disk or diskette cannot be accessed. | ERROR_NOT_DOS_DISK
27 | The drive cannot find the sector requested. | ERROR_SECTOR_NOT_FOUND
28 | The printer is out of paper. | ERROR_OUT_OF_PAPER
29 | The system cannot write to the specified device. | ERROR_WRITE_FAULT
30 | The system cannot read from the specified device. | ERROR_READ_FAULT
31 | A device attached to the system is not functioning. | ERROR_GEN_FAILURE
32 | The process cannot access the file because it is being used by another process. | ERROR_SHARING_VIOLATION
33 | The process cannot access the file because another process has locked a portion of the file. | ERROR_LOCK_VIOLATION
34 | The wrong diskette is in the drive. Insert %2 (Volume Serial Number: %3) into drive %1. | ERROR_WRONG_DISK
36 | Too many files opened for sharing. | ERROR_SHARING_BUFFER_EXCEEDED
38 | Reached the end of the file. | ERROR_HANDLE_EOF
39 | The disk is full. | ERROR_HANDLE_DISK_FULL
50 | The network request is not supported. | ERROR_NOT_SUPPORTED
51 | The remote computer is not available. | ERROR_REM_NOT_LIST
52 | A duplicate name exists on the network. | ERROR_DUP_NAME
53 | The network path was not found. | ERROR_BAD_NETPATH
54 | The network is busy. | ERROR_NETWORK_BUSY
55 | The specified network resource or device is no longer available. | ERROR_DEV_NOT_EXIST
56 | The network BIOS command limit has been reached. | ERROR_TOO_MANY_CMDS
57 | A network adapter hardware error occurred. | ERROR_ADAP_HDW_ERR
58 | The specified server cannot perform the requested operation. | ERROR_BAD_NET_RESP
59 | An unexpected network error occurred. | ERROR_UNEXP_NET_ERR
60 | The remote adapter is not compatible. | ERROR_BAD_REM_ADAP
61 | The printer queue is full. | ERROR_PRINTQ_FULL
62 | Space to store the file waiting to be printed is not available on the server. | ERROR_NO_SPOOL_SPACE
63 | Your file waiting to be printed was deleted. | ERROR_PRINT_CANCELLED
64 | The specified network name is no longer available. | ERROR_NETNAME_DELETED
65 | Network access is denied. | ERROR_NETWORK_ACCESS_DENIED
66 | The network resource type is not correct. | ERROR_BAD_DEV_TYPE
67 | The network name cannot be found. | ERROR_BAD_NET_NAME
68 | The name limit for the local computer network adapter card was exceeded. | ERROR_TOO_MANY_NAMES
69 | The network BIOS session limit was exceeded. | ERROR_TOO_MANY_SESS
70 | The remote server has been paused or is in the process of being started. | ERROR_SHARING_PAUSED
71 | No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept. | ERROR_REQ_NOT_ACCEP
72 | The specified printer or disk device has been paused. | ERROR_REDIR_PAUSED
80 | The file exists. | ERROR_FILE_EXISTS
82 | The directory or file cannot be created. | ERROR_CANNOT_MAKE
83 | Fail on INT 24. | ERROR_FAIL_I24
84 | Storage to process this request is not available. | ERROR_OUT_OF_STRUCTURES
85 | The local device name is already in use. | ERROR_ALREADY_ASSIGNED
86 | The specified network password is not correct. | ERROR_INVALID_PASSWORD
87 | The parameter is incorrect. | ERROR_INVALID_PARAMETER
88 | A write fault occurred on the network. | ERROR_NET_WRITE_FAULT
89 | The system cannot start another process at this time. | ERROR_NO_PROC_SLOTS
100 | Cannot create another system semaphore. | ERROR_TOO_MANY_SEMAPHORES
101 | The exclusive semaphore is owned by another process. | ERROR_EXCL_SEM_ALREADY_OWNED
102 | The semaphore is set and cannot be closed. | ERROR_SEM_IS_SET
103 | The semaphore cannot be set again. | ERROR_TOO_MANY_SEM_REQUESTS
104 | Cannot request exclusive semaphores at interrupt time. | ERROR_INVALID_AT_INTERRUPT_TIME
105 | The previous ownership of this semaphore has ended. | ERROR_SEM_OWNER_DIED
106 | Insert the diskette for drive %1. | ERROR_SEM_USER_LIMIT
107 | The program stopped because an alternate diskette was not inserted. | ERROR_DISK_CHANGE
108 | The disk is in use or locked by another process. | ERROR_DRIVE_LOCKED
109 | The pipe has been ended. | ERROR_BROKEN_PIPE
110 | The system cannot open the device or file specified. | ERROR_OPEN_FAILED
111 | The file name is too long. | ERROR_BUFFER_OVERFLOW
112 | There is not enough space on the disk. | ERROR_DISK_FULL
113 | No more internal file identifiers available. | ERROR_NO_MORE_SEARCH_HANDLES
114 | The target internal file identifier is incorrect. | ERROR_INVALID_TARGET_HANDLE
117 | The IOCTL call made by the application program is not correct. | ERROR_INVALID_CATEGORY
118 | The verify-on-write switch parameter value is not correct. | ERROR_INVALID_VERIFY_SWITCH
119 | The system does not support the command requested. | ERROR_BAD_DRIVER_LEVEL
120 | This function is not supported on this system. | ERROR_CALL_NOT_IMPLEMENTED
121 | The semaphore timeout period has expired. | ERROR_SEM_TIMEOUT
122 | The data area passed to a system call is too small. | ERROR_INSUFFICIENT_BUFFER
123 | The filename, directory name, or volume label syntax is incorrect. | ERROR_INVALID_NAME
124 | The system call level is not correct. | ERROR_INVALID_LEVEL
125 | The disk has no volume label. | ERROR_NO_VOLUME_LABEL
126 | The specified module could not be found. | ERROR_MOD_NOT_FOUND
127 | The specified procedure could not be found. | ERROR_PROC_NOT_FOUND
128 | There are no child processes to wait for. | ERROR_WAIT_NO_CHILDREN
129 | The %1 application cannot be run in Win32 mode. | ERROR_CHILD_NOT_COMPLETE
130 | Attempt to use a file handle to an open disk partition for an operation other than raw disk I/O. | ERROR_DIRECT_ACCESS_HANDLE
131 | An attempt was made to move the file pointer before the beginning of the file. | ERROR_NEGATIVE_SEEK
132 | The file pointer cannot be set on the specified device or file. | ERROR_SEEK_ON_DEVICE
133 | A JOIN or SUBST command cannot be used for a drive that contains previously joined drives. | ERROR_IS_JOIN_TARGET
134 | An attempt was made to use a JOIN or SUBST command on a drive that has already been joined. | ERROR_IS_JOINED
135 | An attempt was made to use a JOIN or SUBST command on a drive that has already been substituted. | ERROR_IS_SUBSTED
136 | The system tried to delete the JOIN of a drive that is not joined. | ERROR_NOT_JOINED
137 | The system tried to delete the substitution of a drive that is not substituted. | ERROR_NOT_SUBSTED
138 | The system tried to join a drive to a directory on a joined drive. | ERROR_JOIN_TO_JOIN
139 | The system tried to substitute a drive to a directory on a substituted drive. | ERROR_SUBST_TO_SUBST
140 | The system tried to join a drive to a directory on a substituted drive. | ERROR_JOIN_TO_SUBST
141 | The system tried to SUBST a drive to a directory on a joined drive. | ERROR_SUBST_TO_JOIN
142 | The system cannot perform a JOIN or SUBST at this time. | ERROR_BUSY_DRIVE
143 | The system cannot join or substitute a drive to or for a directory on the same drive. | ERROR_SAME_DRIVE
144 | The directory is not a subdirectory of the root directory. | ERROR_DIR_NOT_ROOT
145 | The directory is not empty. | ERROR_DIR_NOT_EMPTY
146 | The path specified is being used in a substitute. | ERROR_IS_SUBST_PATH
147 | Not enough resources are available to process this command. | ERROR_IS_JOIN_PATH
148 | The path specified cannot be used at this time. | ERROR_PATH_BUSY
149 | An attempt was made to join or substitute a drive for which a directory on the drive is the target of a previous substitute. | ERROR_IS_SUBST_TARGET
150 | System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed. | ERROR_SYSTEM_TRACE
151 | The number of specified semaphore events for DosMuxSemWait is not correct. | ERROR_INVALID_EVENT_COUNT
152 | DosMuxSemWait did not execute; too many semaphores are already set. | ERROR_TOO_MANY_MUXWAITERS
153 | The DosMuxSemWait list is not correct. | ERROR_INVALID_LIST_FORMAT
154 | The volume label you entered exceeds the label character limit of the target file system. | ERROR_LABEL_TOO_LONG
155 | Cannot create another thread. | ERROR_TOO_MANY_TCBS
156 | The recipient process has refused the signal. | ERROR_SIGNAL_REFUSED
157 | The segment is already discarded and cannot be locked. | ERROR_DISCARDED
158 | The segment is already unlocked. | ERROR_NOT_LOCKED
159 | The address for the thread ID is not correct. | ERROR_BAD_THREADID_ADDR
160 | The argument string passed to DosExecPgm is not correct. | ERROR_BAD_ARGUMENTS
161 | The specified path is invalid. | ERROR_BAD_PATHNAME
162 | A signal is already pending. | ERROR_SIGNAL_PENDING
164 | No more threads can be created in the system. | ERROR_MAX_THRDS_REACHED
167 | Unable to lock a region of a file. | ERROR_LOCK_FAILED
170 | The requested resource is in use. | ERROR_BUSY
173 | A lock request was not outstanding for the supplied cancel region. | ERROR_CANCEL_VIOLATION
174 | The file system does not support atomic changes to the lock type. | ERROR_ATOMIC_LOCKS_NOT_SUPPORTED
180 | The system detected a segment number that was not correct. | ERROR_INVALID_SEGMENT_NUMBER
182 | The operating system cannot run %1. | ERROR_INVALID_ORDINAL
183 | Cannot create a file when that file already exists. | ERROR_ALREADY_EXISTS
186 | The flag passed is not correct. | ERROR_INVALID_FLAG_NUMBER
187 | The specified system semaphore name was not found. | ERROR_SEM_NOT_FOUND
188 | The operating system cannot run %1. | ERROR_INVALID_STARTING_CODESEG
189 | The operating system cannot run %1. | ERROR_INVALID_STACKSEG
190 | The operating system cannot run %1. | ERROR_INVALID_MODULETYPE
191 | Cannot run %1 in Win32 mode. | ERROR_INVALID_EXE_SIGNATURE
192 | The operating system cannot run %1. | ERROR_EXE_MARKED_INVALID
193 | is not a valid Win32 application. | ERROR_BAD_EXE_FORMAT
194 | The operating system cannot run %1. | ERROR_ITERATED_DATA_EXCEEDS_64k
195 | The operating system cannot run %1. | ERROR_INVALID_MINALLOCSIZE
196 | The operating system cannot run this application program. | ERROR_DYNLINK_FROM_INVALID_RING
197 | The operating system is not presently configured to run this application. | ERROR_IOPL_NOT_ENABLED
198 | The operating system cannot run %1. | ERROR_INVALID_SEGDPL
199 | The operating system cannot run this application program. | ERROR_AUTODATASEG_EXCEEDS_64k
200 | The code segment cannot be greater than or equal to 64K. | ERROR_RING2SEG_MUST_BE_MOVABLE
201 | The operating system cannot run %1. | ERROR_RELOC_CHAIN_XEEDS_SEGLIM
202 | The operating system cannot run %1. | ERROR_INFLOOP_IN_RELOC_CHAIN
203 | The system could not find the environment option that was entered. | ERROR_ENVVAR_NOT_FOUND
205 | No process in the command subtree has a signal handler. | ERROR_NO_SIGNAL_SENT
206 | The filename or extension is too long. | ERROR_FILENAME_EXCED_RANGE
207 | The ring 2 stack is in use. | ERROR_RING2_STACK_IN_USE
208 | The global filename characters, * or ?, are entered incorrectly or too many global filename characters are specified. | ERROR_META_EXPANSION_TOO_LONG
209 | The signal being posted is not correct. | ERROR_INVALID_SIGNAL_NUMBER
210 | The signal handler cannot be set. | ERROR_THREAD_1_INACTIVE
212 | The segment is locked and cannot be reallocated. | ERROR_LOCKED
214 | Too many dynamic-link modules are attached to this program or dynamic-link module. | ERROR_TOO_MANY_MODULES
215 | Can't nest calls to LoadModule. | ERROR_NESTING_NOT_ALLOWED
216 | The image file %1 is valid, but is for a machine type other than the current machine. | ERROR_EXE_MACHINE_TYPE_MISMATCH
230 | The pipe state is invalid. | ERROR_BAD_PIPE
231 | All pipe instances are busy. | ERROR_PIPE_BUSY
232 | The pipe is being closed. | ERROR_NO_DATA
233 | No process is on the other end of the pipe. | ERROR_PIPE_NOT_CONNECTED
234 | More data is available. | ERROR_MORE_DATA
240 | The session was canceled. | ERROR_VC_DISCONNECTED
254 | The specified extended attribute name was invalid. | ERROR_INVALID_EA_NAME
255 | The extended attributes are inconsistent. | ERROR_EA_LIST_INCONSISTENT
259 | No more data is available. | ERROR_NO_MORE_ITEMS
266 | The copy functions cannot be used. | ERROR_CANNOT_COPY
267 | The directory name is invalid. | ERROR_DIRECTORY
275 | The extended attributes did not fit in the buffer. | ERROR_EAS_DIDNT_FIT
276 | The extended attribute file on the mounted file system is corrupt. | ERROR_EA_FILE_CORRUPT
277 | The extended attribute table file is full. | ERROR_EA_TABLE_FULL
278 | The specified extended attribute handle is invalid. | ERROR_INVALID_EA_HANDLE
282 | The mounted file system does not support extended attributes. | ERROR_EAS_NOT_SUPPORTED
288 | Attempt to release mutex not owned by caller. | ERROR_NOT_OWNER
298 | Too many posts were made to a semaphore. | ERROR_TOO_MANY_POSTS
299 | Only part of a ReadProcessMemoty or WriteProcessMemory request was completed. | ERROR_PARTIAL_COPY
300 | The oplock request is denied. | ERROR_OPLOCK_NOT_GRANTED
301 | An invalid oplock acknowledgment was received by the system. | ERROR_INVALID_OPLOCK_PROTOCOL
317 | The system cannot find message text for message number 0x%1 in the message file for %2. | ERROR_MR_MID_NOT_FOUND
487 | Attempt to access invalid address. | ERROR_INVALID_ADDRESS
534 | Arithmetic result exceeded 32 bits. | ERROR_ARITHMETIC_OVERFLOW
535 | There is a process on other end of the pipe. | ERROR_PIPE_CONNECTED
536 | Waiting for a process to open the other end of the pipe. | ERROR_PIPE_LISTENING
994 | Access to the extended attribute was denied. | ERROR_EA_ACCESS_DENIED
995 | The I/O operation has been aborted because of either a thread exit or an application request. | ERROR_OPERATION_ABORTED
996 | Overlapped I/O event is not in a signaled state. | ERROR_IO_INCOMPLETE
997 | Overlapped I/O operation is in progress. | ERROR_IO_PENDING
998 | Invalid access to memory location. | ERROR_NOACCESS
999 | Error performing inpage operation. | ERROR_SWAPERROR
1001 | Recursion too deep; the stack overflowed. | ERROR_STACK_OVERFLOW
1002 | The window cannot act on the sent message. | ERROR_INVALID_MESSAGE
1003 | Cannot complete this function. | ERROR_CAN_NOT_COMPLETE
1004 | Invalid flags. | ERROR_INVALID_FLAGS
1005 | The volume does not contain a recognized file system. Please make sure that all required file system drivers are loaded and that the volume is not corrupted. | ERROR_UNRECOGNIZED_VOLUME
1006 | The volume for a file has been externally altered so that the opened file is no longer valid. | ERROR_FILE_INVALID
1007 | The requested operation cannot be performed in full-screen mode. | ERROR_FULLSCREEN_MODE
1008 | An attempt was made to reference a token that does not exist. | ERROR_NO_TOKEN
1009 | The configuration registry database is corrupt. | ERROR_BADDB
1010 | The configuration registry key is invalid. | ERROR_BADKEY
1011 | The configuration registry key could not be opened. | ERROR_CANTOPEN
1012 | The configuration registry key could not be read. | ERROR_CANTREAD
1013 | The configuration registry key could not be written. | ERROR_CANTWRITE
1014 | One of the files in the registry database had to be recovered by use of a log or alternate copy. The recovery was successful. | ERROR_REGISTRY_RECOVERED
1015 | The registry is corrupted. The structure of one of the files that contains registry data is corrupted, or the system's image of the file in memory is corrupted, or the file could not be recovered because the alternate copy or log was absent or corrupted. | ERROR_REGISTRY_CORRUPT
1016 | An I/O operation initiated by the registry failed unrecoverably. The registry could not read in, or write out, or flush, one of the files that contain the system's image of the registry. | ERROR_REGISTRY_IO_FAILED
1017 | The system has attempted to load or restore a file into the registry, but the specified file is not in a registry file format. | ERROR_NOT_REGISTRY_FILE
1018 | Illegal operation attempted on a registry key that has been marked for deletion. | ERROR_KEY_DELETED
1019 | System could not allocate the required space in a registry log. | ERROR_NO_LOG_SPACE
1020 | Cannot create a symbolic link in a registry key that already has subkeys or values. | ERROR_KEY_HAS_CHILDREN
1021 | Cannot create a stable subkey under a volatile parent key. | ERROR_CHILD_MUST_BE_VOLATILE
1022 | A notify change request is being completed and the information is not being returned in the caller's buffer. The caller now needs to enumerate the files to find the changes. | ERROR_NOTIFY_ENUM_DIR
1051 | A stop control has been sent to a service that other running services are dependent on. | ERROR_DEPENDENT_SERVICES_RUNNING
1052 | The requested control is not valid for this service. | ERROR_INVALID_SERVICE_CONTROL
1053 | The service did not respond to the start or control request in a timely fashion. | ERROR_SERVICE_REQUEST_TIMEOUT
1054 | A thread could not be created for the service. | ERROR_SERVICE_NO_THREAD
1055 | The service database is locked. | ERROR_SERVICE_DATABASE_LOCKED
1056 | An instance of the service is already running. | ERROR_SERVICE_ALREADY_RUNNING
1057 | The account name is invalid or does not exist. | ERROR_INVALID_SERVICE_ACCOUNT
1058 | The service cannot be started, either because it is disabled or because it has no enabled devices associated with it. | ERROR_SERVICE_DISABLED
1059 | Circular service dependency was specified. | ERROR_CIRCULAR_DEPENDENCY
1060 | The specified service does not exist as an installed service. | ERROR_SERVICE_DOES_NOT_EXIST
1061 | The service cannot accept control messages at this time. | ERROR_SERVICE_CANNOT_ACCEPT_CTRL
1062 | The service has not been started. | ERROR_SERVICE_NOT_ACTIVE
1063 | The service process could not connect to the service controller. | ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
1064 | An exception occurred in the service when handling the control request. | ERROR_EXCEPTION_IN_SERVICE
1065 | The database specified does not exist. | ERROR_DATABASE_DOES_NOT_EXIST
1066 | The service has returned a service-specific error code. | ERROR_SERVICE_SPECIFIC_ERROR
1067 | The process terminated unexpectedly. | ERROR_PROCESS_ABORTED
1068 | The dependency service or group failed to start. | ERROR_SERVICE_DEPENDENCY_FAIL
1069 | The service did not start due to a logon failure. | ERROR_SERVICE_LOGON_FAILED
1070 | After starting, the service hung in a start-pending state. | ERROR_SERVICE_START_HANG
1071 | The specified service database lock is invalid. | ERROR_INVALID_SERVICE_LOCK
1072 | The specified service has been marked for deletion. | ERROR_SERVICE_MARKED_FOR_DELETE
1073 | The specified service already exists. | ERROR_SERVICE_EXISTS
1074 | The system is currently running with the last-known-good configuration. | ERROR_ALREADY_RUNNING_LKG
1075 | The dependency service does not exist or has been marked for deletion. | ERROR_SERVICE_DEPENDENCY_DELETED
1076 | The current boot has already been accepted for use as the last-known-good control set. | ERROR_BOOT_ALREADY_ACCEPTED
1077 | No attempts to start the service have been made since the last boot. | ERROR_SERVICE_NEVER_STARTED
1078 | The name is already in use as either a service name or a service display name. | ERROR_DUPLICATE_SERVICE_NAME
1079 | The account specified for this service is different from the account specified for other services running in the same process. | ERROR_DIFFERENT_SERVICE_ACCOUNT
1080 | Failure actions can only be set for Win32 services, not for drivers. | ERROR_CANNOT_DETECT_DRIVER_FAILURE
1081 | This service runs in the same process as the service control manager. Therefore, the service control manager cannot take action if this service's process terminates unexpectedly. | ERROR_CANNOT_DETECT_PROCESS_ABORT
1082 | No recovery program has been configured for this service. | ERROR_NO_RECOVERY_PROGRAM
1100 | The physical end of the tape has been reached. | ERROR_END_OF_MEDIA
1101 | A tape access reached a filemark. | ERROR_FILEMARK_DETECTED
1102 | The beginning of the tape or a partition was encountered. | ERROR_BEGINNING_OF_MEDIA
1103 | A tape access reached the end of a set of files. | ERROR_SETMARK_DETECTED
1104 | No more data is on the tape. | ERROR_NO_DATA_DETECTED
1105 | Tape could not be partitioned. | ERROR_PARTITION_FAILURE
1106 | When accessing a new tape of a multivolume partition, the current blocksize is incorrect. | ERROR_INVALID_BLOCK_LENGTH
1107 | Tape partition information could not be found when loading a tape. | ERROR_DEVICE_NOT_PARTITIONED
1108 | Unable to lock the media eject mechanism. | ERROR_UNABLE_TO_LOCK_MEDIA
1109 | Unable to unload the media. | ERROR_UNABLE_TO_UNLOAD_MEDIA
1110 | The media in the drive may have changed. | ERROR_MEDIA_CHANGED
1111 | The I/O bus was reset. | ERROR_BUS_RESET
1112 | No media in drive. | ERROR_NO_MEDIA_IN_DRIVE
1113 | No mapping for the Unicode character exists in the target multi-byte code page. | ERROR_NO_UNICODE_TRANSLATION
1114 | A dynamic link library (DLL) initialization routine failed. | ERROR_DLL_INIT_FAILED
1115 | A system shutdown is in progress. | ERROR_SHUTDOWN_IN_PROGRESS
1116 | Unable to abort the system shutdown because no shutdown was in progress. | ERROR_NO_SHUTDOWN_IN_PROGRESS
1117 | The request could not be performed because of an I/O device error. | ERROR_IO_DEVICE
1118 | No serial device was successfully initialized. The serial driver will unload. | ERROR_SERIAL_NO_DEVICE
1119 | Unable to open a device that was sharing an interrupt request (IRQ) with other devices. At least one other device that uses that IRQ was already opened. | ERROR_IRQ_BUSY
1120 | A serial I/O operation was completed by another write to the serial port. The IOCTL_SERIAL_XOFF_COUNTER reached zero.) | ERROR_MORE_WRITES
1121 | A serial I/O operation completed because the timeout period expired. The IOCTL_SERIAL_XOFF_COUNTER did not reach zero.) | ERROR_COUNTER_TIMEOUT
1122 | No ID address mark was found on the floppy disk. | ERROR_FLOPPY_ID_MARK_NOT_FOUND
1123 | Mismatch between the floppy disk sector ID field and the floppy disk controller track address. | ERROR_FLOPPY_WRONG_CYLINDER
1124 | The floppy disk controller reported an error that is not recognized by the floppy disk driver. | ERROR_FLOPPY_UNKNOWN_ERROR
1125 | The floppy disk controller returned inconsistent results in its registers. | ERROR_FLOPPY_BAD_REGISTERS
1126 | While accessing the hard disk, a recalibrate operation failed, even after retries. | ERROR_DISK_RECALIBRATE_FAILED
1127 | While accessing the hard disk, a disk operation failed even after retries. | ERROR_DISK_OPERATION_FAILED
1128 | While accessing the hard disk, a disk controller reset was needed, but even that failed. | ERROR_DISK_RESET_FAILED
1129 | Physical end of tape encountered. | ERROR_EOM_OVERFLOW
1130 | Not enough server storage is available to process this command. | ERROR_NOT_ENOUGH_SERVER_MEMORY
1131 | A potential deadlock condition has been detected. | ERROR_POSSIBLE_DEADLOCK
1132 | The base address or the file offset specified does not have the proper alignment. | ERROR_MAPPED_ALIGNMENT
1140 | An attempt to change the system power state was vetoed by another application or driver. | ERROR_SET_POWER_STATE_VETOED
1141 | The system BIOS failed an attempt to change the system power state. | ERROR_SET_POWER_STATE_FAILED
1142 | An attempt was made to create more links on a file than the file system supports. | ERROR_TOO_MANY_LINKS
1150 | The specified program requires a newer version of Windows. | ERROR_OLD_WIN_VERSION
1151 | The specified program is not a Windows or MS-DOS program. | ERROR_APP_WRONG_OS
1152 | Cannot start more than one instance of the specified program. | ERROR_SINGLE_INSTANCE_APP
1153 | The specified program was written for an earlier version of Windows. | ERROR_RMODE_APP
1154 | One of the library files needed to run this application is damaged. | ERROR_INVALID_DLL
1155 | No application is associated with the specified file for this operation. | ERROR_NO_ASSOCIATION
1156 | An error occurred in sending the command to the application. | ERROR_DDE_FAIL
1157 | One of the library files needed to run this application cannot be found. | ERROR_DLL_NOT_FOUND
1158 | The current process has used all of its system allowance of handles for Window Manager objects. | ERROR_NO_MORE_USER_HANDLES
1159 | The message can be used only with synchronous operations. | ERROR_MESSAGE_SYNC_ONLY
1160 | The indicated source element has no media. | ERROR_SOURCE_ELEMENT_EMPTY
1161 | The indicated destination element already contains media. | ERROR_DESTINATION_ELEMENT_FULL
1162 | The indicated element does not exist. | ERROR_ILLEGAL_ELEMENT_ADDRESS
1163 | The indicated element is part of a magazine that is not present. | ERROR_MAGAZINE_NOT_PRESENT
1164 | The indicated device requires reinitialization due to hardware errors. | ERROR_DEVICE_REINITIALIZATION_NEEDED
1165 | The device has indicated that cleaning is required before further operations are attempted. | ERROR_DEVICE_REQUIRES_CLEANING
1166 | The device has indicated that its door is open. | ERROR_DEVICE_DOOR_OPEN
1167 | The device is not connected. | ERROR_DEVICE_NOT_CONNECTED
1168 | Element not found. | ERROR_NOT_FOUND
1169 | There was no match for the specified key in the index. | ERROR_NO_MATCH
1170 | The property set specified does not exist on the object. | ERROR_SET_NOT_FOUND
1171 | The point passed to GetMouseMovePoints is not in the buffer. | ERROR_POINT_NOT_FOUND
1172 | The tracking (workstation) service is not running. | ERROR_NO_TRACKING_SERVICE
1173 | The Volume ID could not be found. | ERROR_NO_VOLUME_ID
1200 | The specified device name is invalid. | ERROR_BAD_DEVICE
1201 | The device is not currently connected but it is a remembered connection. | ERROR_CONNECTION_UNAVAIL
1202 | An attempt was made to remember a device that had previously been remembered. | ERROR_DEVICE_ALREADY_REMEMBERED
1203 | No network provider accepted the given network path. | ERROR_NO_NET_OR_BAD_PATH
1204 | The specified network provider name is invalid. | ERROR_BAD_PROVIDER
1205 | Unable to open the network connection profile. | ERROR_CANNOT_OPEN_PROFILE
1206 | The network connection profile is corrupted. | ERROR_BAD_PROFILE
1207 | Cannot enumerate a noncontainer. | ERROR_NOT_CONTAINER
1208 | An extended error has occurred. | ERROR_EXTENDED_ERROR
1209 | The format of the specified group name is invalid. | ERROR_INVALID_GROUPNAME
1210 | The format of the specified computer name is invalid. | ERROR_INVALID_COMPUTERNAME
1211 | The format of the specified event name is invalid. | ERROR_INVALID_EVENTNAME
1212 | The format of the specified domain name is invalid. | ERROR_INVALID_DOMAINNAME
1213 | The format of the specified service name is invalid. | ERROR_INVALID_SERVICENAME
1214 | The format of the specified network name is invalid. | ERROR_INVALID_NETNAME
1215 | The format of the specified share name is invalid. | ERROR_INVALID_SHARENAME
1216 | The format of the specified password is invalid. | ERROR_INVALID_PASSWORDNAME
1217 | The format of the specified message name is invalid. | ERROR_INVALID_MESSAGENAME
1218 | The format of the specified message destination is invalid. | ERROR_INVALID_MESSAGEDEST
1219 | The credentials supplied conflict with an existing set of credentials. | ERROR_SESSION_CREDENTIAL_CONFLICT
1220 | An attempt was made to establish a session to a network server, but there are already too many sessions established to that server. | ERROR_REMOTE_SESSION_LIMIT_EXCEEDED
1221 | The workgroup or domain name is already in use by another computer on the network. | ERROR_DUP_DOMAINNAME
1222 | The network is not present or not started. | ERROR_NO_NETWORK
1223 | The operation was canceled by the user. | ERROR_CANCELLED
1224 | The requested operation cannot be performed on a file with a user-mapped section open. | ERROR_USER_MAPPED_FILE
1225 | The remote system refused the network connection. | ERROR_CONNECTION_REFUSED
1226 | The network connection was gracefully closed. | ERROR_GRACEFUL_DISCONNECT
1227 | The network transport endpoint already has an address associated with it. | ERROR_ADDRESS_ALREADY_ASSOCIATED
1228 | An address has not yet been associated with the network endpoint. | ERROR_ADDRESS_NOT_ASSOCIATED
1229 | An operation was attempted on a nonexistent network connection. | ERROR_CONNECTION_INVALID
1230 | An invalid operation was attempted on an active network connection. | ERROR_CONNECTION_ACTIVE
1231 | The remote network is not reachable by the transport. | ERROR_NETWORK_UNREACHABLE
1232 | The remote system is not reachable by the transport. | ERROR_HOST_UNREACHABLE
1233 | The remote system does not support the transport protocol. | ERROR_PROTOCOL_UNREACHABLE
1234 | No service is operating at the destination network endpoint on the remote system. | ERROR_PORT_UNREACHABLE
1235 | The request was aborted. | ERROR_REQUEST_ABORTED
1236 | The network connection was aborted by the local system. | ERROR_CONNECTION_ABORTED
1237 | The operation could not be completed. A retry should be performed. | ERROR_RETRY
1238 | A connection to the server could not be made because the limit on the number of concurrent connections for this account has been reached. | ERROR_CONNECTION_COUNT_LIMIT
1239 | Attempting to log in during an unauthorized time of day for this account. | ERROR_LOGIN_TIME_RESTRICTION
1240 | The account is not authorized to log in from this station. | ERROR_LOGIN_WKSTA_RESTRICTION
1241 | The network address could not be used for the operation requested. | ERROR_INCORRECT_ADDRESS
1242 | The service is already registered. | ERROR_ALREADY_REGISTERED
1243 | The specified service does not exist. | ERROR_SERVICE_NOT_FOUND
1244 | The operation being requested was not performed because the user has not been authenticated. | ERROR_NOT_AUTHENTICATED
1245 | The operation being requested was not performed because the user has not logged on to the network. The specified service does not exist. | ERROR_NOT_LOGGED_ON
1246 | Continue with work in progress. | ERROR_CONTINUE
1247 | An attempt was made to perform an initialization operation when initialization has already been completed. | ERROR_ALREADY_INITIALIZED
1248 | No more local devices. | ERROR_NO_MORE_DEVICES
1249 | The specified site does not exist. | ERROR_NO_SUCH_SITE
1250 | A domain controller with the specified name already exists. | ERROR_DOMAIN_CONTROLLER_EXISTS
1251 | An error occurred while installing the Windows NT directory service. Please view the event log for more information. | ERROR_DS_NOT_INSTALLED
1300 | Not all privileges referenced are assigned to the caller. | ERROR_NOT_ALL_ASSIGNED
1301 | Some mapping between account names and security IDs was not done. | ERROR_SOME_NOT_MAPPED
1302 | No system quota limits are specifically set for this account. | ERROR_NO_QUOTAS_FOR_ACCOUNT
1303 | No encryption key is available. A well-known encryption key was returned. | ERROR_LOCAL_USER_SESSION_KEY
1304 | The Windows NT password is too complex to be converted to a LAN Manager password. The LAN Manager password returned is a NULL string. | ERROR_NULL_LM_PASSWORD
1305 | The revision level is unknown. | ERROR_UNKNOWN_REVISION
1306 | Indicates two revision levels are incompatible. | ERROR_REVISION_MISMATCH
1307 | This security ID may not be assigned as the owner of this object. | ERROR_INVALID_OWNER
1308 | This security ID may not be assigned as the primary group of an object. | ERROR_INVALID_PRIMARY_GROUP
1309 | An attempt has been made to operate on an impersonation token by a thread that is not currently impersonating a client. | ERROR_NO_IMPERSONATION_TOKEN
1310 | The group may not be disabled. | ERROR_CANT_DISABLE_MANDATORY
1311 | There are currently no logon servers available to service the logon request. | ERROR_NO_LOGON_SERVERS
1312 | A specified logon session does not exist. It may already have been terminated. | ERROR_NO_SUCH_LOGON_SESSION
1313 | A specified privilege does not exist. | ERROR_NO_SUCH_PRIVILEGE
1314 | A required privilege is not held by the client. | ERROR_PRIVILEGE_NOT_HELD
1315 | The name provided is not a properly formed account name. | ERROR_INVALID_ACCOUNT_NAME
1316 | The specified user already exists. | ERROR_USER_EXISTS
1317 | The specified user does not exist. | ERROR_NO_SUCH_USER
1318 | The specified group already exists. | ERROR_GROUP_EXISTS
1319 | The specified group does not exist. | ERROR_NO_SUCH_GROUP
1320 | Either the specified user account is already a member of the specified group, or the specified group cannot be deleted because it contains a member. | ERROR_MEMBER_IN_GROUP
1321 | The specified user account is not a member of the specified group account. | ERROR_MEMBER_NOT_IN_GROUP
1322 | The last remaining administration account cannot be disabled or deleted. | ERROR_LAST_ADMIN
1323 | Unable to update the password. The value provided as the current password is incorrect. | ERROR_WRONG_PASSWORD
1324 | Unable to update the password. The value provided for the new password contains values that are not allowed in passwords. | ERROR_ILL_FORMED_PASSWORD
1325 | Unable to update the password because a password update rule has been violated. | ERROR_PASSWORD_RESTRICTION
1326 | Logon failure: unknown user name or bad password. | ERROR_LOGON_FAILURE
1327 | Logon failure: user account restriction. | ERROR_ACCOUNT_RESTRICTION
1328 | Logon failure: account logon time restriction violation. | ERROR_INVALID_LOGON_HOURS
1329 | Logon failure: user not allowed to log on to this computer. | ERROR_INVALID_WORKSTATION
1330 | Logon failure: the specified account password has expired. | ERROR_PASSWORD_EXPIRED
1331 | Logon failure: account currently disabled. | ERROR_ACCOUNT_DISABLED
1332 | No mapping between account names and security IDs was done. | ERROR_NONE_MAPPED
1333 | Too many local user identifiers (LUIDs) were requested at one time. | ERROR_TOO_MANY_LUIDS_REQUESTED
1334 | No more local user identifiers (LUIDs) are available. | ERROR_LUIDS_EXHAUSTED
1335 | The subauthority part of a security ID is invalid for this particular use. | ERROR_INVALID_SUB_AUTHORITY
1336 | The access control list (ACL) structure is invalid. | ERROR_INVALID_ACL
1337 | The security ID structure is invalid. | ERROR_INVALID_SID
1338 | The security descriptor structure is invalid. | ERROR_INVALID_SECURITY_DESCR
1340 | The inherited access control list (ACL) or access control entry (ACE) could not be built. | ERROR_BAD_INHERITANCE_ACL
1341 | The server is currently disabled. | ERROR_SERVER_DISABLED
1342 | The server is currently enabled. | ERROR_SERVER_NOT_DISABLED
1343 | The value provided was an invalid value for an identifier authority. | ERROR_INVALID_ID_AUTHORITY
1344 | No more memory is available for security information updates. | ERROR_ALLOTTED_SPACE_EXCEEDED
1345 | The specified attributes are invalid, or incompatible with the attributes for the group as a whole. | ERROR_INVALID_GROUP_ATTRIBUTES
1346 | Either a required impersonation level was not provided, or the provided impersonation level is invalid. | ERROR_BAD_IMPERSONATION_LEVEL
1347 | Cannot open an anonymous level security token. | ERROR_CANT_OPEN_ANONYMOUS
1348 | The validation information class requested was invalid. | ERROR_BAD_VALIDATION_CLASS
1349 | The type of the token is inappropriate for its attempted use. | ERROR_BAD_TOKEN_TYPE
1350 | Unable to perform a security operation on an object that has no associated security. | ERROR_NO_SECURITY_ON_OBJECT
1351 | Indicates a Windows NT Server could not be contacted or that objects within the domain are protected such that necessary information could not be retrieved. | ERROR_CANT_ACCESS_DOMAIN_INFO
1352 | The security account manager (SAM) or local security authority (LSA) server was in the wrong state to perform the security operation. | ERROR_INVALID_SERVER_STATE
1353 | The domain was in the wrong state to perform the security operation. | ERROR_INVALID_DOMAIN_STATE
1354 | This operation is only allowed for the Primary Domain Controller of the domain. | ERROR_INVALID_DOMAIN_ROLE
1355 | The specified domain did not exist. | ERROR_NO_SUCH_DOMAIN
1356 | The specified domain already exists. | ERROR_DOMAIN_EXISTS
1357 | An attempt was made to exceed the limit on the number of domains per server. | ERROR_DOMAIN_LIMIT_EXCEEDED
1358 | Unable to complete the requested operation because of either a catastrophic media failure or a data structure corruption on the disk. | ERROR_INTERNAL_DB_CORRUPTION
1359 | The security account database contains an internal inconsistency. | ERROR_INTERNAL_ERROR
1360 | Generic access types were contained in an access mask which should already be mapped to nongeneric types. | ERROR_GENERIC_NOT_MAPPED
1361 | A security descriptor is not in the right format (absolute or self-relative). | ERROR_BAD_DESCRIPTOR_FORMAT
1362 | The requested action is restricted for use by logon processes only. The calling process has not registered as a logon process. | ERROR_NOT_LOGON_PROCESS
1363 | Cannot start a new logon session with an ID that is already in use. | ERROR_LOGON_SESSION_EXISTS
1364 | A specified authentication package is unknown. | ERROR_NO_SUCH_PACKAGE
1365 | The logon session is not in a state that is consistent with the requested operation. | ERROR_BAD_LOGON_SESSION_STATE
1366 | The logon session ID is already in use. | ERROR_LOGON_SESSION_COLLISION
1367 | A logon request contained an invalid logon type value. | ERROR_INVALID_LOGON_TYPE
1368 | Unable to impersonate using a named pipe until data has been read from that pipe. | ERROR_CANNOT_IMPERSONATE
1369 | The transaction state of a registry subtree is incompatible with the requested operation. | ERROR_RXACT_INVALID_STATE
1370 | An internal security database corruption has been encountered. | ERROR_RXACT_COMMIT_FAILURE
1371 | Cannot perform this operation on built-in accounts. | ERROR_SPECIAL_ACCOUNT
1372 | Cannot perform this operation on this built-in special group. | ERROR_SPECIAL_GROUP
1373 | Cannot perform this operation on this built-in special user. | ERROR_SPECIAL_USER
1374 | The user cannot be removed from a group because the group is currently the user's primary group. | ERROR_MEMBERS_PRIMARY_GROUP
1375 | The token is already in use as a primary token. | ERROR_TOKEN_ALREADY_IN_USE
1376 | The specified local group does not exist. | ERROR_NO_SUCH_ALIAS
1377 | The specified account name is not a member of the local group. | ERROR_MEMBER_NOT_IN_ALIAS
1378 | The specified account name is already a member of the local group. | ERROR_MEMBER_IN_ALIAS
1379 | The specified local group already exists. | ERROR_ALIAS_EXISTS
1380 | Logon failure: the user has not been granted the requested logon type at this computer. | ERROR_LOGON_NOT_GRANTED
1381 | The maximum number of secrets that may be stored in a single system has been exceeded. | ERROR_TOO_MANY_SECRETS
1382 | The length of a secret exceeds the maximum length allowed. | ERROR_SECRET_TOO_LONG
1383 | The local security authority database contains an internal inconsistency. | ERROR_INTERNAL_DB_ERROR
1384 | During a logon attempt, the user's security context accumulated too many security IDs. | ERROR_TOO_MANY_CONTEXT_IDS
1385 | Logon failure: the user has not been granted the requested logon type at this computer. | ERROR_LOGON_TYPE_NOT_GRANTED
1386 | A cross-encrypted password is necessary to change a user password. | ERROR_NT_CROSS_ENCRYPTION_REQUIRED
1387 | A new member could not be added to a local group because the member does not exist. | ERROR_NO_SUCH_MEMBER
1388 | A new member could not be added to a local group because the member has the wrong account type. | ERROR_INVALID_MEMBER
1389 | Too many security IDs have been specified. | ERROR_TOO_MANY_SIDS
1390 | A cross-encrypted password is necessary to change this user password. | ERROR_LM_CROSS_ENCRYPTION_REQUIRED
1391 | Indicates an ACL contains no inheritable components. | ERROR_NO_INHERITANCE
1392 | The file or directory is corrupted and unreadable. | ERROR_FILE_CORRUPT
1393 | The disk structure is corrupted and unreadable. | ERROR_DISK_CORRUPT
1394 | There is no user session key for the specified logon session. | ERROR_NO_USER_SESSION_KEY
1395 | The service being accessed is licensed for a particular number of connections. No more connections can be made to the service at this time because there are already as many connections as the service can accept. | ERROR_LICENSE_QUOTA_EXCEEDED
1400 | Invalid window handle. | ERROR_INVALID_WINDOW_HANDLE
1401 | Invalid menu handle. | ERROR_INVALID_MENU_HANDLE
1402 | Invalid cursor handle. | ERROR_INVALID_CURSOR_HANDLE
1403 | Invalid accelerator table handle. | ERROR_INVALID_ACCEL_HANDLE
1404 | Invalid hook handle. | ERROR_INVALID_HOOK_HANDLE
1405 | Invalid handle to a multiple-window position structure. | ERROR_INVALID_DWP_HANDLE
1406 | Cannot create a top-level child window. | ERROR_TLW_WITH_WSCHILD
1407 | Cannot find window class. | ERROR_CANNOT_FIND_WND_CLASS
1408 | Invalid window; it belongs to other thread. | ERROR_WINDOW_OF_OTHER_THREAD
1409 | Hot key is already registered. | ERROR_HOTKEY_ALREADY_REGISTERED
1410 | Class already exists. | ERROR_CLASS_ALREADY_EXISTS
1411 | Class does not exist. | ERROR_CLASS_DOES_NOT_EXIST
1412 | Class still has open windows. | ERROR_CLASS_HAS_WINDOWS
1413 | Invalid index. | ERROR_INVALID_INDEX
1414 | Invalid icon handle. | ERROR_INVALID_ICON_HANDLE
1415 | Using private DIALOG window words. | ERROR_PRIVATE_DIALOG_INDEX
1416 | The list box identifier was not found. | ERROR_LISTBOX_ID_NOT_FOUND
1417 | No wildcards were found. | ERROR_NO_WILDCARD_CHARACTERS
1418 | Thread does not have a clipboard open. | ERROR_CLIPBOARD_NOT_OPEN
1419 | Hot key is not registered. | ERROR_HOTKEY_NOT_REGISTERED
1420 | The window is not a valid dialog window. | ERROR_WINDOW_NOT_DIALOG
1421 | Control ID not found. | ERROR_CONTROL_ID_NOT_FOUND
1422 | Invalid message for a combo box because it does not have an edit control. | ERROR_INVALID_COMBOBOX_MESSAGE
1423 | The window is not a combo box. | ERROR_WINDOW_NOT_COMBOBOX
1424 | Height must be less than 256. | ERROR_INVALID_EDIT_HEIGHT
1425 | Invalid device context (DC) handle. | ERROR_DC_NOT_FOUND
1426 | Invalid hook procedure type. | ERROR_INVALID_HOOK_FILTER
1427 | Invalid hook procedure. | ERROR_INVALID_FILTER_PROC
1428 | Cannot set nonlocal hook without a module handle. | ERROR_HOOK_NEEDS_HMOD
1429 | This hook procedure can only be set globally. | ERROR_GLOBAL_ONLY_HOOK
1430 | The journal hook procedure is already installed. | ERROR_JOURNAL_HOOK_SET
1431 | The hook procedure is not installed. | ERROR_HOOK_NOT_INSTALLED
1432 | Invalid message for single-selection list box. | ERROR_INVALID_LB_MESSAGE
1433 | LB_SETCOUNT sent to non-lazy list box. | ERROR_SETCOUNT_ON_BAD_LB
1434 | This list box does not support tab stops. | ERROR_LB_WITHOUT_TABSTOPS
1435 | Cannot destroy object created by another thread. | ERROR_DESTROY_OBJECT_OF_OTHER_THREAD
1436 | Child windows cannot have menus. | ERROR_CHILD_WINDOW_MENU
1437 | The window does not have a system menu. | ERROR_NO_SYSTEM_MENU
1438 | Invalid message box style. | ERROR_INVALID_MSGBOX_STYLE
1439 | Invalid system-wide (SPI_*) parameter. | ERROR_INVALID_SPI_VALUE
1440 | Screen already locked. | ERROR_SCREEN_ALREADY_LOCKED
1441 | All handles to windows in a multiple-window position structure must have the same parent. | ERROR_HWNDS_HAVE_DIFF_PARENT
1442 | The window is not a child window. | ERROR_NOT_CHILD_WINDOW
1443 | Invalid GW_* command. | ERROR_INVALID_GW_COMMAND
1444 | Invalid thread identifier. | ERROR_INVALID_THREAD_ID
1445 | Cannot process a message from a window that is not a multiple document interface (MDI) window. | ERROR_NON_MDICHILD_WINDOW
1446 | Popup menu already active. | ERROR_POPUP_ALREADY_ACTIVE
1447 | The window does not have scroll bars. | ERROR_NO_SCROLLBARS
1448 | Scroll bar range cannot be greater than 0x7FFF. | ERROR_INVALID_SCROLLBAR_RANGE
1449 | Cannot show or remove the window in the way specified. | ERROR_INVALID_SHOWWIN_COMMAND
1450 | Insufficient system resources exist to complete the requested service. | ERROR_NO_SYSTEM_RESOURCES
1451 | Insufficient system resources exist to complete the requested service. | ERROR_NONPAGED_SYSTEM_RESOURCES
1452 | Insufficient system resources exist to complete the requested service. | ERROR_PAGED_SYSTEM_RESOURCES
1453 | Insufficient quota to complete the requested service. | ERROR_WORKING_SET_QUOTA
1454 | Insufficient quota to complete the requested service. | ERROR_PAGEFILE_QUOTA
1455 | The paging file is too small for this operation to complete. | ERROR_COMMITMENT_LIMIT
1456 | A menu item was not found. | ERROR_MENU_ITEM_NOT_FOUND
1457 | Invalid keyboard layout handle. | ERROR_INVALID_KEYBOARD_HANDLE
1458 | Hook type not allowed. | ERROR_HOOK_TYPE_NOT_ALLOWED
1459 | This operation requires an interactive window station. | ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
1460 | This operation returned because the timeout period expired. | ERROR_TIMEOUT
1461 | Invalid monitor handle. | ERROR_INVALID_MONITOR_HANDLE
1500 | The event log file is corrupted. | ERROR_EVENTLOG_FILE_CORRUPT
1501 | No event log file could be opened, so the event logging service did not start. | ERROR_EVENTLOG_CANT_START
1502 | The event log file is full. | ERROR_LOG_FILE_FULL
1503 | The event log file has changed between read operations. | ERROR_EVENTLOG_FILE_CHANGED
1601 | Failure accessing install service. | ERROR_INSTALL_SERVICE
1602 | The user canceled the installation. | ERROR_INSTALL_USEREXIT
1603 | Fatal error during installation. | ERROR_INSTALL_FAILURE
1604 | Installation suspended, incomplete. | ERROR_INSTALL_SUSPEND
1605 | Product code not registered. | ERROR_UNKNOWN_PRODUCT
1606 | Feature ID not registered. | ERROR_UNKNOWN_FEATURE
1607 | Component ID not registered. | ERROR_UNKNOWN_COMPONENT
1608 | Unknown property. | ERROR_UNKNOWN_PROPERTY
1609 | Handle is in an invalid state. | ERROR_INVALID_HANDLE_STATE
1610 | Configuration data corrupt. | ERROR_BAD_CONFIGURATION
1611 | Language not available. | ERROR_INDEX_ABSENT
1612 | Install source unavailable. | ERROR_INSTALL_SOURCE_ABSENT
1613 | Database version unsupported. | ERROR_BAD_DATABASE_VERSION
1614 | Product is uninstalled. | ERROR_PRODUCT_UNINSTALLED
1615 | SQL query syntax invalid or unsupported. | ERROR_BAD_QUERY_SYNTAX
1616 | Record field does not exist. | ERROR_INVALID_FIELD
1700 | The string binding is invalid. | RPC_S_INVALID_STRING_BINDING
1701 | The binding handle is not the correct type. | RPC_S_WRONG_KIND_OF_BINDING
1702 | The binding handle is invalid. | RPC_S_INVALID_BINDING
1703 | The RPC protocol sequence is not supported. | RPC_S_PROTSEQ_NOT_SUPPORTED
1704 | The RPC protocol sequence is invalid. | RPC_S_INVALID_RPC_PROTSEQ
1705 | The string universal unique identifier (UUID) is invalid. | RPC_S_INVALID_STRING_UUID
1706 | The endpoint format is invalid. | RPC_S_INVALID_ENDPOINT_FORMAT
1707 | The network address is invalid. | RPC_S_INVALID_NET_ADDR
1708 | No endpoint was found. | RPC_S_NO_ENDPOINT_FOUND
1709 | The timeout value is invalid. | RPC_S_INVALID_TIMEOUT
1710 | The object universal unique identifier (UUID) was not found. | RPC_S_OBJECT_NOT_FOUND
1711 | The object universal unique identifier (UUID) has already been registered. | RPC_S_ALREADY_REGISTERED
1712 | The type universal unique identifier (UUID) has already been registered. | RPC_S_TYPE_ALREADY_REGISTERED
1713 | The RPC server is already listening. | RPC_S_ALREADY_LISTENING
1714 | No protocol sequences have been registered. | RPC_S_NO_PROTSEQS_REGISTERED
1715 | The RPC server is not listening. | RPC_S_NOT_LISTENING
1716 | The manager type is unknown. | RPC_S_UNKNOWN_MGR_TYPE
1717 | The interface is unknown. | RPC_S_UNKNOWN_IF
1718 | There are no bindings. | RPC_S_NO_BINDINGS
1719 | There are no protocol sequences. | RPC_S_NO_PROTSEQS
1720 | The endpoint cannot be created. | RPC_S_CANT_CREATE_ENDPOINT
1721 | Not enough resources are available to complete this operation. | RPC_S_OUT_OF_RESOURCES
1722 | The RPC server is unavailable. | RPC_S_SERVER_UNAVAILABLE
1723 | The RPC server is too busy to complete this operation. | RPC_S_SERVER_TOO_BUSY
1724 | The network options are invalid. | RPC_S_INVALID_NETWORK_OPTIONS
1725 | There are no remote procedure calls active on this thread. | RPC_S_NO_CALL_ACTIVE
1726 | The remote procedure call failed. | RPC_S_CALL_FAILED
1727 | The remote procedure call failed and did not execute. | RPC_S_CALL_FAILED_DNE
1728 | A remote procedure call (RPC) protocol error occurred. | RPC_S_PROTOCOL_ERROR
1730 | The transfer syntax is not supported by the RPC server. | RPC_S_UNSUPPORTED_TRANS_SYN
1732 | The universal unique identifier (UUID) type is not supported. | RPC_S_UNSUPPORTED_TYPE
1733 | The tag is invalid. | RPC_S_INVALID_TAG
1734 | The array bounds are invalid. | RPC_S_INVALID_BOUND
1735 | The binding does not contain an entry name. | RPC_S_NO_ENTRY_NAME
1736 | The name syntax is invalid. | RPC_S_INVALID_NAME_SYNTAX
1737 | The name syntax is not supported. | RPC_S_UNSUPPORTED_NAME_SYNTAX
1739 | No network address is available to use to construct a universal unique identifier (UUID). | RPC_S_UUID_NO_ADDRESS
1740 | The endpoint is a duplicate. | RPC_S_DUPLICATE_ENDPOINT
1741 | The authentication type is unknown. | RPC_S_UNKNOWN_AUTHN_TYPE
1742 | The maximum number of calls is too small. | RPC_S_MAX_CALLS_TOO_SMALL
1743 | The string is too long. | RPC_S_STRING_TOO_LONG
1744 | The RPC protocol sequence was not found. | RPC_S_PROTSEQ_NOT_FOUND
1745 | The procedure number is out of range. | RPC_S_PROCNUM_OUT_OF_RANGE
1746 | The binding does not contain any authentication information. | RPC_S_BINDING_HAS_NO_AUTH
1747 | The authentication service is unknown. | RPC_S_UNKNOWN_AUTHN_SERVICE
1748 | The authentication level is unknown. | RPC_S_UNKNOWN_AUTHN_LEVEL
1749 | The security context is invalid. | RPC_S_INVALID_AUTH_IDENTITY
1750 | The authorization service is unknown. | RPC_S_UNKNOWN_AUTHZ_SERVICE
1751 | The entry is invalid. | EPT_S_INVALID_ENTRY
1752 | The server endpoint cannot perform the operation. | EPT_S_CANT_PERFORM_OP
1753 | There are no more endpoints available from the endpoint mapper. | EPT_S_NOT_REGISTERED
1754 | No interfaces have been exported. | RPC_S_NOTHING_TO_EXPORT
1755 | The entry name is incomplete. | RPC_S_INCOMPLETE_NAME
1756 | The version option is invalid. | RPC_S_INVALID_VERS_OPTION
1757 | There are no more members. | RPC_S_NO_MORE_MEMBERS
1758 | There is nothing to unexport. | RPC_S_NOT_ALL_OBJS_UNEXPORTED
1759 | The interface was not found. | RPC_S_INTERFACE_NOT_FOUND
1760 | The entry already exists. | RPC_S_ENTRY_ALREADY_EXISTS
1761 | The entry is not found. | RPC_S_ENTRY_NOT_FOUND
1762 | The name service is unavailable. | RPC_S_NAME_SERVICE_UNAVAILABLE
1763 | The network address family is invalid. | RPC_S_INVALID_NAF_ID
1764 | The requested operation is not supported. | RPC_S_CANNOT_SUPPORT
1765 | No security context is available to allow impersonation. | RPC_S_NO_CONTEXT_AVAILABLE
1766 | An internal error occurred in a remote procedure call (RPC). | RPC_S_INTERNAL_ERROR
1767 | The RPC server attempted an integer division by zero. | RPC_S_ZERO_DIVIDE
1768 | An addressing error occurred in the RPC server. | RPC_S_ADDRESS_ERROR
1769 | A floating-point operation at the RPC server caused a division by zero. | RPC_S_FP_DIV_ZERO
1770 | A floating-point underflow occurred at the RPC server. | RPC_S_FP_UNDERFLOW
1771 | A floating-point overflow occurred at the RPC server. | RPC_S_FP_OVERFLOW
1772 | The list of RPC servers available for the binding of auto handles has been exhausted. | RPC_X_NO_MORE_ENTRIES
1773 | Unable to open the character translation table file. | RPC_X_SS_CHAR_TRANS_OPEN_FAIL
1774 | The file containing the character translation table has fewer than bytes. | RPC_X_SS_CHAR_TRANS_SHORT_FILE
1775 | A null context handle was passed from the client to the host during a remote procedure call. | RPC_X_SS_IN_NULL_CONTEXT
1777 | The context handle changed during a remote procedure call. | RPC_X_SS_CONTEXT_DAMAGED
1778 | The binding handles passed to a remote procedure call do not match. | RPC_X_SS_HANDLES_MISMATCH
1779 | The stub is unable to get the remote procedure call handle. | RPC_X_SS_CANNOT_GET_CALL_HANDLE
1780 | A null reference pointer was passed to the stub. | RPC_X_NULL_REF_POINTER
1781 | The enumeration value is out of range. | RPC_X_ENUM_VALUE_OUT_OF_RANGE
1782 | The byte count is too small. | RPC_X_BYTE_COUNT_TOO_SMALL
1783 | The stub received bad data. | RPC_X_BAD_STUB_DATA
1784 | The supplied user buffer is not valid for the requested operation. | ERROR_INVALID_USER_BUFFER
1785 | The disk media is not recognized. It may not be formatted. | ERROR_UNRECOGNIZED_MEDIA
1786 | The workstation does not have a trust secret. | ERROR_NO_TRUST_LSA_SECRET
1787 | The SAM database on the Windows NT Server does not have a computer account for this workstation trust relationship. | ERROR_NO_TRUST_SAM_ACCOUNT
1788 | The trust relationship between the primary domain and the trusted domain failed. | ERROR_TRUSTED_DOMAIN_FAILURE
1789 | The trust relationship between this workstation and the primary domain failed. | ERROR_TRUSTED_RELATIONSHIP_FAILURE
1790 | The network logon failed. | ERROR_TRUST_FAILURE
1791 | A remote procedure call is already in progress for this thread. | RPC_S_CALL_IN_PROGRESS
1792 | An attempt was made to logon, but the network logon service was not started. | ERROR_NETLOGON_NOT_STARTED
1793 | The user's account has expired. | ERROR_ACCOUNT_EXPIRED
1794 | The redirector is in use and cannot be unloaded. | ERROR_REDIRECTOR_HAS_OPEN_HANDLES
1795 | The specified printer driver is already installed. | ERROR_PRINTER_DRIVER_ALREADY_INSTALLED
1796 | The specified port is unknown. | ERROR_UNKNOWN_PORT
1797 | The printer driver is unknown. | ERROR_UNKNOWN_PRINTER_DRIVER
1798 | The print processor is unknown. | ERROR_UNKNOWN_PRINTPROCESSOR
1799 | The specified separator file is invalid. | ERROR_INVALID_SEPARATOR_FILE
1800 | The specified priority is invalid. | ERROR_INVALID_PRIORITY
1801 | The printer name is invalid. | ERROR_INVALID_PRINTER_NAME
1802 | The printer already exists. | ERROR_PRINTER_ALREADY_EXISTS
1803 | The printer command is invalid. | ERROR_INVALID_PRINTER_COMMAND
1804 | The specified datatype is invalid. | ERROR_INVALID_DATATYPE
1805 | The environment specified is invalid. | ERROR_INVALID_ENVIRONMENT
1806 | There are no more bindings. | RPC_S_NO_MORE_BINDINGS
1807 | The account used is an interdomain trust account. Use your global user account or local user account to access this server. | ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT
1808 | The account used is a computer account. Use your global user account or local user account to access this server. | ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT
1809 | The account used is a server trust account. Use your global user account or local user account to access this server. | ERROR_NOLOGON_SERVER_TRUST_ACCOUNT
1810 | The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain. | ERROR_DOMAIN_TRUST_INCONSISTENT
1811 | The server is in use and cannot be unloaded. | ERROR_SERVER_HAS_OPEN_HANDLES
1812 | The specified image file did not contain a resource section. | ERROR_RESOURCE_DATA_NOT_FOUND
1813 | The specified resource type cannot be found in the image file. | ERROR_RESOURCE_TYPE_NOT_FOUND
1814 | The specified resource name cannot be found in the image file. | ERROR_RESOURCE_NAME_NOT_FOUND
1815 | The specified resource language ID cannot be found in the image file. | ERROR_RESOURCE_LANG_NOT_FOUND
1816 | Not enough quota is available to process this command. | ERROR_NOT_ENOUGH_QUOTA
1817 | No interfaces have been registered. | RPC_S_NO_INTERFACES
1818 | The remote procedure call was cancelled. | RPC_S_CALL_CANCELLED
1819 | The binding handle does not contain all required information. | RPC_S_BINDING_INCOMPLETE
1820 | A communications failure occurred during a remote procedure call. | RPC_S_COMM_FAILURE
1821 | The requested authentication level is not supported. | RPC_S_UNSUPPORTED_AUTHN_LEVEL
1822 | No principal name registered. | RPC_S_NO_PRINC_NAME
1823 | The error specified is not a valid Windows RPC error code. | RPC_S_NOT_RPC_ERROR
1824 | A UUID that is valid only on this computer has been allocated. | RPC_S_UUID_LOCAL_ONLY
1825 | A security package specific error occurred. | RPC_S_SEC_PKG_ERROR
1826 | Thread is not canceled. | RPC_S_NOT_CANCELLED
1827 | Invalid operation on the encoding/decoding handle. | RPC_X_INVALID_ES_ACTION
1828 | Incompatible version of the serializing package. | RPC_X_WRONG_ES_VERSION
1829 | Incompatible version of the RPC stub. | RPC_X_WRONG_STUB_VERSION
1830 | The RPC pipe object is invalid or corrupted. | RPC_X_INVALID_PIPE_OBJECT
1831 | An invalid operation was attempted on an RPC pipe object. | RPC_X_WRONG_PIPE_ORDER
1832 | Unsupported RPC pipe version. | RPC_X_WRONG_PIPE_VERSION
1898 | The group member was not found. | RPC_S_GROUP_MEMBER_NOT_FOUND
1899 | The endpoint mapper database entry could not be created. | EPT_S_CANT_CREATE
1900 | The object universal unique identifier (UUID) is the nil UUID. | RPC_S_INVALID_OBJECT
1901 | The specified time is invalid. | ERROR_INVALID_TIME
1902 | The specified form name is invalid. | ERROR_INVALID_FORM_NAME
1903 | The specified form size is invalid. | ERROR_INVALID_FORM_SIZE
1904 | The specified printer handle is already being waited on | ERROR_ALREADY_WAITING
1905 | The specified printer has been deleted. | ERROR_PRINTER_DELETED
1906 | The state of the printer is invalid. | ERROR_INVALID_PRINTER_STATE
1907 | The user must change his password before he logs on the first time. | ERROR_PASSWORD_MUST_CHANGE
1908 | Could not find the domain controller for this domain. | ERROR_DOMAIN_CONTROLLER_NOT_FOUND
1909 | The referenced account is currently locked out and may not be logged on to. | ERROR_ACCOUNT_LOCKED_OUT
1910 | The object exporter specified was not found. | OR_INVALID_OXID
1911 | The object specified was not found. | OR_INVALID_OID
1912 | The object resolver set specified was not found. | OR_INVALID_SET
1913 | Some data remains to be sent in the request buffer. | RPC_S_SEND_INCOMPLETE
1914 | Invalid asynchronous remote procedure call handle. | RPC_S_INVALID_ASYNC_HANDLE
1915 | Invalid asynchronous RPC call handle for this operation. | RPC_S_INVALID_ASYNC_CALL
1916 | The RPC pipe object has already been closed. | RPC_X_PIPE_CLOSED
1917 | The RPC call completed before all pipes were processed. | RPC_X_PIPE_DISCIPLINE_ERROR
1918 | No more data is available from the RPC pipe. | RPC_X_PIPE_EMPTY
1919 | No site name is available for this machine. | ERROR_NO_SITENAME
1920 | The file can not be accessed by the system. | ERROR_CANT_ACCESS_FILE
1921 | The name of the file cannot be resolved by the system. | ERROR_CANT_RESOLVE_FILENAME
1922 | The directory service evaluated group memberships locally. | ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY
1923 | The specified directory service attribute or value does not exist. | ERROR_DS_NO_ATTRIBUTE_OR_VALUE
1924 | The attribute syntax specified to the directory service is invalid. | ERROR_DS_INVALID_ATTRIBUTE_SYNTAX
1925 | The attribute type specified to the directory service is not defined. | ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED
1926 | The specified directory service attribute or value already exists. | ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS
1927 | The directory service is busy. | ERROR_DS_BUSY
1928 | The directory service is unavailable. | ERROR_DS_UNAVAILABLE
1929 | The directory service was unable to allocate a relative identifier. | ERROR_DS_NO_RIDS_ALLOCATED
1930 | The directory service has exhausted the pool of relative identifiers. | ERROR_DS_NO_MORE_RIDS
1931 | The requested operation could not be performed because the directory service is not the master for that type of operation. | ERROR_DS_INCORRECT_ROLE_OWNER
1932 | The directory service was unable to initialize the subsystem that allocates relative identifiers. | ERROR_DS_RIDMGR_INIT_ERROR
1933 | The requested operation did not satisfy one or more constraints associated with the class of the object. | ERROR_DS_OBJ_CLASS_VIOLATION
1934 | The directory service can perform the requested operation only on a leaf object. | ERROR_DS_CANT_ON_NON_LEAF
1935 | The directory service cannot perform the requested operation on the RDN attribute of an object. | ERROR_DS_CANT_ON_RDN
1936 | The directory service detected an attempt to modify the object class of an object. | ERROR_DS_CANT_MOD_OBJ_CLASS
1937 | The requested cross domain move operation could not be performed. | ERROR_DS_CROSS_DOM_MOVE_ERROR
1938 | Unable to contact the global catalog server. | ERROR_DS_GC_NOT_AVAILABLE
2000 | The pixel format is invalid. | ERROR_INVALID_PIXEL_FORMAT
2001 | The specified driver is invalid. | ERROR_BAD_DRIVER
2002 | The window style or class attribute is invalid for this operation. | ERROR_INVALID_WINDOW_STYLE
2003 | The requested metafile operation is not supported. | ERROR_METAFILE_NOT_SUPPORTED
2004 | The requested transformation operation is not supported. | ERROR_TRANSFORM_NOT_SUPPORTED
2005 | The requested clipping operation is not supported. | ERROR_CLIPPING_NOT_SUPPORTED
2108 | The network connection was made successfully, but the user had to be prompted for a password other than the one originally specified. | ERROR_CONNECTED_OTHER_PASSWORD
2202 | The specified username is invalid. | ERROR_BAD_USERNAME
2250 | This network connection does not exist. | ERROR_NOT_CONNECTED
2300 | The specified color management module is invalid. | ERROR_INVALID_CMM
2301 | The specified color profile is invalid. | ERROR_INVALID_PROFILE
2302 | The specified tag was not found. | ERROR_TAG_NOT_FOUND
2303 | A required tag is not present. | ERROR_TAG_NOT_PRESENT
2304 | The specified tag is already present. | ERROR_DUPLICATE_TAG
2305 | The specified color profile is not associated with any device. | ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE
2306 | The specified color profile was not found. | ERROR_PROFILE_NOT_FOUND
2307 | The specified color space is invalid. | ERROR_INVALID_COLORSPACE
2308 | Image Color Management is not enabled. | ERROR_ICM_NOT_ENABLED
2309 | There was an error while deleting the color transform. | ERROR_DELETING_ICM_XFORM
2310 | The specified color transform is invalid. | ERROR_INVALID_TRANSFORM
2401 | This network connection has files open or requests pending. | ERROR_OPEN_FILES
2402 | Active connections still exist. | ERROR_ACTIVE_CONNECTIONS
2404 | The device is in use by an active process and cannot be disconnected. | ERROR_DEVICE_IN_USE
3000 | The specified print monitor is unknown. | ERROR_UNKNOWN_PRINT_MONITOR
3001 | The specified printer driver is currently in use. | ERROR_PRINTER_DRIVER_IN_USE
3002 | The spool file was not found. | ERROR_SPOOL_FILE_NOT_FOUND
3003 | A StartDocPrinter call was not issued. | ERROR_SPL_NO_STARTDOC
3004 | An AddJob call was not issued. | ERROR_SPL_NO_ADDJOB
3005 | The specified print processor has already been installed. | ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED
3006 | The specified print monitor has already been installed. | ERROR_PRINT_MONITOR_ALREADY_INSTALLED
3007 | The specified print monitor does not have the required functions. | ERROR_INVALID_PRINT_MONITOR
3008 | The specified print monitor is currently in use. | ERROR_PRINT_MONITOR_IN_USE
3009 | The requested operation is not allowed when there are jobs queued to the printer. | ERROR_PRINTER_HAS_JOBS_QUEUED
3010 | The requested operation is successful. Changes will not be effective until the system is rebooted. | ERROR_SUCCESS_REBOOT_REQUIRED
3011 | The requested operation is successful. Changes will not be effective until the service is restarted. | ERROR_SUCCESS_RESTART_REQUIRED
4000 | WINS encountered an error while processing the command. | ERROR_WINS_INTERNAL
4001 | The local WINS can not be deleted. | ERROR_CAN_NOT_DEL_LOCAL_WINS
4002 | The importation from the file failed. | ERROR_STATIC_INIT
4003 | The backup failed. Was a full backup done before? | ERROR_INC_BACKUP
4004 | The backup failed. Check the directory to which you are backing the database. | ERROR_FULL_BACKUP
4005 | The name does not exist in the WINS database. | ERROR_REC_NON_EXISTENT
4006 | Replication with a nonconfigured partner is not allowed. | ERROR_RPL_NOT_ALLOWED
4100 | The DHCP client has obtained an IP address that is already in use on the network. The local interface will be disabled until the DHCP client can obtain a new address. | ERROR_DHCP_ADDRESS_CONFLICT
4200 | The GUID passed was not recognized as valid by a WMI data provider. | ERROR_WMI_GUID_NOT_FOUND
4201 | The instance name passed was not recognized as valid by a WMI data provider. | ERROR_WMI_INSTANCE_NOT_FOUND
4202 | The data item ID passed was not recognized as valid by a WMI data provider. | ERROR_WMI_ITEMID_NOT_FOUND
4203 | The WMI request could not be completed and should be retried. | ERROR_WMI_TRY_AGAIN
4204 | The WMI data provider could not be located. | ERROR_WMI_DP_NOT_FOUND
4205 | The WMI data provider references an instance set that has not been registered. | ERROR_WMI_UNRESOLVED_INSTANCE_REF
4206 | The WMI data block or event notification has already been enabled. | ERROR_WMI_ALREADY_ENABLED
4207 | The WMI data block is no longer available. | ERROR_WMI_GUID_DISCONNECTED
4208 | The WMI data service is not available. | ERROR_WMI_SERVER_UNAVAILABLE
4209 | The WMI data provider failed to carry out the request. | ERROR_WMI_DP_FAILED
4210 | The WMI MOF information is not valid. | ERROR_WMI_INVALID_MOF
4211 | The WMI registration information is not valid. | ERROR_WMI_INVALID_REGINFO
4300 | The media identifier does not represent a valid medium. | ERROR_INVALID_MEDIA
4301 | The library identifier does not represent a valid library. | ERROR_INVALID_LIBRARY
4302 | The media pool identifier does not represent a valid media pool. | ERROR_INVALID_MEDIA_POOL
4303 | The drive and medium are not compatible or exist in different libraries. | ERROR_DRIVE_MEDIA_MISMATCH
4304 | The medium currently exists in an offline library and must be online to perform this operation. | ERROR_MEDIA_OFFLINE
4305 | The operation cannot be performed on an offline library. | ERROR_LIBRARY_OFFLINE
4306 | The library, drive, or media pool is empty. | ERROR_EMPTY
4307 | The library, drive, or media pool must be empty to perform this operation. | ERROR_NOT_EMPTY
4308 | No media is currently available in this media pool or library. | ERROR_MEDIA_UNAVAILABLE
4309 | A resource required for this operation is disabled. | ERROR_RESOURCE_DISABLED
4310 | The media identifier does not represent a valid cleaner. | ERROR_INVALID_CLEANER
4311 | The drive cannot be cleaned or does not support cleaning. | ERROR_UNABLE_TO_CLEAN
4312 | The object identifier does not represent a valid object. | ERROR_OBJECT_NOT_FOUND
4313 | Unable to read from or write to the database. | ERROR_DATABASE_FAILURE
4314 | The database is full. | ERROR_DATABASE_FULL
4315 | The medium is not compatible with the device or media pool. | ERROR_MEDIA_INCOMPATIBLE
4316 | The resource required for this operation does not exist. | ERROR_RESOURCE_NOT_PRESENT
4317 | The operation identifier is not valid. | ERROR_INVALID_OPERATION
4318 | The media is not mounted or ready for use. | ERROR_MEDIA_NOT_AVAILABLE
4319 | The device is not ready for use. | ERROR_DEVICE_NOT_AVAILABLE
4320 | The operator or administrator has refused the request. | ERROR_REQUEST_REFUSED
4350 | The remote storage service was not able to recall the file. | ERROR_FILE_OFFLINE
4351 | The remote storage service is not operational at this time. | ERROR_REMOTE_STORAGE_NOT_ACTIVE
4352 | The remote storage service encountered a media error. | ERROR_REMOTE_STORAGE_MEDIA_ERROR
4390 | The file or directory is not a reparse point. | ERROR_NOT_A_REPARSE_POINT
4391 | The reparse point attribute cannot be set because it conflicts with an existing attribute. | ERROR_REPARSE_ATTRIBUTE_CONFLICT
5001 | The cluster resource cannot be moved to another group because other resources are dependent on it. | ERROR_DEPENDENT_RESOURCE_EXISTS
5002 | The cluster resource dependency cannot be found. | ERROR_DEPENDENCY_NOT_FOUND
5003 | The cluster resource cannot be made dependent on the specified resource because it is already dependent. | ERROR_DEPENDENCY_ALREADY_EXISTS
5004 | The cluster resource is not online. | ERROR_RESOURCE_NOT_ONLINE
5005 | A cluster node is not available for this operation. | ERROR_HOST_NODE_NOT_AVAILABLE
5006 | The cluster resource is not available. | ERROR_RESOURCE_NOT_AVAILABLE
5007 | The cluster resource could not be found. | ERROR_RESOURCE_NOT_FOUND
5008 | The cluster is being shut down. | ERROR_SHUTDOWN_CLUSTER
5009 | A cluster node cannot be evicted from the cluster while it is online. | ERROR_CANT_EVICT_ACTIVE_NODE
5010 | The object already exists. | ERROR_OBJECT_ALREADY_EXISTS
5011 | The object is already in the list. | ERROR_OBJECT_IN_LIST
5012 | The cluster group is not available for any new requests. | ERROR_GROUP_NOT_AVAILABLE
5013 | The cluster group could not be found. | ERROR_GROUP_NOT_FOUND
5014 | The operation could not be completed because the cluster group is not online. | ERROR_GROUP_NOT_ONLINE
5015 | The cluster node is not the owner of the resource. | ERROR_HOST_NODE_NOT_RESOURCE_OWNER
5016 | The cluster node is not the owner of the group. | ERROR_HOST_NODE_NOT_GROUP_OWNER
5017 | The cluster resource could not be created in the specified resource monitor. | ERROR_RESMON_CREATE_FAILED
5018 | The cluster resource could not be brought online by the resource monitor. | ERROR_RESMON_ONLINE_FAILED
5019 | The operation could not be completed because the cluster resource is online. | ERROR_RESOURCE_ONLINE
5020 | The cluster resource could not be deleted or brought offline because it is the quorum resource. | ERROR_QUORUM_RESOURCE
5021 | The cluster could not make the specified resource a quorum resource because it is not capable of being a quorum resource. | ERROR_NOT_QUORUM_CAPABLE
5022 | The cluster software is shutting down. | ERROR_CLUSTER_SHUTTING_DOWN
5023 | The group or resource is not in the correct state to perform the requested operation. | ERROR_INVALID_STATE
5024 | The properties were stored but not all changes will take effect until the next time the resource is brought online. | ERROR_RESOURCE_PROPERTIES_STORED
5025 | The cluster could not make the specified resource a quorum resource because it does not belong to a shared storage class. | ERROR_NOT_QUORUM_CLASS
5026 | The cluster resource could not be deleted since it is a core resource. | ERROR_CORE_RESOURCE
5027 | The quorum resource failed to come online. | ERROR_QUORUM_RESOURCE_ONLINE_FAILED
5028 | The quorum log could not be created or mounted successfully. | ERROR_QUORUMLOG_OPEN_FAILED
5029 | The cluster log is corrupt. | ERROR_CLUSTERLOG_CORRUPT
5030 | The record could not be written to the cluster log since it exceeds the maximum size. | ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE
5031 | The cluster log exceeds its maximum size. | ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE
5032 | No checkpoint record was found in the cluster log. | ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND
5033 | The minimum required disk space needed for logging is not available. | ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE
6000 | The specified file could not be encrypted. | ERROR_ENCRYPTION_FAILED
6001 | The specified file could not be decrypted. | ERROR_DECRYPTION_FAILED
6002 | The specified file is encrypted and the user does not have the ability to decrypt it. | ERROR_FILE_ENCRYPTED
6003 | There is no encryption recovery policy configured for this system. | ERROR_NO_RECOVERY_POLICY
6004 | The required encryption driver is not loaded for this system. | ERROR_NO_EFS
6005 | The file was encrypted with a different encryption driver than is currently loaded. | ERROR_WRONG_EFS
6006 | There are no EFS keys defined for the user. | ERROR_NO_USER_KEYS
6007 | The specified file is not encrypted. | ERROR_FILE_NOT_ENCRYPTED
6008 | The specified file is not in the defined EFS export format. | ERROR_NOT_EXPORT_FORMAT
6118 | The list of servers for this workgroup is not currently available | ERROR_NO_BROWSER_SERVERS_FOUND


Net Errors - Alphabetical Order

The following table provides a list of network error codes.

Name | Description | Code
NERR_AccountExpired | This user account has expired. | 2239
NERR_AccountUndefined | This user account is undefined. | 2238
NERR_AcctLimitExceeded | A user's session with this server has been deleted | 2434
NERR_ACFFileIOFail | A disk I/O failure occurred. | 2229
NERR_ACFNoParent | The parent directory could not be located. | 2232
NERR_ACFNoRoom | There are too many names in the user accounts database. | 2228
NERR_ACFNotFound | The security database could not be found. | 2219
NERR_ACFNotLoaded | The security database has not been started. | 2227
NERR_ACFTooManyLists | The limit of 64 entries per resource was exceeded. | 2230
NERR_ActiveConns | Active connections still exist. | 2402
NERR_AddForwarded | This message alias has been added but is still forwarded. | 2275
NERR_AlertExists | The specified client is already registered for the specified event. | 2430
NERR_AlreadyExists | This message alias already exists locally. | 2276
NERR_AlreadyForwarded | This message alias has already been forwarded. | 2274
NERR_AlreadyLoggedOn | This workstation is already logged on to the local-area network. | 2200
NERR_BadAsgType | This asg_type is invalid. | 2251
NERR_BadComponent | This path component is invalid. | 2356
NERR_BadControlRecv | The service control dispatcher pipe read failed. | 2193
NERR_BadDest | The destination path is illegal. | 2382
NERR_BadDev | The requested device is invalid. | 2341
NERR_BadDevString | This list of devices is invalid. | 2340
NERR_BadDosFunction | The program below called an unsupported MS-DOS function: | 2502
NERR_BadDosRetCode | The program below returned an MS-DOS error code: | 2500
NERR_BadEventName | The event name is invalid. | 2143
NERR_BadFileCheckSum | The file below is corrupt. | 2504
NERR_BadPassword | The password parameter is invalid. | 2203
NERR_BadPasswordCore | This share name or password is invalid. | 2403
NERR_BadQueueDevString | This device name list is invalid. | 2334
NERR_BadQueuePriority | The queue priority is invalid. | 2335
NERR_BadReceive | The message was sent but not received. | 2282
NERR_BadRecipient | The alert recipient is invalid. | 2433
NERR_BadServiceName | The service name is invalid. | 2185
NERR_BadServiceProgName | The configuration file contains an invalid service program name. | 2188
NERR_BadSource | The source path is illegal. | 2381
NERR_BadTransactConfig | The server is not configured for transactions. | 2141
NERR_BadUasConfig | The user accounts database is not configured correctly. | 2450
NERR_BadUsername | The user name or group name parameter is invalid. | 2202
NERR_BrowserConfiguredToNotRun | The browser service was configured with MaintainServerList=No. | 2550
NERR_BrowserNotStarted | The requested information is not available. | 2139
NERR_BrowserTableIncomplete | The information in the list of servers may be incorrect. | 2319
NERR_BufTooSmall | The API return buffer is too small. | 2123
NERR_CallingRplSrvr | Connecting to the Remoteboot server... | 2515
NERR_CanNotGrowSegment | Unable to add to the security database session cache segment. | 2233
NERR_CanNotGrowUASFile | Unable to add to the user accounts database. | 2456
NERR_CantConnectRplSrvr | Cannot connect to the Remoteboot server. | 2513
NERR_CantOpenImageFile | Cannot open image file on the Remoteboot server. | 2514
NERR_CantType | Could not determine the type of input. | 2357
NERR_CfgCompNotFound | The specified component could not be found in the configuration information. | 2146
NERR_CfgParamNotFound | The specified parameter could not be found in the configuration information. | 2147
NERR_ClientNameNotFound | A session does not exist with that computer name. | 2312
NERR_CommDevInUse | This device is already in use as a communication device. | 2343
NERR_DatabaseUpToDate | No updates are necessary to this replicant network/local security database. | 2248
NERR_DataTypeInvalid | The data type is not supported by the print processor. | 2167
NERR_DCNotFound | Could not find domain controller for this domain. | 2453
NERR_DelComputerName | The computer name could not be deleted. | 2278
NERR_DeleteLater | @W This message alias will be deleted later. | 2298
NERR_DestExists | The printer destination already exists. | 2153
NERR_DestIdle | This printer destination is idle and cannot accept control operations. | 2158
NERR_DestInvalidOp | This printer destination request contains an invalid control function. | 2159
NERR_DestInvalidState | This operation cannot be performed on the print destination in its current state. | 2162
NERR_DestNoRoom | No more printer destinations can be added. | 2157
NERR_DestNotFound | The printer destination cannot be found. | 2152
NERR_DeviceIsShared | This device is currently being shared. | 2252
NERR_DeviceNotShared | This device is not shared. | 2311
NERR_DeviceShareConflict | This device cannot be shared as both a spooled and a non-spooled resource. | 2318
NERR_DevInUse | The device is being accessed by an active process. | 2404
NERR_DevInvalidOpCode | The operation is invalid for this device. | 2331
NERR_DevNotFound | This device cannot be shared. | 2332
NERR_DevNotOpen | This device was not open. | 2333
NERR_DevNotRedirected | The device is not connected. | 2107
NERR_DfsAlreadyShared | The server share specified is already shared in the Dfs | 2664
NERR_DfsBadRenamePath | The specified rename target path is invalid | 2671
NERR_DfsCantCreateJunctionPoint | Unable to create a junction point | 2669
NERR_DfsCyclicalName | A cycle in the Dfs name was detected | 2674
NERR_DfsInternalCorruption | The internal database maintained by the Dfs service is corrupt | 2660
NERR_DfsInternalError | Dfs internal error | 2690
NERR_DfsLeafVolume | The operation is not valid on a leaf volume | 2667
NERR_DfsNoSuchServer | The specified server is not a server for this volume | 2673
NERR_DfsNoSuchShare | The indicated server share does not support the indicated Dfs volume | 2665
NERR_DfsNoSuchVolume | There is no volume whose entry path matches the input Entry Path | 2662
NERR_DfsNotALeafVolume | The operation is not valid on a non-leaf volume | 2666
NERR_DfsNotSupportedInServerDfs | The operation is not supported on a server-based Dfs | 2675
NERR_DfsServerNotDfsAware | The server is not Dfs Aware | 2670
NERR_DfsVolumeAlreadyExists | A volume with the given name already exists | 2663
NERR_DfsVolumeDataCorrupt | One of the records in the internal Dfs database is corrupt | 2661
NERR_DfsVolumeHasMultipleServers | The operation is ambiguous because the volume has multiple servers | 2668
NERR_DfsVolumeIsOffline | The specified Dfs volume is offline | 2672
NERR_DifferentServers | The source and destination paths are on different servers. | 2383
NERR_DriverNotFound | The device driver does not exist. | 2166
NERR_DuplicateName | A duplicate message alias exists on the network. | 2297
NERR_DuplicateShare | The name has already been shared. | 2118
NERR_DupNameReboot | The computer name already exists on the network. Change it and restart the computer. | 2144
NERR_ErrCommRunSrv | An error occurred when communicating with a Run server. | 2389
NERR_ErrorExecingGhost | An error occurred when starting a background process. | 2391
NERR_ExecFailure | A failure occurred when executing a remote administration command. | 2315
NERR_FileIdNotFound | There is not an open file with that identification number. | 2314
NERR_GroupExists | The group already exists. | 2223
NERR_GroupNotFound | The group name could not be found. | 2220
NERR_GrpMsgProcessor | An error occurred in the domain message processor. | 2280
NERR_ImageParamErr | Image parameter substitution failed. | 2508
NERR_IncompleteDel | The message alias was not successfully deleted from all networks. | 2299
NERR_InternalError | An internal Windows NT error occurred. | 2140
NERR_InUseBySpooler | This device is already in use by the spooler. | 2342
NERR_InvalidAPI | The requested API is not supported on the remote server. | 2142
NERR_InvalidComputer | This computer name is invalid. | 2351
NERR_InvalidDatabase | The security database is corrupted. | 2247
NERR_InvalidDevice | This is an invalid device name. | 2294
NERR_InvalidLana | The LAN adapter number is invalid. | 2400
NERR_InvalidLogonHours | The user is not allowed to log on at this time. | 2241
NERR_InvalidLogSeek | The log file does not contain the requested record number. | 2440
NERR_InvalidMaxUsers | The Peer service supports only two simultaneous users. | 2122
NERR_InvalidUASOp | This operation is not permitted when the Netlogon service is running. | 2451
NERR_InvalidWorkstation | The user is not allowed to log on from this workstation. | 2240
NERR_IsDfsShare | The share must be removed from the Distributed File System before it can be deleted. | 2321
NERR_ItemNotFound | The queue is empty. | 2115
NERR_JobInvalidState | This operation cannot be performed on the print job in its current state. | 2164
NERR_JobNoRoom | No more print jobs can be added. | 2156
NERR_JobNotFound | The print job does not exist. | 2151
NERR_LanmanIniError | An error occurred when opening or reading the configuration file. | 2131
NERR_LastAdmin | This operation is not allowed on the last administrative account. | 2452
NERR_LineTooLong | A line in the configuration file is too long. | 2149
NERR_LocalDrive | The drive letter is in use locally. | 2405
NERR_LocalForward | Messages cannot be forwarded back to the same workstation. | 2279
NERR_LogFileChanged | This log file has changed between reads. | 2378
NERR_LogFileCorrupt | Log file %1 is corrupt. | 2379
NERR_LogonDomainExists | There is already a logon domain for this computer. | 2216
NERR_LogonNoUserPath | The server is configured without a valid user path. | 2211
NERR_LogonScriptError | An error occurred while loading or running the logon script. | 2212
NERR_LogonServerConflict | A centralized logon-server conflict occurred. | 2210
NERR_LogonServerNotFound | The logon server could not be found. | 2215
NERR_LogonsPaused | Network logons are paused. | 2209
NERR_LogonTrackingError | Could not set logon information for this user. | 2454
NERR_LogOverflow | Log file %1 is full. | 2377
NERR_MaxLenExceeded | The string and prefix specified are too long. | 2354
NERR_MsgAlreadyStarted | The Messenger service is already started. | 2271
NERR_MsgInitFailed | The Messenger service failed to start. | 2272
NERR_MsgNotStarted | The Messenger service has not been started. | 2284
NERR_MultipleNets | This operation is not supported on computers with multiple networks. | 2300
NERR_NameInUse | The message alias is currently in use. Try again later. | 2283
NERR_NameNotForwarded | Messages for this alias are not currently being forwarded. | 2288
NERR_NameNotFound | The message alias could not be found on the network. | 2273
NERR_NetlogonNotStarted | The Netlogon service has not been started. | 2455
NERR_NetNameNotFound | This shared resource does not exist. | 2310
NERR_NetworkError | A general network error occurred. | 2136
NERR_NoAlternateServers | There are no alternate servers registered on this server. | 2467
NERR_NoCommDevs | There are no shared communication devices. | 2337
NERR_NoComputerName | The computer name could not be added as a message alias. The name may already exist on the network. | 2270
NERR_NoForwardName | The forwarded message alias could not be found on the network. | 2286
NERR_NonDosFloppyUsed | The image was not generated from an MS-DOS diskette formatted with /S. | 2510
NERR_NoNetworkResource | A network resource shortage occurred . | 2105
NERR_NonValidatedLogon | The logon server could not validate the logon. | 2217
NERR_NoRoom | The server is currently out of the requested resource. | 2119
NERR_NoRplBootSystem | No loader is specified in the boot-block definition file. | 2505
NERR_NoSuchAlert | An invalid or nonexistent alert name was raised. | 2432
NERR_NoSuchConnection | The connection identification does not specify a valid connection. | 2462
NERR_NoSuchServer | The server identification does not specify a valid server. | 2460
NERR_NoSuchSession | The session identification does not specify a valid session. | 2461
NERR_NotInCache | This user is not cached in user accounts database session cache. | 2235
NERR_NotInDispatchTbl | The service control dispatcher could not find the service name in the dispatch table. | 2192
NERR_NotLocalDomain | The computer is not active in this domain. | 2320
NERR_NotLocalName | The name is not on the local computer. | 2285
NERR_NotLoggedOn | The workstation is not logged on to the local-area network. | 2201
NERR_NotPrimary | This operation is only allowed on the primary domain controller of the domain. | 2226
NERR_OpenFiles | There are open files on the connection. | 2401
NERR_PasswordCantChange | The password of this user cannot change. | 2243
NERR_PasswordExpired | The password of this user has expired. | 2242
NERR_PasswordHistConflict | This password cannot be used now. | 2244
NERR_PasswordMismatch | A password mismatch has been detected. | 2458
NERR_PasswordTooRecent | The password of this user is too recent to change. | 2246
NERR_PasswordTooShort | The password is shorter than required. | 2245
NERR_PausedRemote | The message was sent, but the recipient has paused the Messenger service. | 2281
NERR_ProcNoRespond | The print processor is not responding. | 2160
NERR_ProcNotFound | The print processor is not installed. | 2168
NERR_ProfileCleanup | The system cannot delete current connections to network resources. | 2372
NERR_ProfileFileTooBig | Profile files cannot exceed 64K. | 2370
NERR_ProfileLoadErr | An error occurred while loading the profile file. | 2374
NERR_ProfileOffset | The start offset is out of range. | 2371
NERR_ProfileSaveErr | @W Errors occurred while saving the profile file. The profile was partially saved. | 2375
NERR_ProfileUnknownCmd | The system was unable to parse the command line in this file. | 2373
NERR_ProgNeedsExtraMem | The program below needs more memory: | 2501
NERR_QExists | The printer queue already exists. | 2154
NERR_QInvalidState | This operation cannot be performed on the printer queue in its current state. | 2163
NERR_QNoRoom | No more printers can be added. | 2155
NERR_QNotFound | The printer does not exist. | 2150
NERR_QueueNotFound | The queue you specified does not exist. | 2338
NERR_RedirectedPath | The operation is invalid on a redirected resource. | 2117
NERR_RemoteBootFailed | The workstation failed to boot. | 2503
NERR_RemoteErr | A remote API error occurred. | 2127
NERR_RemoteFull | The message alias table on the remote station is full. | 2287
NERR_RemoteOnly | This operation is not supported on workstations. | 2106
NERR_ResourceExists | The resource permission list already exists. | 2225
NERR_ResourceNotFound | The resource name could not be found. | 2222
NERR_RPL_CONNECTED | A second connection to a Remoteboot resource is not allowed. | 2519
NERR_RplAdapterInfoCorrupted | Adapter id record information has been corrupted. | 2625
NERR_RplAdapterNameUnavailable | Chosen network adapter id is in use by some other workstation. | 2633
NERR_RplAdapterNotFound | Adapter record was not found. | 2637
NERR_RplBackupDatabase | Service failed to backup Remoteboot database. | 2636
NERR_RplBadDatabase | Service failed to start because its database is absent or corrupt. | 2612
NERR_RplBadRegistry | Service failed to start due to bad startup information in the registry. | 2611
NERR_RplBootInfoCorrupted | Boot block record information has been corrupted. | 2628
NERR_RplBootInUse | There are workstations, profiles, or configurations using this boot block. | 2635
NERR_RplBootNameUnavailable | (boot name, vendor id) is in use by some other boot block record. | 2640
NERR_RplBootNotFound | Boot block record was not found. | 2631
NERR_RplBootRestart | Remote boot will be restarted later. | 2511
NERR_RplBootServiceTerm | Remote boot service was stopped; check the error log for the cause of the problem. | 2517
NERR_RplBootStartFailed | Remote boot startup failed; check the error log for the cause of the problem. | 2518
NERR_RplCannotEnum | Cannot enumerate service records. | 2615
NERR_RplConfigInfoCorrupted | Configuration record information has been corrupted. | 2623
NERR_RplConfigNameUnavailable | Configuration name is in use by some other configuration. | 2641
NERR_RplConfigNotEmpty | There are profiles using this configuration. | 2634
NERR_RplConfigNotFound | Configuration record was not found. | 2624
NERR_RplIncompatibleProfile | Chosen profile is incompatible with this workstation. | 2632
NERR_RplInternal | An internal service error has occurred. | 2626
NERR_RplLoadrDiskErr | A disk I/O error occurred. | 2507
NERR_RplLoadrNetBiosErr | NetBIOS returned an error: The NCB and SMB are dumped above. | 2506
NERR_RplNeedsRPLUSERAcct | The RPLUSER local group could not be found. | 2630
NERR_RplNoAdaptersStarted | Service failed to start since none of the network adapters started with this service. | 2610
NERR_RplNotRplServer | Service failed to start because RPLUSER group is absent. | 2614
NERR_RplProfileInfoCorrupted | Profile record information has been corrupted. | 2619
NERR_RplProfileNameUnavailable | Profile name is in use by some other profile. | 2621
NERR_RplProfileNotEmpty | There are workstations using this profile. | 2622
NERR_RplProfileNotFound | Profile record was not found. | 2620
NERR_RplRplfilesShare | Service failed to start because RPLFILES share is absent. | 2613
NERR_RplSrvrCallFailed | The call to the Remoteboot server failed. | 2512
NERR_RplVendorInfoCorrupted | Vendor id record information has been corrupted. | 2627
NERR_RplVendorNameUnavailable | Vendor name is in use by some other vendor record. | 2639
NERR_RplVendorNotFound | Vendor record was not found. | 2638
NERR_RplWkstaInfoCorrupted | Workstation record information has been corrupted. | 2616
NERR_RplWkstaNameUnavailable | Workstation name is in use by some other workstation. | 2618
NERR_RplWkstaNeedsUserAcct | The user account for this workstation record is missing. | 2629
NERR_RplWkstaNotFound | Workstation record was not found. | 2617
NERR_RunSrvPaused | The Run server you requested is paused. | 2385
NERR_ServerNotStarted | The Server service is not started. | 2114
NERR_ServiceCtlBusy | The service control is busy. | 2187
NERR_ServiceCtlNotValid | The requested pause or stop is not valid for this service. | 2191
NERR_ServiceCtlTimeout | The service is not responding to the control function. | 2186
NERR_ServiceEntryLocked | The service does not respond to control actions. | 2183
NERR_ServiceInstalled | The requested service has already been started. | 2182
NERR_ServiceKillProc | The service ended abnormally. | 2190
NERR_ServiceNotCtrl | The service could not be controlled in its present state. | 2189
NERR_ServiceNotInstalled | The service has not been started. | 2184
NERR_ServiceNotStarting | A thread for the new service could not be created. | 2194
NERR_ServiceTableFull | The service table is full. | 2181
NERR_ServiceTableLocked | The service database is locked. | 2180
NERR_SetupAlreadyJoined | This machine is already joined to a domain. | 2691
NERR_SetupDomainController | This machine is a domain controller and cannot be unjoined from a domain. | 2693
NERR_SetupNotJoined | This machine is not currently joined to a domain. | 2692
NERR_ShareMem | An internal error occurred. The network cannot access a shared memory segment. | 2104
NERR_ShareNotFound | The shared resource you are connected to could not be found. | 2392
NERR_SourceIsDir | The source path cannot be a directory. | 2380
NERR_SpeGroupOp | This operation is not allowed on this special group. | 2234
NERR_SpoolerNotLoaded | The spooler is not running. | 2161
NERR_SpoolNoMemory | A spooler memory allocation failure occurred. | 2165
NERR_StandaloneLogon | The logon server was not specified. Your computer will be logged on as STANDALONE. | 2214
NERR_StartingRplBoot | Connecting to the Remoteboot server... | 2516
NERR_SyncRequired | This replicant database is outdated; synchronization is required. | 2249
NERR_TimeDiffAtDC | This server's clock is not synchronized with the primary domain controller's clock. | 2457
NERR_TmpFile | A failure occurred when opening a remote temporary file. | 2316
NERR_TooManyAlerts | The alert table is full. | 2431
NERR_TooManyConnections | The server has reached the maximum number of connections it supports. | 2465
NERR_TooManyEntries | The buffer for types is not big enough. | 2362
NERR_TooManyFiles | The server cannot open more files because it has reached its maximum number. | 2466
NERR_TooManyImageParams | Too many image parameters cross disk sector boundaries. | 2509
NERR_TooManyItems | Requested addition of items exceeds the maximum allowed. | 2121
NERR_TooManyNames | The maximum number of added message aliases has been exceeded. | 2277
NERR_TooManyServers | There is no space for another entry in the table of available servers. | 2463
NERR_TooManySessions | The server has reached the maximum number of sessions it supports. | 2464
NERR_TooMuchData | The data returned from a remote administration command has been truncated to 64K. | 2317
NERR_TruncatedBroadcast | The broadcast message was truncated. | 2289
NERR_TryDownLevel | Try down-level (remote admin protocol) version of API instead. | 2470
NERR_UnableToAddName_F | The logon processor did not add the message alias. | 2205
NERR_UnableToAddName_W | @W The logon processor did not add the message alias. | 2204
NERR_UnableToDelName_F | The logoff processor did not delete the message alias. | 2207
NERR_UnableToDelName_W | @W The logoff processor did not delete the message alias. | 2206
NERR_UnknownDevDir | The device or directory does not exist. | 2116
NERR_UnknownServer | The server could not be located. | 2103
NERR_UPSDriverNotStarted | The UPS driver could not be accessed by the UPS service. | 2480
NERR_UPSInvalidCommPort | The UPS service could not access the specified Comm Port. | 2482
NERR_UPSInvalidConfig | The UPS service is not configured correctly. | 2481
NERR_UPSShutdownFailed | The UPS service failed to perform a system shut down. | 2484
NERR_UPSSignalAsserted | The UPS indicated a line fail or low battery situation. Service not started. | 2483
NERR_UseNotFound | The network connection could not be found. | 2250
NERR_UserExists | The user account already exists. | 2224
NERR_UserInGroup | The user already belongs to this group. | 2236
NERR_UserLogon | Deleting a user with a session is not allowed. | 2231
NERR_UserNotFound | The user name could not be found. | 2221
NERR_UserNotInGroup | The user does not belong to this group. | 2237
NERR_WkstaInconsistentState | The Workstation service is in an inconsistent state. Restart the computer before restarting the Workstation service. | 2137
NERR_WkstaNotStarted | The Workstation service has not been started. | 2138
NERR_WriteFault | A write fault occurred. | 2295
NETERR_INCLUDED | The workstation driver is not installed. | 2102


Net Errors - Numerical Order

The following table provides a list of network error codes.

Code | Description | Name
2102 | The workstation driver is not installed. | NETERR_INCLUDED
2103 | The server could not be located. | NERR_UnknownServer
2104 | An internal error occurred. The network cannot access a shared memory segment. | NERR_ShareMem
2105 | A network resource shortage occurred . | NERR_NoNetworkResource
2106 | This operation is not supported on workstations. | NERR_RemoteOnly
2107 | The device is not connected. | NERR_DevNotRedirected
2114 | The Server service is not started. | NERR_ServerNotStarted
2115 | The queue is empty. | NERR_ItemNotFound
2116 | The device or directory does not exist. | NERR_UnknownDevDir
2117 | The operation is invalid on a redirected resource. | NERR_RedirectedPath
2118 | The name has already been shared. | NERR_DuplicateShare
2119 | The server is currently out of the requested resource. | NERR_NoRoom
2121 | Requested addition of items exceeds the maximum allowed. | NERR_TooManyItems
2122 | The Peer service supports only two simultaneous users. | NERR_InvalidMaxUsers
2123 | The API return buffer is too small. | NERR_BufTooSmall
2127 | A remote API error occurred. | NERR_RemoteErr
2131 | An error occurred when opening or reading the configuration file. | NERR_LanmanIniError
2136 | A general network error occurred. | NERR_NetworkError
2137 | The Workstation service is in an inconsistent state. Restart the computer before restarting the Workstation service. | NERR_WkstaInconsistentState
2138 | The Workstation service has not been started. | NERR_WkstaNotStarted
2139 | The requested information is not available. | NERR_BrowserNotStarted
2140 | An internal Windows NT error occurred. | NERR_InternalError
2141 | The server is not configured for transactions. | NERR_BadTransactConfig
2142 | The requested API is not supported on the remote server. | NERR_InvalidAPI
2143 | The event name is invalid. | NERR_BadEventName
2144 | The computer name already exists on the network. Change it and restart the computer. | NERR_DupNameReboot
2146 | The specified component could not be found in the configuration information. | NERR_CfgCompNotFound
2147 | The specified parameter could not be found in the configuration information. | NERR_CfgParamNotFound
2149 | A line in the configuration file is too long. | NERR_LineTooLong
2150 | The printer does not exist. | NERR_QNotFound
2151 | The print job does not exist. | NERR_JobNotFound
2152 | The printer destination cannot be found. | NERR_DestNotFound
2153 | The printer destination already exists. | NERR_DestExists
2154 | The printer queue already exists. | NERR_QExists
2155 | No more printers can be added. | NERR_QNoRoom
2156 | No more print jobs can be added. | NERR_JobNoRoom
2157 | No more printer destinations can be added. | NERR_DestNoRoom
2158 | This printer destination is idle and cannot accept control operations. | NERR_DestIdle
2159 | This printer destination request contains an invalid control function. | NERR_DestInvalidOp
2160 | The print processor is not responding. | NERR_ProcNoRespond
2161 | The spooler is not running. | NERR_SpoolerNotLoaded
2162 | This operation cannot be performed on the print destination in its current state. | NERR_DestInvalidState
2163 | This operation cannot be performed on the printer queue in its current state. | NERR_QInvalidState
2164 | This operation cannot be performed on the print job in its current state. | NERR_JobInvalidState
2165 | A spooler memory allocation failure occurred. | NERR_SpoolNoMemory
2166 | The device driver does not exist. | NERR_DriverNotFound
2167 | The data type is not supported by the print processor. | NERR_DataTypeInvalid
2168 | The print processor is not installed. | NERR_ProcNotFound
2180 | The service database is locked. | NERR_ServiceTableLocked
2181 | The service table is full. | NERR_ServiceTableFull
2182 | The requested service has already been started. | NERR_ServiceInstalled
2183 | The service does not respond to control actions. | NERR_ServiceEntryLocked
2184 | The service has not been started. | NERR_ServiceNotInstalled
2185 | The service name is invalid. | NERR_BadServiceName
2186 | The service is not responding to the control function. | NERR_ServiceCtlTimeout
2187 | The service control is busy. | NERR_ServiceCtlBusy
2188 | The configuration file contains an invalid service program name. | NERR_BadServiceProgName
2189 | The service could not be controlled in its present state. | NERR_ServiceNotCtrl
2190 | The service ended abnormally. | NERR_ServiceKillProc
2191 | The requested pause or stop is not valid for this service. | NERR_ServiceCtlNotValid
2192 | The service control dispatcher could not find the service name in the dispatch table. | NERR_NotInDispatchTbl
2193 | The service control dispatcher pipe read failed. | NERR_BadControlRecv
2194 | A thread for the new service could not be created. | NERR_ServiceNotStarting
2200 | This workstation is already logged on to the local-area network. | NERR_AlreadyLoggedOn
2201 | The workstation is not logged on to the local-area network. | NERR_NotLoggedOn
2202 | The user name or group name parameter is invalid. | NERR_BadUsername
2203 | The password parameter is invalid. | NERR_BadPassword
2204 | @W The logon processor did not add the message alias. | NERR_UnableToAddName_W
2205 | The logon processor did not add the message alias. | NERR_UnableToAddName_F
2206 | @W The logoff processor did not delete the message alias. | NERR_UnableToDelName_W
2207 | The logoff processor did not delete the message alias. | NERR_UnableToDelName_F
2209 | Network logons are paused. | NERR_LogonsPaused
2210 | A centralized logon-server conflict occurred. | NERR_LogonServerConflict
2211 | The server is configured without a valid user path. | NERR_LogonNoUserPath
2212 | An error occurred while loading or running the logon script. | NERR_LogonScriptError
2214 | The logon server was not specified. Your computer will be logged on as STANDALONE. | NERR_StandaloneLogon
2215 | The logon server could not be found. | NERR_LogonServerNotFound
2216 | There is already a logon domain for this computer. | NERR_LogonDomainExists
2217 | The logon server could not validate the logon. | NERR_NonValidatedLogon
2219 | The security database could not be found. | NERR_ACFNotFound
2220 | The group name could not be found. | NERR_GroupNotFound
2221 | The user name could not be found. | NERR_UserNotFound
2222 | The resource name could not be found. | NERR_ResourceNotFound
2223 | The group already exists. | NERR_GroupExists
2224 | The user account already exists. | NERR_UserExists
2225 | The resource permission list already exists. | NERR_ResourceExists
2226 | This operation is only allowed on the primary domain controller of the domain. | NERR_NotPrimary
2227 | The security database has not been started. | NERR_ACFNotLoaded
2228 | There are too many names in the user accounts database. | NERR_ACFNoRoom
2229 | A disk I/O failure occurred. | NERR_ACFFileIOFail
2230 | The limit of 64 entries per resource was exceeded. | NERR_ACFTooManyLists
2231 | Deleting a user with a session is not allowed. | NERR_UserLogon
2232 | The parent directory could not be located. | NERR_ACFNoParent
2233 | Unable to add to the security database session cache segment. | NERR_CanNotGrowSegment
2234 | This operation is not allowed on this special group. | NERR_SpeGroupOp
2235 | This user is not cached in user accounts database session cache. | NERR_NotInCache
2236 | The user already belongs to this group. | NERR_UserInGroup
2237 | The user does not belong to this group. | NERR_UserNotInGroup
2238 | This user account is undefined. | NERR_AccountUndefined
2239 | This user account has expired. | NERR_AccountExpired
2240 | The user is not allowed to log on from this workstation. | NERR_InvalidWorkstation
2241 | The user is not allowed to log on at this time. | NERR_InvalidLogonHours
2242 | The password of this user has expired. | NERR_PasswordExpired
2243 | The password of this user cannot change. | NERR_PasswordCantChange
2244 | This password cannot be used now. | NERR_PasswordHistConflict
2245 | The password is shorter than required. | NERR_PasswordTooShort
2246 | The password of this user is too recent to change. | NERR_PasswordTooRecent
2247 | The security database is corrupted. | NERR_InvalidDatabase
2248 | No updates are necessary to this replicant network/local security database. | NERR_DatabaseUpToDate
2249 | This replicant database is outdated; synchronization is required. | NERR_SyncRequired
2250 | The network connection could not be found. | NERR_UseNotFound
2251 | This asg_type is invalid. | NERR_BadAsgType
2252 | This device is currently being shared. | NERR_DeviceIsShared
2270 | The computer name could not be added as a message alias. The name may already exist on the network. | NERR_NoComputerName
2271 | The Messenger service is already started. | NERR_MsgAlreadyStarted
2272 | The Messenger service failed to start. | NERR_MsgInitFailed
2273 | The message alias could not be found on the network. | NERR_NameNotFound
2274 | This message alias has already been forwarded. | NERR_AlreadyForwarded
2275 | This message alias has been added but is still forwarded. | NERR_AddForwarded
2276 | This message alias already exists locally. | NERR_AlreadyExists
2277 | The maximum number of added message aliases has been exceeded. | NERR_TooManyNames
2278 | The computer name could not be deleted. | NERR_DelComputerName
2279 | Messages cannot be forwarded back to the same workstation. | NERR_LocalForward
2280 | An error occurred in the domain message processor. | NERR_GrpMsgProcessor
2281 | The message was sent, but the recipient has paused the Messenger service. | NERR_PausedRemote
2282 | The message was sent but not received. | NERR_BadReceive
2283 | The message alias is currently in use. Try again later. | NERR_NameInUse
2284 | The Messenger service has not been started. | NERR_MsgNotStarted
2285 | The name is not on the local computer. | NERR_NotLocalName
2286 | The forwarded message alias could not be found on the network. | NERR_NoForwardName
2287 | The message alias table on the remote station is full. | NERR_RemoteFull
2288 | Messages for this alias are not currently being forwarded. | NERR_NameNotForwarded
2289 | The broadcast message was truncated. | NERR_TruncatedBroadcast
2294 | This is an invalid device name. | NERR_InvalidDevice
2295 | A write fault occurred. | NERR_WriteFault
2297 | A duplicate message alias exists on the network. | NERR_DuplicateName
2298 | @W This message alias will be deleted later. | NERR_DeleteLater
2299 | The message alias was not successfully deleted from all networks. | NERR_IncompleteDel
2300 | This operation is not supported on computers with multiple networks. | NERR_MultipleNets
2310 | This shared resource does not exist. | NERR_NetNameNotFound
2311 | This device is not shared. | NERR_DeviceNotShared
2312 | A session does not exist with that computer name. | NERR_ClientNameNotFound
2314 | There is not an open file with that identification number. | NERR_FileIdNotFound
2315 | A failure occurred when executing a remote administration command. | NERR_ExecFailure
2316 | A failure occurred when opening a remote temporary file. | NERR_TmpFile
2317 | The data returned from a remote administration command has been truncated to 64K. | NERR_TooMuchData
2318 | This device cannot be shared as both a spooled and a non-spooled resource. | NERR_DeviceShareConflict
2319 | The information in the list of servers may be incorrect. | NERR_BrowserTableIncomplete
2320 | The computer is not active in this domain. | NERR_NotLocalDomain
2321 | The share must be removed from the Distributed File System before it can be deleted. | NERR_IsDfsShare
2331 | The operation is invalid for this device. | NERR_DevInvalidOpCode
2332 | This device cannot be shared. | NERR_DevNotFound
2333 | This device was not open. | NERR_DevNotOpen
2334 | This device name list is invalid. | NERR_BadQueueDevString
2335 | The queue priority is invalid. | NERR_BadQueuePriority
2337 | There are no shared communication devices. | NERR_NoCommDevs
2338 | The queue you specified does not exist. | NERR_QueueNotFound
2340 | This list of devices is invalid. | NERR_BadDevString
2341 | The requested device is invalid. | NERR_BadDev
2342 | This device is already in use by the spooler. | NERR_InUseBySpooler
2343 | This device is already in use as a communication device. | NERR_CommDevInUse
2351 | This computer name is invalid. | NERR_InvalidComputer
2354 | The string and prefix specified are too long. | NERR_MaxLenExceeded
2356 | This path component is invalid. | NERR_BadComponent
2357 | Could not determine the type of input. | NERR_CantType
2362 | The buffer for types is not big enough. | NERR_TooManyEntries
2370 | Profile files cannot exceed 64K. | NERR_ProfileFileTooBig
2371 | The start offset is out of range. | NERR_ProfileOffset
2372 | The system cannot delete current connections to network resources. | NERR_ProfileCleanup
2373 | The system was unable to parse the command line in this file. | NERR_ProfileUnknownCmd
2374 | An error occurred while loading the profile file. | NERR_ProfileLoadErr
2375 | @W Errors occurred while saving the profile file. The profile was partially saved. | NERR_ProfileSaveErr
2377 | Log file %1 is full. | NERR_LogOverflow
2378 | This log file has changed between reads. | NERR_LogFileChanged
2379 | Log file %1 is corrupt. | NERR_LogFileCorrupt
2380 | The source path cannot be a directory. | NERR_SourceIsDir
2381 | The source path is illegal. | NERR_BadSource
2382 | The destination path is illegal. | NERR_BadDest
2383 | The source and destination paths are on different servers. | NERR_DifferentServers
2385 | The Run server you requested is paused. | NERR_RunSrvPaused
2389 | An error occurred when communicating with a Run server. | NERR_ErrCommRunSrv
2391 | An error occurred when starting a background process. | NERR_ErrorExecingGhost
2392 | The shared resource you are connected to could not be found. | NERR_ShareNotFound
2400 | The LAN adapter number is invalid. | NERR_InvalidLana
2401 | There are open files on the connection. | NERR_OpenFiles
2402 | Active connections still exist. | NERR_ActiveConns
2403 | This share name or password is invalid. | NERR_BadPasswordCore
2404 | The device is being accessed by an active process. | NERR_DevInUse
2405 | The drive letter is in use locally. | NERR_LocalDrive
2430 | The specified client is already registered for the specified event. | NERR_AlertExists
2431 | The alert table is full. | NERR_TooManyAlerts
2432 | An invalid or nonexistent alert name was raised. | NERR_NoSuchAlert
2433 | The alert recipient is invalid. | NERR_BadRecipient
2434 | A user's session with this server has been deleted | NERR_AcctLimitExceeded
2440 | The log file does not contain the requested record number. | NERR_InvalidLogSeek
2450 | The user accounts database is not configured correctly. | NERR_BadUasConfig
2451 | This operation is not permitted when the Netlogon service is running. | NERR_InvalidUASOp
2452 | This operation is not allowed on the last administrative account. | NERR_LastAdmin
2453 | Could not find domain controller for this domain. | NERR_DCNotFound
2454 | Could not set logon information for this user. | NERR_LogonTrackingError
2455 | The Netlogon service has not been started. | NERR_NetlogonNotStarted
2456 | Unable to add to the user accounts database. | NERR_CanNotGrowUASFile
2457 | This server's clock is not synchronized with the primary domain controller's clock. | NERR_TimeDiffAtDC
2458 | A password mismatch has been detected. | NERR_PasswordMismatch
2460 | The server identification does not specify a valid server. | NERR_NoSuchServer
2461 | The session identification does not specify a valid session. | NERR_NoSuchSession
2462 | The connection identification does not specify a valid connection. | NERR_NoSuchConnection
2463 | There is no space for another entry in the table of available servers. | NERR_TooManyServers
2464 | The server has reached the maximum number of sessions it supports. | NERR_TooManySessions
2465 | The server has reached the maximum number of connections it supports. | NERR_TooManyConnections
2466 | The server cannot open more files because it has reached its maximum number. | NERR_TooManyFiles
2467 | There are no alternate servers registered on this server. | NERR_NoAlternateServers
2470 | Try down-level (remote admin protocol) version of API instead. | NERR_TryDownLevel
2480 | The UPS driver could not be accessed by the UPS service. | NERR_UPSDriverNotStarted
2481 | The UPS service is not configured correctly. | NERR_UPSInvalidConfig
2482 | The UPS service could not access the specified Comm Port. | NERR_UPSInvalidCommPort
2483 | The UPS indicated a line fail or low battery situation. Service not started. | NERR_UPSSignalAsserted
2484 | The UPS service failed to perform a system shut down. | NERR_UPSShutdownFailed
2500 | The program below returned an MS-DOS error code: | NERR_BadDosRetCode
2501 | The program below needs more memory: | NERR_ProgNeedsExtraMem
2502 | The program below called an unsupported MS-DOS function: | NERR_BadDosFunction
2503 | The workstation failed to boot. | NERR_RemoteBootFailed
2504 | The file below is corrupt. | NERR_BadFileCheckSum
2505 | No loader is specified in the boot-block definition file. | NERR_NoRplBootSystem
2506 | NetBIOS returned an error: The NCB and SMB are dumped above. | NERR_RplLoadrNetBiosErr
2507 | A disk I/O error occurred. | NERR_RplLoadrDiskErr
2508 | Image parameter substitution failed. | NERR_ImageParamErr
2509 | Too many image parameters cross disk sector boundaries. | NERR_TooManyImageParams
2510 | The image was not generated from an MS-DOS diskette formatted with /S. | NERR_NonDosFloppyUsed
2511 | Remote boot will be restarted later. | NERR_RplBootRestart
2512 | The call to the Remoteboot server failed. | NERR_RplSrvrCallFailed
2513 | Cannot connect to the Remoteboot server. | NERR_CantConnectRplSrvr
2514 | Cannot open image file on the Remoteboot server. | NERR_CantOpenImageFile
2515 | Connecting to the Remoteboot server... | NERR_CallingRplSrvr
2516 | Connecting to the Remoteboot server... | NERR_StartingRplBoot
2517 | Remote boot service was stopped; check the error log for the cause of the problem. | NERR_RplBootServiceTerm
2518 | Remote boot startup failed; check the error log for the cause of the problem. | NERR_RplBootStartFailed
2519 | A second connection to a Remoteboot resource is not allowed. | NERR_RPL_CONNECTED
2550 | The browser service was configured with MaintainServerList=No. | NERR_BrowserConfiguredToNotRun
2610 | Service failed to start since none of the network adapters started with this service. | NERR_RplNoAdaptersStarted
2611 | Service failed to start due to bad startup information in the registry. | NERR_RplBadRegistry
2612 | Service failed to start because its database is absent or corrupt. | NERR_RplBadDatabase
2613 | Service failed to start because RPLFILES share is absent. | NERR_RplRplfilesShare
2614 | Service failed to start because RPLUSER group is absent. | NERR_RplNotRplServer
2615 | Cannot enumerate service records. | NERR_RplCannotEnum
2616 | Workstation record information has been corrupted. | NERR_RplWkstaInfoCorrupted
2617 | Workstation record was not found. | NERR_RplWkstaNotFound
2618 | Workstation name is in use by some other workstation. | NERR_RplWkstaNameUnavailable
2619 | Profile record information has been corrupted. | NERR_RplProfileInfoCorrupted
2620 | Profile record was not found. | NERR_RplProfileNotFound
2621 | Profile name is in use by some other profile. | NERR_RplProfileNameUnavailable
2622 | There are workstations using this profile. | NERR_RplProfileNotEmpty
2623 | Configuration record information has been corrupted. | NERR_RplConfigInfoCorrupted
2624 | Configuration record was not found. | NERR_RplConfigNotFound
2625 | Adapter id record information has been corrupted. | NERR_RplAdapterInfoCorrupted
2626 | An internal service error has occurred. | NERR_RplInternal
2627 | Vendor id record information has been corrupted. | NERR_RplVendorInfoCorrupted
2628 | Boot block record information has been corrupted. | NERR_RplBootInfoCorrupted
2629 | The user account for this workstation record is missing. | NERR_RplWkstaNeedsUserAcct
2630 | The RPLUSER local group could not be found. | NERR_RplNeedsRPLUSERAcct
2631 | Boot block record was not found. | NERR_RplBootNotFound
2632 | Chosen profile is incompatible with this workstation. | NERR_RplIncompatibleProfile
2633 | Chosen network adapter id is in use by some other workstation. | NERR_RplAdapterNameUnavailable
2634 | There are profiles using this configuration. | NERR_RplConfigNotEmpty
2635 | There are workstations, profiles, or configurations using this boot block. | NERR_RplBootInUse
2636 | Service failed to backup Remoteboot database. | NERR_RplBackupDatabase
2637 | Adapter record was not found. | NERR_RplAdapterNotFound
2638 | Vendor record was not found. | NERR_RplVendorNotFound
2639 | Vendor name is in use by some other vendor record. | NERR_RplVendorNameUnavailable
2640 | (boot name, vendor id) is in use by some other boot block record. | NERR_RplBootNameUnavailable
2641 | Configuration name is in use by some other configuration. | NERR_RplConfigNameUnavailable
2660 | The internal database maintained by the Dfs service is corrupt | NERR_DfsInternalCorruption
2661 | One of the records in the internal Dfs database is corrupt | NERR_DfsVolumeDataCorrupt
2662 | There is no volume whose entry path matches the input Entry Path | NERR_DfsNoSuchVolume
2663 | A volume with the given name already exists | NERR_DfsVolumeAlreadyExists
2664 | The server share specified is already shared in the Dfs | NERR_DfsAlreadyShared
2665 | The indicated server share does not support the indicated Dfs volume | NERR_DfsNoSuchShare
2666 | The operation is not valid on a non-leaf volume | NERR_DfsNotALeafVolume
2667 | The operation is not valid on a leaf volume | NERR_DfsLeafVolume
2668 | The operation is ambiguous because the volume has multiple servers | NERR_DfsVolumeHasMultipleServers
2669 | Unable to create a junction point | NERR_DfsCantCreateJunctionPoint
2670 | The server is not Dfs Aware | NERR_DfsServerNotDfsAware
2671 | The specified rename target path is invalid | NERR_DfsBadRenamePath
2672 | The specified Dfs volume is offline | NERR_DfsVolumeIsOffline
2673 | The specified server is not a server for this volume | NERR_DfsNoSuchServer
2674 | A cycle in the Dfs name was detected | NERR_DfsCyclicalName
2675 | The operation is not supported on a server-based Dfs | NERR_DfsNotSupportedInServerDfs
2690 | Dfs internal error | NERR_DfsInternalError
2691 | This machine is already joined to a domain. | NERR_SetupAlreadyJoined
2692 | This machine is not currently joined to a domain. | NERR_SetupNotJoined
2693 | This machine is a domain controller and cannot be unjoined from a domain. | NERR_SetupDomainController


Dynamic-Link Libraries

Dynamic-link libraries (DLL) are modules that contain functions and data. A DLL is loaded at runtime by its calling modules (.EXE or DLL). When a DLL is loaded, it is mapped into the address space of the calling process.

DLLs can define two kinds of functions: exported and internal. The exported functions can be called by other modules. Internal functions can only be called from within the DLL where they are defined. Although DLLs can export data, its data is usually only used by its functions.

DLLs provide a way to modularize applications so that functionality can be updated and reused more easily. They also help reduce memory overhead when several applications use the same functionality at the same time, because although each application gets its own copy of the data, they can share the code.

The Microsoft® Win32® application programming interface (API) is implemented as a set of dynamic-link libraries, so any process that uses the Win32 API uses dynamic linking.


About Dynamic-Link Libraries

Dynamic linking allows a module to include only the information the system needs at load time or run time to locate the code for an exported DLL function. Dynamic linking differs from the more familiar static linking, in which the linker copies a library function's code into each module that calls it.

Types of Dynamic Linking

There are two methods for calling a function in a DLL:

  • In load-time dynamic linking, a module makes explicit calls to exported DLL functions. This requires you to link the module with the import library for the DLL. An import library supplies the system with the information needed to load the DLL and locate the exported DLL functions when the application is loaded. For more information, see Load-Time Dynamic Linking.
  • In run-time dynamic linking, a module uses the LoadLibrary or LoadLibraryEx function to load the DLL at run time. After the DLL is loaded, the module calls the GetProcAddress function to get the addresses of the exported DLL functions. The module calls the exported DLL functions using the function pointers returned by GetProcAddress. This eliminates the need for an import library. For more information, see Using Run-Time Dynamic Linking.

DLLs and Memory Management

Every process that loads the DLL maps it into its virtual address space. After the process loads the DLL into its virtual address, it can call the exported DLL functions.

The system maintains a reference count for each DLL. When a thread loads the DLL, its reference count is incremented by one. When the process terminates, or when the reference count goes to 0 (run-time dynamic linking only), the DLL is unloaded from the virtual address space.

Like any other function, an exported DLL function runs in the context of the thread that calls it. Therefore, the following conditions apply:

  • The threads of the process that called the DLL can use handles opened by a DLL function. Similarly, handles opened by any thread of the calling process can be used in the DLL function.
  • The DLL uses the stack of the calling thread and the virtual address space of the calling process.
  • The DLL allocates memory from the virtual address space of the calling process.


Advantages of Dynamic Linking

Dynamic linking has the following advantages over static linking:

  • Processes that load a DLL at the same base address can use a single DLL simultaneously, sharing a single copy of the DLL code in physical memory. Doing this saves memory and reduces swapping.
  • When the functions in a DLL change, the applications that use them do not need to be recompiled or relinked as long as the function arguments, calling conventions, and return values do not change. In contrast, statically linked object code requires that the application be relinked when the functions change.
  • A DLL can provide after-market support. For example, a display driver DLL can be modified to support a display that was not available when the application was initially shipped.
  • Programs written in different programming languages can call the same DLL function as long as the programs follow the same calling convention that the function uses. The calling convention (such as C, Pascal, or standard call) controls the order in which the calling function must push the arguments onto the stack, whether the function or the calling function is responsible for cleaning up the stack, and whether any arguments are passed in registers. For more information, see the documentation included with your compiler.

A potential disadvantage to using DLLs is that the application is not self-contained; it depends on the existence of a separate DLL module. The system terminates processes using load-time dynamic linking if they require a DLL that is not found at process startup and gives an error message to the user. The system does not terminate a process using run-time dynamic linking in this situation, but functions exported by the DLL are not available to the program.


Dynamic-Link Library Creation

To create a DLL, you must create one or more source code files, and possibly a linker file for exporting the functions. If you plan to allow applications that use your DLL to use load-time dynamic linking, you must also create an import library.

Creating Source Files

The source files contain exported functions, internal functions, and an optional entry-point function for the DLL. You may use any development tools that support the creation of Win32-based DLLs.

If your DLL may be used by a multithreaded application, you should make your DLL "thread-safe" by linking only with libraries that have support for multiple threads. Also, be sure to synchronize access to your global data.

Exporting Functions

How you specify exported functions depends on the tools that you are using for development. Some compilers allow you to export a function directly in the source code by using a modifier in the function declaration. Other times, you must specify exports in a file that you pass to the linker.

For example, using Microsoft Visual C++, there are two possible ways to export DLL functions: with _declspec modifier or with a .DEF file. If you use the _declspec modifier, it is not necessary to use a .DEF file.

For more information about exporting functions, see the documentation included with your development tools.

Creating an Import Library

The import library (.LIB) file contains information the linker needs to resolve external references to exported DLL functions, so the system can locate the specified DLL and exported DLL functions at run time. For example, to call the CreateWindow function, you must link your code with the import library USER32.LIB. The reason is that CreateWindow resides in a system DLL. The file USER32.LIB is the import library used to resolve the call to CreateWindow in your code.

For information about creating import libraries, see the documentation included with your development tools.


Dynamic-Link Library Entry-Point Function

Every DLL must have an entry point, just as an application does. The system calls the entry-point function whenever processes and threads load or unload the DLL. If you are linking your DLL with a library, such as the C run-time library, it may provide an entry-point function for you, and allow you to provide a separate initialization function. Check the documentation for your runtime library for more information.

If you are providing your own entry-point, see the DllMain function. The name DllMain is a placeholder for a user-defined function. Earlier versions of the SDK documentation used DllEntryPoint as the entry-point function name. You must specify the actual name you use when you build your DLL. For more information, see the documentation included with your development tools.

Calling the Entry-Point Function

The system calls the entry-point function whenever any one of the following events occurs:

  • A process loads the DLL. For processes using load-time dynamic linking, the DLL is loaded during process initialization. For processes using run-time linking, the DLL is loaded before LoadLibrary or LoadLibraryEx returns.
  • A process unloads the DLL. The DLL is unloaded when the process terminates or calls the FreeLibrary function and the reference count becomes zero. If the process terminates as a result of the TerminateProcess or TerminateThread function, the system does not call the DLL entry-point function.
  • A new thread is created in a process that has loaded the DLL. You can use the DisableThreadLibraryCalls function to disable notification when threads are created.
  • A thread of a process that has loaded the DLL terminates normally, not using TerminateThread or TerminateProcess. When a process unloads the DLL, the entry-point function is called only once for the entire process, rather than once for each existing thread of the process. You can use DisableThreadLibraryCalls to disable notification when threads are terminated.

Only one thread at a time can call the entry-point function.

The system calls the entry-point function in the context of the process or thread that caused the function to be called. This allows a DLL to use its entry-point function for allocating memory in the virtual address space of the calling process or to open handles accessible to the process. The entry-point function can also allocate memory that is private to a new thread by using thread local storage (TLS). For more information about thread local storage, see Thread Local Storage.

Entry-Point Function Definition

The DLL entry-point function must be declared with the standard-call calling convention.

Windows NT: If the DLL entry point is not declared correctly, the DLL is not loaded, and the system displays a message indicating that the DLL entry point must be declared with WINAPI.

Windows 95: If the DLL entry point is not declared correctly, the DLL is not loaded and the system displays a message titled "Error starting program," which instructs the user to check the file to determine the problem.

In the body of the function, you may handle any combination of the following scenarios in which the DLL entry point has been called:

  • A process loads the DLL (DLL_PROCESS_ATTACH).
  • The current process creates a new thread (DLL_THREAD_ATTACH).
  • A thread exits normally (DLL_THREAD_DETACH).
  • A process unloads the DLL (DLL_PROCESS_DETACH).

Your function should perform only simple initialization tasks, such as setting up thread local storage (TLS), creating synchronization objects, and opening files. It must not call the LoadLibrary function, because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, you must not call the FreeLibrary function in the entry-point function, because this can result in a DLL being used after the system has executed its termination code.

Calling Win32 functions other than TLS, synchronization, and file functions may also result in problems that are difficult to diagnose. For example, calling User, Shell, and COM functions can cause access violation errors, because some functions in their DLLs call LoadLibrary to load other system components.

The following example demonstrates how to structure the DLL entry-point function.

BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpReserved )  // reserved
{
    // Perform actions based on the reason for calling.
    switch( fdwReason )
    {
        case DLL_PROCESS_ATTACH:
         // Initialize once for each new process.
         // Return FALSE to fail DLL load.
            break;

        case DLL_THREAD_ATTACH:
         // Do thread-specific initialization.
            break;

        case DLL_THREAD_DETACH:
         // Do thread-specific cleanup.
            break;

        case DLL_PROCESS_DETACH:
         // Perform any necessary cleanup.
            break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

Entry-Point Function Return Value

When a DLL entry-point function is called because a process is loading, the function returns TRUE to indicate success. For processes using load-time linking, a return value of FALSE causes the process initialization to fail and the process terminates. For processes using run-time linking, a return value of FALSE causes the LoadLibrary or LoadLibraryEx function to return NULL, indicating failure. The return value of the entry-point function is disregarded when the function is called for any other reason.


Load-Time Dynamic Linking

When the system starts a program that uses load-time dynamic linking, it uses the information in the file to locate the names of the required DLL(s). The system then searches for the DLLs in the following locations, in sequence:

  1. The directory from which the application loaded.
  2. The current directory.
  3. Windows 95 and Windows 98: The Windows system directory. Use the GetSystemDirectory function to get the path of this directory.

    Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is SYSTEM32.

  4. Windows NT: The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is SYSTEM.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable.

If the system cannot locate a specified DLL, it terminates the process and displays a dialog box that reports the error. Otherwise, the system maps the DLL modules into the virtual address space of the process and increments the DLL reference count.

The system calls the entry-point function. The function receives a code indicating that the process is loading the DLL. If the entry-point function does not return TRUE, the system terminates the process and reports the error. For more information about the entry-point function, see Dynamic-Link Library Entry-Point Function.

Finally, the system modifies the code of the process to provide starting addresses for the referenced DLL functions.

The DLL is mapped into the virtual address space of the process during its initialization and is loaded into physical memory only when needed.


Run-Time Dynamic Linking

When the application calls the LoadLibrary or LoadLibraryEx functions, the system attempts to locate the DLL using the same search sequence used in load-time dynamic linking (see Load-Time Dynamic Linking). If the search succeeds, the system maps the DLL module into the virtual address space of the process and increments the reference count. If the call to LoadLibrary or LoadLibraryEx specifies a DLL whose code is already mapped into the virtual address space of the calling process, the function simply returns a handle to the DLL and increments the DLL reference count. Note that two DLLs that have the same base filename and extension but are found in different directories are not considered to be the same DLL.

The system calls the entry-point function in the context of the thread that called LoadLibrary or LoadLibraryEx. The entry-point function is not called if the DLL was already loaded by the process through a call to LoadLibrary or LoadLibraryEx with no corresponding call to the FreeLibrary function.

If the system cannot find the DLL or if the entry-point function returns FALSE, LoadLibrary or LoadLibraryEx returns NULL. If LoadLibrary or LoadLibraryEx succeeds, it returns a handle to the DLL module. The process can use this handle to identify the DLL in a call to the GetProcAddress, FreeLibrary, or FreeLibraryAndExitThread function.

The GetModuleHandle function returns a handle used in GetProcAddress, FreeLibrary, or FreeLibraryAndExitThread. The GetModuleHandle function succeeds only if the DLL module is already mapped into the address space of the process by load-time linking or by a previous call to LoadLibrary or LoadLibraryEx. Unlike LoadLibrary or LoadLibraryEx, GetModuleHandle does not increment the module reference count. The GetModuleFileName function retrieves the full path of the module associated with a handle returned by GetModuleHandle, LoadLibrary, or LoadLibraryEx.

The process can use GetProcAddress to get the address of an exported function in the DLL using a DLL module handle returned by either LoadLibrary, LoadLibraryEx, or GetModuleHandle.

When the DLL module is no longer needed, the process can call FreeLibrary or FreeLibraryAndExitThread. These functions decrement the module reference count and unmap the DLL code from the virtual address space of the process if the reference count is zero.

Run-time dynamic linking enables the process to continue running even if a DLL is not available. The process can then use an alternate method to accomplish its objective. For example, if a process is unable to locate one DLL, it can try to use another, or it can notify the user of an error. If the user can provide the full path of the missing DLL, the process can use this information to load the DLL even though it is not in the normal search path. This situation contrasts with load-time linking, in which the system simply terminates the process if it cannot find the DLL.

Run-time dynamic linking can cause problems if the DLL uses the DllMain function to perform initialization for each thread of a process, because the entry-point is not called for threads that existed before LoadLibrary or LoadLibraryEx is called. For an example showing how to deal with this problem, see Using Thread Local Storage in a Dynamic-Link Library.


Dynamic-Link Library Data

Win32-based DLLs can contain global data or local data.

Variable Scope

The default scope of DLL variables is the same as that of variables declared in the application. Global variables in a DLL source code file are global to each process using the DLL. Static variables have scope limited to the block in which they are declared. As a result, each process has its own instance of the DLL global and static variables by default.

Your development tools may allow you to override the default scope of global and static variables. For more information, see the documentation included with your development tools.

Dynamic Memory Allocation

When a DLL allocates memory using any of the memory allocation functions (GlobalAlloc, LocalAlloc, HeapAlloc, and VirtualAlloc), the memory is allocated in the virtual address space of the calling process and is accessible only to the threads of that process.

A DLL can use file mapping to allocate memory that can be shared among processes. For a general discussion of how to use file mapping to create named shared memory, see File Mapping. For an example that uses the DllMain function to set up shared memory using file mapping, see Using Shared Memory in a Dynamic-Link Library.

Thread Local Storage

The thread local storage (TLS) functions enable a DLL to allocate an index for storing and retrieving a different value for each thread of a multithreaded process. For example, a spreadsheet application can create a new instance of the same thread each time the user opens a new spreadsheet. A DLL providing the functions for various spreadsheet operations can use TLS to save information about the current state of each spreadsheet (row, column, and so on). For a general discussion of thread local storage, see Thread Local Storage. For an example that uses the DllMain function to set up thread local storage, see Using Thread Local Storage in a Dynamic-Link Library.

Warning The Visual C++ compiler supports a syntax that enables you to declare thread-local variables: _declspec(thread). If you use this syntax in a DLL, you will not be able to load the DLL explicitly using LoadLibrary or LoadLibraryEx. If your DLL will be loaded explicitly, you must use the thread local storage functions instead of _declspec(thread).


Using Dynamic-Link Libraries

  • Creating a simple dynamic-link library
  • Viewing the DLL exports
  • Using load-time dynamic linking
  • Using run-time dynamic linking
  • Using shared memory in a dynamic-link library
  • Using thread local storage in a dynamic-link library


Creating a Simple Dynamic-Link Library

The following example, MYPUTS.C, is the source code needed to create a simple DLL, MYPUTS.DLL. The file MYPUTS.C contains a simple string-printing function called myPuts. The MYPUTS DLL does not define an entry-point function, because it is linked with the C run-time library and has no initialization or cleanup functions of its own to perform.

// File: MYPUTS.C.
// The myPuts function writes a null-terminated string to
// the standard output device.
.

#include <windows.h>

VOID myPuts(LPTSTR lpszMsg)
{
    DWORD cchWritten;
    HANDLE hStdout;

    // Get a handle to the standard output device.

    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    // Write a null-terminated string to the standard output device.

    while (*lpszMsg)
        WriteFile(hStdout, lpszMsg++, 1, &cchWritten, NULL);
}

To build the DLL, follow the directions in the documentation included with your development tools.


Viewing the DLL Exports

If you would like to view the names of the functions that are exported from a given Win32-based DLL, use the following steps.

  • Start the Windows Explorer or Windows NT Explorer from the Start menu.
  • Click the DLL with the right mouse button.
  • Click Quick View from the menu.
  • Scroll to the heading, Export Table. The table contains the ordinal, entry point, and name for each export.

Your linker (or a similar tool) may also provide a list of exported functions. For more information, see the documentation included with your development tools.


Using Load-Time Dynamic Linking

After you have created a DLL, you can use it in an application. The following file, LOADTIME.C, is the source code for a simple console application that uses the myPuts function exported from MYPUTS.DLL.

// File: LOADTIME.C.
// A simple program that uses myPuts from MYPUTS.DLL.

#include <windows.h>

VOID myPuts(LPTSTR);   // a function from a DLL

VOID main(VOID)
{
    myPuts("message printed using the DLL function\n");
}

Because LOADTIME.C calls the DLL function explicitly, the module for the application must be linked with the import library MYPUTS.LIB. For more information about building DLLs, see the documentation included with your development tools.


Using Run-Time Dynamic Linking

You can use the same DLL in both load-time and run-time dynamic linking. The following source code produces the same output as the load-time example in the previous section. The program uses the LoadLibrary function to get a handle to MYPUTS.DLL. If LoadLibrary succeeds, the program uses the returned handle in the GetProcAddress function to get the address of the DLL's myPuts function. After calling the DLL function, the program calls the FreeLibrary function to unload the DLL.

The following example illustrates an important difference between run-time and load-time dynamic linking. If the MYPUTS.DLL file is not available, the application using load-time dynamic linking simply terminates. The run-time dynamic linking example, however, can respond to the error.

// File:  RUNTIME.C
// A simple program that uses LoadLibrary and
// GetProcAddress to access myPuts from MYPUTS.DLL.

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

typedef VOID (*MYPROC)(LPTSTR);

VOID main(VOID)
{
    HINSTANCE hinstLib;
    MYPROC ProcAdd;
    BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;

    // Get a handle to the DLL module.

    hinstLib = LoadLibrary("myputs");

    // If the handle is valid, try to get the function address.

    if (hinstLib != NULL)
    {
        ProcAdd = (MYPROC) GetProcAddress(hinstLib, "myPuts");

        // If the function address is valid, call the function.

        if (fRunTimeLinkSuccess = (ProcAdd != NULL))
            (ProcAdd) ("message via DLL function\n");

        // Free the DLL module.

        fFreeResult = FreeLibrary(hinstLib);
    }

    // If unable to call the DLL function, use an alternative.

    if (! fRunTimeLinkSuccess)
        printf("message via alternative method\n");
}

Because the program uses run-time dynamic linking, you should not link with the import library when creating the program module.


Using Shared Memory in a Dynamic-Link Library

This section shows how the DLL entry-point function can use a file-mapping object to set up memory that can be shared by processes that load the DLL. The shared DLL memory persists only as long as the DLL is loaded.

The example uses file mapping to map a block of named shared memory into the virtual address space of each process that loads the DLL. To do this, the entry-point function must:

  1. Call the CreateFileMapping function to get a handle to a file-mapping object. The first process that loads the DLL creates the file-mapping object. Subsequent processes open a handle to the existing object. For more information, see Creating a File-Mapping Object.
  2. Call the MapViewOfFile function to map a view into the virtual address space. This enables the process to access the shared memory. For more information, see Creating a File View.
// File:  DLLSHMEM.C.
// The DLL entry-point function sets up shared memory using
// a named file-mapping object.

#include <windows.h>
#include <memory.h>

#define SHMEMSIZE 4096

static LPVOID lpvMem = NULL; // pointer to shared memory

BOOL DllMain(HINSTANCE hinstDLL,  // DLL module handle
    DWORD fdwReason,              // reason called
    LPVOID lpvReserved)           // reserved
{
    HANDLE hMapObject = NULL;  // handle to file mapping
    BOOL fInit, fIgnore;

    switch (fdwReason)
    {
        // The DLL is loading due to process
        // initialization or a call to LoadLibrary.

          case DLL_PROCESS_ATTACH:

            // Create a named file mapping object.

            hMapObject = CreateFileMapping(
                (HANDLE) 0xFFFFFFFF, // use paging file
                NULL,                // no security attributes
                PAGE_READWRITE,      // read/write access
                0,                   // size: high 32-bits
                SHMEMSIZE,           // size: low 32-bits
                "dllmemfilemap");    // name of map object
            if (hMapObject == NULL)
                return FALSE;

            // The first process to attach initializes memory.

            fInit = (GetLastError() != ERROR_ALREADY_EXISTS);

            // Get a pointer to the file-mapped shared memory.

            lpvMem = MapViewOfFile(
                hMapObject,     // object to map view of
                FILE_MAP_WRITE, // read/write access
                0,              // high offset:  map from
                0,              // low offset:   beginning
                0);             // default: map entire file
            if (lpvMem == NULL)
                return FALSE;

            // Initialize memory if this is the first process.

            if (fInit)
                memset(lpvMem, '\0', SHMEMSIZE);

            break;

        // The attached process creates a new thread.

        case DLL_THREAD_ATTACH:
            break;

        // The thread of the attached process terminates.

        case DLL_THREAD_DETACH:
            break;

        // The DLL is unloading from a process due to
        // process termination or a call to FreeLibrary.

        case DLL_PROCESS_DETACH:

            // Unmap shared memory from the process's address space.

            fIgnore = UnmapViewOfFile(lpvMem);

            // Close the process's handle to the file-mapping object.

            fIgnore = CloseHandle(hMapObject);

            break;

        default:
          break;
     }

    return TRUE;
    UNREFERENCED_PARAMETER(hinstDLL);
    UNREFERENCED_PARAMETER(lpvReserved);
}

// SetSharedMem sets the contents of shared memory.

VOID SetSharedMem(LPTSTR lpszBuf)
{
    LPTSTR lpszTmp;

    // Get the address of the shared memory block.

    lpszTmp = (LPTSTR) lpvMem;

    // Copy the null-terminated string into shared memory.

    while (*lpszBuf)
        *lpszTmp++ = *lpszBuf++;
    *lpszTmp = '\0';
}

// GetSharedMem gets the contents of shared memory.

VOID GetSharedMem(LPTSTR lpszBuf, DWORD cchSize)
{
    LPTSTR lpszTmp;

    // Get the address of the shared memory block.

    lpszTmp = (LPTSTR) lpvMem;

    // Copy from shared memory into the caller's buffer.

    while (*lpszTmp && --cchSize)
        *lpszBuf++ = *lpszTmp++;
    *lpszBuf = '\0';
}

Note that the shared memory can be mapped to a different address in each process. For this reason, each process has its own instance of the lpvMem parameter, which is declared as a global variable so that it is available to all DLL functions. The example assumes that the DLL global data is not shared, so each process that loads the DLL has its own instance of lpvMem.

In this example, the shared memory is released when the last handle to the file-mapping object is closed. To create persistent shared memory, a DLL can create a detached process (see CreateProcess) when the DLL is first loaded. If this detached process uses the DLL and does not terminate, it has a handle to the file-mapping object that prevents the shared memory from being released.


Using Thread Local Storage in a Dynamic-Link Library

This section shows the use of a DLL entry-point function to set up a thread local storage (TLS) index to provide private storage for each thread of a multithreaded process.

The entry-point function uses the TlsAlloc function to allocate a TLS index whenever a process loads the DLL. Each thread can then use this index to store a pointer to its own block of memory.

When the entry-point function is called with the DLL_PROCESS_ATTACH value, the code performs the following actions:

  1. Uses the TlsAlloc function to allocate a TLS index.
  2. Allocates a block of memory to be used exclusively by the initial thread of the process.
  3. Uses the TLS index in a call to the TlsSetValue function to store a pointer to the allocated memory.

Each time the process creates a new thread, the entry-point function is called with the DLL_THREAD_ATTACH value. The entry-point function then allocates a block of memory for the new thread and stores a pointer to it by using the TLS index. Each thread can use the TLS index in a call to TlsGetValue to retrieve the pointer to its own block of memory.

When a thread terminates, the entry-point function is called with the DLL_THREAD_DETACH value and the memory for that thread is freed. When a process terminates, the entry-point function is called with the DLL_PROCESS_DETACH value and the memory referenced by the pointer in the TLS index is freed.

The TLS index is stored in a global variable, making it available to all of the DLL functions. The following example assumes that the DLL's global data is not shared, because the TLS index is not necessarily the same for each process that loads the DLL.

static DWORD dwTlsIndex; // address of shared memory

// DllMain() is the entry-point function for this DLL.

BOOL DllMain(HINSTANCE hinstDLL,  // DLL module handle
    DWORD fdwReason,              // reason called
    LPVOID lpvReserved)           // reserved
{
    LPVOID lpvData;
    BOOL fIgnore;

    switch (fdwReason) {

        // The DLL is loading due to process
        // initialization or a call to LoadLibrary.

        case DLL_PROCESS_ATTACH:

            // Allocate a TLS index.

            if ((dwTlsIndex = TlsAlloc()) == 0xFFFFFFFF)
                return FALSE;

            // No break: Initialize the index for first thread.

        // The attached process creates a new thread.

        case DLL_THREAD_ATTACH:

            // Initialize the TLS index for this thread.

            lpvData = (LPVOID) LocalAlloc(LPTR, 256);
            if (lpvData != NULL)
                fIgnore = TlsSetValue(dwTlsIndex, lpvData);

            break;

        // The thread of the attached process terminates.

        case DLL_THREAD_DETACH:

            // Release the allocated memory for this thread.

            lpvData = TlsGetValue(dwTlsIndex);
            if (lpvData != NULL)
                LocalFree((HLOCAL) lpvData);

            break;

        // DLL unload due to process termination or FreeLibrary.

        case DLL_PROCESS_DETACH:

            // Release the allocated memory for this thread.

            lpvData = TlsGetValue(dwTlsIndex);
            if (lpvData != NULL)
                LocalFree((HLOCAL) lpvData);

            // Release the TLS index.

            TlsFree(dwTlsIndex);
            break;

        default:
            break;
    }

    return TRUE;
    UNREFERENCED_PARAMETER(hinstDLL);
    UNREFERENCED_PARAMETER(lpvReserved);
}

When a process uses load-time linking with this DLL, the entry-point function is sufficient to manage the thread local storage. Problems can occur with a process that uses run-time linking because the entry-point function is not called for threads that exist before the LoadLibrary function is called, so TLS memory is not allocated for these threads. The following example solves this problem by checking the value returned by the TlsGetValue function and allocating memory if the value indicates that the TLS slot for this thread is not set.

LPVOID lpvData;

// Retrieve a data pointer for the current thread.

lpvData = TlsGetValue(dwTlsIndex);

// If NULL, allocate memory for this thread.

if (lpvData == NULL) {
    lpvData = (LPVOID) LocalAlloc(LPTR, 256);
    if (lpvData != NULL)
        TlsSetValue(dwTlsIndex, lpvData);
}


Dynamic-Link Library Reference

The following elements are used in dynamic linking.

  • Dynamic-Link Library Functions


Dynamic-Link Library Functions

The following functions are used in dynamic linking.

DisableThreadLibraryCalls
DllMain
FreeLibrary
FreeLibraryAndExitThread
GetModuleFileName
GetModuleHandle
GetProcAddress
LoadLibrary
LoadLibraryEx
LoadModule

Obsolete Functions

FreeModule
FreeProcInstance
MakeProcInstance


DisableThreadLibraryCalls

The DisableThreadLibraryCalls function disables the DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications for the dynamic-link library (DLL) specified by hLibModule. This can reduce the size of the working code set for some applications.

BOOL DisableThreadLibraryCalls(
  HMODULE hLibModule  // dynamic-link library for which calls are to be disabled
);

Parameters

hLibModule
Specifies the dynamic-link library module for which the DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications are to be disabled.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. The DisableThreadLibraryCalls function fails if the DLL specified by hLibModule has active static thread local storage, or if hLibModule is an invalid module handle. To get extended error information, call GetLastError.

Remarks

The DisableThreadLibraryCalls function lets a DLL disable the DLL_THREAD_ATTACH and DLL_THREAD_DETACH notification calls. This can be a useful optimization for multithreaded applications that have many DLLs, frequently create and delete threads, and whose DLLs do not need these thread-level notifications of attachment/detachment. A remote procedure call (RPC) server application is an example of such an application. In these sorts of applications, DLL initialization routines often remain in memory to service DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications. By disabling the notifications, the DLL initialization code is not paged in because a thread is created or deleted, thus reducing the size of the application's working code set. To implement the optimization, modify a DLL's DLL_PROCESS_ATTACH code to call DisableThreadLibraryCalls.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Dynamic-Link Libraries Overview, Dynamic-Link Library Functions, FreeLibraryAndExitThread


DllMain

The DllMain function is an optional method of entry into a dynamic-link library (DLL). If the function is used, it is called by the system when processes and threads are initialized and terminated, or upon calls to the LoadLibrary and FreeLibrary functions.

DllMain is a placeholder for the library-defined function name. Earlier versions of the SDK documentation used DllEntryPoint as the entry-point function name. You must specify the actual name you use when you build your DLL. For more information, see the documentation included with your development tools.

BOOL WINAPI DllMain(
  HINSTANCE hinstDLL,  // handle to DLL module
  DWORD fdwReason,     // reason for calling function
  LPVOID lpvReserved   // reserved
);

Parameters

hinstDLL
A handle to the DLL. The value is the base address of the DLL. The HINSTANCE of a DLL is the same as the HMODULE of the DLL, so hinstDLL can be used in subsequent calls to the GetModuleFileName function and other functions that require a module handle.
fdwReason
Specifies a flag indicating why the DLL entry-point function is being called. This parameter can be one of the following values:
Value | Meaning
DLL_PROCESS_ATTACH | Indicates that the DLL is being loaded into the virtual address space of the current process as a result of the process starting up or as a result of a call to LoadLibrary. DLLs can use this opportunity to initialize any instance data or to use the TlsAlloc function to allocate a thread local storage (TLS) index.
DLL_THREAD_ATTACH Indicates that the current process is creating a new thread. When this occurs, the system calls the entry-point function of all DLLs currently attached to the process. The call is made in the context of the new thread. DLLs can use this opportunity to initialize a TLS slot for the thread. A thread calling the DLL entry-point function with DLL_PROCESS_ATTACH does not call the DLL entry-point function with DLL_THREAD_ATTACH.

Note that a DLL's entry-point function is called with this value only by threads created after the DLL is loaded by the process. When a DLL is loaded using LoadLibrary, existing threads do not call the entry-point function of the newly loaded DLL.
DLL_THREAD_DETACH | Indicates that a thread is exiting cleanly. If the DLL has stored a pointer to allocated memory in a TLS slot, it uses this opportunity to free the memory. The system calls the entry-point function of all currently loaded DLLs with this value. The call is made in the context of the exiting thread.
DLL_PROCESS_DETACH | Indicates that the DLL is being unloaded from the virtual address space of the calling process as a result of either a process exit or a call to FreeLibrary. The DLL can use this opportunity to call the TlsFree function to free any TLS indices allocated by using TlsAlloc and to free any thread local data.

lpvReserved
Specifies further aspects of DLL initialization and cleanup.

If fdwReason is DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads and non-NULL for static loads.

If fdwReason is DLL_PROCESS_DETACH, lpvReserved is NULL if DllMain has been called by using FreeLibrary and non-NULL if DllMain has been called during process termination.

Return Values

When the system calls the DllMain function with the DLL_PROCESS_ATTACH value, the function returns TRUE if it succeeds or FALSE if initialization fails. If the return value is FALSE when DllMain is called because the process uses the LoadLibrary function, LoadLibrary returns NULL. If the return value is FALSE when DllMain is called during process initialization, the process terminates with an error. To get extended error information, call GetLastError.

When the system calls the DllMain function with any value other than DLL_PROCESS_ATTACH, the return value is ignored.

Remarks

During initial process startup or after a call to LoadLibrary, the system scans the list of loaded DLLs for the process. For each DLL that has not already been called with the DLL_PROCESS_ATTACH value, the system calls the DLL's entry-point function. This call is made in the context of the thread that caused the process address space to change, such as the primary thread of the process or the thread that called LoadLibrary.

There are cases in which the entry-point function is called for a terminating thread even if the DLL never attached to the thread — for example, the entry-point function was never called with the DLL_THREAD_ATTACH value in the context of the thread in either of these two situations:

  • The thread was the initial thread in the process, so the system called the entry-point function with the DLL_PROCESS_ATTACH value.
  • The thread was already running when a call to the LoadLibrary function was made, so the system never called the entry-point function for it.

When a DLL is unloaded from a process as a result of process termination or as a result of a call to FreeLibrary, the system does not call the DLL's entry-point function with the DLL_THREAD_DETACH value for the individual threads of the process. The DLL is only given DLL_PROCESS_DETACH notification. DLLs can take this opportunity to clean up all resources for all threads known to the DLL.

Warning On attach, the body of your DLL entry-point function should perform only simple initialization tasks, such as setting up thread local storage (TLS), creating synchronization objects, and opening files. You must not call LoadLibrary in the entry-point function, because you may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, you must not call the FreeLibrary function in the entry-point function on detach, because this can result in a DLL being used after the system has executed its termination code.

Calling Win32 functions other than TLS, synchronization, and file functions may result in problems that are difficult to diagnose. For example, calling User, Shell, COM, RPC, and Windows Sockets functions (or any functions that call these functions) can cause access violation errors, because their DLLs call LoadLibrary to load other system components.

To provide more complex initialization, create an initialization routine for the DLL. You can require applications to call the initialization routine before calling any other routines in the DLL. Otherwise, you can have the initialization routine create a named mutex, and have each routine in the DLL call the initialization routine if the mutex does not exist.

See Also

Dynamic-Link Libraries Overview, Dynamic-Link Library Functions, Dynamic-Link Library Entry-Point Function, FreeLibrary, GetModuleFileName, LoadLibrary, TlsAlloc, TlsFree


FreeLibrary

The FreeLibrary function decrements the reference count of the loaded dynamic-link library (DLL) module. When the reference count reaches zero, the module is unmapped from the address space of the calling process and the handle is no longer valid.

BOOL FreeLibrary(
  HMODULE hLibModule   // handle to loaded library module
);

Parameters

hLibModule
Handle to the loaded library module. The LoadLibrary or GetModuleHandle function returns this handle.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Each process maintains a reference count for each loaded library module. This reference count is incremented each time LoadLibrary is called and is decremented each time FreeLibrary is called. A DLL module loaded at process initialization due to load-time dynamic linking has a reference count of one. This count is incremented if the same module is loaded by a call to LoadLibrary.

Before unmapping a library module, the system enables the DLL to detach from the process by calling the DLL's DllMain function, if it has one, with the DLL_PROCESS_DETACH value. Doing so gives the DLL an opportunity to clean up resources allocated on behalf of the current process. After the entry-point function returns, the library module is removed from the address space of the current process.

It is not safe to call FreeLibrary from DllMain. For more information, see the Remarks section in DllMain.

Calling FreeLibrary does not affect other processes using the same library module.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Dynamic-Link Libraries Overview, Dynamic-Link Library Functions, DllMain, FreeLibraryAndExitThread, GetModuleHandle, LoadLibrary


FreeLibraryAndExitThread

The FreeLibraryAndExitThread function decrements the reference count of a loaded dynamic-link library (DLL) by one, and then calls ExitThread to terminate the calling thread. The function does not return.

The FreeLibraryAndExitThread function gives threads that are created and executed within a dynamic-link library an opportunity to safely unload the DLL and terminate themselves.

VOID FreeLibraryAndExitThread(
  HMODULE hLibModule,  // dynamic-link library whose reference count
                       // is to decrement
  DWORD dwExitCode     // exit code for thread
);

Parameters

hLibModule
Specifies the dynamic-link library module whose reference count the function decrements.
dwExitCode
Specifies the exit code for the calling thread.

Return Values

The function has no return value. The function does not return. Invalid hLibModule handles are ignored.

Remarks

The FreeLibraryAndExitThread function is implemented as:

FreeLibrary(hLibModule);
    ExitThread(dwExitCode);

Refer to the reference pages for FreeLibrary and ExitThread for further information on those functions.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Dynamic-Link Libraries Overview, Dynamic-Link Library Functions, FreeLibrary, ExitThread, DisableThreadLibraryCalls


FreeModule

The FreeModule function is obsolete.

This function is provided only for compatibility with 16-bit versions of Windows. Win32-based applications should use the FreeLibrary function.

See Also

Dynamic-Link Libraries Overview, Dynamic-Link Library Functions


FreeProcInstance

The FreeProcInstance function is obsolete.

This function is provided only for compatibility with 16-bit versions of Windows. Win32-based applications should not use this function; it has no meaning in the 32-bit environment.

See Also

Dynamic-Link Libraries Overview, Dynamic-Link Library Functions


GetModuleFileName

The GetModuleFileName function retrieves the full path and filename for the executable file containing the specified module.

Windows 95: The GetModuleFilename function will return long filenames when an application's version number is greater than or equal to 4.00 and the long filename is available. Otherwise, it returns only 8.3 format filenames.

DWORD GetModuleFileName(
  HMODULE hModule,    // handle to module to find filename for
  LPTSTR lpFilename,  // pointer to buffer to receive module path
  DWORD nSize         // size of buffer, in characters
);

Parameters

hModule
Handle to the module whose executable filename is being requested. If this parameter is NULL, GetModuleFileName returns the path for the file used to create the calling process.
lpFilename
Pointer to a buffer that is filled in with the path and filename of the given module.
nSize
Specifies the length, in characters, of the lpFilename buffer. If the length of the path and filename exceeds this limit, the string is truncated.

Return Values

If the function succeeds, the return value is the length, in characters, of the string copied to the buffer.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If a module is loaded in two processes, its module filename in one process may differ in case from its module filename in the other process.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Dynamic-Link Libraries Overview, Dynamic-Link Library Functions, GetModuleHandle, LoadLibrary


GetModuleHandle

The GetModuleHandle function returns a module handle for the specified module if the file has been mapped into the address space of the calling process.

HMODULE GetModuleHandle(
  LPCTSTR lpModuleName   // address of module name to return handle
                         // for
);

Parameters

lpModuleName
Pointer to a null-terminated string that contains the name of the module (either a .DLL or .EXE file). If the filename extension is omitted, the default library extension .DLL is appended. The filename string can include a trailing point character (.) to indicate that the module name has no extension. The string does not have to specify a path. When specifying a path, be sure to use backslashes (\), not forward slashes (/). The name is compared (case independently) to the names of modules currently mapped into the address space of the calling process.

If this parameter is NULL, GetModuleHandle returns a handle to the file used to create the calling process.

Return Values

If the function succeeds, the return value is a handle to the specified module.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The returned handle is not global, inheritable, or duplicative, and it cannot be used by another process.

The handles returned by GetModuleHandle and LoadLibrary can be used in the same functions — for example, GetProcAddress, FreeLibrary, or LoadResource. The difference between the two functions involves the reference count. LoadLibrary maps the module into the address space of the calling process, if necessary, and increments the module's reference count, if it is already mapped. GetModuleHandle, however, returns the handle to a mapped module without incrementing its reference count.

Note that the reference count is used in FreeLibrary to determine whether to unmap the function from the address space of the process. For this reason, use care when using a handle returned by GetModuleHandle in a call to FreeLibrary because doing so can cause a dynamic-link library (DLL) module to be unmapped prematurely.

This function must also be used carefully in a multithreaded application. There is no guarantee that the module handle remains valid between the time this function returns the handle and the time it is used by another function. For example, a thread might retrieve a module handle by calling GetModuleHandle. Before the thread uses the handle in another function, a second thread could free the module and the system could load another module, giving it the same handle as the module that was recently freed. The first thread would then be left with a module handle that refers to a module different than the one intended.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Dynamic-Link Libraries Overview, Dynamic-Link Library Functions, FreeLibrary, GetModuleFileName, GetProcAddress, LoadLibrary, LoadResource


GetProcAddress

The GetProcAddress function returns the address of the specified exported dynamic-link library (DLL) function.

FARPROC GetProcAddress(
  HMODULE hModule,    // handle to DLL module
  LPCSTR lpProcName   // name of function
);

Parameters

hModule
Handle to the DLL module that contains the function. The LoadLibrary or GetModuleHandle function returns this handle.
lpProcName
Pointer to a null-terminated string containing the function name, or specifies the function's ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero.

Return Values

If the function succeeds, the return value is the address of the DLL's exported function.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The GetProcAddress function is used to retrieve addresses of exported functions in DLLs.

The spelling and case of the function name pointed to by lpProcName must be identical to that in the EXPORTS statement of the source DLL's module-definition (.DEF) file. The exported names of Win32 API functions may differ from the names you use when calling these functions in your code. This difference is hidden by macros used in the SDK header files. For more information, see Win32 Function Prototypes.

The lpProcName parameter can identify the DLL function by specifying an ordinal value associated with the function in the EXPORTS statement. GetProcAddress verifies that the specified ordinal is in the range 1 through the highest ordinal value exported in the .DEF file. The function then uses the ordinal as an index to read the function's address from a function table. If the .DEF file does not number the functions consecutively from 1 to N (where N is the number of exported functions), an error can occur where GetProcAddress returns an invalid, non-NULL address, even though there is no function with the specified ordinal.

In cases where the function may not exist, the function should be specified by name rather than by ordinal value.

Windows CE: The lpProcName parameter must be in unicode.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Dynamic-Link Libraries Overview, Dynamic-Link Library Functions, FreeLibrary, GetModuleHandle, LoadLibrary


LoadLibrary

The LoadLibrary function maps the specified executable module into the address space of the calling process.

HINSTANCE LoadLibrary(
  LPCTSTR lpLibFileName   // address of filename of executable module
);

Parameters

lpLibFileName
Pointer to a null-terminated string that names the executable module (either a .DLL or .EXE file). The name specified is the filename of the module and is not related to the name stored in the library module itself, as specified by the LIBRARY keyword in the module-definition (.DEF) file.

If the string specifies a path but the file does not exist in the specified directory, the function fails. When specifying a path, be sure to use backslashes (\), not forward slashes (/).

If the string does not specify a path, the function uses a standard search strategy to find the file. See the Remarks for more information.

Return Values

If the function succeeds, the return value is a handle to the module.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

LoadLibrary can be used to map a DLL module and return a handle that can be used in GetProcAddress to get the address of a DLL function. LoadLibrary can also be used to map other executable modules. For example, the function can specify an .EXE file to get a handle that can be used in FindResource or LoadResource. Do not use LoadLibrary to "run" a .EXE file.

If the module is a DLL not already mapped for the calling process, the system calls the DLL's DllMain function with the DLL_PROCESS_ATTACH value. If the DLL's entry-point function does not return TRUE, LoadLibrary fails and returns NULL.

It is not safe to call LoadLibrary from DllMain. For more information, see the Remarks section in DllMain.

Module handles are not global or inheritable. A call to LoadLibrary by one process does not produce a handle that another process can use — for example, in calling GetProcAddress. The other process must make its own call to LoadLibrary for the module before calling GetProcAddress.

If no filename extension is specified in the lpLibFileName parameter, the default library extension .DLL is appended. However, the filename string can include a trailing point character (.) to indicate that the module name has no extension. When no path is specified, the function searches for loaded modules whose base name matches the base name of the module to be loaded. If the name matches, the load succeeds. Otherwise, the function searches for the file in the following sequence:

  1. The directory from which the application loaded.
  2. The current directory.
  3. Windows 95 and Windows 98: The Windows system directory. Use the GetSystemDirectory function to get the path of this directory.

    Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is SYSTEM32.

  4. Windows NT: The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is SYSTEM.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable.

The first directory searched is the one directory containing the image file used to create the calling process (for more information, see the CreateProcess function). Doing this allows private dynamic-link library (DLL) files associated with a process to be found without adding the process's installed directory to the PATH environment variable.

The Visual C++ compiler supports a syntax that enables you to declare thread-local variables: _declspec(thread). If you use this syntax in a DLL, you will not be able to load the DLL explicitly using LoadLibrary or LoadLibraryEx. If your DLL will be loaded explicitly, you must use the thread local storage functions instead of _declspec(thread).

Windows 95: If you are using LoadLibrary to load a module that contains a resource whose numeric identifier is greater than 0x7FFF, LoadLibrary fails.

Windows CE: Two different modules cannot have the same filename, given that the extensions are different. These effectively have the same "module" name. For example, if LoadLibrary is made on "Sample.cpl", the operating system will not load Sample.cpl, but instead will again load Sample.dll. A similar limitation exists for modules with the same name but residing in different directories. For example, if LoadLibrary is called on "\\Windows\Sample.dll", and then LoadLibrary is called on "\\MyDir\Sample.dll", "\\Windows\Sample.dll" will simply be reloaded.

A search path to the executable module cannot be specified. Unless the full path to the module is given, Windows CE will search the following path for the module:

  1. The root directory of the PC Card RAM expansion card, if one exists.
  2. The windows directory (\Windows).
  3. The root directory (\).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Dynamic-Link Libraries Overview, Dynamic-Link Library Functions, DllMain, FindResource, FreeLibrary, GetProcAddress, GetSystemDirectory, GetWindowsDirectory, LoadLibraryEx, LoadResource


LoadLibraryEx

The LoadLibraryEx function maps a specified executable module into the address space of the calling process. The executable module can be a .DLL or an .EXE file. The specified module may cause other modules to be mapped into the address space.

HINSTANCE LoadLibraryEx(
  LPCTSTR lpLibFileName,  // points to name of executable module
  HANDLE hFile,           // reserved, must be NULL
  DWORD dwFlags           // entry-point execution flag
);

Parameters

lpLibFileName
Pointer to a null-terminated string that names the executable module (either a .DLL or an .EXE file). The name specified is the filename of the executable module. This name is not related to the name stored in a library module itself, as specified by the LIBRARY keyword in the module-definition (.DEF) file.

If the string specifies a path, but the file does not exist in the specified directory, the function fails. When specifying a path, be sure to use backslashes (\), not forward slashes (/).

If the string does not specify a path, and the filename extension is omitted, the function appends the default library extension .DLL to the filename. However, the filename string can include a trailing point character (.) to indicate that the module name has no extension.

If the string does not specify a path, the function uses a standard search strategy to find the file. See the Remarks for more information.

If mapping the specified module into the address space causes the system to map in other, associated executable modules, the function can use either the standard search strategy or an alternate search strategy to find those modules. See the Remarks for more information.

hFile
This parameter is reserved for future use. It must be NULL.
dwFlags
Specifies the action to take when loading the module. If no flags are specified, the behavior of this function is identical to that of the LoadLibrary function. This parameter can be one of the following values:
Flag Meaning
DONT_RESOLVE_DLL_
REFERENCE 		Windows NT: If this value is used, and the executable module is a DLL, the system does not call DllMain for process and thread initialization and termination. Also, the system does not load additional executable modules that are referenced by the specified module.

If this value is not used, and the executable module is a DLL, the system calls DllMain for process and thread initialization and termination. The system loads additional executable modules that are referenced by the specified module.

LOAD_LIBRARY_AS_
DATAFILE 		If this value is used, the system maps the file into the calling process's virtual address space as if it were a data file. Nothing is done to execute or prepare to execute the mapped file. You can use the module handle that the function returns with any Win32 functions that operate on resources. Use this flag when you want to load a DLL only to extract messages or resources from it.
LOAD_WITH_ALTERED
_SEARCH_PATH 		If this value is used, and lpLibFileName specifies a path, the system uses the alternate file search strategy discussed in the Remarks section to find associated executable modules that the specified module causes to be loaded.

If this value is not used, or if lpLibFileName does not specify a path, the system uses the standard search strategy discussed in the Remarks section to find associated executable modules that the specified module causes to be loaded.

Return Values

If the function succeeds, the return value is a handle to the mapped executable module.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The calling process can use the handle returned by this function to identify the module in calls to the GetProcAddress, FindResource, and LoadResource functions.

The LoadLibraryEx function is very similar to the LoadLibrary function. The differences consist of a set of optional behaviors that LoadLibraryEx provides. First, LoadLibraryEx can map a DLL module without calling the DllMain function of the DLL. Second, LoadLibraryEx can use either of two file search strategies to find executable modules that are associated with the specified module. Third, LoadLibraryEx can load a module in a way that is optimized for the case where the module will never be executed, loading the module as if it were a data file. You select these optional behaviors by setting the dwFlags parameter; if dwFlags is zero, LoadLibraryEx behaves identically to LoadLibrary.

It is not safe to call LoadLibraryEx from DllMain. For more information, see the Remarks section in DllMain.

If no path is specified in the lpLibFileName parameter, and the base filename does not match the base filename of a loaded module, the LoadLibraryEx function uses the same standard file search strategy that LoadLibrary, SearchPath, and OpenFile use to find the executable module and any associated executable modules that it causes to be loaded. This standard strategy searches for a file in the following sequence:

  1. The directory from which the application loaded.
  2. The current directory.
  3. Windows 95 and Windows 98: The Windows system directory. Use the GetSystemDirectory function to get the path of this directory.

    Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is SYSTEM32.

  4. Windows NT: The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is SYSTEM.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable.

If a path is specified, and the dwFlags parameter is set to LOAD_WITH_ALTERED_SEARCH_PATH, the LoadLibraryEx function uses an alternate file search strategy to find any executable modules that the specified module causes to be loaded. This alternate strategy searches for a file in the following sequence:

  1. The directory specified by the lpLibFileName path. In other words, the directory that the specified executable module is in.
  2. The current directory.
  3. Windows 95 and Windows 98: The Windows system directory. Use the GetSystemDirectory function to get the path of this directory.

    Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is SYSTEM32.

  4. Windows NT: The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is SYSTEM.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable.

Note that the standard file search strategy and the alternate search strategy differ in just one way: the standard strategy starts its search in the calling application's directory, and the alternate strategy starts its search in the directory of the executable module that LoadLibraryEx is loading.

If you specify the alternate search strategy, its behavior continues until all associated executable modules have been located. Once the system starts processing DLL initialization routines, the system reverts to the standard search strategy.

The Visual C++ compiler supports a syntax that enables you to declare thread-local variables: _declspec(thread). If you use this syntax in a DLL, you will not be able to load the DLL explicitly using LoadLibrary or LoadLibraryEx. If your DLL will be loaded explicitly, you must use the thread local storage functions instead of _declspec(thread).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Dynamic-Link Libraries Overview, Dynamic-Link Library Functions, DllMain, FindResource, FreeLibrary, GetProcAddress, GetSystemDirectory, GetWindowsDirectory, LoadLibrary, LoadResource, OpenFile, SearchPath


LoadModule

The LoadModule function loads and executes an application or creates a new instance of an existing application.

This function is provided for compatibility with 16-bit versions of Windows. Win32-based applications should use the CreateProcess function.

DWORD LoadModule(
  LPCSTR lpModuleName,  // address of filename to load
  LPVOID lpParameterBlock   // address of parameter block for new
                            // module
);

Parameters

lpModuleName
Pointer to a null-terminated string that contains the filename of the application to run. When specifying a path, be sure to use backslashes (\), not forward slashes (/). If the lpModuleName parameter does not contain a directory path, the system searches for the executable file in this order:
  1. The directory from which the application loaded.
  2. The current directory.
  3. Windows 95 and Windows 98: The Windows system directory. Use the GetSystemDirectory function to get the path of this directory.

    Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is SYSTEM32.

  4. Windows NT: The 16-bit Windows system directory. There is no Win32 function that obtains the path of this directory, but it is searched. The name of this directory is SYSTEM.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable.
lpParameterBlock
Pointer to an application-defined LOADPARMS32 structure that defines the new application's parameter block.

The LOADPARMS32 structure has the following form:

typedef struct tagLOADPARMS32 {
    LPSTR lpEnvAddress;  // address of environment strings
    LPSTR lpCmdLine;     // address of command line
    LPSTR lpCmdShow;     // how to show new program
    DWORD dwReserved;    // must be zero
} LOADPARMS32;
Member | Description
lpEnvAddress | Pointer to an array of null-terminated strings that supply the environment strings for the new process. The array has a value of NULL as its last entry. A value of NULL for this parameter causes the new process to start with the same environment as the calling process.
lpCmdLine | Pointer to a Pascal-style string that contains a correctly formed command line. The first byte of the string contains the number of bytes in the string. The remainder of the string contains the command line arguments, excluding the name of the child process. If there are no command line arguments, this parameter must point to a zero length string; it cannot be NULL.
lpCmdShow | Pointer to a structure containing two WORD values. The first value must always be set to two. The second value specifies how the application window is to be shown and is used to supply the wShowWindow member of the STARTUPINFO structure to the CreateProcess function. See the description of the nCmdShow parameter of the ShowWindow function for a list of acceptable values.
dwReserved | This parameter is reserved; it must be zero.

Set all unused members to NULL, except for lpCmdLine, which must point to a null-terminated string if it is not used.

Return Values

If the function succeeds, the return value is greater than 31.

If the function fails, the return value is an error value, which may be one of the following:

Value | Meaning
0 | The system is out of memory or resources.
ERROR_BAD_FORMAT | The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).
ERROR_FILE_NOT_FOUND | The specified file was not found.
ERROR_PATH_NOT_FOUND | The specified path was not found.

Remarks

Win32-based applications should use the CreateProcess function. In the Win32 API, the implementation of the LoadModule function calls CreateProcess. The following section describes how each parameter for CreateProcess is formed:

CreateProcess parameter | Value
lpszImageName | LoadModule lpModuleName parameter.
lpszCommandLine | LoadModule lpParameterBlock->lpCmdLine.
lpsaProcess | NULL.
lpsaThread | NULL.
fInheritHandles | FALSE.
fdwCreate | 0.
lpvEnvironment | LoadModule lpParameterBlock->lpEnvAddress.
lpszCurDir | NULL.
lpsiStartInfo | The structure is initialized to zero. The cb member is set to the size of the structure, and the wShowWindow member is set to the value of the second word of the LoadModule lpParameterBlock->lpCmdShow parameter.
lppiProcInfo.hProcess | The handle is immediately closed.
lppiProcInfo.hThread | The handle is immediately closed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Dynamic-Link Libraries Overview, Dynamic-Link Library Functions, CreateProcess, GetSystemDirectory, GetWindowsDirectory, ShowWindow, STARTUPINFO, WinExec


MakeProcInstance

The MakeProcInstance function is obsolete. Win32 functions can be called directly.

This function is provided only for compatibility with 16-bit versions of Windows. Win32-based applications should not use this function.

See Also

Dynamic-Link Libraries Overview, Dynamic-Link Library Functions


Processes and Threads

A Win32®-based application consists of one or more processes. A process, in the simplest terms, is an executing program. One or more threads run in the context of the process. A thread is the basic unit to which the operating system allocates processor time. A thread can execute any part of the process code, including parts currently being executed by another thread. A fiber is a unit of execution that must be manually scheduled by the application. Fibers run in the context of the threads that schedule them.

A job object allows groups of processes to be managed as a unit. Job objects are namable, securable, sharable objects that control attributes of the processes associated with them. Operations performed on the job object affect all processes associated with the job object.


About Processes and Threads

Each process provides the resources needed to execute a program. A process has a virtual address space, executable code, data, object handles, environment variables, a base priority, and minimum and maximum working set sizes. Each process is started with a single thread, often called the primary thread, but can create additional threads from any of its threads.

All threads of a process share its virtual address space and system resources. In addition, each thread maintains exception handlers, a scheduling priority, and a set of structures the system will use to save the thread context until it is scheduled. The thread context includes the thread's set of machine registers, the kernel stack, a thread environment block, and a user stack in the address space of the thread's process.

Windows NT, Windows 95, and Windows 98 support preemptive multitasking, which creates the effect of simultaneous execution of multiple threads from multiple processes. On a multiprocessor computer, Windows NT can simultaneously execute as many threads as there are processors on the computer.

This overview discusses the following topics:

  • Multitasking
  • Scheduling
  • Multiple Threads
  • Child Processes
  • Process Working Set
  • Fibers


Multitasking

A multitasking operating system divides the available processor time among the processes or threads that need it. The system is designed for preemptive multitasking; it allocates a processor time slice to each thread it executes. The currently executing thread is suspended when its time slice elapses, allowing another thread to run. When the system switches from one thread to another, it saves the context of the preempted thread and restores the saved context of the next thread in the queue.

The length of the time slice depends on the operating system and the processor. Because each time slice is small (approximately 20 milliseconds), multiple threads appear to be executing at the same time. This is actually the case on multiprocessor systems, where the executable threads are distributed among the available processors. However, you must use caution when using multiple threads in an application, because system performance can decrease if there are too many threads.


Advantages of Multitasking

To the user, the advantage of multitasking is the ability to have several applications open and working at the same time. For example, a user can edit a file with one application while another application is recalculating a spreadsheet.

To the application developer, the advantage of multitasking is the ability to create applications that use more than one process and to create processes that use more than one thread of execution. For example, a process can have a user interface thread that manages interactions with the user (keyboard and mouse input), and worker threads that perform other tasks while the user interface thread waits for user input. If you give the user interface thread a higher priority, the application will be more responsive to the user, while the worker threads use the processor efficiently during the times when there is no user input.


When to Use Multitasking

There are two ways to implement multitasking: as a single process with multiple threads or as multiple processes, each with one or more threads. An application can put each thread that requires a private address space and private resources into its own process, to protect it from the activities of other process threads.

A multithreaded process can manage mutually exclusive tasks with threads, such as providing a user interface and performing background calculations. Creating a multithreaded process can also be a convenient way to structure a program that performs several similar or identical tasks concurrently. For example, a named pipe server can create a thread for each client process that attaches to the pipe. This thread manages the communication between the server and the client. Your process could use multiple threads to accomplish the following tasks:

  • Manage input for multiple windows.
  • Manage input from several communications devices.
  • Distinguish tasks of varying priority. For example, a high-priority thread manages time-critical tasks, and a low-priority thread performs other tasks.
  • Allow the user interface to remain responsive, while allocating time to background tasks.

It is typically more efficient for an application to implement multitasking by creating a single, multithreaded process, rather than creating multiple processes, for the following reasons:

  • The system can perform a context switch more quickly for threads than processes, because a process has more overhead than a thread does (the process context is larger than the thread context).
  • All threads of a process share the same address space and can access the process's global variables, which can simplify communication between threads.
  • All threads of a process can share open handles to resources, such as files and pipes.

The Win32 API also provides alternative methods that can be used in the place of multithreading. The most significant of these methods are asynchronous input and output (I/O) and the ability to wait for multiple events.

A single thread can initiate multiple time-consuming I/O requests that can run concurrently using asynchronous I/O. Asynchronous I/O can be performed on files, pipes, and serial communication devices. For more information, see Synchronization and Overlapped Input and Output.

A single thread can block its own execution while waiting for any one or all of several events to occur. This is more efficient than using multiple threads, each waiting for a single event, and more efficient than using a single thread that consumes processor time by continually checking for events to occur. For more information, see Wait Functions.


Multitasking Considerations

Multitasking has resource requirements and potential conflicts to be considered when designing your application. The resource requirements are as follows:

  • The system consumes memory for the context information required by both processes and threads. Therefore, the number of processes and threads that can be created is limited by available memory.
  • Keeping track of a large number of threads consumes significant processor time. If there are too many threads, most of them will not be able to make significant progress. If most of the current threads are in one process, threads in other processes are scheduled less frequently.

Providing shared access to resources can create conflicts. To avoid them, you must synchronize access to shared resources. This is true for system resources (such as communications ports), resources shared by multiple processes (such as file handles), or the resources of a single process (such as global variables) accessed by multiple threads. Failure to synchronize access properly (in the same or in different processes) can lead to problems such as deadlock and race conditions. The Win32 API provides a set of synchronization objects and functions you can use to coordinate resource sharing among multiple threads. For more information about synchronization, see Synchronizing Execution of Multiple Threads.


Scheduling

The system scheduler controls multitasking by determining which of the competing threads receives the next processor time slice. The scheduler determines which thread runs next using its scheduling priority.

This section discusses the following topics:

  • Scheduling Priorities
  • Context Switches
  • Priority Boosts
  • Priority Inversion
  • Multiple Processors


Scheduling Priorities

Each thread is assigned a scheduling priority. The priority levels range from zero (lowest priority) to 31 (highest priority). Only the zero-page thread can have a priority of zero. The zero-page thread is a system thread.

The priority of each thread is determined by the following criteria:

  • The priority class of its process
  • The priority level of the thread within the priority class of its process

The priority class and priority level are combined to form the base priority of a thread.

Priority Class

Each process belongs to one of the following priority classes:

IDLE_PRIORITY_CLASS
NORMAL_PRIORITY_CLASS
HIGH_PRIORITY_CLASS
REALTIME_PRIORITY_CLASS

By default, the priority class of a process is NORMAL_PRIORITY_CLASS. Use the CreateProcess function to specify the priority class of a child process when you create it. Use SetPriorityClass to change the priority class of a process and GetPriorityClass to determine the current priority class of a process.

Processes that monitor the system, such as screen savers or applications that periodically update a display, should use IDLE_PRIORITY_CLASS. This prevents the threads of this process, which do not have high priority, from interfering with higher priority threads.

Use HIGH_PRIORITY_CLASS with care. If a thread runs at the highest priority level for extended periods, other threads in the system will not get processor time. If several threads are set at high priority at the same time, the threads lose their effectiveness. The high-priority class should be reserved for threads that must respond to time-critical events. If your application performs one task that requires the high-priority class while the rest of its tasks are normal priority, use SetPriorityClass to raise the priority class of the application temporarily; then reduce it after the time-critical task has been completed. Another strategy is to create a high-priority process that has all of its threads blocked most of the time, awakening threads only when critical tasks are needed. The important point is that a high-priority thread should execute for a brief time, and only when it has time-critical work to perform.

You should almost never use REALTIME_PRIORITY_CLASS, because this interrupts system threads that manage mouse input, keyboard input, and background disk flushing. This class can be appropriate for applications that "talk" directly to hardware or that perform brief tasks that should have limited interruptions.

Priority Level

The following are priority levels within each priority class

THREAD_PRIORITY_IDLE
THREAD_PRIORITY_LOWEST
THREAD_PRIORITY_BELOW_NORMAL
THREAD_PRIORITY_NORMAL
THREAD_PRIORITY_ABOVE_NORMAL
THREAD_PRIORITY_HIGHEST
THREAD_PRIORITY_TIME_CRITICAL

All threads are created using THREAD_PRIORITY_NORMAL. This means that the thread priority is the same as the process priority class. After you create a thread, use the SetThreadPriority function to adjust its priority relative to other threads in the process.

A typical strategy is to use THREAD_PRIORITY_ABOVE_NORMAL or THREAD_PRIORITY_HIGHEST for the process's input thread, to ensure that the application is responsive to the user. Background threads, particularly those that are processor intensive, can be set to THREAD_PRIORITY_BELOW_NORMAL or THREAD_PRIORITY_LOWEST, to ensure that they can be preempted when necessary. However, if you have a thread waiting for another thread with a lower priority to complete some task, be sure to block the execution of the waiting high-priority thread. To do this, use a wait function, critical section, or the Sleep function, SleepEx, or SwitchToThread function. This is preferable to having the thread execute a loop. Otherwise, the process may become deadlocked, because the thread with lower priority is never scheduled.

To determine the current priority level of a thread, use the GetThreadPriority function.

Base Priority

The priority level of a thread is determined by both the priority class of its process and its priority level. The priority class and priority level are combined to form the base priority of each thread.

The following table shows the base priority levels for combinations of priority class and priority value.

 | Process Priority Class | Thread Priority Level
1 | IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS | THREAD_PRIORITY_IDLE
2 | IDLE_PRIORITY_CLASS | THREAD_PRIORITY_LOWEST
3 | IDLE_PRIORITY_CLASS | THREAD_PRIORITY_BELOW_NORMAL
4 | IDLE_PRIORITY_CLASS | THREAD_PRIORITY_NORMAL
5 | Background NORMAL_PRIORITY_CLASS | THREAD_PRIORITY_LOWEST
 | IDLE_PRIORITY_CLASS | THREAD_PRIORITY_ABOVE_NORMAL
6 | Background NORMAL_PRIORITY_CLASS | THREAD_PRIORITY_BELOW_NORMAL
 | IDLE_PRIORITY_CLASS | THREAD_PRIORITY_HIGHEST
7 | Foreground NORMAL_PRIORITY_CLASS | THREAD_PRIORITY_LOWEST
 | Background NORMAL_PRIORITY_CLASS | THREAD_PRIORITY_NORMAL
8 | Foreground NORMAL_PRIORITY_CLASS | THREAD_PRIORITY_BELOW_NORMAL
 | NORMAL_PRIORITY_CLASS | THREAD_PRIORITY_ABOVE_NORMAL
9 | Foreground NORMAL_PRIORITY_CLASS | THREAD_PRIORITY_NORMAL
 | NORMAL_PRIORITY_CLASS | THREAD_PRIORITY_HIGHEST
10 | Foreground NORMAL_PRIORITY_CLASS | THREAD_PRIORITY_ABOVE_NORMAL
11 | HIGH_PRIORITY_CLASS | THREAD_PRIORITY_LOWEST
 | Foreground NORMAL_PRIORITY_CLASS | THREAD_PRIORITY_HIGHEST
12 | HIGH_PRIORITY_CLASS | THREAD_PRIORITY_BELOW_NORMAL
13 | HIGH_PRIORITY_CLASS | THREAD_PRIORITY_NORMAL
14 | HIGH_PRIORITY_CLASS | THREAD_PRIORITY_ABOVE_NORMAL
15 | IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS | THREAD_PRIORITY_TIME_CRITICAL
 | HIGH_PRIORITY_CLASS | THREAD_PRIORITY_HIGHEST
16 | REALTIME_PRIORITY_CLASS | THREAD_PRIORITY_IDLE
22 | REALTIME_PRIORITY_CLASS | THREAD_PRIORITY_LOWEST
23 | REALTIME_PRIORITY_CLASS | THREAD_PRIORITY_BELOW_NORMAL
24 | REALTIME_PRIORITY_CLASS | THREAD_PRIORITY_NORMAL
25 | REALTIME_PRIORITY_CLASS | THREAD_PRIORITY_ABOVE_NORMAL
26 | REALTIME_PRIORITY_CLASS | THREAD_PRIORITY_HIGHEST
31 | REALTIME_PRIORITY_CLASS | THREAD_PRIORITY_TIME_CRITICAL


Context Switches

The scheduler maintains a queue of executable threads for each priority level. These are known as ready threads. When a processor becomes available, the system performs a context switch. The steps in a context switch are:

  1. Save the context of the thread that just finished executing.
  2. Place the thread that just finished executing at the end of the queue for its priority.
  3. Find the highest priority queue that contains ready threads.
  4. Remove the thread at the head of the queue, load its context, and execute it.

The following classes of threads are not ready threads.

  • Threads created with the CREATE_SUSPENDED flag
  • Threads halted during execution with the SuspendThread or SwitchToThread function
  • Threads waiting for a synchronization object or input.

Until threads that are suspended or blocked become ready to run, the scheduler does not allocate any processor time to them, regardless of their priority.

The most common reasons for a context switch are:

  • The time slice has elapsed.
  • A thread with a higher priority has become ready to run.
  • A running thread needs to wait.

When a running thread needs to wait, it relinquishes the remainder of its time slice.


Priority Boosts

Each thread has a dynamic priority. This is the priority the scheduler uses to determine which thread to execute. Initially, a thread's dynamic priority is the same as its base priority. The system can boost and lower the dynamic priority, to ensure that it is responsive and that no threads are starved for processor time. The system does not boost the priority of threads with a base priority level between 16 and 31. Only threads with a base priority between 0 and 15 receive dynamic priority boosts.

The system boosts the dynamic priority of a thread to enhance its responsiveness as follows.

  • When a process that uses NORMAL_PRIORITY_CLASS is brought to the foreground, the scheduler boosts the priority class of the process associated with the foreground window, so that it is greater than or equal to the priority class of any background processes. The priority class returns to its original setting when the process is no longer in the foreground.

    Windows NT: The user can control the boosting of processes that use NORMAL_PRIORITY_CLASS through the System control panel application.

  • When a window receives input, such as timer messages, mouse messages, or keyboard input, the scheduler boosts the priority of the thread that owns the window.
  • When the wait conditions for a blocked thread are satisfied, the scheduler boosts the priority of the thread. For example, when a wait operation associated with disk or keyboard I/O finishes, the thread receives a priority boost.

    Windows NT: You can disable the priority-boosting feature by calling the SetProcessPriorityBoost or SetThreadPriorityBoost function. To determine whether this feature has been disabled, call the GetProcessPriorityBoost or GetThreadPriorityBoost function.

After raising a thread's dynamic priority, the scheduler reduces that priority by one level each time the thread completes a time slice, until the thread drops back to its base priority. A thread's dynamic priority is never less than its base priority.


Priority Inversion

Priority inversion occurs when two or more threads with different priorities are in contention to be scheduled. Consider a simple case with three threads: thread 1, thread 2, and thread 3. Thread 1 is high priority and becomes ready to be scheduled. Thread 2, a low-priority thread, is executing code in a critical section. Thread 1, the high-priority thread, begins waiting for a shared resource from thread 2. Thread 3 has medium priority. Thread 3 receives all the processor time, because the high-priority thread (thread 1) is waiting for shared resources from the low-priority thread (thread 2). Thread 2 won't leave the critical section, because does not have the highest priority and won't be scheduled.

Windows NT: The scheduler solves this problem by randomly boosting the priority of the ready threads (in this case, the low priority lock-holders). The low priority threads run long enough to exit the critical section, and the high- priority thread can enter the critical section. If the low-priority thread doesn't get enough CPU time to exit the critical section the first time, it will get another chance during the next round of scheduling.

Windows 95: If a high-priority thread is dependent on a low-priority thread that will not be allowed to run because a medium priority thread is getting all of the CPU time, the system recognizes that the high-priority thread is dependent on the low-priority thread. It will boost the low-priority thread's priority up to the priority of the high-priority thread. This will allow the thread that formerly had the lowest priority to run and release the high-priority thread that was waiting for it.


Multiple Processors

Windows NT uses a symmetric multiprocessing (SMP) model to schedule threads on multiple processors. With this model, any thread can be assigned to any processor. Therefore, scheduling threads on a computer with multiple processors is similar to scheduling threads on a computer with a single processor. However, the scheduler has a pool of processors, so that it can schedule threads to run concurrently. Scheduling is still determined by thread priority. However, on a multiprocessor computer, you can also affect scheduling by setting thread affinity and thread ideal processor, as discussed here.

Thread Affinity

Thread affinity forces a thread to run on a specific subset of processors. Use the SetProcessAffinityMask function to specify thread affinity for all threads of the process. To set the thread affinity for a single thread, use the SetThreadAffinityMask function. The thread affinity must be a subset of the process affinity. You can obtain the current process affinity by calling the GetProcessAffinityMask function.

Setting thread affinity should generally be avoided, because it can interfere with the scheduler's ability to schedule threads effectively across processors. This can decrease the performance gains produced by parallel processing. An appropriate use of thread affinity is testing each processor.

Thread Ideal Processor

When you specify a thread ideal processor, the scheduler runs the thread on the specified processor when possible. Use the SetThreadIdealProcessor function to specify a preferred processor for a thread. This does not guarantee that the ideal processor will be chosen, but provides a useful hint to the scheduler.


Multiple Threads

Each process is started with a single thread, but can create additional threads from any of its threads.

This section discusses the following topics:

  • Creating Threads
  • Thread Handles and Identifiers
  • Suspending Thread Execution
  • Synchronizing Execution of Multiple Threads
  • Multiple Threads and GDI Objects
  • Thread Local Storage
  • Creating Windows in Threads
  • Terminating a Thread
  • Thread Times


Creating Threads

The CreateThread function creates a new thread for a process. The creating thread must specify the starting address of the code that the new thread is to execute. Typically, the starting address is the name of a function defined in the program code. This function takes a single parameter and returns a DWORD value. A process can have multiple threads simultaneously executing the same function.

The following example demonstrates how to create a new thread that executes the locally defined function, ThreadFunc.

DWORD WINAPI ThreadFunc( LPVOID lpParam )
{
    char szMsg[80];

    wsprintf( szMsg, "ThreadFunc: Parameter = %d\n", *lpParam );
    MessageBox( NULL, szMsg, "Thread created.", MB_OK );

    return 0;
}

VOID main( VOID )
{
    DWORD dwThreadId, dwThrdParam = 1;
    HANDLE hThread;
    hThread = CreateThread(
        NULL,                        // no security attributes
        0,                           // use default stack size
        ThreadFunc,                  // thread function
        &dwThrdParam,                // argument to thread function
        0,                           // use default creation flags
        &dwThreadId);                // returns the thread identifier

   // Check the return value for success.

   if (hThread == NULL)
      ErrorExit( "CreateThread failed." );

   CloseHandle( hThread );
}

For simplicity, this example passes a pointer to a DWORD value as an argument to the thread function. This could be a pointer to any type of data or structure, or it could be omitted altogether by passing a NULL pointer and deleting the references to the parameter in ThreadFunc.

It is risky to pass the address of a local variable if the creating thread exits before the new thread, because the pointer becomes invalid. Instead, either pass a pointer to dynamically allocated memory or make the creating thread wait for the new thread to terminate. Data can also be passed from the creating thread to the new thread using global variables. With global variables, it is usually necessary to synchronize access by multiple threads. For more information about synchronization, see Synchronizing Execution of Multiple Threads.

In processes where a thread might create multiple threads to execute the same code, it is inconvenient to use global variables. For example, a process that enables the user to open several files at the same time can create a new thread for each file, with each of the threads executing the same thread function. The creating thread can pass the unique information (such as the filename) required by each instance of the thread function as an argument. You cannot use a single global variable for this purpose, but you could use a dynamically allocated string buffer.

The creating thread can use the arguments to CreateThread to specify the following:

  • The security attributes for the handle to the new thread. These security attributes include an inheritance flag that determines whether the handle can be inherited by child processes. The security attributes also include a security descriptor, which the system uses to perform access checks on all subsequent uses of the thread's handle before access is granted.
  • The initial stack size of the new thread. The thread's stack is allocated automatically in the memory space of the process; the system increases the stack as needed and frees it when the thread terminates.
  • A creation flag that enables you to create the thread in a suspended state. When suspended, the thread does not run until the ResumeThread function is called.

You can also create a thread by calling the CreateRemoteThread function. This function is used by debugger processes to create a thread that runs in the address space of the process being debugged.


Thread Stack Size

Each new thread receives its own stack space, consisting of both committed and reserved memory. By default, each thread uses 1 MB of reserved memory, and one page of committed memory. The system will commit one page blocks from the reserved stack memory as needed, until the stack cannot grow any father. To specify a different default stack size, use the STACKSIZE statement in the module definition (.DEF) file. Your linker may also support a command-line option for setting the stack size. For more information, see the documentation included with your linker.

To increase the amount of stack space which is to be initially committed for a thread, specify the value in the dwStackSize parameter of the CreateThread function. This value is rounded to the nearest page and used to set the initial size of the committed memory. The call to CreateThread will fail if there is not enough memory to commit the number of bytes you request. If the dwStackSize value is smaller than the default size, the new thread uses the same size as the thread that created it.

The stack is freed when the thread terminates.


Thread Handles and Identifiers

When a new thread is created by the CreateThread or CreateRemoteThread function, a handle to the thread is returned. By default, this handle has full access rights, and — subject to security access checking — can be used in any of the functions that accept a thread handle. This handle can be inherited by child processes, depending on the inheritance flag specified when it is created. The handle can be duplicated by DuplicateHandle, which enables you to create a thread handle with a subset of the access rights. The handle is valid until closed, even after the thread it represents has been terminated.

The CreateThread and CreateRemoteThread functions also return an identifier that uniquely identifies the thread throughout the system. A thread can use the GetCurrentThreadId function to get its own thread identifier. The identifiers are valid from the time the thread is created until the thread has been terminated.

The Win32 API does not provide a way to get the thread handle from the thread identifier. If the handles were made available this way, the owning process could fail because another process unexpectedly performed an operation on one of its threads, such as suspending it, resuming it, adjusting its priority, or terminating it. Instead, you must request the handle from the thread creator or the thread itself.

A thread can use the GetCurrentThread function to retrieve a pseudo handle to its own thread object. This pseudo handle is valid only for the calling process; it cannot be inherited or duplicated for use by other processes. To get the real handle to the thread, given a pseudo handle, use the DuplicateHandle function.


Suspending Thread Execution

A thread can suspend and resume the execution of another thread using the SuspendThread and ResumeThread functions. While a thread is suspended, it is not scheduled for time on the processor.

The SuspendThread function is not particularly useful for synchronization because it does not control the point in the code at which the thread's execution is suspended. However, you might want to suspend a thread in a situation where you are waiting for user input that could cancel the work the thread is performing. If the user input cancels the work, have the thread exit; otherwise, call ResumeThread.

If a thread is created in a suspended state (with the CREATE_SUSPENDED flag), it does not begin to execute until another thread calls ResumeThread with a handle to the suspended thread. This can be useful for initializing the thread's state before it begins to execute. See Using a Multithreaded Multiple Document Interface Application for an example that uses this method to modify the thread's priority before it can run. Suspending a thread at creation can be useful for one-time synchronization, because this ensures that the suspended thread will execute the starting point of its code when you call ResumeThread.

A thread can temporarily yield its execution for a specified interval by calling the Sleep or SleepEx functions This is useful particularly in cases where the thread responds to user interaction, because it can delay execution long enough to allow users to observe the results of their actions. During the sleep interval, the thread is not scheduled for time on the processor.

The SwitchToThread function is similar to Sleep and SleepEx, except that you cannot specify the interval. SwitchToThread allows the thread to give up its time slice.


Synchronizing Execution of Multiple Threads

To avoid race conditions and deadlocks, it is necessary to synchronize access by multiple threads to shared resources. Synchronization is also necessary to ensure that interdependent code is executed in the proper sequence.

The Win32 API provides a number of objects whose handles can be used to synchronize multiple threads. These objects include:

  • Console input buffers
  • Events
  • Mutexes
  • Processes
  • Semaphores
  • Threads
  • Timers

The state of each of these objects is either signaled or not signaled. When you specify a handle to any of these objects in a call to one of the wait functions, the execution of the calling thread is blocked until the state of the specified object becomes signaled.

Some of these objects are useful in blocking a thread until some event occurs. For example, a console input buffer handle is signaled when there is unread input, such as a keystroke or mouse button click. Process and thread handles are signaled when the process or thread terminates. This allows a process, for example, to create a child process and then block its own execution until the new process has terminated.

Other objects are useful in protecting shared resources from simultaneous access. For example, multiple threads can each have a handle to a mutex object. Before accessing a shared resource, the threads must call one of the wait functions to wait for the state of the mutex to be signaled. When the mutex becomes signaled, only one waiting thread is released to access the resource. The state of the mutex is immediately reset to not signaled so any other waiting threads remain blocked. When the thread is finished with the resource, it must set the state of the mutex to signaled to allow other threads to access the resource.

For the threads of a single process, critical-section objects provide a more efficient means of synchronization than mutexes. A critical section is used like a mutex to enable one thread at a time to use the protected resource. A thread can use the EnterCriticalSection function to request ownership of a critical section. If it is already owned by another thread, the requesting thread is blocked. A thread can use the TryEnterCriticalSection function to request ownership of a critical section, without blocking upon failure to obtain the critical section. After it receives ownership, the thread is free to use the protected resource. The execution of the other threads of the process is not affected unless they attempt to enter the same critical section.

The WaitForInputIdle function makes a thread wait until a specified process is initialized and waiting for user input with no input pending. Calling WaitForInputIdle can be useful for synchronizing parent and child processes, because CreateProcess returns without waiting for the child process to complete its initialization.

For more information, see Synchronization.


Multiple Threads and GDI Objects

To enhance performance, access to graphics device interface (GDI) objects (such as palettes, device contexts, regions, and the like) is not serialized. This creates a potential danger for processes that have multiple threads sharing these objects. For example, if one thread deletes a GDI object while another thread is using it, the results are unpredictable. This danger can be avoided simply by not sharing GDI objects. If sharing is unavoidable (or desirable), the application must provide its own mechanisms for synchronizing access. For more information about synchronizing access, see Synchronizing Execution of Multiple Threads.


Thread Local Storage

All threads of a process share the virtual address space and the global variables of that process. The local variables of a thread function are local to each thread that runs the function. However, the static or global variables used by that function have the same value for all threads. With thread local storage (TLS), you can create a unique copy of a variable for each thread. Using TLS, one thread allocates an index that can be used by any thread of the process to retrieve its unique copy.

Use the following steps to implement TLS:

  1. Use the TlsAlloc function during process or dynamic-link library (DLL) initialization to allocate a TLS index.
  2. For each thread that needs to use the TLS index, allocate dynamic storage, then use the TlsSetValue function to associate the index with a pointer to the dynamic storage.
  3. When you need a thread to access its storage, specify the TLS index in a call to the TlsGetValue function to retrieve the pointer.
  4. When each thread no longer needs the dynamic storage that it has associated with a TLS index, it must free the index. When all threads have finished using a TLS index, use the TlsFree function to free the index.

The constant TLS_MINIMUM_AVAILABLE defines the minimum number of TLS indexes available in each process. This minimum is guaranteed to be at least 64 for all systems.

It is ideal to use TLS in a DLL. Perform the initial TLS operations in the DllMain function in the context of the process or thread attaching to the DLL. When a new process attaches to the DLL, call TlsAlloc in the entry-point function to allocate a TLS index for that process. Then store the TLS index in a global variable that is private to each attached process. When a new thread attaches to the DLL, allocate dynamic memory for that thread in the entry-point function, and use TlsSetValue with the TLS index from TlsAlloc to save private data to the index. Then you can use the TLS index in a call to TlsGetValue to access the private data for the calling thread from within any function in the DLL. When a process detaches from the DLL, call TlsFree.

For an example illustrating the use of thread local storage, see Using Thread Local Storage.


Creating Windows in Threads

Any thread can create a window. The thread that creates the window owns the window and its associated message queue. Therefore, the thread must provide a message loop to process the messages in its message queue. In addition, you must use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx in that thread, rather than the other wait functions, so that it can process messages. Otherwise, the system can become deadlocked when the thread is sent a message while it is waiting.

The AttachThreadInput function can be used to allow a set of threads to share the same input state. By sharing input state, the threads share their concept of the active window. By doing this, one thread can always activate another thread's window. This function is also useful for sharing focus state, mouse capture state, keyboard state, and window Z-order state among windows created by different threads whose input state is shared.


Terminating a Thread

A thread executes until one of the following events occurs:

  • The thread calls the ExitThread function.
  • Any thread of the process calls the ExitProcess function.
  • The thread function returns.
  • Any thread calls the TerminateThread function with a handle to the thread.
  • Any thread calls the TerminateProcess function with a handle to the process.

The GetExitCodeThread function returns the termination status of a thread. While a thread is executing, its termination status is STILL_ACTIVE. When a thread terminates, its termination status changes from STILL_ACTIVE to the exit code of the thread. The exit code is either the value specified in the call to ExitThread, ExitProcess, TerminateThread, or TerminateProcess, or the value returned by the thread function.

When a thread terminates, the state of the thread object changes to signaled, releasing any other threads that had been waiting for the thread to terminate. For more about synchronization, see Synchronizing Execution of Multiple Threads.

If a thread is terminated by ExitThread, the system calls the entry-point function of each attached DLL with a value indicating that the thread is detaching from the DLL (unless you call the DisableThreadLibraryCalls function). If a thread is terminated by ExitProcess, the DLL entry-point functions are invoked once, to indicate that the process is detaching. DLLs are not notified when a thread is terminated by TerminateThread or TerminateProcess. For more information about DLLs, see Dynamic-Link Libraries.

Warning The TerminateThread and TerminateProcess functions should be used only in extreme circumstances, since they do not allow threads to clean up, do not notify attached DLLs, and do not free the initial stack. The following steps provide a better solution:

  • Create an event object using the CreateEvent function.
  • Create the threads.
  • Each thread monitors the event state by calling the WaitForSingleObject function. Use a wait time-out interval of zero.
  • Each thread terminates its own execution when the event is set to the signaled state (WaitForSingleObject returns WAIT_OBJECT_0).


Thread Times

The GetThreadTimes function obtains timing information for a thread. It returns the thread creation time, how much time the thread has been executing in kernel mode, and how much time the thread has been executing in user mode. These times do not include time spent executing system threads or waiting in a suspended or blocked state. If the thread has exited, GetThreadTimes returns the thread exit time.


Child Processes

A child process is a process that is created by another process, called the parent process.

This section discusses the following topics:

  • Creating Processes
  • Setting Window Properties Using STARTUPINFO
  • Process Handles and Identifiers
  • Obtaining Additional Process Information
  • Inheritance
  • Environment Variables
  • Terminating a Process
  • Process Times


Creating Processes

The CreateProcess function creates a new process, which runs independently of the creating process. However, for simplicity, the relationship is referred to as a parent-child relationship.

The following code fragment demonstrates how to create a process.

void main( VOID )
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);

    // Start the child process.
    if( !CreateProcess( NULL, // No module name (use command line).
        "MyChildProcess", // Command line.
        NULL,             // Process handle not inheritable.
        NULL,             // Thread handle not inheritable.
        FALSE,            // Set handle inheritance to FALSE.
        0,                // No creation flags.
        NULL,             // Use parent's environment block.
        NULL,             // Use parent's starting directory.
        &si,              // Pointer to STARTUPINFO structure.
        &pi )             // Pointer to PROCESS_INFORMATION structure.
    )
    {
        ErrorExit( "CreateProcess failed." );
    }

    // Wait until child process exits.
    WaitForSingleObject( pi.hProcess, INFINITE );

    // Close process and thread handles.
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
}

If CreateProcess succeeds, it returns a PROCESS_INFORMATION structure containing handles and identifiers for the new process and its primary thread. The thread and process handles are created with full access rights, although access can be restricted if you specify security descriptors. When you no longer need these handles, close them by using the CloseHandle function.

You can also create a process using the CreateProcessAsUser function. This function allows you to specify the security context of the user account in which the process will execute.


Setting Window Properties Using STARTUPINFO

A parent process can specify properties associated with the main window of its child process. The CreateProcess function takes a pointer to a STARTUPINFO structure as one of its parameters. Use the members of this structure to specify characteristics of the child process's main window. The dwFlags member contains a bit field that determines which other members of the structure are used. This allows you to specify values for any subset of the window properties. The system uses default values for the properties you do not specify. The dwFlags member can also force a feedback cursor to be displayed during the initialization of the new process.

For GUI processes, the STARTUPINFO structure specifies the default values to be used the first time the new process calls the CreateWindow and ShowWindow functions to create and display an overlapped window. The following default values can be specified:

  • The width and height, in pixels, of the window created by CreateWindow.
  • The location, in screen coordinates of the window created by CreateWindow.
  • The nCmdShow parameter of ShowWindow.

For console processes, use the STARTUPINFO structure to specify window properties only when creating a new console (either using CreateProcess with CREATE_NEW_CONSOLE or with the AllocConsole function). The STARTUPINFO structure can be used to specify the following console window properties:

  • The size of the new console window, in character cells.
  • The location of the new console window, in screen coordinates.
  • The size, in character cells, of the new console's screen buffer.
  • The text and background color attributes of the new console's screen buffer.
  • The title of the new console's window.


Process Handles and Identifiers

When a new process is created by the CreateProcess function, handles of the new process and its primary thread are returned. These handles are created with full access rights, and — subject to security access checking — can be used in any of the functions that accept thread or process handles. These handles can be inherited by child processes, depending on the inheritance flag specified when they are created. The handles are valid until closed, even after the process or thread they represent has been terminated.

The CreateProcess function also returns an identifier that uniquely identifies the process throughout the system. A process can use the GetCurrentProcessId function to get its own process identifier. The identifier is valid from the time the process is created until the process has been terminated.

If you have a process identifier, you can get the process handle by calling the OpenProcess function. OpenProcess enables you to specify the handle's access rights and whether it can be inherited.

A process can use the GetCurrentProcess function to retrieve a pseudo handle to its own process object. This pseudo handle is valid only for the calling process; it cannot be inherited or duplicated for use by other processes. To get the real handle to the process, call the DuplicateHandle function.


Obtaining Additional Process Information

The Win32 API provides functions for obtaining information about processes. Some of these functions can be used only for the calling process, because they do not take a process handle as a parameter. You can use functions that take a process handle to obtain information about other processes.

  • To obtain the command-line string for the current process, use the GetCommandLine function.
  • To parse a Unicode command-line string obtained from the Unicode version of GetCommandLine, use the CommandLineToArgvW function.
  • To retrieve the STARTUPINFO structure specified when the current process was created, use the GetStartupInfo function.
  • To obtain the version information from the executable header, use the GetProcessVersion function.
  • To obtain the full path and filename for the executable file containing the process code, use the GetModuleFileName function.
  • To obtain the count of handles to graphical user interface (GUI) objects in use, use the GetGuiResources function.
  • To determine whether a process is being debugged, use the IsDebuggerPresent function.


Inheritance

A child process can inherit several properties and resources from its parent process. You can also prevent a child process from inheriting properties from its parent process. The following can be inherited:

  • Open handles returned by the CreateFile function. This includes handles to files, console input buffers, console screen buffers, named pipes, serial communication devices, and mailslots.
  • Open handles to process, thread, mutex, event, semaphore, named-pipe, anonymous-pipe, and file-mapping objects.
  • Environment variables.
  • The current directory.
  • The console, unless the process is detached or a new console is created. A child console process also inherits the parent's standard handles, as well as access to the input buffer and the active screen buffer.

The child process does not inherit the following:

  • Priority class.
  • Handles returned by LocalAlloc, GlobalAlloc, HeapCreate, and HeapAlloc.
  • Pseudo handles, as in the handles returned by the GetCurrentProcess or GetCurrentThread function. These handles are valid only for the calling process.
  • DLL module handles returned by the LoadLibrary function.
  • GDI or USER handles, such as HBITMAP or HMENU.

Inheriting Handles

To cause a handle to be inherited, you must do two things:

  • Specify that the handle is to be inherited when you create, open, or duplicate the handle.
  • Specify that inheritable handles are to be inherited when you call the CreateProcess function.

This allows a child process to inherit some of its parent's handles, but not inherit others. For example, creation functions such as CreateProcess and CreateFile take a security attributes argument that determines whether the handle can be inherited. Open functions such as OpenMutex and OpenEvent take a handle inheritance flag that determines whether the handle can be inherited. The DuplicateHandle function takes a handle inheritance flag that determines whether the handle can be inherited.

When a child process is created, the fInheritHandles parameter of CreateProcess determines whether the inheritable handles of the parent process are inherited by the child process. An inherited handle refers to the same object in the child process as it does in the parent process. It also has the same value and access privileges. Therefore, when one process changes the state of the object, the change affects both processes. To use a handle, the child process must retrieve the handle value and "know" the object to which it refers. Usually, the parent process communicates this information to the child process through its command line, environment block, or some form of interprocess communication.

The DuplicateHandle function is useful if a process has an inheritable open handle that you do not want to be inherited by the child process. In this case, use DuplicateHandle to open a duplicate of the handle that cannot be inherited, then use the CloseHandle function to close the inheritable handle. You can also use the DuplicateHandle function to open an inheritable duplicate of a handle that cannot be inherited.

Inheriting Environment Variables

A child process inherits the environment variables of its parent process by default. However, CreateProcess enables the parent process to specify a different block of environment variables. For more information, see Environment Variables.

Inheriting the Current Directory

The GetCurrentDirectory function retrieves the current directory of the calling process. A child process inherits the current directory of its parent process by default. However, CreateProcess enables the parent process to specify a different current directory for the child process. To change the current directory of the calling process, use the SetCurrentDirectory function.


Environment Variables

Every process has an environment block that contains a set of environment variables and their values. The command processor provides the set command to display its environment block or to create new environment variables. Programs started by the command processor inherit the command processor's environment variables.

By default, a child process inherits the environment variables of its parent process. However, you can specify a different environment for the child process by creating a new environment block and passing a pointer to it as a parameter to the CreateProcess function.

The GetEnvironmentStrings function returns a pointer to the environment block of the calling process. This should be treated as a read-only block; do not modify it directly. Instead, use the SetEnvironmentVariable function to change an environment variable. When you are finished with the environment block obtained from GetEnvironmentStrings, call the FreeEnvironmentStrings function to free the block.

The GetEnvironmentVariable function determines whether a specified variable is defined in the environment of the calling process, and, if so, what its value is.

For more information, see the examples in Changing Environment Variables.


Terminating a Process

A process executes until one of the following events occurs:

  • Any thread of the process calls the ExitProcess function. This terminates all threads of the process.
  • The primary thread of the process returns. The primary thread can avoid terminating other threads by explicitly calling ExitThread before it returns. One of the remaining threads can still call ExitProcess to ensure that all threads are terminated.
  • The last thread of the process terminates.
  • Any thread calls the TerminateProcess function with a handle to the process. This terminates all threads of the process, without allowing them to clean up or save data.
  • For console processes, the default handler function calls ExitProcess when the console receives a ctrl+c or ctrl+break signal. All console processes attached to the console receive these signals. Detached processes and GUI processes are not affected by ctrl+c or ctrl+break signals. For more information, see SetConsoleCtrlHandler.
  • The user shuts down the system or logs off. Use the SetProcessShutdownParameters function to specify shutdown parameters, such as when a process should terminate relative to the other processes in the system. The GetProcessShutdownParameters function retrieves the current shutdown priority of the process and other shutdown flags.

When a process is terminated, all threads of the process are terminated immediately with no chance to run additional code. This means that the process does not execute code in termination handler blocks. For more information, see Structured Exception Handling.

The GetExitCodeProcess function returns the termination status of a process. While a process is executing, its termination status is STILL_ACTIVE. When a process terminates, its termination status changes from STILL_ACTIVE to the exit code of the process. The exit code is either the value specified in the call to ExitProcess or TerminateProcess, or the value returned by the main or WinMain function of the process. If a process is terminated due to a fatal exception, the exit code is the value of the exception that caused the termination. In addition, this value is used as the exit code for all the threads that were executing when the exception occurred.

When a process terminates, the state of the process object becomes signaled, releasing any threads that had been waiting for the process to terminate. For more about synchronization, see Synchronizing Execution of Multiple Threads.

Open handles to files or other resources are closed automatically when a process terminates. However, the objects themselves exist until all open handles to them are closed. This means that an object remains valid after a process closes, if another process has a handle to it.

If a process is terminated by ExitProcess, the system calls the entry-point function of each attached DLL with a value indicating that the process is detaching from the DLL. DLLs are not notified when a process is terminated by TerminateProcess. For more information about DLLs, see Dynamic-Link Libraries.

Warning The TerminateProcess function should be used only in extreme circumstances, since it does not allow threads to clean up or save data and does not notify attached DLLs. If you need to have one process terminate another process, the following steps provide a better solution:

  • Have both processes call the RegisterWindowMessage function to create a private message.
  • One process can terminate the other process by broadcasting the private message using the BroadcastSystemMessage function as follows:
    BroadcastSystemMessage(
    BSF_IGNORECURRENTTASK, // do not send message to this process
    BSM_APPLICATIONS,      // broadcast only to applications
    private message,       // message registered in previous step
    wParam,                // message-specific value
    lParam );              // message-specific value
  • The process receiving the private message calls ExitProcess to terminate its execution.

Note When the system is terminating a process, it does not terminate any child processes that the process has created.


Process Times

The GetProcessTimes function obtains timing information for a process. It returns the process creation time, how much time the process has been executing in kernel mode, and how much time the process has been executing in user mode. These times do not include time spent executing system threads or waiting in a suspended or blocked state. If the process has exited, GetProcessTimes returns the process exit time.


Process Working Set

The working set of a program is a collection of those pages in its virtual address space that have been recently referenced. It includes both shared and private data. The shared data includes pages that contain all instructions your application executes, including those in your DLLs and the system DLLs. As the working set size increases, memory demand increases.

A process has an associated minimum working set size and maximum working set size. Each time you call CreateProcess, it reserves the minimum working set size for the process. The virtual memory manager attempts to keep enough memory for the minimum working set resident when the process is active, but keeps no more than the maximum size.

To get the requested minimum and maximum sizes of the working set for your application, call the GetProcessWorkingSetSize function.

The system sets the default working set sizes. You can also modify the working set sizes using the SetProcessWorkingSetSize function. Setting these values is not a guarantee that the memory will be reserved or resident. Be careful about requesting too large a minimum or maximum working set size, because doing so can degrade system performance.


Job Objects

[This is preliminary documentation and subject to change.]

A job object allows groups of processes to be managed as a unit. Job objects are namable, securable, sharable objects that control attributes of the processes associated with them. Operations performed on the job object affect all processes associated with the job object.

To create a job object, use the CreateJobObject function. When the job object is created, there are no associated processes. To associate a process with a job object, use the AssignProcessToJobObject function. After you associate a process with a job object, the association cannot be broken. In addition, all processes created by a process associated with the job object are also associated with the job object.

A job object can enforce limits on each associated process, such as the working set size, process priority, end-of-job time limit, and so on. To set limits for a job object, use the SetInformationJobObject function. If a process associated with a job object attempts to increase its working set size or process priority, the function calls are silently ignored.

The job object also records basic accounting information for all its associated processes, including those that have terminated. To retrieve this accounting information, use the QueryInformationJobObject function.

To terminate all processes currently associated with a job object, use the TerminateJobObject function.

To close a job object handle, use the CloseHandle function. The job object is destroyed when its last handle has been closed. If there are running processes still associated with the job object when it is destroyed, they will continue to run even after the job object is destroyed.


Fibers

A fiber is a unit of execution that must be manually scheduled by the application. Fibers run in the context of the threads that schedule them. Each thread can schedule multiple fibers. In general, fibers do not provide advantages over a well-designed multithreaded application. However, using fibers can make it easier to port applications that were designed to schedule their own threads.

From a system standpoint, a fiber assumes the identity of the thread that created it. For example, if a fiber accesses thread local storage (TLS), it is accessing the thread local storage of the thread that created it. In addition, if a fiber calls the ExitThread function, the thread that created it exits. However, a fiber does not have all the same state information associated with it as that associated with a thread. The only state information maintained for a fiber is its stack, a subset of its registers, and the fiber data provided during fiber creation. The saved registers are the set of registers typically preserved across a function call.

Fibers are not preemptively scheduled. You schedule a fiber by switching to it from another fiber. The system still schedules threads to run. When a thread running fibers is preempted, its currently running fiber is preempted. The fiber runs when its thread runs.

Before scheduling the first fiber, call the ConvertThreadToFiber function to create an area in which to save fiber state information. The calling thread is now the currently executing fiber. The stored state information for this fiber includes the fiber data passed as an argument to ConvertThreadToFiber.

The CreateFiber function is used to create a new fiber from an existing fiber; the call requires the stack size, the starting address, and the fiber data. The starting address is typically a user-supplied function, called the fiber function, that takes one parameter (the fiber data) and does not return a value. If your fiber function returns, the thread running the fiber exits. To execute any fiber created with CreateFiber, call the SwitchToFiber function. You can call SwitchToFiber with the address of a fiber created by a different thread. To do this, you must have the address returned to the other thread when it called CreateFiber and you must use proper synchronization.

A fiber can retrieve the fiber data by calling the GetFiberData function. A fiber can retrieve the fiber address at any time by calling the GetCurrentFiber function.

To clean up the data associated with a fiber, call the DeleteFiber function. You must take care when calling DeleteFiber. If you call DeleteFiber for a fiber created by another thread, you can cause the other thread to terminate abnormally. If DeleteFiber is called from the currently running fiber, its thread calls ExitThread.


Using Processes and Threads

  • Using a multithreaded multiple document interface application
  • Creating a child process with redirected input and output
  • Changing environment variables
  • Using thread local storage


Using a Multithreaded Multiple Document Interface Application

The example in this topic shows how to use multiple threads in a multiple document interface (MDI) process. The process has a single main window, but can have any number of child windows. The primary thread of the process performs initialization and also handles messages to all windows through the application-defined MainWndProc and ChildWndProc functions.

Each time a child window is created, a new thread is also created. In the example, the new thread continually checks a global variable to see if it is time to terminate.

The ThreadFunc function is specified in the CreateThread function as the code for the new thread to execute. The handle to the child window associated with the thread is passed as a parameter to ThreadFunc. The child window's handle is also a parameter to ChildWndProc when a message is dispatched to the child window. A handle is necessary for any communication between a child window and its corresponding thread. Both ThreadFunc and ChildWndProc use the window handle in the SetWindowLong function to access the value that is reserved for application use in each window structure. In the example, the value is a termination flag. When ChildWndProc gets the WM_CLOSE message, it sets the flag; ThreadFunc checks the flag each time through its loop.

The example demonstrates how to use normal priority for the primary thread and below-normal priority for the other threads. Because the primary thread handles all messages for both the main window and the child windows, its higher relative priority ensures responsiveness to user input.

When the user terminates the process by closing the main window, the primary thread sets the global parameter to indicate that worker threads should terminate. The primary thread waits for each child thread to terminate before proceeding. This is necessary only if you want the threads to clean up, save changes to a file, or detach from DLLs before closing. If the primary thread does not wait, no other threads will be able to execute, because they have a lower priority.

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

#define MM_NEWWIN       8001
typedef struct _PTHREADLIST
{
   HANDLE hThread;
   LPVOID lpvNext;
} THREADLIST, *PTHREADLIST;

HANDLE hModule;            // handle to .EXE file for this process
HWND   hwndMain = NULL;    // handle to main window
BOOL fKillAll = FALSE;     // sets TRUE to terminate all threads
PTHREADLIST pHead = NULL;  // head of thread information linked list

BOOL InitializeApp(VOID);
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
DWORD ThreadFunc(HWND);
VOID AddThreadToList(HANDLE);
VOID ErrorExit(LPSTR);

// Primary thread:  Initialize the application and dispatch messages.

int WINAPI WinMain( HINSTANCE hInst,
   HINSTANCE hPrevInst,
   LPSTR lpszCmdLn,
   int nShowCmd)
{
   MSG msg;
   hModule = GetModuleHandle(NULL);
   if (! InitializeApp())
      ErrorExit("InitializeApp failure!");
   while (GetMessage(&msg, NULL, 0, 0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }
   return 1;
   UNREFERENCED_PARAMETER(hInst);
   UNREFERENCED_PARAMETER(hPrevInst);
   UNREFERENCED_PARAMETER(lpszCmdLn);
   UNREFERENCED_PARAMETER(nShowCmd);
}

// Register window classes and create the main window.

BOOL InitializeApp(VOID)
{
   HMENU hmenuMain, hmenuPopup;
   WNDCLASS wc;

// Register a window class for the main window.

   wc.style            = CS_OWNDC;
   wc.lpfnWndProc      = MainWndProc;
   wc.cbClsExtra       = 0;
   wc.cbWndExtra       = 0;
   wc.hInstance        = hModule;
   wc.hIcon            = LoadIcon(NULL,IDI_APPLICATION);
   wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
   wc.hbrBackground    = (HBRUSH)(COLOR_BACKGROUND+1);
   wc.lpszMenuName     = NULL;
   wc.lpszClassName    = "MainWindowClass";
   if (! RegisterClass(&wc))
      return FALSE;

// Register a window class for child windows.

   wc.lpfnWndProc      = ChildWndProc;
   wc.lpszClassName    = "ThreadWindowClass";
   if (! RegisterClass(&wc))
      return FALSE;

// Create a menu for the main window.

   hmenuMain = CreateMenu();
   hmenuPopup = CreateMenu();
   if (!AppendMenu(hmenuPopup, MF_STRING, MM_NEWWIN, "&New Window"))
      return FALSE;
   if (!AppendMenu(hmenuMain, MF_POPUP, (UINT)hmenuPopup, "&Threads"))
      return FALSE;

// Create the main window.

   hwndMain = CreateWindow("MainWindowClass", "Primary Window",
      WS_OVERLAPPED | WS_CAPTION | WS_BORDER | WS_THICKFRAME |
      WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_CLIPCHILDREN |
      WS_VISIBLE | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT,
      CW_USEDEFAULT, CW_USEDEFAULT, NULL, hmenuMain, hModule,
      NULL);
   if (hwndMain == NULL)
      return FALSE;

// Set the initial focus.

   SetFocus(hwndMain);
   return TRUE;
}

// Main window procedure: Handle messages for the main window.

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uiMessage,
   WPARAM wParam, LPARAM lParam)
{
   static HWND hwndClient;
   static DWORD dwCount = 1;
   CLIENTCREATESTRUCT ccsClientCreate;
   HWND hwndChildWnd;
   DWORD IDThread;
   PTHREADLIST pNode;

   switch (uiMessage)
   {
   // Create a client window to receive child window messages.

      case WM_CREATE:
         ccsClientCreate.hWindowMenu = NULL;
         ccsClientCreate.idFirstChild = 1;
         hwndClient = CreateWindow("MDICLIENT", NULL,
            WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE, 0, 0, 0, 0,
            hwnd, NULL, hModule, (LPVOID)&ccsClientCreate);
         return 0L;

   // Close the main window. First set fKillAll to TRUE to
   // terminate all threads. Then wait for the threads to exit
   // before passing a close message to a default handler.  If you
   // don't wait for threads to terminate, the process terminates
   // with no chance for thread cleanup.

      case WM_CLOSE:
         fKillAll = TRUE;
         pNode = pHead;
         while (pNode)
         {
            DWORD dwRes;
            SetThreadPriority(pNode->hThread,
               THREAD_PRIORITY_HIGHEST);
            dwRes = WaitForSingleObject(pNode->hThread,
               INFINITE);
            pNode = (PTHREADLIST) pNode->lpvNext;
         }
         return DefFrameProc(hwnd, hwndClient, uiMessage,
            wParam, lParam);

   // Terminate the process.

      case WM_DESTROY:
         PostQuitMessage(0);
         return 0L;

   // Handle the menu commands.

      case WM_COMMAND:
         switch (LOWORD(wParam))
         {
         // Create a child window and start a thread for it.
            case MM_NEWWIN:
               HANDLE hThrd;
               MDICREATESTRUCT mdicCreate;
               TCHAR tchTitleBarText[32];
               LONG lPrev;

               sprintf(tchTitleBarText, "Thread Window %d", dwCount);
               mdicCreate.szClass = "ThreadWindowClass";
               mdicCreate.szTitle = tchTitleBarText;
               mdicCreate.hOwner  = hModule;
               mdicCreate.x = mdicCreate.y =
               mdicCreate.cx = mdicCreate.cy = CW_USEDEFAULT;
               mdicCreate.style = mdicCreate.lParam = 0L;

            // Send a "create child window" message to the
            // client window.

               hwndChildWnd = (HWND) SendMessage(hwndClient,
                  WM_MDICREATE, 0L, (LONG)&mdicCreate);
               if (hwndChildWnd == NULL)
                  ErrorExit("Failed in Creating Thread Window!");

            // Window structure used to pass a quit message to
            // the thread.

               lPrev = SetWindowLong(hwndChildWnd, GWL_USERDATA, 0);

            // Create a suspended thread; alter its priority before
            // calling ResumeThread.

               hThrd = CreateThread(NULL,  // no security attributes
                         0,                // use default stack size
                         (LPTHREAD_START_ROUTINE) ThreadFunc,
                         (LPVOID)hwndChildWnd, // param to thread func
                         CREATE_SUSPENDED, // creation flag
                         &IDThread);       // thread identifier
               if (hThrd == NULL)
                  ErrorExit("CreateThread Failed!");
               AddThreadToList(hThrd);
               dwCount++;

            // Set the priority lower than the primary (input)
            // thread, so the process is responsive to user
            // input.  Then resume the thread.

               if (!SetThreadPriority(hThrd,
                  THREAD_PRIORITY_BELOW_NORMAL))
                  ErrorExit("SetThreadPriority failed!");
               if ((ResumeThread(hThrd)) == -1)
                  ErrorExit("ResumeThread failed!");
               return 0L;

            default:
               return DefFrameProc(hwnd, hwndClient, uiMessage,
                  wParam, lParam);
         }

      default:
         return DefFrameProc(hwnd, hwndClient, uiMessage,
            wParam, lParam);
   }
}

// Process messages for the child windows.

LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT uiMessage, WPARAM
   wParam, LPARAM lParam)
{
   LONG lPrevLong;
   switch (uiMessage)
   {
   // Use a window structure to pass "close" message to thread.

      case WM_CLOSE:
         lPrevLong = SetWindowLong(hwnd, GWL_USERDATA, 1);
         return DefMDIChildProc(hwnd, uiMessage, wParam, lParam);

      case WM_DESTROY:
         return 0L;

      default:
         return DefMDIChildProc(hwnd, uiMessage, wParam, lParam);
   }
}

// Each child window has a thread that can be used to perform tasks
// associated with that window--for example, drawing its contents.

DWORD ThreadFunc(HWND hwnd)
{
   LONG lKillMe = 0L;
   while (TRUE)
   {
      lKillMe = GetWindowLong(hwnd, GWL_USERDATA);
      if (fKillAll || lKillMe) break;

   // Perform tasks.

   }

   // Perform actions needed before thread termination.

   return 0;
}

VOID AddThreadToList(HANDLE hThread)
{
   PTHREADLIST pNode;
   pNode = (PTHREADLIST) LocalAlloc(LPTR, sizeof(PTHREADLIST));
   if (pNode == NULL)
   {
      ErrorExit("malloc Failed!");
   }
   pNode->hThread = hThread;
   pNode->lpvNext = (LPVOID) pHead;
   pHead = pNode;
}

VOID ErrorExit(LPSTR lpszMessage)
{
   MessageBox(hwndMain, lpszMessage, "Error", MB_OK);
   ExitProcess(0);
}


Creating a Child Process with Redirected Input and Output

The example in this topic demonstrates how to create a child process from a console process. It also demonstrates a technique for using anonymous pipes to redirect the child process's standard input and output handles.

The CreatePipe function uses the SECURITY_ATTRIBUTES structure to create inheritable handles to the read and write ends of two pipes. The read end of one pipe serves as standard input for the child process, and the write end of the other pipe is the standard output for the child process. These pipe handles are specified in the SetStdHandle function, which makes them the standard handles inherited by the child process. After the child process is created, SetStdHandle is used again to restore the original standard handles for the parent process.

The parent process uses the other ends of the pipes to write to the child process's input and read the child process's output. The handles to these ends of the pipe are also inheritable. However, the handle must not be inherited. Before creating the child process, the parent process must use DuplicateHandle to create a duplicate of the application-defined hChildStdinWr global variable that cannot be inherited. It then uses CloseHandle to close the inheritable handle. For more information, see Pipes.

The following is the parent process.

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

#define BUFSIZE 4096

HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
   hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
   hInputFile, hSaveStdin, hSaveStdout;

BOOL CreateChildProcess(VOID);
VOID WriteToPipe(VOID);
VOID ReadFromPipe(VOID);
VOID ErrorExit(LPTSTR);
VOID ErrMsg(LPTSTR, BOOL);

DWORD main(int argc, char *argv[])
{
   SECURITY_ATTRIBUTES saAttr;
   BOOL fSuccess;

// Set the bInheritHandle flag so pipe handles are inherited.

   saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
   saAttr.bInheritHandle = TRUE;
   saAttr.lpSecurityDescriptor = NULL;

   // The steps for redirecting child process's STDOUT:
   //     1. Save current STDOUT, to be restored later.
   //     2. Create anonymous pipe to be STDOUT for child process.
   //     3. Set STDOUT of the parent process to be write handle to
   //        the pipe, so it is inherited by the child process.
   //     4. Create a noninheritable duplicate of the read handle and
   //        close the inheritable read handle.

// Save the handle to the current STDOUT.

   hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);

// Create a pipe for the child process's STDOUT.

   if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
      ErrorExit("Stdout pipe creation failed\n");

// Set a write handle to the pipe to be STDOUT.

   if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
      ErrorExit("Redirecting STDOUT failed");

// Create noninheritable read handle and close the inheritable read
// handle.

    fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
        GetCurrentProcess(), &hChildStdoutRdDup , 0,
        FALSE,
        DUPLICATE_SAME_ACCESS);
    if( !fSuccess )
        ErrorExit("DuplicateHandle failed");
    CloseHandle(hChildStdoutRd);

   // The steps for redirecting child process's STDIN:
   //     1.  Save current STDIN, to be restored later.
   //     2.  Create anonymous pipe to be STDIN for child process.
   //     3.  Set STDIN of the parent to be the read handle to the
   //         pipe, so it is inherited by the child process.
   //     4.  Create a noninheritable duplicate of the write handle,
   //         and close the inheritable write handle.

// Save the handle to the current STDIN.

   hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);

// Create a pipe for the child process's STDIN.

   if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
      ErrorExit("Stdin pipe creation failed\n");

// Set a read handle to the pipe to be STDIN.

   if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
      ErrorExit("Redirecting Stdin failed");

// Duplicate the write handle to the pipe so it is not inherited.

   fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
      GetCurrentProcess(), &hChildStdinWrDup, 0,
      FALSE,                  // not inherited
      DUPLICATE_SAME_ACCESS);
   if (! fSuccess)
      ErrorExit("DuplicateHandle failed");

   CloseHandle(hChildStdinWr);

// Now create the child process.

   if (! CreateChildProcess())
      ErrorExit("Create process failed");

// After process creation, restore the saved STDIN and STDOUT.

   if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin))
      ErrorExit("Re-redirecting Stdin failed\n");

   if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout))
      ErrorExit("Re-redirecting Stdout failed\n");

// Get a handle to the parent's input file.

   if (argc > 1)
      hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL,
         OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
   else
      hInputFile = hSaveStdin;

   if (hInputFile == INVALID_HANDLE_VALUE)
      ErrorExit("no input file\n");

// Write to pipe that is the standard input for a child process.

   WriteToPipe();

// Read from pipe that is the standard output for child process.

   ReadFromPipe();

   return 0;
}

BOOL CreateChildProcess()
{
   PROCESS_INFORMATION piProcInfo;
   STARTUPINFO siStartInfo;

// Set up members of STARTUPINFO structure.

   ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
   siStartInfo.cb = sizeof(STARTUPINFO);

// Create the child process.

   return CreateProcess(NULL,
      "child",       // command line
      NULL,          // process security attributes
      NULL,          // primary thread security attributes
      TRUE,          // handles are inherited
      0,             // creation flags
      NULL,          // use parent's environment
      NULL,          // use parent's current directory
      &siStartInfo,  // STARTUPINFO pointer
      &piProcInfo);  // receives PROCESS_INFORMATION
}

VOID WriteToPipe(VOID)
{
   DWORD dwRead, dwWritten;
   CHAR chBuf[BUFSIZE];

// Read from a file and write its contents to a pipe.

   for (;;)
   {
      if (! ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL) ||
         dwRead == 0) break;
      if (! WriteFile(hChildStdinWrDup, chBuf, dwRead,
         &dwWritten, NULL)) break;
   }

// Close the pipe handle so the child process stops reading.

   if (! CloseHandle(hChildStdinWrDup))
      ErrorExit("Close pipe failed\n");
}

VOID ReadFromPipe(VOID)
{
   DWORD dwRead, dwWritten;
   CHAR chBuf[BUFSIZE];
   HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

// Close the write end of the pipe before reading from the
// read end of the pipe.

   if (!CloseHandle(hChildStdoutWr))
      ErrorExit("Closing handle failed");

// Read output from the child process, and write to parent's STDOUT.

   for (;;)
   {
      if( !ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead,
         NULL) || dwRead == 0) break;
      if (! WriteFile(hSaveStdout, chBuf, dwRead, &dwWritten, NULL))
         break;
   }
}

VOID ErrorExit (LPTSTR lpszMessage)
{
   fprintf(stderr, "%s\n", lpszMessage);
   ExitProcess(0);
}

// The code for the child process.

#include <windows.h>
#define BUFSIZE 4096

VOID main(VOID)
{
   CHAR chBuf[BUFSIZE];
   DWORD dwRead, dwWritten;
   HANDLE hStdin, hStdout;
   BOOL fSuccess;

   hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
   hStdin = GetStdHandle(STD_INPUT_HANDLE);
   if ((hStdout == INVALID_HANDLE_VALUE) ||
      (hStdin == INVALID_HANDLE_VALUE))
      ExitProcess(1);

   for (;;)
   {
   // Read from standard input.
      fSuccess = ReadFile(hStdin, chBuf, BUFSIZE, &dwRead, NULL);
      if (! fSuccess || dwRead == 0)
         break;

   // Write to standard output.
      fSuccess = WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL);
      if (! fSuccess)
         break;
   }
}


Changing Environment Variables

Each process has an environment block associated with it. The environment block consists of a null-terminated block of null-terminated strings (meaning there are two null bytes at the end of the block), where each string is in the form:

name=value

All strings in the environment block must be sorted alphabetically by name. Because the equal sign is a separator, it must not be used in the name of an environment variable.

By default, a child process inherits a copy of the environment block of the parent process. The following example demonstrates how to create a new environment block to pass to a child process.

LPTSTR lpszCurrentVariable;
BOOL fSuccess;

// Copy environment strings into an environment block.

lpszCurrentVariable = tchNewEnv;
if (lstrcpy(lpszCurrentVariable, "OperatingSystem=Windows") == NULL)
   ErrorExit("lstrcpy failed");

lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
if (lstrcpy(lpszCurrentVariable, "API=Win32") == NULL)
   ErrorExit("lstrcpy failed");

// Terminate the block with a NULL byte.

lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
*lpszCurrentVariable = '\0';

// Create the child process, specifying a new environment block.

fSuccess = CreateProcess(NULL, "childenv", NULL, NULL, TRUE, 0,
   (LPVOID) tchNewEnv,        // new environment block
   NULL, &siStartInfo, &piProcInfo);

if (! fSuccess)
    ErrorExit("CreateProcess failed");

If you want the child process to inherit most of the parent's environment with only a few changes, save the current values, make changes for the child process to inherit, create the child process, and then restore the saved values, as shown following.

LPTSTR lpszOldValue;
TCHAR tchBuf[BUFSIZE];
BOOL fSuccess;

// lpszOldValue gets current value of "varname", or NULL if "varname"
// environment variable does not exist. Set "varname" to new value,
// create child process, then use SetEnvironmentVariable to restore
// original value of "varname". If lpszOldValue is NULL, the "varname"
// variable will be deleted.

lpszOldValue = ((GetEnvironmentVariable("varname",
    tchBuf, BUFSIZE) > 0) ? tchBuf : NULL);

// Set a value for the child process to inherit.

if (! SetEnvironmentVariable("varname", "newvalue"))
   ErrorExit("SetEnvironmentVariable failed");

// Create a child process.

fSuccess = CreateProcess(NULL, "childenv", NULL, NULL, TRUE, 0,
   NULL,     // inherit parent's environment
   NULL, &siStartInfo, &piProcInfo);
if (! fSuccess)
   ErrorExit("CreateProcess failed");

// Restore the parent's environment.

if (! SetEnvironmentVariable("varname", lpszOldValue))
   ErrorExit("SetEnvironmentVariable failed");

The following example, taken from a console process, prints the contents of the process's environment block.

LPTSTR lpszVariable;
LPVOID lpvEnv;

// Get a pointer to the environment block.

lpvEnv = GetEnvironmentStrings();

// Variable strings are separated by NULL byte, and the block is
// terminated by a NULL byte.

for (lpszVariable = (LPTSTR) lpvEnv; *lpszVariable; lpszVariable++)
{
   while (*lpszVariable)
      putchar(*lpszVariable++);
   putchar('\n');
}


Using Thread Local Storage

Thread local storage (TLS) enables multiple threads of the same process to use an index allocated by the TlsAlloc function to store and retrieve a value that is local to the thread. In this example, an index is allocated when the process starts. When each thread starts, it allocates a block of dynamic memory and stores a pointer to this memory by using the TLS index. The TLS index is used by the locally defined CommonFunc function to access the data local to the calling thread. Before each thread terminates, it releases its dynamic memory.

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

#define THREADCOUNT 4
DWORD dwTlsIndex;

VOID ErrorExit(LPTSTR);

VOID CommonFunc(VOID)
{
   LPVOID lpvData;

// Retrieve a data pointer for the current thread.

   lpvData = TlsGetValue(dwTlsIndex);
   if ((lpvData == 0) && (GetLastError() != 0))
      ErrorExit("TlsGetValue error");

// Use the data stored for the current thread.

   printf("common: thread %d: lpvData=%lx\n",
      GetCurrentThreadId(), lpvData);

   Sleep(5000);
}

DWORD WINAPI ThreadFunc(VOID)
{
   LPVOID lpvData;

// Initialize the TLS index for this thread.

   lpvData = (LPVOID) LocalAlloc(LPTR, 256);
   if (! TlsSetValue(dwTlsIndex, lpvData))
      ErrorExit("TlsSetValue error");

   printf("thread %d: lpvData=%lx\n", GetCurrentThreadId(), lpvData);

   CommonFunc();

// Release the dynamic memory before the thread returns.

   lpvData = TlsGetValue(dwTlsIndex);
   if (lpvData != 0)
      LocalFree((HLOCAL) lpvData);

   return 0;
}

DWORD main(VOID)
{
   DWORD IDThread;
   HANDLE hThread[THREADCOUNT];
   int i;

// Allocate a TLS index.

   if ((dwTlsIndex = TlsAlloc()) == 0xFFFFFFFF)
      ErrorExit("TlsAlloc failed");

// Create multiple threads.

   for (i = 0; i < THREADCOUNT; i++)
   {
      hThread[i] = CreateThread(NULL, // no security attributes
         0,                           // use default stack size
         (LPTHREAD_START_ROUTINE) ThreadFunc, // thread function
         NULL,                    // no thread function argument
         0,                       // use default creation flags
         &IDThread);              // returns thread identifier

   // Check the return value for success.
      if (hThread[i] == NULL)
         ErrorExit("CreateThread error\n");
   }

   for (i = 0; i < THREADCOUNT; i++)
      WaitForSingleObject(hThread[i], INFINITE);

   return 0;
}

VOID ErrorExit (LPTSTR lpszMessage)
{
   fprintf(stderr, "%s\n", lpszMessage);
   ExitProcess(0);
}


Process and Thread Reference

The following elements are used with processes and threads.

  • Process and Thread Functions
  • Process and Thread Structures


Process and Thread Functions

The following functions are used with processes and threads.

AttachThreadInput
CommandLineToArgvW
CreateProcess
CreateProcessAsUser
CreateRemoteThread
CreateThread
ExitProcess
ExitThread
FreeEnvironmentStrings
GetCommandLine
GetCurrentProcess
GetCurrentProcessId
GetCurrentThread
GetCurrentThreadId
GetEnvironmentStrings
GetEnvironmentVariable
GetExitCodeProcess
GetExitCodeThread
GetGuiResources
GetPriorityClass
GetProcessAffinityMask
GetProcessPriorityBoost
GetProcessShutdownParameters
GetProcessTimes
GetProcessVersion
GetProcessWorkingSetSize
GetStartupInfo
GetThreadPriority
GetThreadPriorityBoost
GetThreadTimes
OpenProcess
ResumeThread
SetEnvironmentVariable
SetPriorityClass
SetProcessAffinityMask
SetProcessPriorityBoost
SetProcessShutdownParameters
SetProcessWorkingSetSize
SetThreadAffinityMask
SetThreadIdealProcessor
SetThreadPriority
SetThreadPriorityBoost
Sleep
SleepEx
SuspendThread
SwitchToThread
TerminateProcess
TerminateThread
ThreadProc
TlsAlloc
TlsFree
TlsGetValue
TlsSetValue
WaitForInputIdle

Job Object Functions

The following functions are used with job objects.

AssignProcessToJobObject
CreateJobObject
OpenJobObject
OpenJobObjectToken
QueryInformationJobObject
SetInformationJobObject
TerminateJobObject
UserHandleGrantAccess

Fiber Functions

The following functions are used with fibers.

ConvertThreadToFiber
CreateFiber
DeleteFiber
FiberProc
GetCurrentFiber
GetFiberData
SwitchToFiber

Obsolete Functions

WinExec
Yield


AssignProcessToJobObject

[This is preliminary documentation and subject to change.]

The AssignProcessToJobObject function associates a process with an existing job object.

BOOL AssignProcessToJobObject(
  HANDLE hJob,
  HANDLE hProcess
);

Parameters

hJob
Handle to the job object to which the process will be associated. The CreateJobObject or OpenJobObject function returns this handle. The handle must have the JOB_OBJECT_ASSIGN_PROCESS access right associated with it.
hProcess
Handle to the process to associate with the job object. The process must not already be assigned to a job. The handle must have PROCESS_SET_QUOTA and PROCESS_TERMINATE access to the process.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

After you associate a process with a job object using AssignProcessToJobObject, the process is subject to the limits set for the job object. To set limits for a job object, use the SetInformationJobObject function.

If the job object has a user-mode time limit, and the time limit has been exhausted, AssignProcessToJobObject fails and the specified process is terminated. If the job object has an active process limit, and the limit would be exceeded by associating this process, AssignProcessToJobObject fails, and the specified process is terminated.

If the process is already running and the job object has security limitations, AssignProcessToJobObject may fail. For example, if the primary token of the process contains the local administrators group, but the job object has the security limitation JOB_OBJECT_SECURITY_NO_ADMIN, the function fails. If the job object has the security limitation JOB_OBJECT_SECURITY_ONLY_TOKEN, the process must be created suspended. To create a suspended process, call the CreateProcess function with the CREATE_SUSPENDED flag.

A process can be associated only with a single job object. If a process is associated with a job object, all processes it creates are also associated with that job object. A process inherits limits from the job object it is associated with and adds its accounting information to the job object.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, , Process and Thread Functions, Processes and Threads Overview, Process and Thread Functions, Processes and Threads OverviewCreateJobObject, OpenJobObject, SetInformationJobObject


AttachThreadInput

The AttachThreadInput function attaches the input processing mechanism of one thread to that of another thread.

BOOL AttachThreadInput(
  DWORD idAttach,    // thread to attach
  DWORD idAttachTo,  // thread to attach to
  BOOL fAttach       // attach or detach
);

Parameters

idAttach
Specifies the identifier of the thread to be attached to another thread. The thread to be attached cannot be a system thread.
idAttachTo
Specifies the identifier of the thread to be attached to. This thread cannot be a system thread.

A thread cannot attach to itself. Therefore, idAttachTo cannot equal idAttach.

fAttach
Specifies whether to attach or detach the threads. If this parameter is TRUE, the two threads are attached. If the parameter is FALSE, the threads are detached.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. There is no extended error information; do not call GetLastError.

Remarks

Windows created in different threads typically process input independently of each other. That is, they have their own input states (focus, active, capture windows, key state, queue status, and so on), and they are not synchronized with the input processing of other threads. By using the AttachThreadInput function, a thread can attach its input processing to another thread. This also allows threads to share their input states, so they can call the SetFocus function to set the keyboard focus to a window of a different thread. This also allows threads to get key-state information. These capabilities are not generally possible.

The AttachThreadInput function fails if either of the specified threads does not have a message queue. The system creates a thread's message queue when the thread makes its first call to one of the Win32 USER or GDI functions. The AttachThreadInput function also fails if a journal record hook is installed. Journal record hooks attach all input queues together.

Note that key state, which can be ascertained by calls to the GetKeyState or GetKeyboardState function, is reset after a call to AttachThreadInput.

Windows NT: You cannot attach a thread to a thread in another desktop.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetCurrentThreadId, GetKeyState, GetKeyboardState, GetWindowThreadProcessId, SetFocus


CommandLineToArgvW

The CommandLineToArgvW function parses a wide-character Unicode command-line string. It returns a pointer to a set of wide-character Unicode argument strings and a count of arguments, similar to the standard C run-time argv and argc values. The function provides a way to obtain a Unicode set of argv and argc values from a Unicode command-line string.

LPWSTR CommandLineToArgvW(
  LPCWSTR lpCmdLine,  // pointer to a command-line string
  int *pNumArgs       // pointer to a variable that receives the
                      // argument count
);

Parameters

lpCmdLine
Pointer to a null-terminated Unicode command-line string. An application will usually directly pass on the value returned by a call to GetCommandLineW.
pNumArgs
Pointer to an integer variable that the function sets to the count of arguments parsed.

Return Values

If the function succeeds, the return value is a non-NULL pointer to the constructed argument list, which is a set of Unicode wide-character argument strings.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

It is the caller's responsibility to free the memory used by the argument list when it is no longer needed. To free the memory, use a single call to either the GlobalFree or LocalFree function.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in shellapi.h.
Import Library: Use shell32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetCommandLine, GlobalFree, LocalFree


ConvertThreadToFiber

The ConvertTheadToFiber function converts the current thread into a fiber. You must convert a thread into a fiber before you can schedule other fibers.

LPVOID ConvertThreadToFiber(
  LPVOID lpParameter  // fiber data for new fiber
);

Parameters

lpParameter
Specifies a single variable that is passed to the fiber. The fiber can retrieve this value by using the GetFiberData function.

Return Values

If the function succeeds, the return value is the address of the fiber.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

Only fibers can execute other fibers. If a thread needs to execute a fiber, it must call ConvertThreadToFiber to create an area in which to save fiber state information. The thread is now the current fiber. The state information for this fiber includes the fiber data specified by lpParameter.

QuickInfo

Windows NT: Requires version 3.51 SP3 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetFiberData


CreateFiber

The CreateFiber function allocates a fiber object, assigns it a stack, and sets up execution to begin at the specified start address, typically the fiber function. This function does not schedule the fiber.

LPVOID CreateFiber(
  DWORD dwStackSize,  // initial thread stack size, in bytes
  LPFIBER_START_ROUTINE lpStartAddress,
                      // pointer to fiber function
  LPVOID lpParameter  // argument for new fiber
);

Parameters

dwStackSize
Specifies the size, in bytes, of the stack for the new fiber. If zero is specified, the stack size defaults to the same size as that of the main thread. The function fails if it cannot commit dwStackSize bytes. Note that the system increases the stack size dynamically, if necessary. For more information, see Thread Stack Size.
lpStartAddress
Pointer to the application-defined function of type LPFIBER_START_ROUTINE to be executed by the fiber and represents the starting address of the fiber. Execution of the newly created fiber does not begin until another fiber calls the SwitchToFiber function with this address. For more information of the fiber callback function, see FiberProc.
lpParameter
Specifies a single argument that is passed to the fiber. This value can be retrieved by the fiber using the GetFiberData function.

Return Values

If the function succeeds, the return value is the address of the fiber.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

Before a thread can schedule a fiber using the SwitchToFiber function, it must call the ConvertThreadToFiber function so there is a fiber associated with the thread.

QuickInfo

Windows NT: Requires version 3.51 SP3 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, ConvertThreadToFiber, FiberProc, GetFiberData, SwitchToFiber


CreateJobObject

[This is preliminary documentation and subject to change.]

The CreateJobObject function creates a job object.

HANDLE CreateJobObject(
  LPSECURITY_ATTRIBUTES lpJobAttributes,
  LPCTSTR lpName
);

Parameters

lpJobAttributes
Pointer to a SECURITY_ATTRIBUTES structure that specifies the security descriptor for the job object and determines whether child processes can inherit the returned handle. If lpJobAttributes is NULL, the job object gets a default security descriptor and the handle cannot be inherited.
lpName
Pointer to a null-terminated string specifying the name of the job object. The name is limited to MAX_PATH characters, and can contain any character except the backslash (\) character. Name comparison is case-sensitive.

If lpName is NULL, the job object is created without a name.

If lpName matches the name of an existing event, semaphore, mutex, waitable timer, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space.

Return Values

If the function succeeds, the return value is a handle to the job object. The handle provides full access to the job object. If the object existed before the function call, the function returns a handle to the existing job object and GetLastError returns ERROR_ALREADY_EXISTS.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

When a job object is created, its accounting information is initialized to zero, all limits are inactive, and there are no associated processes. To associate a process with a job object, use the AssignProcessToJobObject function. To set limits for a job object, use the SetInformationJobObject function. To query accounting information, use the QueryInformationJobObject function.

To close a job object handle, use the CloseHandle function. The job object is destroyed when its last handle has been closed. If there are running processes still associated with the job object when it is destroyed, they will continue to run even after the job object is destroyed.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Processes and Threads Overview, Process and Thread Functions, AssignProcessToJobObject, CloseHandle, QueryInformationJobObject, SECURITY_ATTRIBUTES, SetInformationJobObject


CreateProcess

The CreateProcess function creates a new process and its primary thread. The new process executes the specified executable file.

BOOL CreateProcess(
  LPCTSTR lpApplicationName,
                         // pointer to name of executable module
  LPTSTR lpCommandLine,  // pointer to command line string
  LPSECURITY_ATTRIBUTES lpProcessAttributes,  // process security attributes
  LPSECURITY_ATTRIBUTES lpThreadAttributes,   // thread security attributes
  BOOL bInheritHandles,  // handle inheritance flag
  DWORD dwCreationFlags, // creation flags
  LPVOID lpEnvironment,  // pointer to new environment block
  LPCTSTR lpCurrentDirectory,   // pointer to current directory name
  LPSTARTUPINFO lpStartupInfo,  // pointer to STARTUPINFO
  LPPROCESS_INFORMATION lpProcessInformation  // pointer to PROCESS_INFORMATION
);

Parameters

lpApplicationName
Pointer to a null-terminated string that specifies the module to execute.

The string can specify the full path and filename of the module to execute or it can specify a partial name. In the case of a partial name, the function uses the current drive and current directory to complete the specification.

The lpApplicationName parameter can be NULL. In that case, the module name must be the first white space-delimited token in the lpCommandLine string. If you are using a long filename that contains a space, use quoted strings to indicate where the filename ends and the arguments begin, otherwise, the filename is ambiguous. For example, consider the string "c:\program files\sub dir\program name". This string can be interpreted in a number of ways. The system tries the possibilities in the following order:

c:\program.exe files\sub dir\program name
c:\program files\sub.exe dir\program name
c:\program files\sub dir\program.exe name
c:\program files\sub dir\program name.exe

The specified module can be a Win32-based application. It can be some other type of module (for example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.

Windows NT: If the executable module is a 16-bit application, lpApplicationName should be NULL, and the string pointed to by lpCommandLine should specify the executable module. A 16-bit application is one that executes as a VDM or WOW process.

lpCommandLine
Pointer to a null-terminated string that specifies the command line to execute. The system adds a null character to the command line, trimming the string if necessary, to indicate which file was actually used.

The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the command line.

If both lpApplicationName and lpCommandLine are non-NULL, *lpApplicationName specifies the module to execute, and *lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. C runtime processes can use the argc and argv arguments.

If lpApplicationName is NULL, the first white space-delimited token of the command line specifies the module name. If you are using a long filename that contains a space, use quoted strings to indicate where the filename ends and the arguments begin (see the explanation for the lpApplicationName parameter). If the filename does not contain an extension, .EXE is assumed. If the filename ends in a period (.) with no extension, or the filename contains a path, .EXE is not appended. If the filename does not contain a directory path, the system searches for the executable file in the following sequence:

  1. The directory from which the application loaded.
  2. The current directory for the parent process.
  3. Windows 95 and Windows 98: The Windows system directory. Use the GetSystemDirectory function to get the path of this directory.

    Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is SYSTEM32.

  4. Windows NT: The 16-bit Windows system directory. There is no Win32 function that obtains the path of this directory, but it is searched. The name of this directory is SYSTEM.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable.

If the process to be created is an MS-DOS - based or 16-bit Windows-based application, lpCommandLine should be a full command line in which the first element is the application name. Because this also works well for Win32-based applications, it is the most robust way to set lpCommandLine.

lpProcessAttributes
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpProcessAttributes is NULL, the handle cannot be inherited.

Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new process. If lpProcessAttributes is NULL, the process gets a default security descriptor.

lpThreadAttributes
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpThreadAttributes is NULL, the handle cannot be inherited.

Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the main thread. If lpThreadAttributes is NULL, the thread gets a default security descriptor.

bInheritHandles
Indicates whether the new process inherits handles from the calling process. If TRUE, each inheritable open handle in the calling process is inherited by the new process. Inherited handles have the same value and access privileges as the original handles.
dwCreationFlags
Specifies additional flags that control the priority class and the creation of the process. The following creation flags can be specified in any combination, except as noted:
Value Meaning
CREATE_DEFAULT_ERROR_MODE
The new process does not inherit the error mode of the calling process. Instead, CreateProcess gives the new process the current default error mode. An application sets the current default error mode by calling SetErrorMode.

This flag is particularly useful for multi-threaded shell applications that run with hard errors disabled.

The default behavior for CreateProcess is for the new process to inherit the error mode of the caller. Setting this flag changes that default behavior.
CREATE_NEW_CONSOLE
The new process has a new console, instead of inheriting the parent's console. This flag cannot be used with the DETACHED_PROCESS flag.
CREATE_NEW_PROCESS_GROUP
The new process is the root process of a new process group. The process group includes all processes that are descendants of this root process. The process identifier of the new process group is the same as the process identifier, which is returned in the lpProcessInformation parameter. Process groups are used by the GenerateConsoleCtrlEvent function to enable sending a ctrl+c or ctrl+break signal to a group of console processes.
CREATE_SEPARATE_WOW_VDM
Windows NT: This flag is valid only when starting a 16-bit Windows-based application. If set, the new process is run in a private Virtual DOS Machine (VDM). By default, all 16-bit Windows-based applications are run as threads in a single, shared VDM. The advantage of running separately is that a crash only kills the single VDM; any other programs running in distinct VDMs continue to function normally. Also, 16-bit Windows-based applications that are run in separate VDMs have separate input queues. That means that if one application hangs momentarily, applications in separate VDMs continue to receive input. The disadvantage of running separately is that it takes significantly more memory to do so. You should use this flag only if the user requests that 16-bit applications should run in them own VDM.
CREATE_SHARED_WOW_VDM
Windows NT: The flag is valid only when starting a 16-bit Windows-based application. If the DefaultSeparateVDM switch in the Windows section of WIN.INI is TRUE, this flag causes the CreateProcess function to override the switch and run the new process in the shared Virtual DOS Machine.
CREATE_SUSPENDED
The primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called.
CREATE_UNICODE_ENVIRONMENT
If set, the environment block pointed to by lpEnvironment uses Unicode characters. If clear, the environment block uses ANSI characters.
DEBUG_PROCESS
If this flag is set, the calling process is treated as a debugger, and the new process is a process being debugged. The system notifies the debugger of all debug events that occur in the process being debugged.

If you create a process with this flag set, only the calling thread (the thread that called CreateProcess) can call the WaitForDebugEvent function.

Windows 95 and Windows 98: This flag is not valid if the new process is a 16-bit application.

DEBUG_ONLY_THIS_PROCESS
If not set and the calling process is being debugged, the new process becomes another process being debugged by the calling process's debugger. If the calling process is not a process being debugged, no debugging-related actions occur.
DETACHED_PROCESS
For console processes, the new process does not have access to the console of the parent process. The new process can call the AllocConsole function at a later time to create a new console. This flag cannot be used with the CREATE_NEW_CONSOLE flag.

The dwCreationFlags parameter also controls the new process's priority class, which is used in determining the scheduling priorities of the process's threads. If none of the following priority class flags is specified, the priority class defaults to NORMAL_PRIORITY_CLASS unless the priority class of the creating process is IDLE_PRIORITY_CLASS. In this case the default priority class of the child process is IDLE_PRIORITY_CLASS. One of the following flags can be specified:
Priority | Meaning
HIGH_PRIORITY_CLASS | Indicates a process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a high-priority class process preempt the threads of normal-priority or idle-priority class processes. An example is the Task List, which must respond quickly when called by the user, regardless of the load on the system. Use extreme care when using the high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles.
IDLE_PRIORITY_CLASS | Indicates a process whose threads run only when the system is idle and are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes.
NORMAL_PRIORITY_CLASS | Indicates a normal process with no special scheduling needs.
REALTIME_PRIORITY_CLASS | Indicates a process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.

lpEnvironment
Pointer to an environment block for the new process. If this parameter is NULL, the new process uses the environment of the calling process.

An environment block consists of a null-terminated block of null-terminated strings. Each string is in the form:

name=value

Because the equal sign is used as a separator, it must not be used in the name of an environment variable.

If an application provides an environment block, rather than passing NULL for this parameter, the current directory information of the system drives is not automatically propagated to the new process. For a discussion of this situation and how to handle it, see the following Remarks section.

An environment block can contain Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains Unicode characters, the dwCreationFlags field's CREATE_UNICODE_ENVIRONMENT flag will be set. If the block contains ANSI characters, that flag will be clear.

Note that an ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block.

lpCurrentDirectory
Pointer to a null-terminated string that specifies the current drive and directory for the child process. The string must be a full path and filename that includes a drive letter. If this parameter is NULL, the new process is created with the same current drive and directory as the calling process. This option is provided primarily for shells that need to start an application and specify its initial drive and working directory.
lpStartupInfo
Pointer to a STARTUPINFO structure that specifies how the main window for the new process should appear.
lpProcessInformation
Pointer to a PROCESS_INFORMATION structure that receives identification information about the new process.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The CreateProcess function is used to run a new program. The WinExec and LoadModule functions are still available, but they are implemented as calls to CreateProcess.

In addition to creating a process, CreateProcess also creates a thread object. The thread is created with an initial stack whose size is described in the image header of the specified program's executable file. The thread begins execution at the image's entry point.

The new process and the new thread handles are created with full access rights. For either handle, if a security descriptor is not provided, the handle can be used in any function that requires an object handle to that type. When a security descriptor is provided, an access check is performed on all subsequent uses of the handle before access is granted. If the access check denies access, the requesting process is not able to use the handle to gain access to the thread.

The process is assigned a 32-bit process identifier. The identifier is valid until the process terminates. It can be used to identify the process, or specified in the OpenProcess function to open a handle to the process. The initial thread in the process is also assigned a 32-bit thread identifier. The identifier is valid until the thread terminates and can be used to uniquely identify the thread within the system. These identifiers are returned in the PROCESS_INFORMATION structure.

When specifying an application name in the lpApplicationName or lpCommandLine strings, it doesn't matter whether the application name includes the filename extension, with one exception: an MS-DOS – based or Windows-based application whose filename extension is .COM must include the .COM extension.

The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because CreateProcess returns without waiting for the new process to finish its initialization. For example, the creating process would use WaitForInputIdle before trying to find a window associated with the new process.

The preferred way to shut down a process is by using the ExitProcess function, because this function notifies all dynamic-link libraries (DLLs) attached to the process of the approaching termination. Other means of shutting down a process do not notify the attached DLLs. Note that when a thread calls ExitProcess, other threads of the process are terminated without an opportunity to execute any additional code (including the thread termination code of attached DLLs).

ExitProcess, ExitThread, CreateThread, CreateRemoteThread, and a process that is starting (as the result of a call by CreateProcess) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means the following restrictions hold:

  • During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.
  • Only one thread in a process can be in a DLL initialization or detach routine at a time.
  • The ExitProcess function does not return until no threads are in their DLL initialization or detach routines.

The created process remains in the system until all threads within the process have terminated and all handles to the process and any of its threads have been closed through calls to CloseHandle. The handles for both the process and the main thread must be closed through calls to CloseHandle. If these handles are not needed, it is best to close them immediately after the process is created.

When the last thread in a process terminates, the following events occur:

  • All objects opened by the process are implicitly closed.
  • The process's termination status (which is returned by GetExitCodeProcess) changes from its initial value of STILL_ACTIVE to the termination status of the last thread to terminate.
  • The thread object of the main thread is set to the signaled state, satisfying any threads that were waiting on the object.
  • The process object is set to the signaled state, satisfying any threads that were waiting on the object.

If the current directory on drive C is \MSVC\MFC, there is an environment variable called =C: whose value is C:\MSVC\MFC. As noted in the previous description of lpEnvironment, such current directory information for a system's drives does not automatically propagate to a new process when the CreateProcess function's lpEnvironment parameter is non-NULL. An application must manually pass the current directory information to the new process. To do so, the application must explicitly create the =X environment variable strings, get them into alphabetical order (because the system uses a sorted environment), and then put them into the environment block specified by lpEnvironment. Typically, they will go at the front of the environment block, due to the previously mentioned environment block sorting.

One way to obtain the current directory variable for a drive X is to call GetFullPathName ("X:",. .). That avoids an application having to scan the environment block. If the full path returned is X:\, there is no need to pass that value on as environment data, since the root directory is the default current directory for drive X of a new process.

The handle returned by the CreateProcess function has PROCESS_ALL_ACCESS access to the process object.

The current directory specified by the lpcurrentDirectory parameter is the current directory for the child process. The current directory specified in item 2 under the lpCommandLine parameter is the current directory for the parent process.

Windows NT: When a process is created with CREATE_NEW_PROCESS_GROUP specified, an implicit call to SetConsoleCtrlHandler(NULL,TRUE) is made on behalf of the new process; this means that the new process has ctrl+c disabled. This lets good shells handle ctrl+c themselves, and selectively pass that signal on to sub-processes. ctrl+break is not disabled, and may be used to interrupt the process/process group.

Windows CE: The name of the module to execute must be specified by the lpApplicationName parameter. Windows CE does not support passing NULL for lpApplicationName. The execution module cannot be specified in the command line string.

Windows CE searches the directories indicated by the lpApplicationName parameter in the following order:

  • The root of the PC Card if it exists
  • The windows (\windows) directory
  • The root (\ ) directory of the device

The following parameters are not supported and require the following settings:

  • lpProcessAttributes must be NULL
  • lpThreadAttributes must be NULL
  • bInheritHandles must be FALSE
  • lpEnvironment must be NULL
  • lpCurrentDirectory must be NULL
  • lpStartupInfo must be NULL

For Windows CE version 1.0, the dwCreationFlags parameter only supports the following values: CREATE_SUSPENDED and zero.

For Windows CE version 2.0, the dwCreationFlags parameter only supports the following values: CREATE_SUSPENDED, DEBUG_PROCESS, DEBUG_ONLY_THIS_PROCESS and zero.

Priority classes for processes are not supported.

The loader has a limited search path.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Processes and Threads Overview, Process and Thread Functions, AllocConsole, CloseHandle, CreateRemoteThread, CreateThread, ExitProcess, ExitThread, GenerateConsoleCtrlEvent, GetCommandLine, GetEnvironmentStrings, GetExitCodeProcess, GetFullPathName, GetStartupInfo, GetSystemDirectory, GetWindowsDirectory, LoadModule, OpenProcess, PROCESS_INFORMATION, ResumeThread, SECURITY_ATTRIBUTES, SetConsoleCtrlHandler, SetErrorMode, STARTUPINFO, TerminateProcess, WaitForInputIdle, WaitForDebugEvent, WinExec


CreateProcessAsUser

The CreateProcessAsUser function creates a new process and its primary thread. The new process then executes a specified executable file. The CreateProcessAsUser function is similar to the CreateProcess function, except that the new process runs in the security context of the user represented by the hToken parameter. By default, the new process is non-interactive, that is, it runs on a desktop that is not visible and cannot receive user input. Also, by default, the new process inherits the environment of the calling process, rather than the environment associated with the specified user.

BOOL CreateProcessAsUser(
  HANDLE hToken,         // handle to a token representing the logged-on user
  LPCTSTR lpApplicationName,  // pointer to name of executable module
  LPTSTR lpCommandLine,       // pointer to command line string
  LPSECURITY_ATTRIBUTES lpProcessAttributes, // process security attributes
  LPSECURITY_ATTRIBUTES lpThreadAttributes,  // thread security attributes
  BOOL bInheritHandles,         // whether new process inherits handles
  DWORD dwCreationFlags,        // creation flags
  LPVOID lpEnvironment,         // pointer to new environment block
  LPCTSTR lpCurrentDirectory,   // pointer to current directory name
  LPSTARTUPINFO lpStartupInfo,  // pointer to STARTUPINFO
  LPPROCESS_INFORMATION lpProcessInformation  // pointer to PROCESS_INFORMATION
);

Parameters

hToken
Handle to a primary token that represents a user. The handle must have TOKEN_QUERY, TOKEN_DUPLICATE, and TOKEN_ASSIGN_PRIMARY access. For more information, see Access Rights for Access-Token Objects. The user represented by the token must have read and execute access to the application specified by the lpApplicationName or the lpCommandLine parameter.

If your process has the SE_TCB_NAME privilege, it can call the LogonUser function to get a primary token that represents a specified user.

Alternatively, you can call the DuplicateTokenEx function to convert an impersonation token into a primary token. This allows a server application that is impersonating a client to create a process that has the security context of the client.

The other parameters of the CreateProcessAsUser function behave just like the analogous parameters of the CreateProcess function.

lpApplicationName
Pointer to a null-terminated string specifying the full path and filename of the module to execute. If a partial name is specified, the current drive and current directory are used by default. If this parameter is NULL, the module name must be the first white space-delimited token in the lpCommandLine string. The specified module can be a Win32-based application, or it can be some other type of module (for example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.
lpCommandLine
Pointer to a null-terminated string specifying the command line for the application to be executed. If this parameter is NULL, the lpApplicationName string is used as the command line. If both lpApplicationName and lpCommandLine are non-NULL, lpApplicationName specifies the module to execute and lpCommandLine is used as the command line. The new process can use GetCommandLine to retrieve the entire command line; or C runtime processes can use the argc/argv mechanism.

If lpApplicationName is NULL, the first white space-delimited token of the command line specifies the module name. If the filename does not contain an extension, .EXE is assumed. If the filename ends in a period (.) with no extension, or the filename contains a path, .EXE is not appended. If the filename does not contain a directory path, the system searches for the executable file in the following sequence:

  1. The directory from which the application loaded.
  2. The current directory.
  3. The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is SYSTEM32.
  4. The 16-bit Windows system directory. There is no Win32 function that obtains the path of this directory, but it is searched. The name of this directory is SYSTEM.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable.

If the process to be created is an MS-DOS – based or 16-bit Windows-based application, lpCommandLine should be a full command line in which the first element is the application name. Because this also works well for Win32-based applications, it is the most robust way to set lpCommandLine.

lpProcessAttributes
Pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new process and determines whether child processes can inherit the returned handle. If lpProcessAttributes is NULL, the process gets a default security descriptor and the handle cannot be inherited.
lpThreadAttributes
Pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new process and determines whether child processes can inherit the returned handle. If lpThreadAttributes is NULL, the thread gets a default security descriptor and the handle cannot be inherited.
bInheritHandles
Indicates whether the new process inherits handles from the calling process. If TRUE, each inheritable open handle in the calling process is inherited by the new process. Inherited handles have the same value and access privileges as the original handles.
dwCreationFlags
Specifies additional flags that control the priority class and the creation of the process. The following creation flags can be specified in any combination, except as noted:
Value Meaning
CREATE_DEFAULT_ERROR_MODE
The new process does not inherit the error mode of the calling process. Instead, CreateProcessAsUser gives the new process the current default error mode. An application sets the current default error mode by calling SetErrorMode.

This flag is particularly useful for multi-threaded shell applications that run with hard errors disabled.

The default behavior for CreateProcessAsUser is for the new process to inherit the error mode of the caller. Setting this flag changes that default behavior.
CREATE_NEW_CONSOLE
The new process has a new console, instead of inheriting the parent's console. This flag cannot be used with the DETACHED_PROCESS flag.
CREATE_NEW_PROCESS_GROUP
The new process is the root process of a new process group. The process group includes all processes that are descendants of this root process. The process identifier of the new process group is the same as the process identifier, which is returned in the lpProcessInformation parameter. Process groups are used by the GenerateConsoleCtrlEvent function to enable sending a ctrl+c or ctrl+break signal to a group of console processes.
CREATE_SEPARATE_WOW_VDM
This flag is only valid only starting a 16-bit Windows-based application. If set, the new process is run in a private Virtual DOS Machine (VDM). By default, all 16-bit Windows-based applications are run in a single, shared VDM. The advantage of running separately is that a crash only kills the single VDM; any other programs running in distinct VDMs continue to function normally. Also, 16-bit Windows-based applications that are run in separate VDMs have separate input queues. That means that if one application hangs momentarily, applications in separate VDMs continue to receive input.
CREATE_SUSPENDED
The primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called.
CREATE_UNICODE_ENVIRONMENT
If set, the environment block pointed to by lpEnvironment uses Unicode characters. If clear, the environment block uses ANSI characters.
DEBUG_PROCESS
If set, the calling process is treated as a debugger, and the new process is a process being debugged. The system notifies the debugger of all debug events that occur in the process being debugged.
DEBUG_ONLY_THIS_PROCESS
If not set and the calling process is being debugged, the new process becomes another process being debugged by the calling process's debugger. If the calling process is not a process being debugged, no debugging-related actions occur.
DETACHED_PROCESS
For console processes, the new process does not have access to the console of the parent process. The new process can call the AllocConsole function at a later time to create a new console. This flag cannot be used with the CREATE_NEW_CONSOLE flag.

The dwCreationFlags parameter also controls the new process's priority class, which is used in determining the scheduling priorities of the process's threads. If none of the following priority class flags is specified, the priority class defaults to NORMAL_PRIORITY_CLASS unless the priority class of the creating process is IDLE_PRIORITY_CLASS. In this case the default priority class of the child process is IDLE_PRIORITY_CLASS. One of the following flags can be specified:
Priority | Meaning
HIGH_PRIORITY_CLASS | Indicates a process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a high-priority class process preempt the threads of normal-priority or idle-priority class processes. An example is the Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles.
IDLE_PRIORITY_CLASS | Indicates a process whose threads run only when the system is idle and are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes.
NORMAL_PRIORITY_CLASS | Indicates a normal process with no special scheduling needs.
REALTIME_PRIORITY_CLASS | Indicates a process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.

lpEnvironment
Pointer to an environment block for the new process. If this parameter is NULL, the new process uses the environment of the calling process.

An environment block consists of a null-terminated block of null-terminated strings. Each string is in the form:

name=value

Because the equal sign is used as a separator, it must not be used in the name of an environment variable.

If an application provides an environment block, rather than passing NULL for this parameter, the current directory information of the system drives is not automatically propagated to the new process. For a discussion of this situation and how to handle it, see the following Remarks section.

An environment block can contain Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains Unicode characters, the dwCreationFlags field's CREATE_UNICODE_ENVIRONMENT flag will be set. If the block contains ANSI characters, that flag will be clear.

Note that an ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block.

lpCurrentDirectory
Pointer to a null-terminated string that specifies the current drive and directory for the new process. The string must be a full path and filename that includes a drive letter. If this parameter is NULL, the new process is created with the same current drive and directory as the calling process. This option is provided primarily for shells that need to start an application and specify its initial drive and working directory.
lpStartupInfo
Pointer to a STARTUPINFO structure that specifies how the main window for the new process should appear.
lpProcessInformation
Pointer to a PROCESS_INFORMATION structure that receives identification information about the new process.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Typically, the process that calls the CreateProcessAsUser function must have the SE_ASSIGNPRIMARYTOKEN_NAME and SE_INCREASE_QUOTA_NAME privileges. However, if hToken is a restricted version of the caller's primary token, the SE_ASSIGNPRIMARYTOKEN_NAME privilege is not required. If the necessary privileges are not already enabled, CreateProcessAsUser enables them for the duration of the call.

CreateProcessAsUser must be able to open the primary token of the calling process for TOKEN_DUPLICATE and TOKEN_IMPERSONATE access.

By default, CreateProcessAsUser creates the new process on a noninteractive window station with a desktop that is not visible and cannot receive user input. To enable user interaction with the new process, you must specify the name of the default interactive window station and desktop, "winsta0\default", in the lpDesktop member of the STARTUPINFO structure. In addition, before calling CreateProcessAsUser, you must change the discretionary access control list (DACL) of both the default interactive window station and the default desktop. The DACLs for the window station and desktop must grant access to the user or the logon session represented by the hToken parameter.

CreateProcessAsUser does not load the specified user's profile into the HKEY_USERS registry key. This means that access to information in the HKEY_CURRENT_USER registry key may not produce results consistent with a normal interactive logon. It is your responsibility to load the user's registry hive into HKEY_USERS before calling CreateProcessAsUser.

If the lpEnvironment parameter is NULL, the new process inherits the environment of the calling process. CreateProcessAsUser does not automatically modify the environment block to include environment variables specific to the user represented by hToken. For example, the USERNAME and USERDOMAIN variables are inherited from the calling process if lpEnvironment is NULL. It is your responsibility to prepare the environment block for the new process and specify it in lpEnvironment.

CreateProcessAsUser allows you to access the specified directory and executable image in the security context of the caller or the target user. By default, CreateProcessAsUser accesses the directory and executable image in the security context of the caller. In this case, if the caller does not have access to the directory and executable image, the function fails. To access the directory and executable image using the security context of the target user, specify hToken in a call to the ImpersonateLoggedOnUser function before calling CreateProcessAsUser.

The new process and the new thread handles are created with full access rights (PROCESS_ALL_ACCESS and THREAD_ALL_ACCESS). For either handle, if a security descriptor is not provided, the handle can be used in any function that requires an object handle of that type. When a security descriptor is provided, an access check is performed on all subsequent uses of the handle before access is granted. If the access check denies access, the requesting process is not able to use the handle to gain access to the process or thread.

If the lpProcessAttributes parameter is NULL, the default security descriptor for the user referenced in the hToken parameter will be used. This security descriptor may not allow access for the caller, in which case the process may not be opened again once it is run. The handle returned in the PROCESS_INFORMATION structure is valid and will continue to have all access. This is also true for thread attributes.

Handles in PROCESS_INFORMATION must be closed with CloseHandle when they are no longer needed.

The process is assigned a process identifier. The identifier is valid until the process terminates. It can be used to identify the process, or specified in the OpenProcess function to open a handle to the process. The initial thread in the process is also assigned a thread identifier. The identifier is valid until the thread terminates and can be used to uniquely identify the thread within the system. These identifiers are returned in the PROCESS_INFORMATION structure.

When specifying an application name in the lpApplicationName or lpCommandLine strings, it doesn't matter whether the application name includes the filename extension, with one exception: an MS-DOS – based or Windows-based application whose filename extension is .COM must include the .COM extension.

The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because CreateProcessAsUser returns without waiting for the new process to finish its initialization. For example, the creating process would use WaitForInputIdle before trying to find a window associated with the new process.

The preferred way to shut down a process is by using the ExitProcess function, because this function notifies all dynamic-link libraries (DLLs) attached to the process of the approaching termination. Other means of shutting down a process do not notify the attached DLLs. Note that when a thread calls ExitProcess, other threads of the process are terminated without an opportunity to execute any additional code (including the thread termination code of attached DLLs).

ExitProcess, ExitThread, CreateThread, CreateRemoteThread, and a process that is starting (as the result of a call by CreateProcessAsUser) are serialized between each other within a process. Only one of these events can happen at a time. This means the following restrictions hold:

  • During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.
  • Only one thread in a process can be in a DLL initialization or detach routine at a time.
  • The ExitProcess function does not return until no threads are executing DLL initialization or detach routines.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Processes and Threads Overview, Process and Thread Functions, AllocConsole, CloseHandle, CreateProcess, CreateRemoteThread, CreateRestrictedToken, CreateThread, DuplicateTokenEx, ExitProcess, ExitThread, GenerateConsoleCtrlEvent, GetCommandLine, GetEnvironmentStrings, GetExitCodeProcess, GetFullPathName, GetStartupInfo, GetSystemDirectory, GetWindowsDirectory, ImpersonateLoggedOnUser, LoadModule, LogonUser, OpenProcess, PROCESS_INFORMATION, ResumeThread, SECURITY_ATTRIBUTES, SetConsoleCtrlHandler, SetErrorMode, STARTUPINFO, TerminateProcess, WaitForInputIdle, WinExec


CreateRemoteThread

The CreateRemoteThread function creates a thread that runs in the address space of another process.

HANDLE CreateRemoteThread(
  HANDLE hProcess,        // handle to process to create thread in
  LPSECURITY_ATTRIBUTES lpThreadAttributes,  // pointer to security attributes
  DWORD dwStackSize,      // initial thread stack size, in bytes
  LPTHREAD_START_ROUTINE lpStartAddress, // pointer to thread function
  LPVOID lpParameter,     // argument for new thread
  DWORD dwCreationFlags,  // creation flags
  LPDWORD lpThreadId      // pointer to returned thread identifier
);

Parameters

hProcess
Handle to the process in which the thread is to be created. The handle must have the PROCESS_CREATE_THREAD, PROCESS_VM_OPERATION, PROCESS_VM_WRITE, and PROCESS_VM_READ access rights.
lpThreadAttributes
Pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new thread and determines whether child processes can inherit the returned handle. If lpThreadAttributes is NULL, the thread gets a default security descriptor and the handle cannot be inherited.
dwStackSize
Specifies the initial commit size of the stack, in bytes. The system rounds this value to the nearest page. If this value is zero, or is smaller than the default commit size, the default is to use the same size as the calling thread. For more information, see Thread Stack Size.
lpStartAddress
Pointer to the application-defined function of type LPTHREAD_START_ROUTINE to be executed by the thread and represents the starting address of the thread in the remote process. The function must exist in the remote process. For more information on the thread function, see ThreadProc.
lpParameter
Specifies a single 32-bit value passed to the thread function.
dwCreationFlags
Specifies additional flags that control the creation of the thread. If the CREATE_SUSPENDED flag is specified, the thread is created in a suspended state and will not run until the ResumeThread function is called. If this value is zero, the thread runs immediately after creation.
lpThreadId
Pointer to a 32-bit variable that receives the thread identifier.

Windows NT: If this parameter is NULL, the thread identifier is not returned.

Windows 95 and Windows 98: This parameter may not be NULL.

Return Values

If the function succeeds, the return value is a handle to the new thread.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The CreateRemoteThread function causes a new thread of execution to begin in the address space of the specified process. The thread has access to all objects opened by the process.

The new thread handle is created with full access to the new thread. If a security descriptor is not provided, the handle may be used in any function that requires a thread object handle. When a security descriptor is provided, an access check is performed on all subsequent uses of the handle before access is granted. If the access check denies access, the requesting process cannot use the handle to gain access to the thread.

CreateRemoteThread may succeed even if lpStartAddress points to data, code, or is not accessible. If the start address is invalid when the thread runs, an exception occurs, and the thread terminates. Thread termination due to a invalid start address is handled as an error exit for the thread's process. This behavior is similar to the asynchronous nature of CreateProcess, where the process is created even if it refers to invalid or missing dynamic-link libraries (DLLs).

The thread is created with a thread priority of THREAD_PRIORITY_NORMAL. Use the GetThreadPriority and SetThreadPriority functions to get and set the priority value of a thread.

When a thread terminates, the thread object attains a signaled state, satisfying any threads that were waiting for the object.

The thread object remains in the system until the thread has terminated and all handles to it have been closed through a call to CloseHandle.

The ExitProcess, ExitThread, CreateThread, CreateRemoteThread functions, and a process that is starting (as the result of a CreateProcess call) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means the following restrictions hold:

  • During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.
  • Only one thread in a process can be in a DLL initialization or detach routine at a time.
  • ExitProcess does not return until no threads are in their DLL initialization or detach routines.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CloseHandle, CreateProcess, CreateThread, ExitProcess, ExitThread, GetThreadPriority, ResumeThread, SECURITY_ATTRIBUTES, SetThreadPriority, ThreadProc


CreateThread

The CreateThread function creates a thread to execute within the address space of the calling process.

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES lpThreadAttributes,  // pointer to security attributes
  DWORD dwStackSize,                         // initial thread stack size
  LPTHREAD_START_ROUTINE lpStartAddress,     // pointer to thread function
  LPVOID lpParameter,                        // argument for new thread
  DWORD dwCreationFlags,                     // creation flags
  LPDWORD lpThreadId                         // pointer to receive thread ID
);

Parameters

lpThreadAttributes
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpThreadAttributes is NULL, the handle cannot be inherited.

Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new thread. If lpThreadAttributes is NULL, the thread gets a default security descriptor.

dwStackSize
Specifies the initial commit size of the stack, in bytes. The system rounds this value to the nearest page. If this value is zero, or is smaller than the default commit size, the default is to use the same size as the calling thread. For more information, see Thread Stack Size.
lpStartAddress
Pointer to the application-defined function of type LPTHREAD_START_ROUTINE to be executed by the thread and represents the starting address of the thread. For more information on the thread function, see ThreadProc.
lpParameter
Specifies a single 32-bit parameter value passed to the thread.
dwCreationFlags
Specifies additional flags that control the creation of the thread. If the CREATE_SUSPENDED flag is specified, the thread is created in a suspended state, and will not run until the ResumeThread function is called. If this value is zero, the thread runs immediately after creation. At this time, no other values are supported.
lpThreadId
Pointer to a 32-bit variable that receives the thread identifier.

Windows NT: If this parameter is NULL, the thread identifier is not returned.

Windows 95 and Windows 98: This parameter may not be NULL.

Return Values

If the function succeeds, the return value is a handle to the new thread.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Windows 95 and Windows 98: CreateThread succeeds only when it is called in the context of a 32-bit program. A 32-bit DLL cannot create an additional thread when that DLL is being called by a 16-bit program.

Remarks

The new thread handle is created with THREAD_ALL_ACCESS to the new thread. If a security descriptor is not provided, the handle can be used in any function that requires a thread object handle. When a security descriptor is provided, an access check is performed on all subsequent uses of the handle before access is granted. If the access check denies access, the requesting process cannot use the handle to gain access to the thread.

The thread execution begins at the function specified by the lpStartAddress parameter. If this function returns, the DWORD return value is used to terminate the thread in an implicit call to the ExitThread function. Use the GetExitCodeThread function to get the thread's return value.

The CreateThread function may succeed even if lpStartAddress points to data, code, or is not accessible. If the start address is invalid when the thread runs, an exception occurs, and the thread terminates. Thread termination due to a invalid start address is handled as an error exit for the thread's process. This behavior is similar to the asynchronous nature of CreateProcess, where the process is created even if it refers to invalid or missing dynamic-link libraries (DLLs).

The thread is created with a thread priority of THREAD_PRIORITY_NORMAL. Use the GetThreadPriority and SetThreadPriority functions to get and set the priority value of a thread.

When a thread terminates, the thread object attains a signaled state, satisfying any threads that were waiting on the object.

The thread object remains in the system until the thread has terminated and all handles to it have been closed through a call to CloseHandle.

The ExitProcess, ExitThread, CreateThread, CreateRemoteThread functions, and a process that is starting (as the result of a call by CreateProcess) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means that the following restrictions hold:

  • During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.
  • Only one thread in a process can be in a DLL initialization or detach routine at a time.
  • ExitProcess does not return until no threads are in their DLL initialization or detach routines.

A thread that uses functions from the C run-time libraries should use the beginthread and endthread C run-time functions for thread management rather than CreateThread and ExitThread. Failure to do so results in small memory leaks when ExitThread is called.

Windows CE: The lpThreadAttributes parameter must be set to NULL. The dwStackSize parameter must be zero. Only zero or CREATE_SUSPENDED values are supported for the dwCreationFlags parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.01 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CloseHandle, CreateProcess, CreateRemoteThread, ExitProcess, ExitThread, GetExitCodeThread, GetThreadPriority, ResumeThread, SetThreadPriority, SECURITY_ATTRIBUTES, ThreadProc


DeleteFiber

The DeleteFiber function deletes an existing fiber.

VOID DeleteFiber(
  LPVOID lpFiber   // pointer to the fiber to delete
);

Parameters

lpFiber
Specifies the address of the fiber to delete.

Return Values

This function does not return a value.

Remarks

The DeleteFiber function deletes all data associated with the fiber. This data includes the stack, a subset of the registers, and the fiber data. If the currently running fiber calls DeleteFiber, the ExitThread function is called and the thread terminates. If the currently running fiber is deleted by another thread, the thread associated with the fiber is likely to terminate abnormally because the fiber stack has been freed.

QuickInfo

Windows NT: Requires version 3.51 SP3 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, ExitThread


ExitProcess

The ExitProcess function ends a process and all its threads.

VOID ExitProcess(
  UINT uExitCode   // exit code for all threads
);

Parameters

uExitCode
Specifies the exit code for the process, and for all threads that are terminated as a result of this call. Use the GetExitCodeProcess function to retrieve the process's exit value. Use the GetExitCodeThread function to retrieve a thread's exit value.

Return Values

This function does not return a value.

Remarks

ExitProcess is the preferred method of ending a process. This function provides a clean process shutdown. This includes calling the entry-point function of all attached dynamic-link libraries (DLLs) with a value indicating that the process is detaching from the DLL. If a process terminates by calling TerminateProcess, the DLLs that the process is attached to are not notified of the process termination.

After all attached DLLs have executed any process termination value, this function terminates the current process.

Terminating a process causes the following:

  1. All of the object handles opened by the process are closed.
  2. All of the threads in the process terminate their execution.
  3. The state of the process object becomes signaled, satisfying any threads that had been waiting for the process to terminate.
  4. The states of all threads of the process become signaled, satisfying any threads that had been waiting for the threads to terminate.
  5. The termination status of the process changes from STILL_ACTIVE to the exit value of the process.

Terminating a process does not cause child processes to be terminated.

Terminating a process does not necessarily remove the process object from the operating system. A process object is deleted when the last handle to the process is closed.

The ExitProcess, ExitThread, CreateThread, CreateRemoteThread functions, and a process that is starting (as the result of a call by CreateProcess) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means the following restrictions hold:

  • During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.
  • Only one thread in a process can be in a DLL initialization or detach routine at a time.
  • ExitProcess does not return until no threads are in their DLL initialization or detach routines.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateProcess, CreateRemoteThread, CreateThread, ExitThread, GetExitCodeProcess, GetExitCodeThread, OpenProcess, TerminateProcess


ExitThread

The ExitThread function ends a thread.

VOID ExitThread(
  DWORD dwExitCode   // exit code for this thread
);

Parameters

dwExitCode
Specifies the exit code for the calling thread. Use the GetExitCodeThread function to retrieve a thread's exit code.

Return Values

This function does not return a value.

Remarks

ExitThread is the preferred method of exiting a thread. When this function is called (either explicitly or by returning from a thread procedure), the current thread's stack is deallocated and the thread terminates. The entry-point function of all attached dynamic-link libraries (DLLs) is invoked with a value indicating that the thread is detaching from the DLL.

If the thread is the last thread in the process when this function is called, the thread's process is also terminated.

The state of the thread object becomes signaled, releasing any other threads that had been waiting for the thread to terminate. The thread's termination status changes from STILL_ACTIVE to the value of the dwExitCode parameter.

Terminating a thread does not necessarily remove the thread object from the operating system. A thread object is deleted when the last handle to the thread is closed.

The ExitProcess, ExitThread, CreateThread, CreateRemoteThread functions, and a process that is starting (as the result of a CreateProcess call) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means the following restrictions hold:

  • During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.
  • Only one thread in a process can be in a DLL initialization or detach routine at a time.
  • ExitProcess does not return until no threads are in their DLL initialization or detach routines.

A thread that uses functions from the C run-time libraries should use the _beginthread and _endthread C run-time functions for thread management rather than CreateThread and ExitThread. Failure to do so results in small memory leaks when ExitThread is called.

Windows CE: If the primary thread calls the ExitThread function, the application will exit.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateProcess, CreateRemoteThread, CreateThread, ExitProcess, FreeLibraryAndExitThread, GetExitCodeThread, TerminateThread


FiberProc

The FiberProc function is an application-defined function used with the CreateFiber function. It serves as the starting address for a fiber. The LPFIBER_START_ROUTINE type defines a pointer to this callback function. FiberProc is a placeholder for the application-defined function name.

VOID CALLBACK FiberProc(
  PVOID lpParameter   // fiber data
);

Parameters

lpParameter
Receives the fiber data passed to the function using the lpParameter parameter of the CreateFiber function.

Return Values

This function does not return a value.

QuickInfo

Windows NT: Requires version 3.51 SP3 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: User-defined.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateFiber


FreeEnvironmentStrings

The FreeEnvironmentStrings function frees a block of environment strings.

BOOL FreeEnvironmentStrings(
  LPTSTR lpszEnvironmentBlock  // pointer to a block of environment
                               // strings
);

Parameters

lpszEnvironmentBlock
Pointer to a block of environment strings. The pointer to the block must be obtained by calling the GetEnvironmentStrings function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero To get extended error information, call GetLastError.

Remarks

When GetEnvironmentStrings is called, it allocates memory for a block of environment strings. When the block is no longer needed, it should be freed by calling FreeEnvironmentStrings.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Processes and Threads Overview, Process and Thread Functions, GetEnvironmentStrings


GetCommandLine

The GetCommandLine function returns a pointer to the command-line string for the current process.

LPTSTR GetCommandLine(VOID)

Parameters

This function has no parameters.

Return Values

The return value is a pointer to the command-line string for the current process.

Remarks

ANSI console processes written in C can use the argc and argv arguments of the main function to access the command-line arguments. ANSI GUI applications can use the lpCmdLine parameter of the WinMain function to access the command-line string, excluding the program name. The reason that main and WinMain cannot return Unicode strings is that argc, argv, and lpCmdLine use the LPSTR data type for parameters, not the LPTSTR data type. The GetCommandLine function can be used to access Unicode strings, because it uses the LPTSTR data type.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows and Windows NT.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateProcess, WinMain


GetCurrentFiber

The GetCurrentFiber function returns the address of the current fiber.

PVOID GetCurrentFiber(VOID)

Parameters

This function has no parameters.

Return Values

The return value is the address of the currently running fiber.

Remarks

The CreateFiber and ConvertThreadToFiber functions return the fiber address when the fiber is created. The GetCurrentFiber function allows you to retrieve the address at any other time.

QuickInfo

Windows NT: Requires version 3.51 SP3 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winnt.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateFiber, ConvertThreadToFiber


GetCurrentProcess

The GetCurrentProcess function returns a pseudohandle for the current process.

HANDLE GetCurrentProcess(VOID)

Parameters

This function has no parameters.

Return Values

The return value is a pseudohandle to the current process.

Remarks

A pseudohandle is a special constant that is interpreted as the current process handle. The calling process can use this handle to specify its own process whenever a process handle is required. Pseudohandles are not inherited by child processes.

This handle has the maximum possible access to the process object. For systems that support security descriptors, this is the maximum access allowed by the security descriptor for the calling process. For systems that do not support security descriptors, this is PROCESS_ALL_ACCESS.

A process can create a "real" handle to itself that is valid in the context of other processes, or that can be inherited by other processes, by specifying the pseudohandle as the source handle in a call to the DuplicateHandle function. A process can also use the OpenProcess function to open a real handle to itself.

The pseudohandle need not be closed when it is no longer needed. Calling the CloseHandle function with a pseudohandle has no effect. If the pseudohandle is duplicated by DuplicateHandle, the duplicate handle must be closed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CloseHandle, DuplicateHandle, GetCurrentProcessId, GetCurrentThread, OpenProcess


GetCurrentProcessId

The GetCurrentProcessId function returns the process identifier of the calling process.

DWORD GetCurrentProcessId(VOID)

Parameters

This function has no parameters.

Return Values

The return value is the process identifier of the calling process.

Remarks

Until the process terminates, the process identifier uniquely identifies the process throughout the system.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetCurrentProcess, OpenProcess


GetCurrentThread

The GetCurrentThread function returns a pseudohandle for the current thread.

HANDLE GetCurrentThread(VOID)

Parameters

This function has no parameters.

Return Values

The return value is a pseudohandle for the current thread.

Remarks

A pseudohandle is a special constant that is interpreted as the current thread handle. The calling thread can use this handle to specify itself whenever a thread handle is required. Pseudohandles are not inherited by child processes.

This handle has the maximum possible access to the thread object. For systems that support security descriptors, this is the maximum access allowed by the security descriptor for the calling process. For systems that do not support security descriptors, this is THREAD_ALL_ACCESS.

The function cannot be used by one thread to create a handle that can be used by other threads to refer to the first thread. The handle is always interpreted as referring to the thread that is using it. A thread can create a "real" handle to itself that can be used by other threads, or inherited by other processes, by specifying the pseudohandle as the source handle in a call to the DuplicateHandle function.

The pseudohandle need not be closed when it is no longer needed. Calling the CloseHandle function with this handle has no effect. If the pseudohandle is duplicated by DuplicateHandle, the duplicate handle must be closed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CloseHandle, DuplicateHandle, GetCurrentProcess, GetCurrentThreadId


GetCurrentThreadId

The GetCurrentThreadId function returns the thread identifier of the calling thread.

DWORD GetCurrentThreadId(VOID)

Parameters

This function has no parameters.

Return Values

The return value is the thread identifier of the calling thread.

Remarks

Until the thread terminates, the thread identifier uniquely identifies the thread throughout the system.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetCurrentThread


GetEnvironmentStrings

The GetEnvironmentStrings function returns the address of the environment block for the current process. This function replaces the GetDOSEnvironment function.

LPVOID GetEnvironmentStrings(VOID)

Parameters

This function has no parameters.

Return Values

The return value is a pointer to an environment block for the current process.

Remarks

Do not use the return value of GetEnvironmentStrings to get or set environment variables. Instead, use the GetEnvironmentVariable and SetEnvironmentVariable functions to access the environment variables within this block. When the block is no longer needed, it should be freed by calling FreeEnvironmentStrings.

A process can use this function's return value to specify the environment address used by the CreateProcess function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateProcess, GetEnvironmentVariable, SetEnvironmentVariable, FreeEnvironmentStrings


GetEnvironmentVariable

The GetEnvironmentVariable function retrieves the value of the specified variable from the environment block of the calling process. The value is in the form of a null-terminated string of characters.

DWORD GetEnvironmentVariable(
  LPCTSTR lpName,  // address of environment variable name
  LPTSTR lpBuffer, // address of buffer for variable value
  DWORD nSize      // size of buffer, in characters
);

Parameters

lpName
Pointer to a null-terminated string that specifies the environment variable.
lpBuffer
Pointer to a buffer to receive the value of the specified environment variable.
nSize
Specifies the size, in characters, of the buffer pointed to by the lpBuffer parameter.

Return Values

If the function succeeds, the return value is the number of characters stored into the buffer pointed to by lpBuffer, not including the terminating null character.

If the specified environment variable name was not found in the environment block for the current process, the return value is zero.

If the buffer pointed to by lpBuffer is not large enough, the return value is the buffer size, in characters, required to hold the value string and its terminating null character.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Processes and Threads Overview, Process and Thread Functions, GetEnvironmentStrings, SetEnvironmentVariable


GetExitCodeProcess

The GetExitCodeProcess function retrieves the termination status of the specified process.

BOOL GetExitCodeProcess(
  HANDLE hProcess,     // handle to the process
  LPDWORD lpExitCode   // address to receive termination status
);

Parameters

hProcess
Handle to the process.

Windows NT: The handle must have PROCESS_QUERY_INFORMATION access.

lpExitCode
Pointer to a 32-bit variable to receive the process termination status.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the specified process has not terminated, the termination status returned is STILL_ACTIVE. If the process has terminated, the termination status returned may be one of the following:

  • The exit value specified in the ExitProcess or TerminateProcess function.
  • The return value from the main or WinMain function of the process.
  • The exception value for an unhandled exception that caused the process to terminate.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, ExitProcess, ExitThread, TerminateProcess, WinMain


GetExitCodeThread

The GetExitCodeThread function retrieves the termination status of the specified thread.

BOOL GetExitCodeThread(
  HANDLE hThread,      // handle to the thread
  LPDWORD lpExitCode   // address to receive termination status
);

Parameters

hThread
Handle to the thread.

Windows NT: The handle must have THREAD_QUERY_INFORMATION access.

lpExitCode
Pointer to a 32-bit variable to receive the thread termination status.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the specified thread has not terminated, the termination status returned is STILL_ACTIVE. If the thread has terminated, the termination status returned may be one of the following:

  • The exit value specified in the ExitThread or TerminateThread function.
  • The return value from the thread function.
  • The exit value of the thread's process.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, ExitThread, GetExitCodeProcess, TerminateThread


GetFiberData

The GetFiberData function returns the fiber data associated with the current fiber.

PVOID GetFiberData(VOID)

Parameters

This function has no parameters.

Return Values

The return value is the fiber data for the currently running fiber.

Remarks

The fiber data is the value passed to the CreateFiber or ConvertThreadToFiber functions in the lpParameter parameter. This value is also received as the parameter to the fiber function. It is stored as part of the fiber state information.

QuickInfo

Windows NT: Requires version 3.51 SP3 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winnt.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateFiber, ConvertThreadToFiber


GetGuiResources

[This is preliminary documentation and subject to change.]

The GetGuiResources function returns the count of handles to graphical user interface (GUI) objects in use by the specified process.

DWORD GetGuiResource (
  HANDLE hProcess,  // identifies the process of interest
  DWORD uiFlags     // indicates the GUI object type
);

Parameters

hProcess
Handle to the process. The handle must have the PROCESS_QUERY_INFORMATION access right.
uiFlags
Specifies the GUI object type. You can specify one of the following values:
Value | Meaning
GR_GDIOBJECTS | Return the count of GDI objects.
GR_USEROBJECTS | Return the count of USER objects.

Return Values

If the function succeeds, the return value is the count of handles to GUI objects in use by the process. If no GUI objects are in use, the return value is zero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A process without a graphical user interface does not use GUI resources, therefore, GetGuiResources will return zero.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateProcess, GetCurrentProcess, OpenProcess


GetPriorityClass

The GetPriorityClass function returns the priority class for the specified process. This value, together with the priority value of each thread of the process, determines each thread's base priority level.

DWORD GetPriorityClass(
  HANDLE hProcess   // handle to the process
);

Parameters

hProcess
Handle to the process.

Windows NT: The handle must have PROCESS_QUERY_INFORMATION access.

Return Values

If the function succeeds, the return value is the priority class of the specified process.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

The process's priority class is one of the following values:

Priority | Meaning
HIGH_PRIORITY_CLASS | Indicates a process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a high-priority class process preempt the threads of normal or idle priority class processes. An example is the Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles.
IDLE_PRIORITY_CLASS | Indicates a process whose threads run only when the system is idle and are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle priority class is inherited by child processes.
NORMAL_PRIORITY_CLASS | Indicates a normal process with no special scheduling needs.
REALTIME_PRIORITY_CLASS | Indicates a process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.

Remarks

Every thread has a base priority level determined by the thread's priority value and the priority class of its process. The operating system uses the base priority level of all executable threads to determine which thread gets the next slice of CPU time. Threads are scheduled in a round-robin fashion at each priority level, and only when there are no executable threads at a higher level will scheduling of threads at a lower level take place.

For a table that shows the base priority levels for each combination of priority class and thread priority value, see the SetPriorityClass function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetThreadPriority, SetPriorityClass, SetThreadPriority


GetProcessAffinityMask

The GetProcessAffinityMask function obtains a process affinity mask for the specified process and the system affinity mask for the system.

A process affinity mask is a bit vector in which each bit represents the processors that a process is allowed to run on. A system affinity mask is a bit vector in which each bit represents the processors that are configured into a system.

A process affinity mask is a proper subset of a system affinity mask. A process is only allowed to run on the processors configured into a system.

BOOL GetProcessAffinityMask(
  HANDLE hProcess,              // handle to the process of interest
  LPDWORD lpProcessAffinityMask,  // pointer to structure to receive
                                  // process affinity mask
  LPDWORD lpSystemAffinityMask    // pointer to structure to receive
                                  // system affinity mask
);

Parameters

hProcess
An open handle to the process whose affinity mask is desired.

Windows NT: This handle must have PROCESS_QUERY_INFORMATION access.

lpProcessAffinityMask
Pointer to a DWORD that the function sets to the process affinity mask for the specified process.
lpSystemAffinityMask
Pointer to a DWORD that the function sets to the system affinity mask for the system.

Return Values

If the function succeeds, the return value is nonzero.

Windows NT: Upon success, the function sets the DWORD variables pointed to by lpProcessAffinityMask and lpSystemAffinityMask to the appropriate affinity masks.

Windows 95 and Windows 98: Upon success, the function sets the DWORD variables pointed to by lpProcessAffinityMask and lpSystemAffinityMask to the value one.

If the function fails, the return value is zero, and the values of the DWORD variables pointed to by lpProcessAffinityMask and lpSystemAffinityMask are undefined. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, SetProcessAffinityMask, SetThreadAffinityMask


GetProcessPriorityBoost

The GetProcessPriorityBoost function returns the priority boost control state of the specified process.

BOOL GetProcessPriorityBoost(
  HANDLE hProcess,  // handle to process
  PBOOL pDisablePriorityBoost
                    // indicates priority boost control state
);

Parameters

hProcess
Handle to the process. This handle must have the PROCESS_QUERY_INFORMATION access right.
pDisablePriorityBoost
Pointer to a Boolean variable that receives the priority boost control state. A value of TRUE indicates that dynamic boosting is disabled. A value of FALSE indicates normal behavior.

Return Values

If the function succeeds, the return value is nonzero. In that case, the Boolean variable pointed to by the pDisablePriorityBoost parameter receives the priority boost control state.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, SetProcessPriorityBoost


GetProcessShutdownParameters

The GetProcessShutdownParameters function retrieves shutdown parameters for the currently calling process.

BOOL GetProcessShutdownParameters(
  LPDWORD lpdwLevel, // shutdown priority
  LPDWORD lpdwFlags  // shutdown flag
);

Parameters

lpdwLevel
Pointer to a variable that receives the shutdown priority level. Higher levels shut down first. System level shutdown orders are reserved for system components. Higher numbers shut down first. Following are the level conventions:
Value | Meaning
000–0FF | System reserved last shutdown range.
100–1FF | Application reserved last shutdown range.
200–2FF | Application reserved "in between" shutdown range.
300–3FF | Application reserved first shutdown range.
400–4FF | System reserved first shutdown range.

All processes start at shutdown level 0x280.

lpdwFlags
Pointer to a variable that receives the shutdown flags. It can be the following value:
Value | Meaning
SHUTDOWN_NORETRY | If this process takes longer than the specified timeout to shut down, do not display a retry dialog box for the user. Instead, just cause the process to directly exit.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, SetProcessShutdownParameters


GetProcessTimes

The GetProcessTimes function obtains timing information about a specified process.

BOOL GetProcessTimes(
  HANDLE hProcess,           // specifies the process of interest
  LPFILETIME lpCreationTime, // when the process was created
  LPFILETIME lpExitTime,     // when the process exited
  LPFILETIME lpKernelTime,   // time the process has spent in kernel
                             // mode
  LPFILETIME lpUserTime      // time the process has spent in user mode
);

Parameters

hProcess
Handle to the process whose timing information is sought. This handle must be created with PROCESS_QUERY_INFORMATION access.
lpCreationTime
Pointer to a FILETIME structure that receives the creation time of the process.
lpExitTime
Pointer to a FILETIME structure that receives the exit time of the process. If the process has not exited, the content of this structure is undefined.
lpKernelTime
Pointer to a FILETIME structure that receives the amount of time that the process has executed in kernel mode. The time that each of the threads of the process has executed in kernel mode is determined, and then all of those times are summed together to obtain this value.
lpUserTime
Pointer to a FILETIME structure that receives the amount of time that the process has executed in user mode. The time that each of the threads of the process has executed in user mode is determined, and then all of those times are summed together to obtain this value.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

All times are expressed using FILETIME data structures. Such a structure contains two 32-bit values that combine to form a 64-bit count of 100-nanosecond time units.

Process creation and exit times are points in time expressed as the amount of time that has elapsed since midnight on January 1, 1601 at Greenwich, England. The Win32 API provides several functions that an application can use to convert such values to more generally useful forms.

Process kernel mode and user mode times are amounts of time. For example, if a process has spent one second in kernel mode, this function will fill the FILETIME structure specified by lpKernelTime with a 64-bit value of ten million. That is the number of 100-nanosecond units in one second.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, FILETIME, FileTimeToDosDateTime, FileTimeToLocalFileTime, FileTimeToSystemTime


GetProcessVersion

The GetProcessVersion function obtains the major and minor version numbers of the system on which a specified process expects to run.

DWORD GetProcessVersion(
  DWORD ProcessId  // identifier specifying the process of interest
);

Parameters

ProcessId
Process identifier that specifies the process of interest. A ProcessId value of zero specifies the calling process.

Return Values

If the function succeeds, the return value is the version of the system on which the process expects to run. The high word of the return value contains the major version number. The low word of the return value contains the minor version number.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The function fails if ProcessId is an invalid value.

Remarks

The GetProcessVersion function performs less quickly when ProcessId is nonzero, specifying a process other than the calling process.

The version number returned by this function is the version number stamped in the image header of the .EXE file the process is running. Linker programs set this value.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions


GetProcessWorkingSetSize

The GetProcessWorkingSetSize function obtains the minimum and maximum working set sizes of a specified process.

The "working set" of a process is the set of memory pages currently visible to the process in physical RAM memory. These pages are resident and available for an application to use without triggering a page fault. The size of a process' working set is specified in bytes. The minimum and maximum working set sizes affect the virtual memory paging behavior of a process.

BOOL GetProcessWorkingSetSize(
  HANDLE hProcess,  // open handle to the process of interest
  LPDWORD lpMinimumWorkingSetSize,
                    // points to variable to receive minimum working
                    // set size
  LPDWORD lpMaximumWorkingSetSize
                    // points to variable to receive maximum working
                    // set size
);

Parameters

hProcess
An open handle to the process whose working set sizes will be obtained. The handle must have PROCESS_QUERY_INFORMATION access rights.
lpMinimumWorkingSetSize
Pointer to a variable that receives the minimum working set size of the specified process. The virtual memory manager attempts to keep at least this much memory resident in the process whenever the process is active.
lpMaximumWorkingSetSize
Pointer to a variable that receives the maximum working set size of the specified process. The virtual memory manager attempts to keep no more than this much memory resident in the process whenever the process is active when memory is in short supply.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, SetProcessWorkingSetSize


GetStartupInfo

The GetStartupInfo function retrieves the contents of the STARTUPINFO structure that was specified when the calling process was created.

VOID GetStartupInfo(
  LPSTARTUPINFO lpStartupInfo   // address of STARTUPINFO structure
);

Parameters

lpStartupInfo
Pointer to a STARTUPINFO structure that is filled in by the function.

Return Values

This function does not return a value.

Remarks

The STARTUPINFO structure was specified by the process that created the calling process. It can be used to specify properties associated with the main window of the calling process.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateProcess, STARTUPINFO


GetThreadPriority

The GetThreadPriority function returns the priority value for the specified thread. This value, together with the priority class of the thread's process, determines the thread's base-priority level.

int GetThreadPriority(
  HANDLE hThread   // handle to thread
);

Parameters

hThread
Handle to the thread.

Windows NT: The handle must have THREAD_QUERY_INFORMATION access.

Return Values

If the function succeeds, the return value is the thread's priority level.

If the function fails, the return value is THREAD_PRIORITY_ERROR_RETURN. To get extended error information, call GetLastError.

The thread's priority level is one of the following values:

Priority | Meaning
THREAD_PRIORITY_ABOVE_NORMAL
 | Indicates 1 point above normal priority for the priority class.
THREAD_PRIORITY_BELOW_NORMAL
 | Indicates 1 point below normal priority for the priority class.
THREAD_PRIORITY_HIGHEST
 | Indicates 2 points above normal priority for the priority class.
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_NORMAL
 | Indicates 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.

Remarks

Every thread has a base-priority level determined by the thread's priority value and the priority class of its process. The operating system uses the base-priority level of all executable threads to determine which thread gets the next slice of CPU time. Threads are scheduled in a round-robin fashion at each priority level, and only when there are no executable threads at a higher level will scheduling of threads at a lower level take place.

For a table that shows the base-priority levels for each combination of priority class and thread priority value, refer to the SetPriorityClass function.

Windows CE: The thread's priority level is one of the following values:

THREAD_PRIORITY_TIME_CRITICAL
Indicates 3 points above normal priority.
THREAD_PRIORITY_HIGHEST

Indicates 2 points above normal priority.

THREAD_PRIORITY_ABOVE_NORMAL
Indicates 1 point above normal priority.

THREAD_PRIORITY_NORMAL

Indicates normal priority.

THREAD_PRIORITY_BELOW_NORMAL
Indicates 1 point below normal priority.

THREAD_PRIORITY_LOWEST

Indicates 2 points below normal priority.

THREAD_PRIORITY_ABOVE_IDLE

Indicates 3 points below normal priority.

THREAD_PRIORITY_IDLE
Indicates 4 points below normal priority.

Windows CE does not support priority classes. The order in which threads are scheduled is determined only by their thread priorities.

When manipulating priorities, ensure that a high-priority thread does not consume all of the available CPU time. A thread with a priority level of THREAD_PRIORITY_TIME_CRITICAL will execute until it explicitly yields processing to other threads. Processing of these threads is not yielded to other threads with the THREAD_PRIORITY_TIME_CRITICAL priority level. Such a thread can interfere with the normal operation of the operating system if the thread doesn't explicitly yield processing quickly.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetPriorityClass, SetPriorityClass, SetThreadPriority


GetThreadPriorityBoost

The GetThreadPriorityBoost function returns the priority boost control state of the specified thread.

BOOL GetThreadPriorityBoost(
  HANDLE hThread,  // handle to thread
  PBOOL pDisablePriorityBoost
                   // indicates priority boost control state
);

Parameters

hThread
Handle to the thread. This thread must have THREAD_QUERY_INFORMATION access.
pDisablePriorityBoost
Pointer to a Boolean variable that receives the priority boost control state. A value of TRUE indicates that dynamic boosting is disabled. A value of FALSE indicates normal behavior.

Return Values

If the function succeeds, the return value is nonzero. In that case, the Boolean variable pointed to by the pDisablePriorityBoost parameter receives the priority boost control state.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, SetThreadPriorityBoost


GetThreadTimes

The GetThreadTimes function obtains timing information about a specified thread.

BOOL GetThreadTimes(
  HANDLE hThread,             // specifies the thread of interest
  LPFILETIME lpCreationTime,  // when the thread was created
  LPFILETIME lpExitTime,      // when the thread was destroyed
  LPFILETIME lpKernelTime,    // time the thread has spent in kernel
                              // mode
  LPFILETIME lpUserTime       // time the thread has spent in user mode
);

Parameters

hThread
An open handle that specifies the thread whose timing information is sought. This handle must be created with THREAD_QUERY_INFORMATION access.
lpCreationTime
Pointer to a FILETIME structure that receives the creation time of the thread.
lpExitTime
Pointer to a FILETIME structure that receives the exit time of the thread. If the thread has not exited, the content of this structure is undefined.
lpKernelTime
Pointer to a FILETIME structure that receives the amount of time that the thread has executed in kernel mode.
lpUserTime
Pointer to a FILETIME structure that receives the amount of time that the thread has executed in user mode.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

All times are expressed using FILETIME data structures. Such a structure contains two 32-bit values that combine to form a 64-bit count of 100-nanosecond time units.

Thread creation and exit times are points in time expressed as the amount of time that has elapsed since midnight on January 1, 1601 at Greenwich, England. The Win32 API provides several functions that an application can use to convert such values to more generally useful forms; see Time and Date Functions, and the functions noted in the following See Also section.

Thread kernel mode and user mode times are amounts of time. For example, if a thread has spent one second in kernel mode, this function will fill the FILETIME structure specified by lpKernelTime with a 64-bit value of ten million. That is the number of 100-nanosecond units in one second.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, FILETIME, FileTimeToDosDateTime, FileTimeToLocalFileTime, FileTimeToSystemTime


OpenJobObject

[This is preliminary documentation and subject to change.]

The OpenJobObject function opens an existing job object.

HANDLE OpenJobObject(
  DWORD dwDesiredAccess,
  BOOL bInheritHandles,
  LPCTSTR lpName
);

Parameters

dwDesiredAccess
Specifies the desired access mode to the job object. This parameter can be one or more of the following values.
Value | Meaning
MAXIMUM_ALLOWED | Specifies maximum access rights to the job object that are valid for the caller.
JOB_OBJECT_ASSIGN_PROCESS | Specifies the assign process access right to the object. Allows processes to be assigned to the job.
JOB_OBJECT_SET_ATTRIBUTES | Specifies the set attribute access right to the object. Allows job object attributes to be set.
JOB_OBJECT_QUERY | Specifies the query access right to the object. Allows job object attributes and accounting information to be queried.
JOB_OBJECT_TERMINATE | Specifies the terminate access right to the object. Allows termination of all processes in the job object.
JOB_OBJECT_SET_SECURITY_ATTRIBUTES | Specifies the security attributes access right to the object. Allows security limitations on all processes in the job object to be set.
JOB_OBJECT_ALL_ACCESS | Specifies the full access right to the job object.

bInheritHandle
Specifies whether the returned handle is inherited when a new process is created. If this parameter is TRUE, the new process inherits the handle.
lpName
Pointer to a null-terminated string specifying the name of the job object to be opened. Name comparisons are case sensitive.

Return Values

If the function succeeds, the return value is a handle to the job object. The handle provides the requested access to the job object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

To associate a process with a job object, use the AssignProcessToJobObject function.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Processes and Threads Overview, Process and Thread Functions, AssignProcessToJobObject


OpenJobObjectToken

[This is preliminary documentation and subject to change.]

The OpenJobObjectToken function opens an existing job object and retrieves the token associated with the job object. By using this function, a process can read the accounting and limit information for a job object without needing an open handle to the job object.

BOOL OpenJobObjectToken(
  HANDLE hJob,
  ACCESS_MASK DesiredAccess,
  HANDLE *phToken
);

Parameters

hJob
Handle to the job object whose limits are being set. The handle must have JOB_OBJECT_QUERY access.

If this value is NULL and the process is associated with a job object, the job object associated with the process is used.

DesiredAccess
Specifies the desired access to the token. This parameter can be one or more of the following values.
Value | Meaning
TOKEN_ADJUST_DEFAULT | Required to change the default ACL, primary group, or owner of an access token.
TOKEN_ADJUST_GROUPS | Required to change the groups specified in a token.
TOKEN_ADJUST_PRIVILEGES | Required to change the privileges specified in a token.
TOKEN_ALL_ACCESS | Combines the STANDARD_RIGHTS_REQUIRED access rights with all access rights for tokens.
TOKEN_ASSIGN_PRIMARY | Required to attach a primary token to a process, along with the SE_CREATE_TOKEN_NAME privilege.
TOKEN_DUPLICATE | Required to duplicate a token.
TOKEN_EXECUTE | Combines the STANDARD_RIGHTS_EXECUTE access rights with the TOKEN_IMPERSONATE access right.
TOKEN_IMPERSONATE | Required to attach an impersonation token to a process.
TOKEN_QUERY | Required to query the contents of a token.
TOKEN_QUERY_SOURCE | Required to query the source of a token.
TOKEN_READ | Combines the STANDARD_RIGHTS_READ access rights with the TOKEN_QUERY access right.
TOKEN_WRITE | Combines the STANDARD_RIGHTS_WRITE access rights with the TOKEN_ADJUST_PRIVILEGES, TOKEN_ADJUST_GROUPS, and TOKEN_ADJUST_DEFAULT access rights.

phToken
Pointer the HANDLE variable that receives the handle to the token.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

To associate a process with a job object, use the AssignProcessToJobObject function.

To set security limitations for the job object, see the JOBOBJECT_SECURITY_LIMIT_INFORMATION structure.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, AssignProcessToJobObject, JOBOBJECT_SECURITY_LIMIT_INFORMATION


OpenProcess

The OpenProcess function returns a handle to an existing process object.

HANDLE OpenProcess(
  DWORD dwDesiredAccess,  // access flag
  BOOL bInheritHandle,    // handle inheritance flag
  DWORD dwProcessId       // process identifier
);

Parameters

dwDesiredAccess
Specifies the access to the process object. For operating systems that support security checking, this access is checked against any security descriptor for the target process. Any combination of the following access flags can be specified in addition to the STANDARD_RIGHTS_REQUIRED access flags:
Access | Description
PROCESS_ALL_ACCESS | Specifies all possible access flags for the process object.
PROCESS_CREATE_PROCESS | Used internally.
PROCESS_CREATE_THREAD | Enables using the process handle in the CreateRemoteThread function to create a thread in the process.
PROCESS_DUP_HANDLE | Enables using the process handle as either the source or target process in the DuplicateHandle function to duplicate a handle.
PROCESS_QUERY_INFORMATION | Enables using the process handle in the GetExitCodeProcess and GetPriorityClass functions to read information from the process object.
PROCESS_SET_INFORMATION | Enables using the process handle in the SetPriorityClass function to set the priority class of the process.
PROCESS_TERMINATE | Enables using the process handle in the TerminateProcess function to terminate the process.
PROCESS_VM_OPERATION | Enables using the process handle in the VirtualProtectEx and WriteProcessMemory functions to modify the virtual memory of the process.
PROCESS_VM_READ | Enables using the process handle in the ReadProcessMemory function to read from the virtual memory of the process.
PROCESS_VM_WRITE | Enables using the process handle in the WriteProcessMemory function to write to the virtual memory of the process.
SYNCHRONIZE | Windows NT: Enables using the process handle in any of the wait functions to wait for the process to terminate.

bInheritHandle
Specifies whether the returned handle can be inherited by a new process created by the current process. If TRUE, the handle is inheritable.
dwProcessId
Specifies the process identifier of the process to open.

Return Values

If the function succeeds, the return value is an open handle to the specified process.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The handle returned by the OpenProcess function can be used in any function that requires a handle to a process, such as the wait functions, provided the appropriate access rights were requested.

When you are finished with the handle, be sure to close it using the CloseHandle function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CloseHandle, CreateProcess, CreateRemoteThread, DuplicateHandle, GetCurrentProcess, GetCurrentProcessId, GetExitCodeProcess, GetPriorityClass, ReadProcessMemory, SetPriorityClass, TerminateProcess, VirtualProtectEx, WriteProcessMemory


QueryInformationJobObject

[This is preliminary documentation and subject to change.]

The QueryInformationJobObject function obtains limit and job state information from the job object.

BOOL QueryInformationJobObject(
  HANDLE hJob,
  JOBOBJECTINFOCLASS JobObjectInformationClass,
  LPVOID lpJobObjectInformation,
  DWORD cbJobObjectInformationLength,
  LPDWORD lpReturnLength
);

Parameters

hJob
Handle to the job object whose information is being queried. The CreateJobObject or OpenJobObject function returns this handle. The handle must have the JOB_OBJECT_QUERY access right associated with it.

If this value is NULL and the calling process is associated with a job object, the job object associated with the calling process is used.

JobObjectInformationClass
Specifies the information class for limits to be queried. This parameter can be one of the following values.
Value | Meaning
JobObjectAssociateCompletionPortInformation | The lpJobObjectInformation parameter is a pointer to a JOBOBJECT_ASSOCIATE_COMPLETION_PORT structure.
JobObjectBasicAccountingInformation | The lpJobObjectInformation parameter is a pointer to a JOBOBJECT_BASIC_ACCOUNTING_INFORMATION structure.
JobObjectBasicLimitInformation | The lpJobObjectInformation parameter is a pointer to a JOBOBJECT_BASIC_LIMIT_INFORMATION structure.
JobObjectBasicProcessIdList | The lpJobObjectInformation parameter is a pointer to a JOBOBJECT_BASIC_PROCESS_ID_LIST structure.
JobObjectBasicUIRestrictions | The lpJobObjectInformation parameter is a pointer to a JOBOBJECT_BASIC_UI_RESTRICTIONS structure.
JobObjectEndOfJobTimeInformation | The lpJobObjectInformation parameter is a pointer to a JOBOBJECT_END_OF_JOB_TIME_INFORMATION structure.
JobObjectSecurityLimitInformation | The lpJobObjectInformation parameter is a pointer to a JOBOBJECT_SECURITY_LIMIT_INFORMATION structure.

lpJobObjectInformation
Specifies the limits to be queried for the job object. The format of this data depends on the value of the JobObjectInformationClass parameter.
cbJobObjectInformationLength
Specifies the count, in bytes, of the job object information being queried.
lpReturnLength
Pointer to a DWORD variable that receives the length of data written to the structure pointed to by the lpJobObjectInformation parameter. If you do not want to receive this information, specify NULL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

You can use QueryInformationJobObject to obtain the current limits, modify them, then use the SetInformationJobObject function to set new limits.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, JOBOBJECT_ASSOCIATE_COMPLETION_PORT, JOBOBJECT_BASIC_ACCOUNTING_INFORMATION, JOBOBJECT_BASIC_LIMIT_INFORMATION, JOBOBJECT_BASIC_PROCESS_ID_LIST, JOBOBJECT_BASIC_UI_RESTRICTIONS, JOBOBJECT_END_OF_JOB_TIME_INFORMATION, SetInformationJobObject


ResumeThread

The ResumeThread function decrements a thread's suspend count. When the suspend count is decremented to zero, the execution of the thread is resumed.

DWORD ResumeThread(
  HANDLE hThread   // identifies thread to restart
);

Parameters

hThread
Specifies a handle for the thread to be restarted.

Windows NT: The handle must have THREAD_SUSPEND_RESUME access to the thread.

Return Values

If the function succeeds, the return value is the thread's previous suspend count.

If the function fails, the return value is 0xFFFFFFFF. To get extended error information, call GetLastError.

Remarks

The ResumeThread function checks the suspend count of the subject thread. If the suspend count is 0, the thread is not currently suspended. Otherwise, the subject thread's suspend count is decremented. If the resulting value is 0, then the execution of the subject thread is resumed.

If the return value is 0, the specified thread was not suspended. If the return value is 1, the specified thread was suspended but was restarted. If the return value is greater than 1, the specified thread is still suspended.

Note that while reporting debug events, all threads within the reporting process are frozen. Debuggers are expected to use the SuspendThread and ResumeThread functions to limit the set of threads that can execute within a process. By suspending all threads in a process except for the one reporting a debug event, it is possible to "single step" a single thread. The other threads are not released by a continue operation if they are suspended.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, SuspendThread


SetEnvironmentVariable

The SetEnvironmentVariable function sets the value of an environment variable for the current process.

BOOL SetEnvironmentVariable(
  LPCTSTR lpName,  // address of environment variable name
  LPCTSTR lpValue  // address of new value for variable
);

Parameters

lpName
Pointer to a null-terminated string that specifies the environment variable whose value is being set. The operating system creates the environment variable if it does not exist and lpValue is not NULL.
lpValue
Pointer to a null-terminated string containing the new value of the specified environment variable. If this parameter is NULL, the variable is deleted from the current process's environment.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Processes and Threads Overview, Process and Thread Functions, GetEnvironmentVariable


SetInformationJobObject

[This is preliminary documentation and subject to change.]

The SetInformationJobObject function is used to set limits for a job object.

BOOL SetInformationJobObject(
  HANDLE hJob,
  JOBOBJECTINFOCLASS JobObjectInformationClass,
  LPVOID lpJobObjectInformation,
  DWORD cbJobObjectInformationLength
);

Parameters

hJob
Handle to the job object whose limits are being set. The CreateJobObject or OpenJobObject function returns this handle. The handle must have the JOB_OBJECT_SET_ATTRIBUTES access right associated with it.
JobObjectInformationClass
Specifies the information class for limits to be set. This parameter can be one of the following values.
Value | Meaning
JobObjectAssociateCompletionPortInformation | The lpJobObjectInformation parameter is a pointer to a JOBOBJECT_ASSOCIATE_COMPLETION_PORT structure.
JobObjectBasicLimitInformation | The lpJobObjectInformation parameter is a pointer to a JOBOBJECT_BASIC_LIMIT_INFORMATION structure.
JobObjectBasicUIRestrictions | The lpJobObjectInformation parameter is a pointer to a JOBOBJECT_BASIC_UI_RESTRICTIONS structure.
JobObjectEndOfJobTimeInformation | The lpJobObjectInformation parameter is a pointer to a JOBOBJECT_END_OF_JOB_TIME_INFORMATION structure.
JobObjectSecurityLimitInformation | The lpJobObjectInformation parameter is a pointer to a JOBOBJECT_SECURITY_LIMIT_INFORMATION structure.

lpJobObjectInformation
Specifies the limits to be set for the job object. The format of this data depends on the value of JobObjectInformationClass.
cbJobObjectInformationLength
Specifies the count, in bytes, of the job object information being set.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

You can use the SetInformationJobObject function to set several limits in a single call. If you want to establish the limits one at a time or change a subset of the limits, call the QueryInformationJobObject function to obtain the current limits, modify these limits, and then call SetInformationJobObject.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, JOBOBJECT_ASSOCIATE_COMPLETION_PORT, JOBOBJECT_BASIC_LIMIT_INFORMATION, JOBOBJECT_BASIC_UI_RESTRICTIONS, JOBOBJECT_END_OF_JOB_TIME_INFORMATION, JOBOBJECT_SECURITY_LIMIT_INFORMATION , QueryInformationJobObject


SetPriorityClass

The SetPriorityClass function sets the priority class for the specified process. This value together with the priority value of each thread of the process determines each thread's base priority level.

BOOL SetPriorityClass(
  HANDLE hProcess,        // handle to the process
  DWORD dwPriorityClass   // priority class value
);

Parameters

hProcess
Handle to the process.

Windows NT: The handle must have the PROCESS_SET_INFORMATION access right.

dwPriorityClass
Specifies the priority class for the process. Specify one of the following values:
Priority | Meaning
HIGH_PRIORITY_CLASS | Specify this class for a process that performs time-critical tasks that must be executed immediately. The threads of the process preempt the threads of normal or idle priority class processes. An example is the Task List, which must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because a high-priority class application can use nearly all available CPU time.
IDLE_PRIORITY_CLASS | Specify this class for a process whose threads run only when the system is idle. The threads of the process are preempted by the threads of any process running in a higher priority class. An example is a screen saver. The idle-priority class is inherited by child processes.
NORMAL_PRIORITY_CLASS | Specify this class for a process with no special scheduling needs.
REALTIME_PRIORITY_CLASS | Specify this class for a process that has the highest possible priority. The threads of the process preempt the threads of all other processes, including operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Every thread has a base priority level determined by the thread's priority value and the priority class of its process. The system uses the base priority level of all executable threads to determine which thread gets the next slice of CPU time. The SetThreadPriority function enables setting the base priority level of a thread relative to the priority class of its process. For more information, see Scheduling Priorities.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateProcess, CreateThread, GetPriorityClass, GetThreadPriority, SetThreadPriority


SetProcessAffinityMask

The SetProcessAffinityMask function sets a processor affinity mask for the threads of a specified process.

A process affinity mask is a bit vector in which each bit represents the processor on which the threads of the process are allowed to run.

The value of the process affinity mask must be a proper subset of the mask values obtained by the GetProcessAffinityMask function.

BOOL SetProcessAffinityMask(
  HANDLE hProcess,             // handle to process
  DWORD dwProcessAffinityMask  // process affinity mask
);

Parameters

hProcess
A handle to the process whose affinity mask the function sets. This handle must have the PROCESS_SET_INFORMATION access right.
dwProcessAffinityMask
Specifies an affinity mask for the threads of the process.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Process affinity is inherited by any process that you start with the CreateProcess function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateProcess, GetProcessAffinityMask


SetProcessPriorityBoost

The SetProcessPriorityBoost function disables the ability of the system to temporarily boost the priority of the threads of the specified process.

BOOL SetProcessPriorityBoost(
  HANDLE hProcess,           // handle to process
  BOOL DisablePriorityBoost  // priority boost control state
);

Parameters

hProcess
Handle to the process. This handle must have the PROCESS_SET_INFORMATION access right.
DisablePriorityBoost
A Boolean variable that is used to set the priority boost control state. A value of TRUE indicates that dynamic boosting is to be disabled. A value of FALSE restores normal behavior.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

When a thread is running in one of the dynamic priority classes, the system temporarily boosts the thread's priority when it is taken out of a wait state. If SetProcessPriorityBoost is called with the DisablePriorityBoost parameter set to TRUE, its threads' priorities are not boosted. This setting affects all existing threads and any threads subsequently created by the process. To restore normal behavior, call SetProcessPriorityBoost with DisablePriorityBoost set to FALSE.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetProcessPriorityBoost


SetProcessShutdownParameters

The SetProcessShutdownParameters function sets shutdown parameters for the currently calling process. This function sets a shutdown order for a process relative to the other processes in the system.

BOOL SetProcessShutdownParameters(
  DWORD dwLevel,  // shutdown priority
  DWORD dwFlags   // shutdown flags
);

Parameters

dwLevel
Specifies the shutdown priority for a process relative to other processes in the system. The system shuts down processes from high dwLevel values to low. The highest and lowest shutdown priorities are reserved for system components. This parameter must be in the following range of values:
Value | Meaning
000–0FF | System reserved last shutdown range.
100–1FF | Application reserved last shutdown range.
200–2FF | Application reserved "in between" shutdown range.
300–3FF | Application reserved first shutdown range.
400–4FF | System reserved first shutdown range.

All processes start at shutdown level 0x280.

dwFlags
Specifies a flags parameter. It can be the following value:
Value | Meaning
SHUTDOWN_NORETRY | Specifies whether to retry the shutdown if the specified time-out period expires. If this flag is specified, the system terminates the process without displaying a retry dialog box for the user.

Return Values

If the function is succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Applications running in the system security context do not get shut down by the operating system. They get notified of shutdown or logoff through the callback function installable via SetConsoleCtrlHandler. They also get notified in the order specified by the dwLevel parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetProcessShutdownParameters, SetConsoleCtrlHandler


SetProcessWorkingSetSize

The SetProcessWorkingSetSize function sets the minimum and maximum working set sizes for a specified process.

The working set of a process is the set of memory pages currently visible to the process in physical RAM memory. These pages are resident and available for an application to use without triggering a page fault. The size of the working set of a process is specified in bytes. The minimum and maximum working set sizes affect the virtual memory paging behavior of a process.

BOOL SetProcessWorkingSetSize(
  HANDLE hProcess,                // handle to the process of interest
  DWORD dwMinimumWorkingSetSize,  // specifies minimum working set size
  DWORD dwMaximumWorkingSetSize   // specifies maximum working set size
);

Parameters

hProcess
An open handle to the process whose working set sizes will be set.

Windows NT: The handle must have PROCESS_SET_QUOTA access rights.

dwMinimumWorkingSetSize
Specifies a minimum working set size for the process. The virtual memory manager attempts to keep at least this much memory resident in the process whenever the process is active.

If both dwMinimumWorkingSetSize and dwMaximumWorkingSetSize have the value 0xffffffff, the function temporarily trims the working set of the specified process to zero. This essentially swaps the process out of physical RAM memory.

dwMaximumWorkingSetSize
Specifies a maximum working set size for the process. The virtual memory manager attempts to keep no more than this much memory resident in the process whenever the process is active and memory is in short supply.

If both dwMinimumWorkingSetSize and dwMaximumWorkingSetSize have the value 0xffffffff, the function temporarily trims the working set of the specified process to zero. This essentially swaps the process out of physical RAM memory.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. Call GetLastError to obtain extended error information.

Remarks

The working set of the specified process can be emptied by specifying the value 0xffffffff for both the minimum and maximum working set sizes.

If the values of either dwMinimumWorkingSetSize or dwMaximumWorkingSetSize are greater than the process' current working set sizes, the specified process must have the SE_INC_BASE_PRIORITY_NAME privilege. Users in the Administrators and Power Users groups generally have this privilege. For more information about security privileges, see Privileges.

The operating system allocates working set sizes on a first-come, first-served basis. For example, if an application successfully sets 40 megabytes as its minimum working set size on a 64-megabyte system, and a second application requests a 40-megabyte working set size, the operating system denies the second application's request.

Using the SetProcessWorkingSetSize function to set an application's minimum and maximum working set sizes does not guarantee that the requested memory will be reserved, or that it will remain resident at all times. When the application is idle, or a low-memory situation causes a demand for memory, the operating system can reduce the application's working set. An application can use the VirtualLock function to lock ranges of the application's virtual address space in memory; however, that can potentially degrade the performance of the system.

When you increase the working set size of an application, you are taking away physical memory from the rest of the system. This can degrade the performance of other applications and the system as a whole. It can also lead to failures of operations that require physical memory to be present; for example, creating processes, threads, and kernel pool. Thus, you must use the SetProcessWorkingSetSize function carefully. You must always consider the performance of the whole system when you are designing an application.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetProcessWorkingSetSize, VirtualLock


SetThreadAffinityMask

The SetThreadAffinityMask function sets a processor affinity mask for a specified thread.

A thread affinity mask is a bit vector in which each bit represents the processors that a thread is allowed to run on.

A thread affinity mask must be a proper subset of the process affinity mask for the containing process of a thread. A thread is only allowed to run on the processors its process is allowed to run on.

DWORD SetThreadAffinityMask (
  HANDLE hThread,             // handle to the thread of interest
  DWORD dwThreadAffinityMask  // a thread affinity mask
);

Parameters

hThread
A handle to the thread whose affinity mask the function sets.

Windows NT: This handle must have the THREAD_SET_INFORMATION access right associated with it.

dwThreadAffinityMask
Windows NT: Specifies an affinity mask for the thread.

Windows 95 and Windows 98: This value must be 1.

Return Values

If the function succeeds, the return value is nonzero.

Windows NT: The return value is the thread's previous affinity mask.

Windows 95 and Windows 98: The return value is 1. To succeed, hThread must be valid and dwThreadAffinityMask must be 1.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetProcessAffinityMask, SetThreadIdealProcessor


SetThreadIdealProcessor

The SetThreadIdealProcessor function is used to specify a preferred processor for a thread. The system schedules threads on their preferred processors whenever possible.

DWORD SetThreadIdealProcessor(
  HANDLE hThread,         // handle to the thread
  DWORD dwIdealProcessor  // ideal processor number
);

Parameters

hThread
Handle to the thread whose preferred processor is to be set. The handle must have the THREAD_SET_INFORMATION access right associated with it.
dwIdealProcessor
Specifies the number of the preferred processor for the thread. A value of MAXIMUM_PROCESSORS tells the system that the thread has no preferred processor.

Return Values

If the function succeeds, the return value is the previous preferred processor or MAXIMUM_PROCESSORS if the thread does not have a preferred processor.

If the function fails, the return value is – 1. To get extended error information, call GetLastError.

Remarks

You can use the GetSystemInfo function to determine the number of processors on the computer. You can also use the GetProcessAffinityMask function to check the processors on which the thread is allowed to run. Note that GetProcessAffinityMask returns a bit mask whereas SetThreadIdealProcessor uses an integer value to represent the processor.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetProcessAffinityMask, GetSystemInfo, SetThreadAffinityMask


SetThreadPriority

The SetThreadPriority function sets the priority value for the specified thread. This value, together with the priority class of the thread's process, determines the thread's base priority level.

BOOL SetThreadPriority(
  HANDLE hThread, // handle to the thread
  int nPriority   // thread priority level
);

Parameters

hThread
Handle to the thread whose priority value is to be set.

Windows NT: The handle must have the THREAD_SET_INFORMATION access right associated with it.

nPriority
Specifies the priority value for the thread. This parameter can be one of the following values:
Priority | Meaning
THREAD_PRIORITY_ABOVE_NORMAL | Indicates 1 point above normal priority for the priority class.
THREAD_PRIORITY_BELOW_NORMAL | Indicates 1 point below normal priority for the priority class.
THREAD_PRIORITY_HIGHEST | Indicates 2 points above normal priority for the priority class.
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_NORMAL | Indicates 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.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Every thread has a base priority level determined by the thread's priority value and the priority class of its process. The system uses the base priority level of all executable threads to determine which thread gets the next slice of CPU time. Threads are scheduled in a round-robin fashion at each priority level, and only when there are no executable threads at a higher level does scheduling of threads at a lower level take place.

The SetThreadPriority function enables setting the base priority level of a thread relative to the priority class of its process. For example, specifying THREAD_PRIORITY_HIGHEST in a call to SetThreadPriority for a thread of an IDLE_PRIORITY_CLASS process sets the thread's base priority level to 6. For a table that shows the base priority levels for each combination of priority class and thread priority value, see the SetPriorityClass function.

For IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, and HIGH_PRIORITY_CLASS processes, the system dynamically boosts a thread's base priority level when events occur that are important to the thread. REALTIME_PRIORITY_CLASS processes do not receive dynamic boosts.

All threads initially start at THREAD_PRIORITY_NORMAL. Use the GetPriorityClass and SetPriorityClass functions to get and set the priority class of a process. Use the GetThreadPriority function to get the priority value of a thread.

Use the priority class of a process to differentiate between applications that are time critical and those that have normal or below normal scheduling requirements. Use thread priority values to differentiate the relative priorities of the tasks of a process. For example, a thread that handles input for a window could have a higher priority level than a thread that performs intensive calculations for the CPU.

When manipulating priorities, be very careful to ensure that a high-priority thread does not consume all of the available CPU time. A thread with a base priority level above 11 interferes with the normal operation of the operating system. Using REALTIME_PRIORITY_CLASS may cause disk caches to not flush, hang the mouse, and so on.

Windows CE: The thread's priority level is one of the following values:

THREAD_PRIORITY_TIME_CRITICAL
Indicates 3 points above normal priority.
THREAD_PRIORITY_HIGHEST
Indicates 2 points above normal priority.
THREAD_PRIORITY_ABOVE_NORMAL
Indicates 1 point above normal priority.
THREAD_PRIORITY_NORMAL
Indicates normal priority.
THREAD_PRIORITY_BELOW_NORMAL
Indicates 1 point below normal priority.
THREAD_PRIORITY_LOWEST
Indicates 2 points below normal priority.
THREAD_PRIORITY_ABOVE_IDLE
Indicates 3 points below normal priority.
THREAD_PRIORITY_IDLE
Indicates 4 points below normal priority.

Windows CE does not support priority classes. The order in which threads are scheduled is determined only by their thread priorities.

When manipulating priorities, ensure that a high-priority thread does not consume all of the available CPU time. A thread with a priority level of THREAD_PRIORITY_TIME_CRITICAL will execute until it explicitly yields processing to other threads. Processing of these threads is not yielded to other threads with the THREAD_PRIORITY_TIME_CRITICAL priority level. Such a thread can interfere with the normal operation of the operating system if the thread does not explicitly yield processing quickly.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetPriorityClass, GetThreadPriority, SetPriorityClass


SetThreadPriorityBoost

The SetThreadPriorityBoost function disables the ability of the system to temporarily boost the priority of a thread.

BOOL SetThreadPriorityBoost(
  HANDLE hThread,            // handle to thread
  BOOL DisablePriorityBoost  // priority boost control state
);

Parameters

hThread
Handle to the thread whose priority is to be boosted. This thread must have the THREAD_SET_INFORMATION access right associated with it.
DisablePriorityBoost
A Boolean variable that is used to set the priority boost control state. A value of TRUE indicates that dynamic boosting is to be disabled. A value of FALSE restores normal behavior.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

When a thread is running in one of the dynamic priority classes, the system temporarily boosts the thread's priority when it is taken out of a wait state. If SetThreadPriorityBoost is called with the DisablePriorityBoost parameter set to TRUE, the thread's priority is not boosted. To restore normal behavior, call SetThreadPriorityBoost with DisablePriorityBoost set to FALSE.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetThreadPriorityBoost


Sleep

The Sleep function suspends the execution of the current thread for a specified interval.

VOID Sleep(
  DWORD dwMilliseconds   // sleep time in milliseconds
);

Parameters

dwMilliseconds
Specifies the time, in milliseconds, for which to suspend execution. A value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, and the thread continues execution. A value of INFINITE causes an infinite delay.

Return Values

This function does not return a value.

Remarks

A thread can relinquish the remainder of its time slice by calling this function with a sleep time of zero milliseconds.

You have to be careful when using Sleep and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. If you have a thread that uses Sleep with infinite delay, the system will deadlock. Two examples of code that indirectly creates windows are DDE and COM CoInitialize. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than Sleep.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, MsgWaitForMultipleObjects, MsgWaitForMultipleObjectsEx, SleepEx


SleepEx

The SleepEx function causes the current thread to enter a wait state until one of the following occurs:

  • An I/O completion callback function is called
  • An asynchronous procedure call (APC) is queued to the thread.
  • The time-out interval elapses
DWORD SleepEx(
  DWORD dwMilliseconds,  // time-out interval in milliseconds
  BOOL bAlertable        // early completion flag
);

Parameters

dwMilliseconds
Specifies the time, in milliseconds, that the delay is to occur. A value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, and the thread continues execution. A value of INFINITE causes an infinite delay.
bAlertable
Specifies whether the function may terminate early due to an I/O completion callback function or an APC. If bAlertable is FALSE, the function does not return until the time-out period has elapsed. If an I/O completion callback occurs, the function does not return and the I/O completion function is not executed. If an APC is queued to the thread, the function does not return and the APC function is not executed.

If bAlertable is TRUE and the thread that called this function is the same thread that called the extended I/O function (ReadFileEx or WriteFileEx), the function returns when either the time-out period has elapsed or when an I/O completion callback function occurs. If an I/O completion callback occurs, the I/O completion function is called. If an APC is queued to the thread (QueueUserAPC), the function returns when either the timer-out period has elapsed or when the APC function is called.

Return Values

The return value is zero if the specified time interval expired.

The return value is WAIT_IO_COMPLETION if the function returned due to one or more I/O completion callback functions. This can happen only if bAlertable is TRUE, and if the thread that called the SleepEx function is the same thread that called the extended I/O function.

Remarks

This function can be used with the ReadFileEx or WriteFileEx functions to suspend a thread until an I/O operation has been completed. These functions specify a completion routine that is to be executed when the I/O operation has been completed. For the completion routine to be executed, the thread that called the I/O function must be in an alertable wait state when the completion callback function occurs. A thread goes into an alertable wait state by calling either SleepEx, MsgWaitForMultipleObjectsEx, WaitForSingleObjectEx, or WaitForMultipleObjectsEx, with the function's bAlertable parameter set to TRUE.

A thread can relinquish the remainder of its time slice by calling this function with a sleep time of zero milliseconds.

You have to be careful when using SleepEx and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. If you have a thread that uses SleepEx with infinite delay, the system will deadlock. Two examples of code that indirectly creates windows are DDE and COM CoInitialize. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than SleepEx.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, MsgWaitForMultipleObjects, MsgWaitForMultipleObjectsEx, QueueUserAPC, ReadFileEx, Sleep, WaitForMultipleObjectsEx, WaitForSingleObjectEx, WriteFileEx


SuspendThread

The SuspendThread function suspends the specified thread.

DWORD SuspendThread(
  HANDLE hThread   // handle to the thread
);

Parameters

hThread
Handle to the thread.

Windows NT: The handle must have THREAD_SUSPEND_RESUME access.

Return Values

If the function succeeds, the return value is the thread's previous suspend count; otherwise, it is 0xFFFFFFFF. To get extended error information, use the GetLastError function.

Remarks

If the function succeeds, execution of the specified thread is suspended and the thread's suspend count is incremented.

Suspending a thread causes the thread to stop executing user-mode (application) code.

Each thread has a suspend count (with a maximum value of MAXIMUM_SUSPEND_COUNT). If the suspend count is greater than zero, the thread is suspended; otherwise, the thread is not suspended and is eligible for execution. Calling SuspendThread causes the target thread's suspend count to be incremented. Attempting to increment past the maximum suspend count causes an error without incrementing the count.

The ResumeThread function decrements the suspend count of a suspended thread.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, ResumeThread


SwitchToFiber

The SwitchToFiber function schedules a fiber. The caller of must be a fiber.

VOID SwitchToFiber(
  LPVOID lpFiber  // pointer to fiber to switch to
);

Parameters

lpFiber
Specifies the address of the fiber to switch to.

Return Values

This function does not return a value.

Remarks

You create fibers with CreateFiber. Before you can schedule fibers associated with a thread, you must call ConvertThreadToFiber to set up an area in which to save the fiber state information. The thread is now the currently executing fiber.

The SwitchToFiber function saves the state information of the current fiber and restores the state of the specified fiber. You can call SwitchToFiber with the address of a fiber created by a different thread. To do this, you must have the address returned to the other thread when it called CreateFiber and you must use proper synchronization.

Warning Avoid making the following call:

SwitchToFiber( GetCurrentFiber() );

This call causes unpredictable problems.

QuickInfo

Windows NT: Requires version 3.51 SP3 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateFiber, ConvertThreadToFiber


SwitchToThread

The SwitchToThread function causes the calling thread to yield execution to another thread that is ready to run on the current processor. The operating system selects the thread to yield to.

BOOL SwitchToThread(VOID)

Parameters

This function has no parameters.

Return Values

If calling the SwitchToThread function causes the operating system to switch execution to another thread, the return value is nonzero.

If there are no other threads ready to execute, the operating system does not switch execution to another thread, and the return value is zero.

Remarks

The yield of execution is in effect for up to one thread-scheduling time slice. After that, the operating system reschedules execution for the yielding thread. The rescheduling is determined by the priority of the yielding thread and the status of other threads that are available to run.

Note The yield of execution is limited to the processor of the calling thread. The operating system will not switch execution to another processor, even if that processor is idle or is running a thread of lower priority.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, SuspendThread


TerminateJobObject

[This is preliminary documentation and subject to change.]

The TerminateJobObject function terminates all processes currently associated with the job.

BOOL TerminateJobObject(
  HANDLE hJob,
  UINT uExitCode
);

Parameters

hJob
Handle to the job whose processes will be terminated. The CreateJobObject or OpenJobObject function returns this handle. This handle must have the JOB_OBJECT_TERMINATE access right.
uExitCode
Specifies the exit code for the processes and threads terminated as a result of this call.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

It is not possible for any of the processes associated with the job to postpone or handle the termination. It is as if TerminateProcess were called for each process associated with the job.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateJobObject, OpenJobObject, TerminateProcess


TerminateProcess

The TerminateProcess function terminates the specified process and all of its threads.

BOOL TerminateProcess(
  HANDLE hProcess, // handle to the process
  UINT uExitCode   // exit code for the process
);

Parameters

hProcess
Handle to the process to terminate.

Windows NT: The handle must have PROCESS_TERMINATE access.

uExitCode
Specifies the exit code for the process and for all threads terminated as a result of this call. Use the GetExitCodeProcess function to retrieve the process's exit value. Use the GetExitCodeThread function to retrieve a thread's exit value.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The TerminateProcess function is used to unconditionally cause a process to exit. Use it only in extreme circumstances. The state of global data maintained by dynamic-link libraries (DLLs) may be compromised if TerminateProcess is used rather than ExitProcess.

TerminateProcess causes all threads within a process to terminate, and causes a process to exit, but DLLs attached to the process are not notified that the process is terminating.

Terminating a process causes the following:

  1. All of the object handles opened by the process are closed.
  2. All of the threads in the process terminate their execution.
  3. The state of the process object becomes signaled, satisfying any threads that had been waiting for the process to terminate.
  4. The states of all threads of the process become signaled, satisfying any threads that had been waiting for the threads to terminate.
  5. The termination status of the process changes from STILL_ACTIVE to the exit value of the process.

Terminating a process does not cause child processes to be terminated.

Terminating a process does not necessarily remove the process object from the system. A process object is deleted when the last handle to the process is closed.

Windows CE: Windows CE does not support exit codes for processes, so the uExitCode parameter is ignored.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, ExitProcess, OpenProcess, GetExitCodeProcess, GetExitCodeThread


TerminateThread

The TerminateThread function terminates a thread.

BOOL TerminateThread(
  HANDLE hThread,    // handle to the thread
  DWORD dwExitCode   // exit code for the thread
);

Parameters

hThread
Handle to the thread to terminate.

Windows NT: The handle must have THREAD_TERMINATE access.

dwExitCode
Specifies the exit code for the thread. Use the GetExitCodeThread function to retrieve a thread's exit value.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

TerminateThread is used to cause a thread to exit. When this occurs, the target thread has no chance to execute any user-mode code and its initial stack is not deallocated. DLLs attached to the thread are not notified that the thread is terminating.

TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems:

  • If the target thread owns a critical section, the critical section will not be released.
  • If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent.
  • If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL.

A thread cannot protect itself against TerminateThread, other than by controlling access to its handles. The thread handle returned by the CreateThread and CreateProcess functions has THREAD_TERMINATE access, so any caller holding one of these handles can terminate your thread.

If the target thread is the last thread of a process when this function is called, the thread's process is also terminated.

The state of the thread object becomes signaled, releasing any other threads that had been waiting for the thread to terminate. The thread's termination status changes from STILL_ACTIVE to the value of the dwExitCode parameter.

Terminating a thread does not necessarily remove the thread object from the system. A thread object is deleted when the last thread handle is closed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateProcess, CreateThread, ExitThread, GetExitCodeThread


ThreadProc

The ThreadProc function is an application-defined function that serves as the starting address for a thread. Specify this address when calling the CreateThread or CreateRemoteThread function. The LPTHREAD_START_ROUTINE type defines a pointer to this callback function. ThreadProc is a placeholder for the application-defined function name.

DWORD WINAPI ThreadProc(
  LPVOID lpParameter   // thread data
);

Parameters

lpParameter
Receives the thread data passed to the function using the lpParameter parameter of the CreateThread or CreateRemoteThread function.

Return Values

The function should return a value that indicates its success or failure.

Remarks

A process can obtain the return value of the ThreadProc of a thread it created with CreateThread by calling the GetExitCodeThread function. A process cannot obtain the return value from the ThreadProc of a thread it created with CreateRemoteThread.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: User-defined.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateThread, CreateRemoteThread, GetExitCodeThread


TlsAlloc

The TlsAlloc function allocates a thread local storage (TLS) index. Any thread of the process can subsequently use this index to store and retrieve values that are local to the thread.

DWORD TlsAlloc(VOID)

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is a TLS index.

If the function fails, the return value is 0xFFFFFFFF. To get extended error information, call GetLastError.

Remarks

The threads of the process can use the TLS index in subsequent calls to the TlsFree, TlsSetValue, or TlsGetValue functions.

TLS indexes are typically allocated during process or dynamic-link library (DLL) initialization. Once allocated, each thread of the process can use a TLS index to access its own TLS storage slot. To store a value in its slot, a thread specifies the index in a call to TlsSetValue. The thread specifies the same index in a subsequent call to TlsGetValue, to retrieve the stored value.

The constant TLS_MINIMUM_AVAILABLE defines the minimum number of TLS indexes available in each process. This minimum is guaranteed to be at least 64 for all systems.

TLS indexes are not valid across process boundaries. A DLL cannot assume that an index assigned in one process is valid in another process.

A DLL might use TlsAlloc, TlsSetValue, TlsGetValue, and TlsFree as follows:

  1. When a DLL attaches to a process, the DLL uses TlsAlloc to allocate a TLS index. The DLL then allocates some dynamic storage and uses the TLS index in a call to TlsSetValue to store the address in the TLS slot. This concludes the per-thread initialization for the initial thread of the process. The TLS index is stored in a global or static variable of the DLL.
  2. Each time the DLL attaches to a new thread of the process, the DLL allocates some dynamic storage for the new thread and uses the TLS index in a call to TlsSetValue to store the address in the TLS slot. This concludes the per-thread initialization for the new thread.
  3. Each time an initialized thread makes a DLL call requiring the data in its dynamic storage, the DLL uses the TLS index in a call to TlsGetValue to retrieve the address of the dynamic storage for that thread.

For additional information on thread local storage, see Thread Local Storage.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, TlsFree, TlsGetValue, TlsSetValue


TlsFree

The TlsFree function releases a thread local storage (TLS) index, making it available for reuse.

BOOL TlsFree(
  DWORD dwTlsIndex   // TLS index to free
);

Parameters

dwTlsIndex
Specifies a TLS index that was allocated by the TlsAlloc function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the threads of the process have allocated dynamic storage and used the TLS index to store pointers to this storage, they should free the storage before calling TlsFree. The TlsFree function does not free any dynamic storage that has been associated with the TLS index. It is expected that DLLs call this function (if at all) only during their process detach routine.

For a brief discussion of typical uses of the TLS functions, see the Remarks section of the TlsAlloc function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, TlsAlloc, TlsGetValue, TlsSetValue


TlsGetValue

The TlsGetValue function retrieves the value in the calling thread's thread local storage (TLS) slot for a specified TLS index. Each thread of a process has its own slot for each TLS index.

LPVOID TlsGetValue(
  DWORD dwTlsIndex   // TLS index to retrieve value for
);

Parameters

dwTlsIndex
Specifies a TLS index that was allocated by the TlsAlloc function.

Return Values

If the function succeeds, the return value is the value stored in the calling thread's TLS slot associated with the specified index.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Note The data stored in a TLS slot can have a value of zero. In this case, the return value is zero and GetLastError returns NO_ERROR.

Remarks

TLS indexes are typically allocated by the TlsAlloc function during process or DLL initialization. Once allocated, each thread of the process can use a TLS index to access its own TLS storage slot for that index. The storage slot for each thread is initialized to NULL. A thread specifies a TLS index in a call to TlsSetValue, to store a value in its slot. The thread specifies the same index in a subsequent call to TlsGetValue, to retrieve the stored value.

TlsSetValue and TlsGetValue were implemented with speed as the primary goal. These functions perform minimal parameter validation and error checking. In particular, this function succeeds if dwTlsIndex is in the range 0 through (TLS_MINIMUM_AVAILABLE – 1). It is up to the programmer to ensure that the index is valid.

Win32 functions that return indications of failure call SetLastError when they fail. They generally do not call SetLastError when they succeed. The TlsGetValue function is an exception to this general rule. The TlsGetValue function calls SetLastError to clear a thread's last error when it succeeds. That allows checking for the error-free retrieval of NULL values.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, GetLastError, SetLastError, TlsAlloc, TlsFree, TlsSetValue


TlsSetValue

The TlsSetValue function stores a value in the calling thread's thread local storage (TLS) slot for a specified TLS index. Each thread of a process has its own slot for each TLS index.

BOOL TlsSetValue(
  DWORD dwTlsIndex,  // TLS index to set value for
  LPVOID lpTlsValue  // value to be stored
);

Parameters

dwTlsIndex
Specifies a TLS index that was allocated by the TlsAlloc function.
lpTlsValue
Specifies the value to be stored in the calling thread's TLS slot specified by dwTlsIndex.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

TLS indexes are typically allocated by the TlsAlloc function during process or DLL initialization. Once allocated, each thread of the process can use a TLS index to access its own TLS storage slot for that index. The storage slot for each thread is initialized to NULL. A thread specifies a TLS index in a call to TlsSetValue, to store a value in its slot. The thread specifies the same index in a subsequent call to TlsGetValue, to retrieve the stored value.

TlsSetValue and TlsGetValue were implemented with speed as the primary goal. These functions perform minimal parameter validation and error checking. In particular, this function succeeds if dwTlsIndex is in the range 0 through (TLS_MINIMUM_AVAILABLE – 1). It is up to the programmer to ensure that the index is valid.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, TlsAlloc, TlsFree, TlsGetValue


UserHandleGrantAccess

[This is preliminary documentation and subject to change.]

The UserHandleGrantAccess function grants or denies access to a USER handle to a job that has a user-interface restriction. When access is granted, all processes associated with the job can subsequently recognize and use the handle. When access is denied, the processes can no longer use the handle. For more information see User Objects.

BOOL UserHandleGrantAccess(
  HANDLE hUserHandle,
  HANDLE hJob,
  BOOL bGrant
);

Parameters

hUserHandle
A USER handle.
hJob
Handle to the job object to be granted access to the USER handle. The CreateJobObject or OpenJobObject function returns this handle. This handle must have the JOB_OBJECT_LIMIT_USER_INTERACTION access right.
bGrant
Specifies whether access is to be denied or granted to hUserHandle. If bGrant is TRUE, all processes associated with the job can recognize and use the handle. If bGrant is FALSE, the processes can no longer use the handle.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The UserHandleGrantAccess function can be called only from a process not associated with the job object specified by the hJob parameter. The USER handle must not be owned by a process or thread associated with the job object.

To create user-interface restrictions, call the SetInformationJobObject function with the JobObjectBasicUIRestrictions job object information class.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateJobObject, OpenJobObject, SetInformationJobObject


WaitForInputIdle

The WaitForInputIdle function waits until the given process is waiting for user input with no input pending, or until the time-out interval has elapsed.

The WaitForInputIdle function only works with GUI applications. If a console application calls the function, it returns immediately, with no wait.

DWORD WaitForInputIdle(
  HANDLE hProcess,       // handle to process
  DWORD dwMilliseconds   // time-out interval in milliseconds
);

Parameters

hProcess
Handle to the process.
dwMilliseconds
Specifies the time-out interval, in milliseconds. If dwMilliseconds is INFINITE, the function does not return until the process is idle.

Return Values

The following table shows the possible return values:

Value | Meaning
0 | The wait was satisfied successfully.
WAIT_TIMEOUT | The wait was terminated because the time-out interval elapsed.
0xFFFFFFFF | An error occurred. To get extended error information, use the GetLastError function.

Remarks

The WaitForInputIdle function enables a thread to suspend its execution until a specified process has finished its initialization and is waiting for user input with no input pending. This can be useful for synchronizing a parent process and a newly created child process. When a parent process creates a child process, the CreateProcess function returns without waiting for the child process to finish its initialization. Before trying to communicate with the child process, the parent process can use WaitForInputIdle to determine when the child's initialization has been completed. For example, the parent process should use WaitForInputIdle before trying to find a window associated with the child process.

The WaitForInputIdle function can be used at any time, not just during application startup.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateProcess


WinExec

The WinExec function runs the specified application.

This function is provided for compatibility with 16-bit Windows. Win32-based applications should use the CreateProcess function.

UINT WinExec(
  LPCSTR lpCmdLine,  // address of command line
  UINT uCmdShow      // window style for new application
);

Parameters

lpCmdLine
Pointer to a null-terminated character string that contains the command line (filename plus optional parameters) for the application to be executed. If the name of the executable file in the lpCmdLine parameter does not contain a directory path, the system searches for the executable file in this sequence:
  1. The directory from which the application loaded.
  2. The current directory.
  3. The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.
  4. The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.
  5. The directories listed in the PATH environment variable.
uCmdShow
Specifies how a Windows-based application window is to be shown and is used to supply the wShowWindow member of the STARTUPINFO parameter to the CreateProcess function. For a list of the acceptable values, see the description of the nCmdShow parameter of the ShowWindow function. For a non-Windows – based application, the PIF file, if any, for the application determines the window state.

Return Values

If the function succeeds, the return value is greater than 31.

If the function fails, the return value is one of the following error values:

Value | Meaning
0 | The system is out of memory or resources.
ERROR_BAD_FORMAT | The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).
ERROR_FILE_NOT_FOUND | The specified file was not found.
ERROR_PATH_NOT_FOUND | The specified path was not found.

Remarks

In Win32, the WinExec function returns when the started process calls the GetMessage function or a time-out limit is reached. To avoid waiting for the time out delay, call the GetMessage function as soon as possible in any process started by a call to WinExec.

See Also

Processes and Threads Overview, Process and Thread Functions, CreateProcess, GetMessage, GetSystemDirectory, GetWindowsDirectory, LoadModule, ShowWindow


Yield

The Yield function is obsolete. This function is provided only for compatibility with 16-bit versions of Windows. In the Win32-based application programming interface (API), this function does nothing.

Threads that contain windows should use the DispatchMessage, PeekMessage, or TranslateMessage functions. The message-loop functions handle message synchronization properly and yield at the appropriate times.

Threads that do not contain windows should use the Sleep function with a sleep time of zero milliseconds to give up the remainder of their current time slice.

Threads that create a process can use WaitForInputIdle to wait until the new process has finished its initialization.

See Also

Processes and Threads Overview, Process and Thread Functions, DispatchMessage, PeekMessage, Sleep, TranslateMessage, WaitForInputIdle


Process and Thread Structures

The following structures are used with processes and threads.

PROCESS_INFORMATION
STARTUPINFO

Job Object Structures

The following structures are used with job objects.

JOBOBJECT_ASSOCIATE_COMPLETION_PORT
JOBOBJECT_BASIC_ACCOUNTING_INFORMATION
JOBOBJECT_BASIC_LIMIT_INFORMATION
JOBOBJECT_BASIC_PROCESS_ID_LIST
JOBOBJECT_BASIC_UI_RESTRICTIONS
JOBOBJECT_END_OF_JOB_TIME_INFORMATION
JOBOBJECT_SECURITY_LIMIT_INFORMATION


JOBOBJECT_ASSOCIATE_COMPLETION_PORT

[This is preliminary documentation and subject to change.]

The JOBOBJECT_ASSOCIATE_COMPLETION_PORT structure contains information used to associate a completion port with a job object.

typedef struct _JOBOBJECT_ASSOCIATE_COMPLETION_PORT {
    PVOID CompletionKey;
    HANDLE CompletionPort;
} JOBOBJECT_ASSOCIATE_COMPLETION_PORT, PJOBOBJECT_ASSOCIATE_COMPLETION_PORT;

Members

CompletionKey
Specifies the value to use in the dwCompletionKey parameter of PostQueuedCompletionStatus when messages are sent on behalf of the job object.
CompletionPort
Specifies the completion port to use in the CompletionPort parameter of the PostQueuedCompletionStatus function when messages are sent on behalf of the job object.

Remarks

The job object sends messages to the completion port when certain events occur. All messages are sent directly from the job object as if the job object had called the PostQueuedCompletionStatus function. A thread monitoring the completion port using the GetQueuedCompletionStatus function must pick up the messages. The thread receives information in the GetQueuedCompletionStatus parameters shown in the following table.

Parameter | Information Received
lpCompletionKey | The value specified in CompletionKey during the completion-port assocation. If a completion port is associated with multiple job objects, CompletionKey should help the caller determine which completion port is sending a message.
lpOverlapped | Message-specific value. For more information, see the following table of message identifiers.
lpNumberOfBytesTransfered | The message identifier that indicates which job-related event occurred. For more information, see the following table of message identifiers.

The following messages can be sent to the completion port.

Message Identifier | Description
JOB_OBJECT_MSG_END_OF_JOB_TIME | Indicates that the JOB_OBJECT_POST_AT_END_OF_JOB option is in effect and the end-of-job time limit has been reached. Upon posting this message, the time limit is canceled and the job's processes can continue to run. The value of lpOverlapped in NULL.
JOB_OBJECT_MSG_END_OF_PROCESS_TIME | This message is sent whenever a process exceeds a per-process time limit. It is sent after the process termination has been requested. The value of lpOverlapped is the identifier of the process that exceeded its limit.
JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT | This message is sent when the active process limit has been exceeded. The value of lpOverlapped is NULL.
JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO | This message is sent whenever the active process count is decremented to 0. For example, if the job currently has two active processes, this message is sent after they both terminate. The value of lpOverlapped is NULL.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Processes and Threads Overview, Process and Thread Structures, PostQueuedCompletionStatus, QueryInformationJobObject, SetInformationJobObject


JOBOBJECT_BASIC_ACCOUNTING_INFORMATION

[This is preliminary documentation and subject to change.]

The JOBOBJECT_BASIC_ACCOUNTING_INFORMATION structure contains basic accounting information for a job object.

typedef struct _JOBOBJECT_BASIC_ACCOUNTING_INFORMATION {
    LARGE_INTEGER TotalUserTime;
    LARGE_INTEGER TotalKernelTime;
    LARGE_INTEGER ThisPeriodTotalUserTime;
    LARGE_INTEGER ThisPeriodTotalKernelTime;
    DWORD TotalPageFaultCount;
    DWORD TotalProcesses;
    DWORD ActiveProcesses;
    DWORD TotalTerminatedProcesses;
} JOBOBJECT_BASIC_ACCOUNTING_INFORMATION, *PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION;

Members

TotalUserTime
Specifies the total amount of user-mode execution time, in 100-nanosecond ticks, for all active processes associated with the job object, as well as all terminated processes no longer associated with the job object.
TotalKernelTime
Specifies the total amount of kernel-mode execution time, in 100-nanosecond ticks, for all active processes associated with the job object, as well as all terminated processes no longer associated with the job object.
ThisPeriodTotalUserTime
Specifies the total amount of user-mode execution time, in 100-nanosecond ticks, for all active processes associated with the job object (as well as all terminated processes no longer associated with the job object) since the last call that set a per-job user-mode time limit.

This member is set to 0 on creation of the job object, and each time a per-job user-mode time limit is established.

ThisPeriodTotalKernelTime
Specifies the total amount of kernel-mode execution time, in 100-nanosecond ticks, for all active processes associated with the job object (as well as all terminated processes no longer associated with the job object) since the last call that set a per-job kernel-mode time limit.

This member is set to 0 on creation of the job object, and each time a per-job kernel-mode time limit is established.

TotalPageFaultCount
Specifies the total number of page faults encountered by all active processes associated with the job object, as well as all terminated processes no longer associated with the job object.
TotalProcesses
Specifies the total number of processes associated with the job object during its lifetime, including those that have terminated. For example, when a process is associated with a job, but the association fails because of a limit violation, this value is incremented.
ActiveProcesses
Specifies the total number of processes currently associated with the job object. When a process is associated with a job, but the association fails because of a limit violation, this value is temporarily incremented. When the terminated process exits and all references to the process are released, this value is decremented.
TotalTerminatedProcesses
Specifies the total number of processes terminated because of a limit violation.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Processes and Threads Overview, Process and Thread Structures, QueryInformationJobObject, SetInformationJobObject


JOBOBJECT_BASIC_LIMIT_INFORMATION

[This is preliminary documentation and subject to change.]

The JOBOBJECT_BASIC_LIMIT_INFORMATION structure contains basic limit information for a job object.

typedef struct _JOBOBJECT_BASIC_LIMIT_INFORMATION {
    LARGE_INTEGER PerProcessUserTimeLimit;
    LARGE_INTEGER PerJobUserTimeLimit;
    DWORD LimitFlags;
    DWORD MinimumWorkingSetSize;
    DWORD MaximumWorkingSetSize;
    DWORD ActiveProcessLimit;
    DWORD Affinity;
    DWORD PriorityClass;
} JOBOBJECT_BASIC_LIMIT_INFORMATION, *PJOBOBJECT_BASIC_LIMIT_INFORMATION;

Members

PerProcessUserTimeLimit
Ignored unless LimitFlags specifies JOB_OBJECT_LIMIT_PROCESS_TIME. Specifies the per-process user-mode execution time limit, in 100-nanosecond ticks.

The system periodically checks to see if each process associated with the job object has accumulated more user-mode time than the set limit. If it has, the process is terminated.

PerJobUserTimeLimit
Ignored unless LimitFlags specifies JOB_OBJECT_LIMIT_JOB_TIME. Specifies the per-job user-mode execution time limit, in 100-nanosecond ticks.

The system periodically checks to see if the sum of the user-mode execution time for all processes is greater than this end-of-job limit. If it is, the action specified in the EndOfJobTimeAction member of the JOBOBJECT_END_OF_JOB_TIME_INFORMATION structure is carried out. By default, all processes are terminated and the status code is set to ERROR_NOT_ENOUGH_QUOTA.

LimitFlags
Specifies the limit flags that are in effect. This member is a bit field that determines whether other structure members are used. Any combination of the following values can be specified.
Value | Meaning
JOB_OBJECT_LIMIT_ACTIVE_PROCESS | Establishes a maximum number of simultaneously active processes associated with the job object.
JOB_OBJECT_LIMIT_AFFINITY | Causes all processes associated with the job object to use the same processor affinity.
JOB_OBJECT_LIMIT_JOB_TIME | Establishes a user-mode execution time limit for the job object.
JOB_OBJECT_LIMIT_PRIORITY_CLASS | Causes all processes associated with the job to use the same priority class. For more information, see Scheduling Priorities.
JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME | Preserves any job time limits you previously set. As long as this flag is set, you can establish a per-job time limit once, then alter other limits in subsequent calls.
JOB_OBJECT_LIMIT_PROCESS_TIME | Establishes a user-mode execution time limit for each currently active process and for all future processes associated with the job object.
JOB_OBJECT_LIMIT_WORKINGSET | Causes all processes associated with the job to use the same minimum and maximum working set sizes.

MinimumWorkingSetSize
Ignored unless the LimitFlags member specifies JOB_OBJECT_LIMIT_WORKINGSET. Specifies the minimum working set size for all processes associated with the job object.
MaximumWorkingSetSize
Ignored unless LimitFlags specifies JOB_OBJECT_LIMIT_WORKINGSET. Specifies the maximum working set size for all processes associated with the job object.
ActiveProcessLimit
Ignored unless LimitFlags specifies JOB_OBJECT_LIMIT_ACTIVE_PROCESS. Specifies the active process limit for the job object. If you try to associate a process with a job object, and this causes the active process count to exceed this limit, the process is terminated and the association fails.
Affinity
Ignored unless LimitFlags specifies JOB_OBJECT_LIMIT_AFFINITY. Specifies the processor affinity for all processes associated with the job object. The affinity must be a proper subset of the system affinity mask obtained by calling the GetProcessAffinityMask function. The affinity of each thread is set to this value, but threads are free to subsequently set their affinity, as long as it is a subset of the specified affinity mask. Processes cannot set their own affinity mask.
PriorityClass
Ignored unless LimitFlags specifies JOB_OBJECT_LIMIT_PRIORITY_CLASS. Specifies the priority class for all processes associated with the job object. Processes and threads cannot increase their priority class. The calling process must have the SE_INCREASEBASEPRIORITY_NAME privilege.

Remarks

Processes can still empty their working sets using the SetProcessWorkingSetSize function, even when JOB_OBJECT_LIMIT_WORKINGSET is used. However, you cannot use SetProcessWorkingSetSize to change the minimum or maximum working set size.

The system increments the active process count when you attempt to associate a process with a job object. If the limit is exceeded, the system decrements the active process count only when the process terminates and all handles to the process are closed. Therefore, if you have an open handle to a process that has been terminated in such a manner, you cannot associate any new processes until the handle is closed and the active process count is below the limit.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Processes and Threads Overview, Process and Thread Structures, GetProcessAffinityMask, JOBOBJECT_END_OF_JOB_TIME_INFORMATION, QueryInformationJobObject, SetInformationJobObject, SetProcessWorkingSetSize


JOBOBJECT_BASIC_PROCESS_ID_LIST

[This is preliminary documentation and subject to change.]

The JOBOBJECT_BASIC_PROCESS_ID_LIST structure contains the process identifier list for a job object.

typedef struct _JOBOBJECT_BASIC_PROCESS_ID_LIST {
    DWORD NumberOfAssignedProcesses;
    DWORD NumberOfProcessIdsInList;
    DWORD ProcessIdList[1];
} JOBOBJECT_BASIC_PROCESS_ID_LIST, *PJOBOBJECT_BASIC_PROCESS_ID_LIST;

Members

NumberOfAssignedProcesses
Specifies the number of process identifiers to be stored in ProcessIdList.
NumberOfProcessIdsInList
Specifies the number of process identifiers returned in the ProcessIdList buffer. If this number is less than NumberOfAssignedProcesses, increase the size of the buffer to accommodate the complete list.
ProcessIdList
Specifies the variable-length array of process identifiers returned by this call. Array elements 0 through NumberOfProcessIdsInList – 1 contain valid process identifiers.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Processes and Threads Overview, Process and Thread Structures, QueryInformationJobObject, SetInformationJobObject


JOBOBJECT_BASIC_UI_RESTRICTIONS

[This is preliminary documentation and subject to change.]

The JOBOBJECT_BASIC_UI_RESTRICTIONS structure contains basic user-interface restrictions for a job object.

typedef struct _JOBOBJECT_BASIC_UI_RESTRICTIONS {
    DWORD UIRestrictionsClass;
} JOBOBJECT_BASIC_UI_RESTRICTIONS, *PJOBOBJECT_BASIC_UI_RESTRICTIONS;

Members

UIRestrictionsClass
Specifies the restriction class for the user interface. This member can be one or more of the following values.
Value | Meaning
JOB_OBJECT_UILIMIT_EXITWINDOWS | Prevents processes associated with the job object from calling the ExitWindows or ExitWindowsEx function.
JOB_OBJECT_UILIMIT_HANDLES | Prevents processes associated with the job object from using USER handles owned by processes not associated with the same job.
JOB_OBJECT_UILIMIT_READCLIPBOARD | Prevents processes associated with the job object from reading data from the clipboard.
JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | Prevents processes associated with the job object from changing system parameters by using the SystemParametersInfo function.
JOB_OBJECT_UILIMIT_WRITECLIPBOARD | Prevents processes associated with the job object from writing data to the clipboard.

Remarks

If you specify the JOB_OBJECT_UILIMIT_HANDLES flag, when a process associated with the job object broadcasts messages, they are only sent to top-level windows owned by processes associated with the same job. In addition, hooks can be installed only on threads belonging to processes associated with the job object.

To grant access to a USER handle to a job that has a user-interface restriction, use the UserHandleGrantAccess function.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Processes and Threads Overview, Process and Thread Structures, ExitWindows, ExitWindowsEx QueryInformationJobObject, SetInformationJobObject, SystemParametersInfo, UserHandleGrantAccess


JOBOBJECT_END_OF_JOB_TIME_INFORMATION

[This is preliminary documentation and subject to change.]

The JOBOBJECT_END_OF_JOB_TIME_INFORMATION structure specifies the action the system will perform when an end-of-job time limit is exceeded.

typedef struct _JOBOBJECT_END_OF_JOB_TIME_INFORMATION {
    DWORD EndOfJobTimeAction;
} JOBOBJECT_END_OF_JOB_TIME_INFORMATION, PJOBOBJECT_END_OF_JOB_TIME_INFORMATION;

Members

EndOfJobTimeAction
Specifies the action that the system will perform when the end-of-job time limit has been exceeded. This member can be one of the following values.
Value Meaning
JOB_OBJECT_TERMINATE_AT_END_OF_JOB Terminates all processes and sets the exit status to ERROR_NOT_ENOUGH_QUOTA. The processes cannot prevent or delay their own termination. The job object is set to the signaled state and remains signaled until this limit is reset. No additional processes can be assigned to the job object until the limit is reset.

This is the default termination action.
JOB_OBJECT_POST_AT_END_OF_JOB Posts a completion packet to the completion port using the PostQueuedCompletionStatus function. After the completion packet is posted, the system clears the end-of-job time limit, and processes in the job object can continue their execution.

If no completion port is associated with the job when the time limit has been exceeded, the action taken is the same as for JOB_OBJECT_TERMINATE_AT_END_OF_JOB.

Remarks

The end-of-job time limit is specified in the PerJobUserTimeLimit member of the JOBOBJECT_BASIC_LIMIT_INFORMATION structure.

To associate a completion port with a job object, use the JOBOBJECT_ASSOCIATE_COMPLETION_PORT structure.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Processes and Threads Overview, Process and Thread Structures, JOBOBJECT_ASSOCIATE_COMPLETION_PORT, JOBOBJECT_BASIC_LIMIT_INFORMATION, PostQueuedCompletionStatus, QueryInformationJobObject, SetInformationJobObject


JOBOBJECT_SECURITY_LIMIT_INFORMATION

[This is preliminary documentation and subject to change.]

The JOBOBJECT_SECURITY_LIMIT_INFORMATION structure contains the security limitations for a job object.

typedef struct _JOBOBJECT_SECURITY_LIMIT_INFORMATION {
    DWORD SecurityLimitFlags ;
    HANDLE JobToken ;
    PTOKEN_GROUPS SidsToDisable ;
    PTOKEN_PRIVILEGES PrivilegesToDelete ;
    PTOKEN_GROUPS RestrictedSids ;
} JOBOBJECT_SECURITY_LIMIT_INFORMATION, *PJOBOBJECT_SECURITY_LIMIT_INFORMATION ;

Members

SecurityLimitFlags
Specifies the security limitations for the job object. This member can be one or more of the following values.
Value | Meaning
JOB_OBJECT_SECURITY_NO_ADMIN | Prevents any process in the job object from using a token that specifies the local administrators group.
JOB_OBJECT_SECURITY_RESTRICTED_TOKEN | Prevents any process in the job object from using a token that was not created with the CreateRestrictedToken function.
JOB_OBJECT_SECURITY_ONLY_TOKEN | Forces processes in the job object to run under a specific token. Requires a token handle in the JobToken member.
JOB_OBJECT_SECURITY_FILTER_TOKENS | Applies a filter to the token when a process impersonates a client. Requires at least one of the following members to be set: SidsToDisable, PrivilegesToDelete, or RestrictedSids.

JobToken
Handle to a primary token that represents a user. The handle must have TOKEN_ASSIGN_PRIMARY access.

If the token was created with CreateRestrictedToken, all processes in the job are limited to that token or a further restricted token. Otherwise, the caller must have the SE_ASSIGNPRIMARYTOKEN_NAME privilege.

SidsToDisable
Pointer to a TOKEN_GROUPS structure that specifies the SIDs to disable for access checking, if SecurityLimitFlags is JOB_OBJECT_SECURITY_FILTER_TOKENS.

This member can be NULL if you do not want to disable any SIDs.

PrivilegesToDelete
Pointer to a TOKEN_PRIVILEGES structure that specifies the privileges to delete from the token, if SecurityLimitFlags is JOB_OBJECT_SECURITY_FILTER_TOKENS.

This member can be NULL if you do not want to delete any privileges.

RestrictedSids
Pointer to a TOKEN_GROUPS structure that specifies the deny-only SIDs that will be added to the access token, if SecurityLimitFlags is JOB_OBJECT_SECURITY_FILTER_TOKENS.

This member can be NULL if you do not want to specify any deny-only SIDs.

Remarks

After security limitations are placed on processes in a job object, they cannot be revoked.

To retrieve the token for a job object, use the OpenJobObjectToken function.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Processes and Threads Overview, Process and Thread Structures, CreateRestrictedToken, OpenJobObjectToken, QueryInformationJobObject, SetInformationJobObject, TOKEN_GROUPS, TOKEN_PRIVILEGES


PROCESS_INFORMATION

The PROCESS_INFORMATION structure is filled in by the CreateProcess function with information about a newly created process and its primary thread.

typedef struct _PROCESS_INFORMATION { // pi
    HANDLE hProcess;
    HANDLE hThread;
    DWORD dwProcessId;
    DWORD dwThreadId;
} PROCESS_INFORMATION;

Members

hProcess
Returns a handle to the newly created process. The handle is used to specify the process in all functions that perform operations on the process object.
hThread
Returns a handle to the primary thread of the newly created process. The handle is used to specify the thread in all functions that perform operations on the thread object.
dwProcessId
Returns a global process identifier that can be used to identify a process. The value is valid from the time the process is created until the time the process is terminated.
dwThreadId
Returns a global thread identifiers that can be used to identify a thread. The value is valid from the time the thread is created until the time the thread is terminated.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.

See Also

Processes and Threads Overview, Process and Thread Structures, CreateProcess


STARTUPINFO

The STARTUPINFO structure is used with the CreateProcess function to specify main window properties if a new window is created for the new process. For graphical user interface (GUI) processes, this information affects the first window created by the CreateWindow function and shown by the ShowWindow function. For console processes, this information affects the console window if a new console is created for the process. A process can use the GetStartupInfo function to retrieve the STARTUPINFO structure specified when the process was created.

typedef struct _STARTUPINFO { // si
    DWORD   cb;
    LPTSTR  lpReserved;
    LPTSTR  lpDesktop;
    LPTSTR  lpTitle;
    DWORD   dwX;
    DWORD   dwY;
    DWORD   dwXSize;
    DWORD   dwYSize;
    DWORD   dwXCountChars;
    DWORD   dwYCountChars;
    DWORD   dwFillAttribute;
    DWORD   dwFlags;
    WORD    wShowWindow;
    WORD    cbReserved2;
    LPBYTE  lpReserved2;
    HANDLE  hStdInput;
    HANDLE  hStdOutput;
    HANDLE  hStdError;
} STARTUPINFO, *LPSTARTUPINFO;

Members

cb
Specifies the size, in bytes, of the structure.
lpReserved
Reserved. Set this member to NULL before passing the structure to CreateProcess.
lpDesktop
Windows NT: Pointer to a zero-terminated string that specifies either the name of the desktop only or the name of both the desktop and window station for this process. A backslash in the string pointed to by lpDesktop indicates that the string includes both desktop and window station names. If lpDesktop is NULL, the new process inherits the desktop and window station of its parent process. If lpDesktop is an empty string, the process does not inherit the desktop and window station of its parent process; instead, the system determines if a new desktop and window station need to be created. If the impersonated user already has a desktop, the system will use the existing desktop.
lpTitle
For console processes, this is the title displayed in the title bar if a new console window is created. If NULL, the name of the executable file is used as the window title instead. This parameter must be NULL for GUI or console processes that do not create a new console window.
dwX, dwY
Ignored unless dwFlags specifies STARTF_USEPOSITION. Specifies the x and y offsets, in pixels, of the upper left corner of a window if a new window is created. The offsets are from the upper left corner of the screen. For GUI processes, the specified position is used the first time the new process calls CreateWindow to create an overlapped window if the x parameter of CreateWindow is CW_USEDEFAULT.
dwXSize, dwYSize
Ignored unless dwFlags specifies STARTF_USESIZE. Specifies the width (dwXSize) and height (dwYSize), in pixels, of the window if a new window is created. For GUI processes, this is used only the first time the new process calls CreateWindow to create an overlapped window if the nWidth parameter of CreateWindow is CW_USEDEFAULT.
dwXCountChars, dwYCountChars
Ignored unless dwFlags specifies STARTF_USECOUNTCHARS. For console processes, if a new console window is created, dwXCountChars specifies the screen buffer width in character columns, and dwYCountChars specifies the screen buffer height in character rows. These values are ignored in GUI processes.
dwFillAttribute
Ignored unless dwFlags specifies STARTF_USEFILLATTRIBUTE. Specifies the initial text and background colors if a new console window is created in a console application. These values are ignored in GUI applications. This value can be any combination of the following values: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following combination of values produces red text on a whilte background:
FOREGROUND_RED | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
dwFlags
This is a bit field that determines whether certain STARTUPINFO members are used when the process creates a window. Any combination of the following values can be specified:
Value | Meaning
STARTF_USESHOWWINDOW | If this value is not specified, the wShowWindow member is ignored.
STARTF_USEPOSITION | If this value is not specified, the dwX and dwY members are ignored.
STARTF_USESIZE | If this value is not specified, the dwXSize and dwYSize members are ignored.
STARTF_USECOUNTCHARS | If this value is not specified, the dwXCountChars and dwYCountChars members are ignored.
STARTF_USEFILLATTRIBUTE | If this value is not specified, the dwFillAttribute member is ignored.
STARTF_FORCEONFEEDBACK | If this value is specified, the cursor is in feedback mode for two seconds after CreateProcess is called. If during those two seconds the process makes the first GUI call, the system gives five more seconds to the process. If during those five seconds the process shows a window, the system gives five more seconds to the process to finish drawing the window.
The system turns the feedback cursor off after the first call to GetMessage, regardless of whether the process is drawing.
For more information on feedback, see the following Remarks section.
STARTF_FORCEOFFFEEDBACK | If specified, the feedback cursor is forced off while the process is starting. The normal cursor is displayed. For more information on feedback, see the following Remarks section.
STARTF_USESTDHANDLES | If this value is specified, sets the standard input of the process, standard output, and standard error handles to the handles specified in the hStdInput, hStdOutput, and hStdError members of the STARTUPINFO structure. The CreateProcess function's fInheritHandles parameter must be set to TRUE for this to work properly.
If this value is not specified, the hStdInput, hStdOutput, and hStdError members of the STARTUPINFO structure are ignored.

wShowWindow
Ignored unless dwFlags specifies STARTF_USESHOWWINDOW. The wshowWindow member can be any of the SW_ constants defined in WINUSER.H. For GUI processes, wShowWindow specifies the default value the first time ShowWindow is called. The nCmdShow parameter of ShowWindow is ignored. In subsequent calls to ShowWindow, the wShowWindow member is used if the nCmdShow parameter of ShowWindow is set to SW_SHOWDEFAULT.
cbReserved2
Reserved; must be zero.
lpReserved2
Reserved; must be NULL.
hStdInput
Ignored unless dwFlags specifies STARTF_USESTDHANDLES. Specifies a handle that will be used as the standard input handle to the process if STARTF_USESTDHANDLES is specified.
hStdOutput
Ignored unless dwFlags specifies STARTF_USESTDHANDLES. Specifies a handle that will be used as the standard output handle to the process if STARTF_USESTDHANDLES is specified.
hStdError
Ignored unless dwFlags specifies STARTF_USESTDHANDLES. Specifies a handle that will be used as the standard error handle to the process if STARTF_USESTDHANDLES is specified.

Remarks

If a GUI process is being started and neither STARTF_FORCEONFEEDBACK or STARTF_FORCEOFFFEEDBACK is specified, the process feedback cursor is used. A GUI process is one whose subsystem is specified as "windows."

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Processes and Threads Overview, Process and Thread Structures, CreateProcess, CreateProcessAsUser, CreateWindow, GetMessage, GetStartupInfo, PeekMessage, ShowWindow, WinMain


Services

Microsoft® Windows NT® supports an application type known as a service. A Win32-based service conforms to the interface rules of the Service Control Manager (SCM). It can be started automatically at system boot, by a user through the Services control panel applet, or by a Win32-based application that uses the service functions included in the Microsoft® Win32® application programming interface (API). Services can execute even when no user is logged on to the system.

Windows NT also supports a driver service, which conforms to the device driver protocols for Windows NT. It is similar to the Win32-based service, but it does not interact with the SCM. For simplicity, the term service refers to a Win32-based service in this overview.

Note Windows 95 and Windows 98 support a subset of the functionality provided by the Windows NT SCM. For more information, see Windows 95 Service Control Manager.


About Services

The Service Control Manager (SCM) maintains a database of installed services and driver services, and provides a unified and secure means of controlling them. The database includes information on how each service or driver service should be started. It also enables system administrators to customize security requirements for each service and thereby control access to the service.

Three types of programs use the functions provided by the SCM:

Type | Description
Service Programs | A program that provides executable code for one or more services. Service programs use functions that connect to the SCM and send status information to the SCM.
Service Configuration Program | A program that queries or modifies the services database. Service configuration programs use functions that open the database, install or delete services in the database, and query or modify the configuration and security parameters for installed services. Service configuration programs manage both services and driver services.
Service Control Program | A program that starts and controls services and driver services. Service control programs use functions that send requests to the SCM, which carries out the request.

This overview discusses the following topics:

  • Service Control Manager
  • Service Programs
  • Service Configuration Programs
  • Service Control Programs
  • Service Security
  • Interactive Services
  • Debugging a Service


Service Control Manager

The service control manager (SCM) is started by Windows NT at system boot. It is a remote procedure call (RPC) server, so that service configuration and service control programs can manipulate services on remote machines.

The Win32 API includes a set of functions that provide an interface for the following tasks performed by the SCM:

  • Maintaining the database of installed services.
  • Starting services and driver services either upon system startup or upon demand.
  • Enumerating installed services and driver services.
  • Maintaining status information for running services and driver services.
  • Transmitting control requests to running services.
  • Locking and unlocking the service database.
  • The following sections describe the SCM in more detail.
  • Database of Installed Services
  • Automatically Starting Services
  • Starting Services on Demand
  • Service Record List
  • SCM Handles


Database of Installed Services

The SCM maintains a database of installed services in the registry. The database is used by the SCM and programs that add, modify, or configure services. The following is the registry key for this database.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

This key contains a subkey for each installed service and driver service. The name of the subkey is the name of the service, as specified by the CreateService function when the service was installed by a service configuration program.

An initial copy of the database is created during setup of Windows NT, which contains entries for the device drivers required during system boot. The database includes the following information about each installed service and driver service:

  • The service type. This indicates whether the service executes in its own process or shares a process with other services. For driver services, this indicates whether the service is a kernel driver or a file system driver.
  • The start type. This indicates whether the service or driver service is started automatically at system startup (auto-start service) or whether the SCM starts it when requested by a service control program (demand-start service). The start type can also indicate that the service or driver service is disabled, in which case it cannot be started.
  • The error control level. This specifies the severity of the error if the service or driver service fails to start during system startup and determines the action that the startup program will take.
  • The fully qualified path of the executable file. The filename extension is .EXE for services and .SYS for driver services.
  • Optional dependency information used to determine the proper order for starting services or driver services. For services, this information can include a list of services that the SCM must start before it can start the specified service, the name of a load ordering group that the service is part of, and a tag identifier that indicates the start order of the service in its load ordering group. For driver services, this information includes a list of drivers that must be started before the specified driver.
  • For services, an optional account name and password. The service program runs in the context of this account. If no account is specified, the service executes in the context of the LocalSystem account.
  • For driver services, an optional driver object name (for example, \FileSystem\Rdr or \Driver\Xns), used by the I/O system to load the device driver. If no name is specified, the I/O system creates a default name based on the driver service name.

Note This database is also known as the ServicesActive database or the SCM database. You must use the functions provided by the SCM, instead of modifying the database directly.


Automatically Starting Services

During system boot, the SCM starts all auto-start services and the services on which they depend. For example, if an auto-start service depends on a demand-start service, the demand-start service is also started automatically. The load order is determined by the following:

  1. The order of groups in the load ordering group list, ServiceGroupOrder, in the following registry key:

    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control

  2. The order of services within a group specified in the tags order vector, GroupOrderList, in the following registry key

    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control

  3. The dependencies listed for each service.

When the boot is complete, the system executes the boot verification program specified by BootVerificationProgram value of the following registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control

By default, this value is not set. The system simply reports that the boot was successful after the first user has logged on. You can supply a boot verification program that checks the system for problems and reports the boot status to the SCM using the NotifyBootConfigStatus function.

After a successful boot, the system saves a clone of the database in the last-known-good (LKG) configuration. The system can restore this copy of the database if changes made to the active database cause the system reboot to fail. The following is the registry key for this database,

HKEY_LOCAL_MACHINE\SYSTEM\ControlSetXXX\Services

where XXX is the value saved in the following registry key value: HKEY_LOCAL_MACHINE\System\Select\LastKnownGood.

If an auto-start service with a SERVICE_ERROR_CRITICAL error control level fails to start, the SCM reboots the machine using the LKG configuration. If the LKG configuration is already being used, the boot fails.


Starting Services on Demand

The user can start a service with the Services control panel applet. A service control program can start a service with the StartService function. When the service is started, the SCM performs the following steps:

  • Retrieve the account information stored in the database.
  • Log on the service account.
  • Create the service in the suspended state.
  • Assign the logon token to the process.
  • Allow the process to execute.


Service Record List

As each service entry is read from the database of installed services, the SCM creates a service record for the service. A service record includes:

  • Service name
  • Start type (auto-start or demand-start)
  • Service status (see the SERVICE_STATUS structure)
    • Type
    • Current state
    • Acceptable control codes
    • Exit code
    • Wait hint
  • Pointer to dependency list

The user name and password of an account are specified at the time the service is installed. The SCM stores the user name in the registry and the password in a secure portion of the Local Security Authority (LSA). The system administrator can create accounts with passwords that never expire. Alternatively, the system administrator can create accounts with passwords that expire and manage the accounts by changing the passwords periodically.

The SCM updates the service status when a service sends it status notifications using the SetServiceStatus function. The SCM maintains the status of a driver service by querying the I/O system, instead of receiving status notifications, as it does from a service.

A service can register additional type information by calling the SetServiceBits function. The NetServerGetInfo and NetServerEnum functions obtain the supported service types.


SCM Handles

The SCM supports handle types to allow access to the following objects.

  • The database of installed services.
  • A service.
  • The database lock.

An SCManager object represents the database of installed services. It is a container object that holds service objects. The OpenSCManager function returns a handle to an SCManager object on a specified computer. This handle is used when installing, deleting, opening, and enumerating services and when locking the services database.

A service object represents an installed service. The CreateService and OpenService functions return handles to installed services.

The OpenSCManager, CreateService, and OpenService functions can request different types of access to SCManager and service objects. The requested access is granted or denied depending on the access token of the calling process and the security descriptor associated with the SCManager or service object.

The CloseServiceHandle function closes handles to SCManager and service objects. When you no longer need these handles, be sure to close them.

A lock object is created during SCM initialization to serialize access to the database of installed services. The SCM acquires the lock before starting a service or driver service. Service configuration programs use the LockServiceDatabase function to acquire the lock before reconfiguring a service and use the UnlockServiceDatabase function to release the lock.


Service Programs

A service program contains executable code for one or more services. A service created with the type SERVICE_WIN32_OWN_PROCESS only contains the code for one service. The service can be configured to execute in the context of a user account from either the built-in (local), primary, or trusted domain. A service created with the type SERVICE_WIN32_SHARE_PROCESS contains code for more than one service. The services must all execute in the context of the LocalSystem account. For more information, see CreateService.

The following sections describe the interface requirements of the SCM that a service program must include. These sections do not apply to driver services.

  • The main Function
  • The ServiceMain Function
  • The Control Handler Function


The main Function

Service programs are generally written as console applications. The entry point of a console application is the main function. The main function receives arguments from the ImagePath value from the registry key for the service.

When the SCM starts a service program, it waits for it to call the StartServiceCtrlDispatcher function. Use the following guidelines.

  • A service of type SERVICE_WIN32_OWN_PROCESS should call StartServiceCtrlDispatcher immediately, from its main thread. You can perform any initialization after the service starts, as described in The ServiceMain Function.
  • If the service type is SERVICE_WIN32_SHARE_PROCESS and there is common initialization for all services in the program, you can perform the initialization in the main thread before calling StartServiceCtrlDispatcher, as long as it takes less than 30 seconds. Otherwise, you must create another thread to do the common initialization, while the main thread calls StartServiceCtrlDispatcher. You should still perform any service-specific initialization as described in The ServiceMain Function.

The StartServiceCtrlDispatcher function takes a SERVICE_TABLE_ENTRY structure for each service contained in the process. Each structure specifies the service name and the entry point for the service.

If StartServiceCtrlDispatcher succeeds, the calling thread does not return until all running services in the process have terminated. The SCM sends control requests to this thread through a named pipe. The thread acts as a control dispatcher, performing the following tasks:

  • Create a new thread to call the appropriate entry point when a new service is started.
  • Call the appropriate Handler function to handle service control requests.

For more information, see Writing a Service Program's main Function.


The ServiceMain Function

The ServiceMain function is the entry point for a service.

When a service control program requests that a new service run, the SCM starts the service and sends a start request to the control dispatcher. The control dispatcher creates a new thread to execute the ServiceMain function for the service.

The ServiceMain function should perform the following tasks:

  1. Call the RegisterServiceCtrlHandler function immediately to register a Handler function to handle control requests for the service. The return value of RegisterServiceCtrlHandler is a service status handle that will be used in calls to notify the SCM of the service status.
  2. Perform initialization. If the execution time of the initialization code is expected to be very short (less than one second), initialization can be performed directly in ServiceMain.

    If the initialization time is expected to be longer than one second, call the SetServiceStatus function, specifying the SERVICE_START_PENDING service state in the SERVICE_STATUS structure. As initialization continues, the service should make additional calls to SetServiceStatus to report progress. Sending multiple SetServiceStatus calls is useful for debugging services.

  3. When initialization is complete, call SetServiceStatus, specifying the SERVICE_RUNNING state in the SERVICE_STATUS structure.
  4. Perform the service tasks, or, if there are no pending tasks, return. Any change in the state of the service warrants a call to SetServiceStatus to report new status information.
  5. If an error occurs while the service is initializing or running, the service should call SetServiceStatus, specifying the SERVICE_STOP_PENDING state in the SERVICE_STATUS structure, if cleanup will be lengthy. Once cleanup is complete, call SetServiceStatus from the last thread to terminate, specifying SERVICE_STOPPED in the SERVICE_STATUS structure. Be sure to set the dwServiceSpecificExitCode and dwWin32ExitCode members of the SERVICE_STATUS structure to identify the error.

For more information, see Writing a ServiceMain Function.


The Control Handler Function

Each service has a control handler, the Handler function, that is invoked by the control dispatcher when the service process receives a control request from a service control program. Therefore, this function executes in the context of the control dispatcher.

Whenever the Handler function is invoked, the service must call the SetServiceStatus function to report its status to the SCM. This must be done regardless of whether the status changed.

The service control program send control requests using the ControlService function. All services must accept and process the SERVICE_CONTROL_INTERROGATE control code. You can enable or disable acceptance of the other standard control codes by calling SetServiceStatus. Services can also handle additional user-defined control codes.

The control handler must return within 30 seconds, or the SCM will return an error. If a service needs to do lengthy processing when the service is executing the control handler, it should create a secondary thread to perform the lengthy processing, then return. This prevents the service from tying up the control dispatcher. For example, when handling the stop request for a service that will take a long time, create another thread to handle the stop process. The control handler should simply call SetServiceStatus with the SERVICE_STOP_PENDING message and return.

When the user shuts down the system, all control handlers receive the SERVICE_CONTROL_SHUTDOWN control code. They are notified in the order that they appear in the database of installed services. By default, a service has approximately 20 seconds to perform cleanup tasks before the system shuts down. However, if the system is left in the shutdown state (not restarted or powered down) the service continues to run. You can change the time the system will wait for service shutdown by modifying the WaitToKillServiceTimeout value in the following registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control

For more information, see Writing a Control Handler Function.


Service Configuration Programs

Programmers and system administrators use service configuration programs to modify or query the database of installed services. The database can also be accessed by using the registry functions. However, you should only use the SCM configuration functions, which ensure that the service is properly installed and configured.

The SCM configuration functions require either a handle to an SCManager object or a handle to a service object. To obtain these handles, the service configuration program must:

  1. Use the OpenSCManager function to obtain a handle to the SCM database on a specified machine. For more information, see Opening an SCManager Database.
  2. Use the OpenService or CreateService function to obtain a handle to the service object.


Service Installation, Removal, and Enumeration

A configuration program uses the CreateService function to install a new service in the SCM database. This function specifies the name of the service and provides configuration information that is stored in the database. For a description of the information stored in the database for each service, see Database of Installed Services. For sample code, see Installing a Service.

A configuration program uses the DeleteService function to remove an installed service from the database. For more information, see Deleting a Service.

To obtain the service name, call the GetServiceKeyName function. The service display name, used in the Services control panel applet, can be obtained by calling the GetServiceDisplayName function.

A service configuration program can use the EnumServicesStatus function to enumerate all services and their statuses. It can also use the EnumDependentServices function to enumerate which services are dependent on a specified service object.


Service Configuration

To modify the configuration information for a service object, a configuration program uses the ChangeServiceConfig or ChangeServiceConfig2 function. For an example, see Changing a Service Configuration.

To retrieve the configuration information for a service object, the configuration program uses the QueryServiceConfig or QueryServiceConfig2 function. For an example, see Querying a Service's Configuration.

To modify the security descriptor for either an SCManager object or a service object, a configuration program uses the SetServiceObjectSecurity function. To retrieve a copy of the security descriptor, the configuration program uses the QueryServiceObjectSecurity function.

Before you reconfigure a service object, you should use the LockServiceDatabase function. This function tries to acquire a lock on the database and, if successful, prevents the SCM from starting a service while the database is being reconfigured. Failure to acquire a lock does not prevent a configuration program from successfully reconfiguring a service object. To release the lock on the database when the reconfiguration is complete, use the UnlockServiceDatabase function. To determine whether the database is locked, use the QueryServiceLockStatus function.


Configuring a Service Using SC

The Platform SDK contains a command-line utility, SC.EXE, that can be used to query or modify the database of installed services. Its commands correspond to the functions provided by the SCM. The syntax is:

sc ServerName [command] ServiceName

ServerName
Optional server name. Use the form \\ServerName.
Command
query
config
qc
delete
create
GetDisplayName
GetKeyName
EnumDepend
ServiceName
The name of the service, as specified when it was installed.


Service Control Programs

A service control program performs the following actions:

  • Starts a service or driver service, if the start type is SERVICE_DEMAND_START.
  • Sends control requests to a running service.
  • Queries the current status of a running service.

These actions require an open handle to the service object. To obtain the handle, the service control program must:

  1. Use the OpenSCManager function to obtain a handle to the SCM database on a specified machine.
  2. Use the OpenService or CreateService function to obtain a handle to the service object.


Service Startup

To start a service or driver service, the service control program uses the StartService function. The StartService function fails if the database is locked. If this occurs, the service control program should wait a few seconds and call StartService again. It can check the current lock status of the database by calling the QueryServiceLockStatus function.

If the service control program is starting a service, it can use the StartService function to specify an array of arguments to be passed to the service's ServiceMain function. The StartService function returns after a new thread has been created to execute the ServiceMain function. The service control program can retrieve the status of the newly started service in a SERVICE_STATUS structure by calling the QueryServiceStatus function. During initialization, the dwCurrentState member should be SERVICE_START_PENDING. The dwWaitHint member is a time interval, in milliseconds, that indicates how long the service control program should wait before calling QueryServiceStatus again. When the initialization is complete, the service changes dwCurrentState to SERVICE_RUNNING.

If the program is starting a driver service, StartService returns after the device driver has completed its initialization.

For more information, see Starting a Service.


Service Control Requests

To send control requests to a running service, a service control program uses the ControlService function. This function specifies a control value that is passed to the Handler function of the specified service. This control value can be a user-defined code, or it can be one of the standard codes that enable the calling program to perform the following actions:

  • Stop a service (SERVICE_CONTROL_STOP).
  • Pause a service (SERVICE_CONTROL_PAUSE).
  • Resume executing a paused service (SERVICE_CONTROL_CONTINUE).
  • Retrieve updated status information from a service (SERVICE_CONTROL_INTERROGATE).

For more information, see Sending Control Requests to a Service.

Each service specifies the control values that it will accept and process. To determine which of the standard control values are accepted by a service, use the QueryServiceStatus function or specify the SERVICE_CONTROL_INTERROGATE control value in a call to the ControlService function. The dwControlsAccepted member of the SERVICE_STATUS structure returned by these functions indicates whether the service can be stopped, paused, or resumed. All services accept the SERVICE_CONTROL_INTERROGATE control value.

Note The QueryServiceStatus function reports the most recent status for a specified service, but does not get an updated status from the service itself. Using the SERVICE_CONTROL_INTERROGATE control value in a call to ControlService ensures that the status information returned is current.


Controlling a Service Using SC

The Platform SDK contains a command-line utility, SC.EXE, that can be used to control a service. Its commands correspond to the functions provided by the SCM. The syntax is:

sc ServerName [command] ServiceName

ServerName
Optional server name. Use the form \\ServerName.
Command
start
pause
interrogate
continue
stop
control
ServiceName
The name of the service, as specified when it was installed.


Service Security

When a process uses the OpenSCManager function to open a handle to a database of installed services, it can request different types of access. The system performs a security check before granting the requested access. All processes are permitted the following access to the database:

  • SC_MANAGER_CONNECT
  • SC_MANAGER_ENUMERATE_SERVICE
  • SC_MANAGER_QUERY_LOCK_STATUS

This enables any process to open a handle to the SCManager object that it can use in calls to the OpenService, EnumServicesStatus, and QueryServiceLockStatus functions. Only processes with Administrator privileges are able to open handles to the SCManager object that can be used by the CreateService and LockServiceDatabase functions.

When a process uses the OpenService function, the system performs an access check. The type of access permitted to different users depends on the SECURITY_DESCRIPTOR structure associated with the service object. The SCM creates a service object's security descriptor when the service is installed by the CreateService function. You can use the QueryServiceObjectSecurity and SetServiceObjectSecurity functions to query and set the security descriptor of a service object. The default security descriptor of a service object permits the following access:

  • All users have SERVICE_QUERY_CONFIG, SERVICE_QUERY_STATUS, SERVICE_ENUMERATE_DEPENDENTS, SERVICE_INTERROGATE, and SERVICE_USER_DEFINED_CONTROL access.
  • Members of the Power Users group and the LocalSystem account have SERVICE_START, SERVICE_PAUSE_CONTINUE, and SERVICE_STOP access, plus the access rights granted to all users.
  • Members of the Administrators and System Operators groups have SERVICE_ALL_ACCESS access.


Service User Accounts

Each service executes in the security context of a user account. The user name and password of an account are specified by the CreateService function at the time the service is installed. The user name and password can be changed by using the ChangeServiceConfig function. You can use the QueryServiceConfig function to get the user name (but not the password) associated with a service object.

When starting a service, the SCM logs on to the account associated with the service. If the log on is successful, the system produces an access token and attaches it to the new service process. This token identifies the service process in all subsequent interactions with securable objects (objects that have a security descriptor associated with them). For example, if the service tries to open a handle to a pipe, the system compares the service's access token to the pipe's security descriptor before granting access.

The SCM does not maintain the passwords of service user accounts. If a password is expired, the logon fails and the service fails to start. The system administrator who assigns accounts to services can create accounts with passwords that never expire. The administrator can also manage accounts with passwords that expire by using a service configuration program to periodically change the passwords.

If a service needs to recognize another service before sharing its information, the second service can either use the same account as the first service, or it can run in an account belonging to an alias that is recognized by the first service. Services that need to run in a distributed manner across the network should run in domain-wide accounts.


The LocalSystem Account

The LocalSystem account is a predefined local account used by system processes. The name of the account is .\System. This account does not have a password. If you specify the LocalSystem account in a call to the CreateService function, any password information you supply is ignored.

A service that runs in the context of the LocalSystem account inherits the security context of the SCM. It is not associated with any logged-on user account and does not have credentials (domain name, user name, and password) to be used for verification. This has several implications:

  • The service cannot open the registry key HKEY_CURRENT_USER.
  • The service can open the registry key HKEY_LOCAL_MACHINE\SECURITY.
  • The service has limited access to network resources, such as shares and pipes, because it has no credentials and must connect using a null session. The following registry key contains the NullSessionPipes and NullSessionShares values, which are used to specify the pipes and shares to which null sessions may connect:
    • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
      LanmanServer\Parameters
  • Alternatively, you could add the REG_DWORD value RestrictNullSessAccess to the key and set it to 0 to allow all null sessions to access all pipes and shares created on that machine.
  • The service cannot share objects (pipes, file mapping, synchronization, and so on) with other applications, unless it creates them using either a DACL which allows a user or group of users access to the object or a NULL DACL, which allows everyone access to the object. Note that specifying a NULL DACL is not the same as specifying NULL. If you specify NULL in the lpSecurityDescriptor member of the SECURITY_ATTRIBUTES structure, access to the object is granted only to processes with the same security context as the process that created the object. For information on specifying a NULL DACL in the security descriptor field, see Allowing Access Using the Low-Level Functions.
  • If the service opens a command window and runs a batch file, the user could hit CTRL+C to terminate the batch file and gain access to a command window with LocalSystem permissions.


Interactive Services

An interactive service is a service that can interact with the input desktop. Other desktops do not receive user input. For more information, see Window Stations and Desktops.

An interactive service must run in the context of the LocalSystem account and be configured to run interactively. Services are configured to run interactively when the dwServiceType parameter in a CreateService call is set to include the SERVICE_INTERACTIVE_PROCESS flag. However, the following registry key contains a value, NoInteractiveServices, that controls the effect of the SERVICE_INTERACTIVE_PROCESS flag:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows

The NoInteractiveServices value defaults to 0, which means that services marked with the SERVICE_INTERACTIVE_PROCESS flag will be allowed to run interactively. When the NoInteractiveServices value is set to a nonzero value, no service started thereafter, regardless of whether it has been configured with SERVICE_INTERACTIVE_PROCESS, will be allowed to run interactively.

Note It is possible to display a message box from a service, even if it is not running in the LocalSystem account or not configured to run interactively. Simply call the MessageBox function using the MB_SERVICE_NOTIFICATION flag. Do not call MessageBox during service initialization or from the Handler routine, unless you call it from a separate thread, so that you return to the SCM in a timely manner.

It is also possible to interact with the desktop from a non-interactive service by modifying the DACLs on the interface window station and desktop or by impersonating the logged-on user and opening the interactive window station and desktop directly. For more information, see Interacting with the User by a Win32 Service.


Debugging a Service

You can use the following methods to debug your service.

  • Use your debugger to debug the service while it is running. First, obtain the process identifier (PID) of the service process. This information is available from the PView application. After you have obtained the PID, attach to the running process. For syntax information, see the documentation included with your debugger.
  • Call the DebugBreak function to invoke the debugger for just-in-time debugging.
  • Specify a debugger to use when starting a program. To do so, create a key called Image File Execution Options in the following registry location:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion

    Create a subkey with the same name as your service (for example, MYSERV.EXE). To this subkey, add a value of type REG_SZ, named Debugger. Use the full path to the debugger as the string value. In the Services control panel applet, select your service, click Startup and check Allow Service to Interact with Desktop.

Note To debug the initialization code of an auto-start service, you will have to temporarily install and run the service as a demand-start service.


Using Services

  • Writing a service program's main function
  • Writing a ServiceMain function
  • Writing a control handler function
  • Opening an SCManager database
  • Installing a service
  • Deleting a service
  • Changing a service configuration
  • Querying a service's configuration
  • Starting a service
  • Sending control requests to a service


Writing a Service Program's main Function

The main function of a service program calls the StartServiceCtrlDispatcher function to connect to the SCM and start the control dispatcher thread. The dispatcher thread loops, waiting for incoming control requests for the services specified in the dispatch table. This thread does not return until there is an error or all of the services in the process have terminated. When all services in a process have terminated, the SCM sends a control request to the dispatcher thread telling it to shut down. The thread can then return from the StartServiceCtrlDispatcher call and the process can terminate.

The following example is a service process that supports only one service. It takes two parameters: a string that can contain one formatted output character and a numeric value to be used as the formatted character. The SvcDebugOut function prints informational messages and errors to the debugger.

SERVICE_STATUS          MyServiceStatus;
SERVICE_STATUS_HANDLE   MyServiceStatusHandle;

VOID  MyServiceStart (DWORD argc, LPTSTR *argv);
VOID  MyServiceCtrlHandler (DWORD opcode);
DWORD MyServiceInitialization (DWORD argc, LPTSTR *argv,
        DWORD *specificError);

VOID _CRTAPI1 main( )
{
    SERVICE_TABLE_ENTRY   DispatchTable[] =
    {
        { TEXT("MyService"), MyServiceStart      },
        { NULL,              NULL                }
    };

    if (!StartServiceCtrlDispatcher( DispatchTable))
    {
        SvcDebugOut(" [MY_SERVICE] StartServiceCtrlDispatcher error =
            %d\n", GetLastError());
    }
}

VOID SvcDebugOut(LPSTR String, DWORD Status)
{
    CHAR  Buffer[1024];
    if (strlen(String) < 1000)
    {
        sprintf(Buffer, String, Status);
        OutputDebugStringA(Buffer);
    }
}

If your service program supports multiple services, the implementation of the main function will differ slightly. The names of the additional services should be added to the dispatch table so they can be monitored by the dispatcher thread.


Writing a ServiceMain Function

The MyServiceStart function in the following example is the entry point for the service. MyServiceStart has access to the command-line arguments, in the way that the main function of a console application does. The first parameter contains the number of arguments being passed to the service. There will always be at least one argument. The second parameter is a pointer to an array of string pointers. The first item in the array always points to the service name.

The MyServiceStart function first fills in the SERVICE_STATUS structure including the control codes that it accepts. Although this service accepts SERVICE_CONTROL_PAUSE and SERVICE_CONTROL_CONTINUE, it does nothing significant when told to pause. The flags SERVICE_ACCEPT_PAUSE_CONTINUE was included for illustration purposes only; if pausing does not add value to your service, do not support it.

The MyServiceStart function then calls the RegisterServiceCtrlHandler function to register MyService as the service's Handler function and begin initialization. The following sample initialization function, MyServiceInitialization, is included for illustration purposes; it does not perform any initialization tasks such as creating additional threads. If your service's initialization performs tasks that are expected to take longer than one second, your code must call the SetServiceStatus function periodically to send out wait hints and check points indicating that progress is being made.

When initialization has completed successfully, the example calls SetServiceStatus with a status of SERVICE_RUNNING and the service continues with its work. If an error has occurred in initialization, MyServiceStart reports SERVICE_STOPPED with the SetServiceStatus function and returns.

Because this sample service does not complete any real tasks, MyServiceStart simply returns control to the caller. However, your service should use this thread to complete whatever tasks it was designed to do. If a service does not need a thread to do its work (such as a service that only processes RPC requests), its ServiceMain function should return control to the caller. It is important for the function to return, rather than call the ExitThread function, because returning allows for cleanup of the memory allocated for the arguments.

To output debugging information, MyServiceStart calls SvcDebugOut. The source code for SvcDebugOut is given in Writing a Service Program's main Function.

void MyServiceStart (DWORD argc, LPTSTR *argv)
{
    DWORD status;
    DWORD specificError;

    MyServiceStatus.dwServiceType        = SERVICE_WIN32;
    MyServiceStatus.dwCurrentState       = SERVICE_START_PENDING;
    MyServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP |
        SERVICE_ACCEPT_PAUSE_CONTINUE;
    MyServiceStatus.dwWin32ExitCode      = 0;
    MyServiceStatus.dwServiceSpecificExitCode = 0;
    MyServiceStatus.dwCheckPoint         = 0;
    MyServiceStatus.dwWaitHint           = 0;

    MyServiceStatusHandle = RegisterServiceCtrlHandler(
        TEXT("MyService"),
        MyServiceCtrlHandler);

    if (MyServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
    {
        SvcDebugOut(" [MY_SERVICE] RegisterServiceCtrlHandler
            failed %d\n", GetLastError());
        return;
    }

    // Initialization code goes here.
    status = MyServiceInitialization(argc,argv, &specificError);

    // Handle error condition
    if (status != NO_ERROR)
    {
        MyServiceStatus.dwCurrentState       = SERVICE_STOPPED;
        MyServiceStatus.dwCheckPoint         = 0;
        MyServiceStatus.dwWaitHint           = 0;
        MyServiceStatus.dwWin32ExitCode      = status;
        MyServiceStatus.dwServiceSpecificExitCode = specificError;

        SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus);
        return;
    }

    // Initialization complete - report running status.
    MyServiceStatus.dwCurrentState       = SERVICE_RUNNING;
    MyServiceStatus.dwCheckPoint         = 0;
    MyServiceStatus.dwWaitHint           = 0;

    if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus))
    {
        status = GetLastError();
        SvcDebugOut(" [MY_SERVICE] SetServiceStatus error
            %ld\n",status);
    }

    // This is where the service does its work.
    SvcDebugOut(" [MY_SERVICE] Returning the Main Thread \n",0);

    return;
}

// Stub initialization function.
DWORD MyServiceInitialization(DWORD   argc, LPTSTR  *argv,
    DWORD *specificError)
{
    argv;
    argc;
    specificError;
    return(0);
}


Writing a Control Handler Function

The MyServiceCtrlHandler function in the following example is the Handler function. When this function is called by the dispatcher thread, it handles the control code passed in the Opcode parameter and then calls the SetServiceStatus function to update the service's status. Every time a Handler function receives a control code, it is appropriate to return status with a call to SetServiceStatus regardless of whether the service acts on the control.

When the pause control is received, MyServiceCtrlHandler simply sets the dwCurrentState field in the SERVICE_STATUS structure to SERVICE_PAUSED. Likewise, when the continue control is received, the state is set to SERVICE_RUNNING. Therefore, MyServiceCtrlHandler is not a good example of how to handle the pause and continue controls. Because MyServiceCtrlHandler is a template for a Handler function, code for the pause and continue controls is included for completeness. A service that supports either the pause or continue control should handle these controls in a way that makes sense. Many services support neither the pause or continue control. If the service indicates that it does not support pause or continue with the dwControlsAccepted parameter, then the SCM will not send pause or continue controls to the service's Handler function.

To output debugging information, MyServiceCtrlHandler calls SvcDebugOut. The source code for SvcDebugOut is listed in Writing a Service Program's main Function.

VOID MyServiceCtrlHandler (DWORD Opcode)
{
    DWORD status;

    switch(Opcode)
    {
        case SERVICE_CONTROL_PAUSE:
        // Do whatever it takes to pause here.
            MyServiceStatus.dwCurrentState = SERVICE_PAUSED;
            break;

        case SERVICE_CONTROL_CONTINUE:
        // Do whatever it takes to continue here.
            MyServiceStatus.dwCurrentState = SERVICE_RUNNING;
            break;

        case SERVICE_CONTROL_STOP:
        // Do whatever it takes to stop here.
            MyServiceStatus.dwWin32ExitCode = 0;
            MyServiceStatus.dwCurrentState  = SERVICE_STOPPED_PENDING;
            MyServiceStatus.dwCheckPoint    = 0;
            MyServiceStatus.dwWaitHint      = 0;

            if (!SetServiceStatus (MyServiceStatusHandle,
                &MyServiceStatus))
            {
                status = GetLastError();
                SvcDebugOut(" [MY_SERVICE] SetServiceStatus error
                    %ld\n",status);
            }

            SvcDebugOut(" [MY_SERVICE] Leaving MyService \n",0);
            return;

        case SERVICE_CONTROL_INTERROGATE:
        // Fall through to send current status.
            break;

        default:
            SvcDebugOut(" [MY_SERVICE] Unrecognized opcode %ld\n",
                Opcode);
    }

    // Send current status.
    if (!SetServiceStatus (MyServiceStatusHandle,  &MyServiceStatus))
    {
        status = GetLastError();
        SvcDebugOut(" [MY_SERVICE] SetServiceStatus error
            %ld\n",status);
    }
    return;
}


Opening an SCManager Database

Many operations require an open handle to an SCManager object. The following example demonstrates how to obtain the handle.

Different operations on the SCM database require different levels of access, and you should only request the minimum access required. If SC_MANAGER_ALL_ACCESS is requested, the OpenSCManager function fails if the calling process does not have administrator privileges. The following example shows how to request full access to the ServicesActive database on the local machine.

// Open a handle to the SC Manager database.

schSCManager = OpenSCManager(
    NULL,                    // local machine
    NULL,                    // ServicesActive database
    SC_MANAGER_ALL_ACCESS);  // full access rights

if (schSCManager == NULL)
    MyErrorExit("OpenSCManager");


Installing a Service

A service configuration program uses the CreateService function to install a service in a SCM database. The application-defined schSCManager handle must have SC_MANAGER_CREATE_SERVICE access to the SCManager object. The following example shows how to install a service.

VOID CreateSampleService()
{
    LPCTSTR lpszBinaryPathName =
        TEXT("%SystemRoot%\\system\\testserv.exe");

    schService = CreateService(
        schSCManager,              // SCManager database
        TEXT("Sample_Srv"),        // name of service
        lpszDisplayName,           // service name to display
        SERVICE_ALL_ACCESS,        // desired access
        SERVICE_WIN32_OWN_PROCESS, // service type
        SERVICE_DEMAND_START,      // start type
        SERVICE_ERROR_NORMAL,      // error control type
        lpszBinaryPathName,        // service's binary
        NULL,                      // no load ordering group
        NULL,                      // no tag identifier
        NULL,                      // no dependencies
        NULL,                      // LocalSystem account
        NULL);                     // no password

    if (schService == NULL)
        MyErrorExit("CreateService");
    else
        printf("CreateService SUCCESS\n");

    CloseServiceHandle(schService);
}


Deleting a Service

In the following example, a service configuration program uses the OpenService function to get a handle with DELETE access to an installed service object. The program then uses the service object handle in the DeleteService function to remove the service from the SCM database.

VOID DeleteSampleService()
{
    schService = OpenService(
        schSCManager,       // SCManager database
        TEXT("Sample_Srv"), // name of service
        DELETE);            // only need DELETE access

    if (schService == NULL)
        MyErrorExit("OpenService");

    if (! DeleteService(schService) )
        MyErrorExit("DeleteService");
    else
        printf("DeleteService SUCCESS\n");

    CloseServiceHandle(schService);
}


Changing a Service Configuration

In the following example, a service configuration program uses the ChangeServiceConfig function to change the configuration parameters of an installed service. The program first tries to lock the database, to prevent the SCM from starting a service while it is being reconfigured. If it successfully locks the database, the program opens a handle to the service object, modifies its configuration, unlocks the database, and then closes the service object handle. If the program does not successfully in lock the database, it uses the QueryServiceLockStatus function to retrieve information about the lock.

VOID ReconfigureSampleService(BOOL fDisable)
{
    SC_LOCK sclLock;
    LPQUERY_SERVICE_LOCK_STATUS lpqslsBuf;
    DWORD dwBytesNeeded, dwStartType;

    // Need to acquire database lock before reconfiguring.

    sclLock = LockServiceDatabase(schSCManager);

    // If the database cannot be locked, report the details.

    if (sclLock == NULL)
    {
        // Exit if the database is not locked by another process.

        if (GetLastError() != ERROR_SERVICE_DATABASE_LOCKED)
            MyErrorExit("LockServiceDatabase");

        // Allocate a buffer to get details about the lock.

        lpqslsBuf = (LPQUERY_SERVICE_LOCK_STATUS) LocalAlloc(
            LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS)+256);
        if (lpqslsBuf == NULL)
            MyErrorExit("LocalAlloc");

        // Get and print the lock status information.

        if (!QueryServiceLockStatus(
            schSCManager,
            lpqslsBuf,
            sizeof(QUERY_SERVICE_LOCK_STATUS)+256,
            &dwBytesNeeded) )
            MyErrorExit("QueryServiceLockStatus");

        if (lpqslsBuf->fIsLocked)
            printf("Locked by: %s, duration: %d seconds\n",
                lpqslsBuf->lpLockOwner,
                lpqslsBuf->dwLockDuration);
        else
            printf("No longer locked\n");

        LocalFree(lpqslsBuf);
        MyErrorExit("Could not lock database");
    }

    // The database is locked, so it is safe to make changes.

    // Open a handle to the service.

    schService = OpenService(
        schSCManager,           // SCManager database
        TEXT("Sample_Srv"),     // name of service
        SERVICE_CHANGE_CONFIG); // need CHANGE access
    if (schService == NULL)
        MyErrorExit("OpenService");

    dwStartType = (fDisable) ? SERVICE_DISABLED :
                            SERVICE_DEMAND_START;

    if (! ChangeServiceConfig(
        schService,        // handle of service
        SERVICE_NO_CHANGE, // service type: no change
        dwStartType,       // change service start type
        SERVICE_NO_CHANGE, // error control: no change
        NULL,              // binary path: no change
        NULL,              // load order group: no change
        NULL,              // tag ID: no change
        NULL,              // dependencies: no change
        NULL,              // account name: no change
        NULL) )            // password: no change
    {
        MyErrorExit("ChangeServiceConfig");
    }
    else
        printf("ChangeServiceConfig SUCCESS\n");

    // Release the database lock.

    UnlockServiceDatabase(sclLock);

    // Close the handle to the service.

    CloseServiceHandle(schService);
}


Querying a Service's Configuration

In the following example, a service configuration program uses the OpenService function to get a handle with SERVICE_QUERY_CONFIG access to an installed service object. Then the program uses the service object handle in the QueryServiceConfig function to retrieve the current configuration of the service.

VOID GetSampleServiceConfig()
{
    LPQUERY_SERVICE_CONFIG lpqscBuf;
    DWORD dwBytesNeeded;

    // Open a handle to the service.

    schService = OpenService(
        schSCManager,           // SCManager database
        TEXT("Sample_Srv"),     // name of service
        SERVICE_QUERY_CONFIG);  // need QUERY access
    if (schService == NULL)
        MyErrorExit("OpenService");

    // Allocate a buffer for the information configuration.

    lpqscBuf = (LPQUERY_SERVICE_CONFIG) LocalAlloc(
        LPTR, 4096);
    if (lpqscBuf == NULL)
        MyErrorExit("LocalAlloc");

    // Get and print the information configuration.

    if (! QueryServiceConfig(
        schService,
        lpqscBuf,
        4096,
        &dwBytesNeeded) )
    {
        MyErrorExit("QueryServiceConfig");
    }

    printf("\nSample_Srv configuration: \n");
    printf("  Type: 0x%x\n", lpqscBuf->dwServiceType);
    printf("  Start Type: 0x%x\n", lpqscBuf->dwStartType);
    printf("  Err Control: 0x%x\n", lpqscBuf->dwErrorControl);
    printf("  Binary path: %s\n", lpqscBuf->lpBinaryPathName);

    if (lpqscBuf->lpLoadOrderGroup != NULL)
        printf("  Load order group: %s\n",
            lpqscBuf->lpLoadOrderGroup);
    if (lpqscBuf->dwTagId != 0)
        printf("  Tag ID: %d\n", lpqscBuf->dwTagId);
    if (lpqscBuf->lpDependencies != NULL)
        printf("  Dependencies: %s\n", lpqscBuf->lpDependencies);
    if (lpqscBuf->lpServiceStartName != NULL)
        printf("  Start Name: %s\n",
            lpqscBuf->lpServiceStartName);

    LocalFree(lpqscBuf);
}


Starting a Service

To start a service, the following example opens a handle to an installed database and then specifies the handle in a call to the StartService function. It can be used to start either a service or a driver service, but this example assumes that a service is being started. After starting the service, the program uses the members of the SERVICE_STATUS structure returned by the QueryServiceStatus function to track the progress of the service.

VOID StartSampleService()
{
    SERVICE_STATUS ssStatus;
    DWORD dwOldCheckPoint;

    schService = OpenService(
        schSCManager,          // SCM database
        TEXT("Sample_Srv"),    // service name
        SERVICE_ALL_ACCESS);

    if (schService == NULL)
        MyErrorExit("OpenService");

    if (!StartService(
            schService,  // handle to service
            0,           // number of arguments
            NULL) )      // no arguments
    {
        MyErrorExit("StartService");
    }
    else
        printf("Service start pending\n");

    // Check the status until the service is no longer start pending.

    if (!QueryServiceStatus(
            schService,   // handle to service
            &ssStatus) )  // address of status information
            MyErrorExit("QueryServiceStatus");

    while (ssStatus.dwCurrentState == SERVICE_START_PENDING)
    {
        // Save the current checkpoint.

        dwOldCheckPoint = ssStatus.dwCheckPoint;

        // Wait for the specified interval.

        Sleep(ssStatus.dwWaitHint);

        // Check the status again.

        if (!QueryServiceStatus(
                schService,   // handle to service
                &ssStatus) )  // address of status information
            break;

        // Break if the checkpoint has not been incremented.

        if (dwOldCheckPoint >= ssStatus.dwCheckPoint)
            break;
    }

    if (ssStatus.dwCurrentState == SERVICE_RUNNING)
        printf("StartService SUCCESS\n");
    else
    {
        printf("  Current State: %d\n",
            ssStatus.dwCurrentState);
        printf("  Exit Code: %d\n", ssStatus.dwWin32ExitCode);
        printf("  Service Specific Exit Code: %d\n",
            ssStatus.dwServiceSpecificExitCode);
        printf("  Check Point: %d\n", ssStatus.dwCheckPoint);
        printf("  Wait Hint: %d\n", ssStatus.dwWaitHint);
    }

    CloseServiceHandle(schService);
}


Sending Control Requests to a Service

The following example uses the ControlService function to send a control value to a running service. Different control values require different levels of access to the service object. For example, a service object handle must have SERVICE_STOP access to send the SERVICE_CONTROL_STOP code. When ControlService returns, a SERVICE_STATUS structure contains the latest status information for the service.

VOID ControlSampleService(DWORD fdwControl)
{
    SERVICE_STATUS ssStatus;
    DWORD fdwAccess;

    // The required service object access depends on the control.

    switch (fdwControl)
    {
        case SERVICE_CONTROL_STOP:
            fdwAccess = SERVICE_STOP;
            break;

        case SERVICE_CONTROL_PAUSE:
        case SERVICE_CONTROL_CONTINUE:
            fdwAccess = SERVICE_PAUSE_CONTINUE;
            break;

        case SERVICE_CONTROL_INTERROGATE:
            fdwAccess = SERVICE_INTERROGATE;
            break;

        default:
            fdwAccess = SERVICE_INTERROGATE;
    }

    // Open a handle to the service.

    schService = OpenService(
        schSCManager,        // SCManager database
        TEXT("Sample_Srv"),  // name of service
        fdwAccess);          // specify access
    if (schService == NULL)
        MyErrorExit("OpenService");

    // Send a control value to the service.

    if (! ControlService(
            schService,   // handle of service
            fdwControl,   // control value to send
            &ssStatus) )  // address of status info
    {
        MyErrorExit("ControlService");
    }

    // Print the service status.

    printf("  Service Type: 0x%x\n", ssStatus.dwServiceType);
    printf("  Current State: 0x%x\n", ssStatus.dwCurrentState);
    printf("  Controls Accepted: 0x%x\n",
        ssStatus.dwControlsAccepted);
    printf("  Exit Code: %d\n", ssStatus.dwWin32ExitCode);
    printf("  Service Specific Exit Code: %d\n",
        ssStatus.dwServiceSpecificExitCode);
    printf("  Check Point: %d\n", ssStatus.dwCheckPoint);
    printf("  Wait Hint: %d\n", ssStatus.dwWaitHint);

    return;
}


Service Reference

The following elements are used with services.

  • Service Functions
  • Service Structures


Service Functions

The following functions are used by services and by programs that control or configure services.

ChangeServiceConfig
ChangeServiceConfig2
CloseServiceHandle
ControlService
CreateService
DeleteService
EnumDependentServices
EnumServicesStatus
GetServiceDisplayName
GetServiceKeyName
Handler
LockServiceDatabase
NotifyBootConfigStatus
OpenSCManager
OpenService
QueryServiceConfig
QueryServiceConfig2
QueryServiceLockStatus
QueryServiceObjectSecurity
QueryServiceStatus
RegisterServiceCtrlHandler
ServiceMain
SetServiceBits
SetServiceObjectSecurity
SetServiceStatus
StartService
StartServiceCtrlDispatcher
UnlockServiceDatabase


ChangeServiceConfig

The ChangeServiceConfig function changes the configuration parameters of a service.

BOOL ChangeServiceConfig(
  SC_HANDLE hService     // handle to service
  DWORD dwServiceType,   // type of service
  DWORD dwStartType,     // when to start service
  DWORD dwErrorControl,  // severity if service fails to start
  LPCTSTR lpBinaryPathName,  // pointer to service binary file name
  LPCTSTR lpLoadOrderGroup,  // pointer to load ordering group name
  LPDWORD lpdwTagId,     // pointer to variable to get tag identifier
  LPCTSTR lpDependencies,    // pointer to array of dependency names
  LPCTSTR lpServiceStartName,
                             // pointer to account name of service
  LPCTSTR lpPassword,   // pointer to password for service account
  LPCTSTR lpDisplayName      // pointer to display name
);

Parameters

hService
Handle to the service. This handle is returned by the OpenService or CreateService function and must have SERVICE_CHANGE_CONFIG access.
dwServiceType
A set of bit flags that specify the type of service. Specify SERVICE_NO_CHANGE if you are not changing the existing service type; otherwise, specify one of the following flags to indicate the service type.
Value | Meaning
SERVICE_WIN32_OWN_PROCESS | Specifies a Win32-based service that runs in its own process.
SERVICE_WIN32_SHARE_PROCESS | Specifies a Win32-based service that shares a process with other services.
SERVICE_KERNEL_DRIVER | Specifies a driver service.
SERVICE_FILE_SYSTEM_DRIVER | Specifies a file system driver service.

If you specify either SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS, you can also specify the following flag.

Value | Meaning
SERVICE_INTERACTIVE_PROCESS | Enables a Win32-based service process to interact with the desktop.

dwStartType
Specifies when to start the service. Specify SERVICE_NO_CHANGE if you are not changing the existing start type; otherwise, specify one of the following flags to indicate the start type.
Value | Meaning
SERVICE_BOOT_START | Specifies a device driver started by the system loader. This value is valid only for driver services.
SERVICE_SYSTEM_START | Specifies a device driver started by the IoInitSystem function. This value is valid only for driver services.
SERVICE_AUTO_START | Specifies a service to be started automatically by the service control manager during system startup.
SERVICE_DEMAND_START | Specifies a service to be started by the service control manager when a process calls the StartService function.
SERVICE_DISABLED | Specifies a service that can no longer be started.

dwErrorControl
Specifies the severity of the error if this service fails to start during startup, and determines the action taken by the startup program if failure occurs. Specify SERVICE_NO_CHANGE if you are not changing the existing error control; otherwise, specify one of the following flags to indicate the error control.
Value | Meaning
SERVICE_ERROR_IGNORE | The startup program logs the error but continues the startup operation.
SERVICE_ERROR_NORMAL | The startup program logs the error and puts up a message box pop-up but continues the startup operation.
SERVICE_ERROR_SEVERE | The startup program logs the error. If the last-known-good configuration is being started, the startup operation continues. Otherwise, the system is restarted with the last-known-good configuration.
SERVICE_ERROR_CRITICAL | The startup program logs the error, if possible. If the last-known-good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known good configuration.

lpBinaryPathName
Pointer to a null-terminated string that contains the fully qualified path to the service binary file. Specify NULL if you are not changing the existing path. If the path contains a space, it must be quoted so that it is correctly interpreted. For example, "d:\\my share\\myservice.exe" should be specified as "\"d:\\my share\\myservice.exe\"".
lpLoadOrderGroup
Pointer to a null-terminated string that names the load ordering group of which this service is a member. Specify NULL if you are not changing the existing group. Specify an empty string if the service does not belong to a group.
lpdwTagId
Pointer to a DWORD variable that receives a tag value that is unique in the group specified in the lpLoadOrderGroup parameter. Specify NULL if you are not changing the existing tag.

You can use a tag for ordering service startup within a load ordering group by specifying a tag order vector in the GroupOrderList value of the following registry key:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control

Tags are only evaluated for driver services that have SERVICE_BOOT_START or SERVICE_SYSTEM_START start types.

lpDependencies
Pointer to a double null-terminated array of null-separated names of services or load ordering groups that the system must start before this service can be started. (Dependency on a group means that this service can run if at least one member of the group is running after an attempt to start all members of the group.) Specify NULL if you are not changing the existing dependencies. Specify an empty string if the service has no dependencies.

You must prefix group names with SC_GROUP_IDENTIFIER so that they can be distinguished from a service name, because services and service groups share the same name space.

lpServiceStartName
Pointer to a null-terminated string that names the service. Specify NULL if you are not changing the existing name. If the service type is SERVICE_WIN32_OWN_PROCESS, use an account name in the form DomainName\UserName. The service process will be logged on as this user. If the account belongs to the built-in domain, you can specify .\UserName. If the service type is SERVICE_WIN32_SHARE_PROCESS you must specify the LocalSystem account.

If the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER, the name is the driver object name that the system uses to load the device driver. Specify NULL if the driver is to use a default object name created by the I/O system.

lpPassword
Pointer to a null-terminated string that contains the password to the account name specified by the lpServiceStartName parameter. Specify NULL if you are not changing the password. Specify an empty string if the service has no password.

Passwords are ignored for driver services.

lpDisplayName
Pointer to a null-terminated string that is to be used by applications to identify the service for its users. This string has a maximum length of 256 characters. The name is case-preserved in the service control manager. Display name comparisons are always case-insensitive.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED
 | The specified handle was not opened with SERVICE_CHANGE_CONFIG access.
ERROR_CIRCULAR_DEPENDENCY
 | A circular service dependency was specified.
ERROR_DUP_NAME
 | The display name already exists in the service controller manager database, either as a service name or as another display name.
ERROR_INVALID_HANDLE
 | The specified handle is invalid.
ERROR_INVALID_PARAMETER
 | A parameter that was specified is invalid.
ERROR_INVALID_SERVICE_ACCOUNT
 | The account name does not exist, or a service is specified to share the same binary file as an already installed service but with an account name that is not the same as the installed service.
ERROR_SERVICE_MARKED_FOR_DELETE
 | The service has been marked for deletion.

Remarks

The ChangeServiceConfig function changes the configuration information for the specified service in the service control manager database. You can obtain the current configuration information by using the QueryServiceConfig function.

If the configuration is changed for a service that is running, with the exception of lpDisplayName, the changes do not take effect until the service is stopped.

The startup program uses load ordering groups to load groups of services in a specified order with respect to the other groups in the list. The list of load ordering groups is contained in the ServiceGroupOrder value of the following registry key:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, CreateService, OpenService, QueryServiceConfig, StartService


ChangeServiceConfig2

[This is preliminary documentation and subject to change.]

The ChangeServiceConfig2 function changes the optional configuration parameters of a service.

BOOL ChangeServiceConfig2(
  SC_HANDLE hService,
  DWORD dwInfoLevel,
  LPVOID lpInfo
);

Parameters

hService
Handle to the service. This handle is returned by the OpenService or CreateService function and must have the SERVICE_CHANGE_CONFIG access right.

If one of the specified service controller actions is SC_ACTION_RESTART, hService must have the SERVICE_START access right.

dwInfoLevel
Specifies the configuration information to change. This parameter can be one of the following values.
Value | Meaning
SERVICE_CONFIG_DESCRIPTION | The lpInfo parameter is a pointer to a SERVICE_DESCRIPTION structure.
SERVICE_CONFIG_FAILURE_ACTIONS | The lpInfo parameter is a pointer to a SERVICE_FAILURE_ACTIONS structure.

lpInfo
Pointer to the new value to be set for the configuration information. The format of this data depends on the value of the dwInfoLevel parameter. If this value is NULL, the information remains unchanged.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ChangeServiceConfig2 function changes the optional configuration information for the specified service in the service control manager database. You can obtain the current optional configuration information by using the QueryServiceConfig2 function.

You cannot set the SERVICE_CONFIG_FAILURE_ACTIONS value for a service that shares the service control manager's process. This includes all services whose executable image is "services.exe".

You can change and query additional configuration information using the ChangeServiceConfig and QueryServiceConfig functions, respectively.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, ChangeServiceConfig, CreateService, OpenService, QueryServiceConfig, QueryServiceConfig2, SERVICE_DESCRIPTION, SERVICE_FAILURE_ACTIONS


CloseServiceHandle

The CloseServiceHandle function closes the following types of handles:

  • a handle to a service control manager object as returned by the OpenSCManager function
  • a handle to a service object as returned by either the OpenService or CreateService function
BOOL CloseServiceHandle(
  SC_HANDLE hSCObject   // handle to service or service control
                        // manager database
);

Parameters

hSCObject
Handle to the service control manager object or the service object to close.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error code can be set by the service control manager. Other error codes can be set by registry functions that are called by the service control manager.

Value | Meaning
ERROR_INVALID_HANDLE | The specified handle is invalid.

Remarks

The CloseServiceHandle function does not destroy the service control manager object referred to by the handle. A service control manager object cannot be destroyed. A service object can be destroyed by calling the DeleteService function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.

See Also

Services Overview, Service Functions, CreateService, DeleteService, OpenSCManager, OpenService


ControlService

The ControlService function sends a control code to a Win32-based service.

BOOL ControlService(
  SC_HANDLE hService,  // handle to service
  DWORD dwControl,     // control code
  LPSERVICE_STATUS lpServiceStatus
                       // pointer to service status structure
);

Parameters

hService
Handle to the service. This handle is returned by the OpenService or CreateService function. The access required for this handle depends on the dwControl code requested.
dwControl
Specifies the requested control code. This value can be one of the standard control codes in the following table:
Value | Meaning
SERVICE_CONTROL_STOP | Requests the service to stop. The hService handle must have SERVICE_STOP access.
SERVICE_CONTROL_PAUSE | Requests the service to pause. The hService handle must have SERVICE_PAUSE_CONTINUE access.
SERVICE_CONTROL_
CONTINUE 		Requests the paused service to resume. The hService handle must have SERVICE_PAUSE_CONTINUE access.
SERVICE_CONTROL_
INTERROGATE 		Requests the service to update immediately its current status information to the service control manager. The hService handle must have SERVICE_INTERROGATE access.
SERVICE_CONTROL_
SHUTDOWN 		The ControlService function fails if this control code is specified.

This value can also be a user-defined control code, as described in the following table:
Value | Meaning
Range 128 to 255. | The service defines the action associated with the control code. The hService handle must have SERVICE_USER_DEFINED_CONTROL access.

lpServiceStatus
Pointer to a SERVICE_STATUS structure to receive the latest service status information. The information returned reflects the most recent status that the service reported to the service control manager.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED
 | The specified handle was not opened with the necessary access.
ERROR_DEPENDENT_SERVICES_RUNNING
 | The service cannot be stopped because other running services are dependent on it.
ERROR_INVALID_SERVICE_CONTROL
 | The requested control code is not valid, or it is unacceptable to the service.
ERROR_SERVICE_CANNOT_ACCEPT_CTRL
 | The requested control code cannot be sent to the service because the state of the service is SERVICE_STOPPED, SERVICE_START_PENDING, or SERVICE_STOP_PENDING.
ERROR_SERVICE_NOT_ACTIVE
 | The service has not been started.
ERROR_SERVICE_REQUEST_TIMEOUT
 | The service did not respond to the start request in a timely fashion.

Remarks

The ControlService function asks the service control manager to send the requested control code to the service. The service control manager sends the code if the service accepts the control and if the service is in a state in which a control can be sent to it. You cannot stop and start a service unless the security descriptor allows you to. The default security descriptor allows LocalSystem, Administrators, and Power Users to stop and start services. To change the security descriptor of a service, use SetServiceObjectSecurity.

The QueryServiceStatus or function returns a SERVICE_STATUS structure whose dwCurrentState and dwControlsAccepted members indicate the current state and controls accepted by a running service. All running services accept the SERVICE_CONTROL_INTERROGATE control code by default. Each service specifies the other control codes that it accepts when it calls the SetServiceStatus function to report its status. A service should always accept these codes when it is running, no matter what it is doing.

The following table shows the action of the service control manager in each of the possible service states:

Service state | Stop | Other controls
STOPPED | (c) | (c)
STOP_PENDING | (b) | (b)
START_PENDING | (a) | (b)
RUNNING | (a) | (a)
CONTINUE_PENDING | (a) | (a)
PAUSE_PENDING | (a) | (a)
PAUSED | (a) | (a)

(a) | If the service accepts this control code, send the request to the service; otherwise, ControlService returns zero and GetLastError returns ERROR_INVALID_SERVICE_CONTROL.
(b) | The service is not in a state in which a control can be sent to it, so ControlService returns zero and GetLastError returns ERROR_SERVICE_CANNOT_ACCEPT_CTRL.
(c) | The service is not active, so ControlService returns zero and GetLastError returns ERROR_SERVICE_NOT_ACTIVE.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.

See Also

Services Overview, Service Functions, CreateService, OpenService, QueryServiceStatus, SetServiceObjectSecurity, SetServiceStatus, SERVICE_STATUS


CreateService

The CreateService function creates a service object and adds it to the specified service control manager database.

SC_HANDLE CreateService(
  SC_HANDLE hSCManager,  // handle to service control manager
                         // database
  LPCTSTR lpServiceName, // pointer to name of service to start
  LPCTSTR lpDisplayName, // pointer to display name
  DWORD dwDesiredAccess, // type of access to service
  DWORD dwServiceType,   // type of service
  DWORD dwStartType,     // when to start service
  DWORD dwErrorControl,  // severity if service fails to start
  LPCTSTR lpBinaryPathName,  // pointer to name of binary file
  LPCTSTR lpLoadOrderGroup,  // pointer to name of load ordering
                             // group
  LPDWORD lpdwTagId,     // pointer to variable to get tag identifier
  LPCTSTR lpDependencies,  // pointer to array of dependency names
  LPCTSTR lpServiceStartName,
                           // pointer to account name of service
  LPCTSTR lpPassword       // pointer to password for service account
);

Parameters

hSCManager
Handle to the service control manager database. This handle is returned by the OpenSCManager function and must have SC_MANAGER_CREATE_SERVICE access.
lpServiceName
Pointer to a null-terminated string that names the service to install. The maximum string length is 256 characters. The service control manager database preserves the case of the characters, but service name comparisons are always case insensitive. Forward-slash (/) and back-slash (\) are invalid service name characters.
lpDisplayName
Pointer to a null-terminated string that is to be used by user interface programs to identify the service. This string has a maximum length of 256 characters. The name is case-preserved in the service control manager. display name comparisons are always case-insensitive.
dwDesiredAccess
Specifies the access to the service. Before granting the requested access, the system checks the access token of the calling process.

The STANDARD_RIGHTS_REQUIRED constant enables the following service object access types:
Standard rights | Description
DELETE | Enables calling of the DeleteService function to delete the service.
READ_CONTROL | Enables calling of the QueryServiceObjectSecurity function to query the security descriptor of the service object.
WRITE_DAC|WRITE_OWNER | Enables calling of the SetServiceObjectSecurity function to modify the security descriptor of the service object.

You can specify any or all of the following service object access types:
Access | Description
SERVICE_ALL_ACCESS | Includes STANDARD_RIGHTS_REQUIRED in addition to all of the access types listed in this table.
SERVICE_CHANGE_CONFIG | Enables calling of the ChangeServiceConfig function to change the service configuration.
SERVICE_ENUMERATE_DEPENDENTS | Enables calling of the EnumDependentServices function to enumerate all the services dependent on the service.
SERVICE_INTERROGATE | Enables calling of the ControlService function to ask the service to report its status immediately.
SERVICE_PAUSE_CONTINUE | Enables calling of the ControlService function to pause or continue the service.
SERVICE_QUERY_CONFIG | Enables calling of the QueryServiceConfig function to query the service configuration.
SERVICE_QUERY_STATUS | Enables calling of the QueryServiceStatus function to ask the service control manager about the status of the service.
SERVICE_START | Enables calling of the StartService function to start the service.
SERVICE_STOP | Enables calling of the ControlService function to stop the service.
SERVICE_USER_DEFINED_CONTROL | Enables calling of the ControlService function to specify a user-defined control code.

You can specify any of the following generic access types:
Generic access | Service access
GENERIC_READ | Combines the following access types: STANDARD_RIGHTS_READ, SERVICE_QUERY_CONFIG, SERVICE_QUERY_STATUS, and SERVICE_ENUMERATE_DEPENDENTS.
GENERIC_WRITE | Combines the following access types: STANDARD_RIGHTS_WRITE and SERVICE_CHANGE_CONFIG.
GENERIC_EXECUTE | Combines the following access types: STANDARD_RIGHTS_EXECUTE, SERVICE_START, SERVICE_STOP, SERVICE_PAUSE_CONTINUE, SERVICE_INTERROGATE, and SERVICE_USER_DEFINED_CONTROL.

dwServiceType
A set of bit flags that specify the type of service. You must specify one of the following service types.
Value | Meaning
SERVICE_WIN32_OWN_PROCESS | Specifies a Win32-based service that runs in its own process.
SERVICE_WIN32_SHARE_PROCESS | Specifies a Win32-based service that shares a process with other services.
SERVICE_KERNEL_DRIVER | Specifies a driver service.
SERVICE_FILE_SYSTEM_DRIVER | Specifies a file system driver service.

If you specify either SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS, you can also specify the following flag.
Value | Meaning
SERVICE_INTERACTIVE_PROCESS | Enables a Win32-based service process to interact with the desktop.

dwStartType
Specifies when to start the service. You must specify one of the following start types.
Value | Meaning
SERVICE_BOOT_START | Specifies a device driver started by the system loader. This value is valid only for driver services.
SERVICE_SYSTEM_START | Specifies a device driver started by the IoInitSystem function. This value is valid only for driver services.
SERVICE_AUTO_START | Specifies a service to be started automatically by the service control manager during system startup.
SERVICE_DEMAND_START | Specifies a service to be started by the service control manager when a process calls the StartService function.
SERVICE_DISABLED | Specifies a service that can no longer be started.

dwErrorControl
Specifies the severity of the error if this service fails to start during startup, and determines the action taken by the startup program if failure occurs. You must specify one of the following error control flags.
Value | Meaning
SERVICE_ERROR_IGNORE | The startup program logs the error but continues the startup operation.
SERVICE_ERROR_NORMAL | The startup program logs the error and puts up a message box pop-up but continues the startup operation.
SERVICE_ERROR_SEVERE | The startup program logs the error. If the last-known-good configuration is being started, the startup operation continues. Otherwise, the system is restarted with the last-known-good configuration.
SERVICE_ERROR_CRITICAL | The startup program logs the error, if possible. If the last-known-good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known good configuration.

lpBinaryPathName
Pointer to a null-terminated string that contains the fully qualified path to the service binary file. If the path contains a space, it must be quoted so that it is correctly interpreted. For example, "d:\\my share\\myservice.exe" should be specified as "\"d:\\my share\\myservice.exe\"".
lpLoadOrderGroup
Pointer to a null-terminated string that names the load ordering group of which this service is a member. Specify NULL or an empty string if the service does not belong to a group.
lpdwTagId
Pointer to a DWORD variable that receives a tag value that is unique in the group specified in the lpLoadOrderGroup parameter. Specify NULL if you are not changing the existing tag.

You can use a tag for ordering service startup within a load ordering group by specifying a tag order vector in the GroupOrderList value of the following registry key:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control

Tags are only evaluated for driver services that have SERVICE_BOOT_START or SERVICE_SYSTEM_START start types.

lpDependencies
Pointer to a double null-terminated array of null-separated names of services or load ordering groups that the system must start before this service. Specify NULL or an empty string if the service has no dependencies. Dependency on a group means that this service can run if at least one member of the group is running after an attempt to start all members of the group.

You must prefix group names with SC_GROUP_IDENTIFIER so that they can be distinguished from a service name, because services and service groups share the same name space.

lpServiceStartName
Pointer to a null-terminated string that names the service. If the service type is SERVICE_WIN32_OWN_PROCESS, use an account name in the form DomainName\UserName. The service process will be logged on as this user. If the account belongs to the built-in domain, you can specify .\UserName. If the service type is SERVICE_WIN32_SHARE_PROCESS you must specify the LocalSystem account. If you specify NULL, CreateService uses the LocalSystem account.

If the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER, the name is the driver object name that the system uses to load the device driver. Specify NULL if the driver is to use a default object name created by the I/O system.

lpPassword
Pointer to a null-terminated string that contains the password to the account name specified by the lpServiceStartName parameter. If the pointer is NULL or if it points to an empty string, the service has no password. Passwords are ignored for driver services. If lpServiceStartName is LocalSystem, the password must be NULL.

Return Values

If the function succeeds, the return value is a handle to the service.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Errors

The following error codes can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED | The handle to the specified service control manager database does not have SC_MANAGER_CREATE_SERVICE access.
ERROR_CIRCULAR_DEPENDENCY | A circular service dependency was specified.
ERROR_DUP_NAME | The display name already exists in the service control manager database either as a service name or as another display name.
ERROR_INVALID_HANDLE | The handle to the specified service control manager database is invalid.
ERROR_INVALID_NAME | The specified service name is invalid.
ERROR_INVALID_PARAMETER | A parameter that was specified is invalid.
ERROR_INVALID_SERVICE_ACCOUNT | The user account name specified in the lpServiceStartName parameter does not exist.
ERROR_SERVICE_EXISTS | The specified service already exists in this database.

Remarks

The CreateService function creates a service object and installs it in the service control manager database by creating a key with the same name as the service under the following registry key:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services

Information specified for this function is saved as values under this key. Setup programs and the service itself can create subkeys under this key for any service specific information.

The returned handle is only valid for the process that called CreateService. It can be closed by calling the CloseServiceHandle function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, ChangeServiceConfig, CloseServiceHandle, ControlService, DeleteService, EnumDependentServices, OpenSCManager, QueryServiceConfig, QueryServiceObjectSecurity, QueryServiceStatus, SetServiceObjectSecurity, StartService


DeleteService

The DeleteService function marks the specified service for deletion from the service control manager database.

BOOL DeleteService(
  SC_HANDLE hService   // handle to service
);

Parameters

hService
Handle to the service. This handle is returned by the OpenService or CreateService function, and it must have DELETE access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes may be set by the service control manager. Others may be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED | The specified handle was not opened with DELETE access.
ERROR_INVALID_HANDLE | The specified handle is invalid.
ERROR_SERVICE_MARKED_FOR_DELETE | The specified service has already been marked for deletion.

Remarks

The DeleteService function marks a service for deletion from the service control manager database. The database entry is not removed until all open handles to the service have been closed by calls to the CloseServiceHandle function, and the service is not running. A running service is stopped by a call to the ControlService function with the SERVICE_CONTROL_STOP control code. If the service cannot be stopped, the database entry is removed when the system is restarted.

The service control manager deletes the service by deleting the service key and its subkeys from the registry.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.

See Also

Services Overview, Service Functions, CloseServiceHandle, ControlService, CreateService, OpenService


EnumDependentServices

The EnumDependentServices function provides the name and status of each service that depends on the specified service; that is, the specified service must be running before the dependent services can run.

BOOL EnumDependentServices(
  SC_HANDLE hService,      // handle to service
  DWORD dwServiceState,    // state of services to enumerate
  LPENUM_SERVICE_STATUS lpServices,
                           // pointer to service status buffer
  DWORD cbBufSize,         // size of service status buffer
  LPDWORD pcbBytesNeeded,  // pointer to variable for bytes needed
  LPDWORD lpServicesReturned
                           // pointer to variable for number returned
);

Parameters

hService
Handle to the service. This handle is returned by the OpenService or CreateService function, and it must have SERVICE_ENUMERATE_DEPENDENTS access.
dwServiceState
Specifies the services to enumerate based on their running state. It must be one or both of the following values:
Value | Meaning
SERVICE_ACTIVE | Enumerates services that are in the following states: SERVICE_START_PENDING, SERVICE_STOP_PENDING, SERVICE_RUNNING, SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING, and SERVICE_PAUSED.
SERVICE_INACTIVE | Enumerates services that are in the SERVICE_STOPPED state.
SERVICE_STATE_ALL | Combines the following states: SERVICE_ACTIVE and SERVICE_INACTIVE.

lpServices
Pointer to an array of ENUM_SERVICE_STATUS structures in which name and service status information for each dependent service in the database is returned. The buffer must be large enough to hold the structures, plus the strings to which their members point.

The order of the services in this array is the reverse of the start order of the services. In other words, the first service in the array is the one that would be started last, and the last service in the array is the one that would be started first.

cbBufSize
Specifies the size, in bytes, of the buffer pointed to by the lpServices parameter.
pcbBytesNeeded
Pointer to a variable that receives the number of bytes needed to store the array of service entries. The variable only receives this value if the buffer pointed to by lpServices is too small, indicated by function failure and the ERROR_MORE_DATA error; otherwise, the contents of pcbBytesNeeded are undefined.
lpServicesReturned
Pointer to a variable that receives the number of service entries returned.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED
 | The specified handle was not opened with SERVICE_ENUMERATE_DEPENDENTS access.
ERROR_INVALID_HANDLE
 | The specified handle is invalid.
ERROR_INVALID_PARAMETER
 | A parameter that was specified is invalid.
ERROR_MORE_DATA
 | The buffer pointed to by lpServices is not large enough. The function sets the variable pointed to by lpServicesReturned to the actual number of service entries stored into the buffer. The function sets the variable pointed to by pcbBytesNeeded to the number of bytes required to store all of the service entries.

Remarks

The returned services entries are ordered in the reverse order of the start order, with group order taken into account. If you need to stop the dependent services, you can use the order of entries written to the lpServices buffer to stop the dependent services in the proper order.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, CreateService, ENUM_SERVICE_STATUS, EnumServicesStatus, OpenService


EnumServicesStatus

The EnumServicesStatus function enumerates services in the specified service control manager database. The name and status of each service are provided.

BOOL EnumServicesStatus(
  SC_HANDLE hSCManager, // handle to service control manager database
  DWORD dwServiceType,     // type of services to enumerate
  DWORD dwServiceState,    // state of services to enumerate
  LPENUM_SERVICE_STATUS lpServices,
                           // pointer to service status buffer
  DWORD cbBufSize,         // size of service status buffer
  LPDWORD pcbBytesNeeded,  // pointer to variable for bytes needed
  LPDWORD lpServicesReturned,
                           // pointer to variable for number returned
  LPDWORD lpResumeHandle   // pointer to variable for next entry
);

Parameters

hSCManager
Handle to the service control manager database. The OpenSCManager function returns this handle, which must have SC_MANAGER_ENUMERATE_SERVICE access.
dwServiceType
Specifies the type of services to enumerate. It must be one or both of the following values:
Value | Meaning
SERVICE_WIN32 | Enumerates services of type SERVICE_WIN32_OWN_PROCESS and SERVICE_WIN32_SHARE_PROCESS.
SERVICE_DRIVER | Enumerates services of type SERVICE_KERNEL_DRIVER and SERVICE_FILE_SYSTEM_DRIVER.

dwServiceState
Specifies the services to enumerate based on their running state. It must be one or both of the following values:
Value | Meaning
SERVICE_ACTIVE | Enumerates services that are in the following states: SERVICE_START_PENDING, SERVICE_STOP_PENDING, SERVICE_RUNNING, SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING, and SERVICE_PAUSED.
SERVICE_INACTIVE | Enumerates services that are in the SERVICE_STOPPED state.
SERVICE_STATE_ALL | Combines the following states: SERVICE_ACTIVE and SERVICE_INACTIVE.

lpServices
Pointer to an array of ENUM_SERVICE_STATUS structures in which the name and service status information for each service in the database is returned. The buffer must be large enough to hold the structures, plus the strings to which their members point.
cbBufSize
Specifies the size, in bytes, of the buffer pointed to by the lpServices parameter.
pcbBytesNeeded
Pointer to a variable that receives the number of bytes needed to return the remaining service entries.
lpServicesReturned
Pointer to a variable that receives the number of service entries returned.
lpResumeHandle
Pointer to a DWORD variable that is used for both input and output. On input, this value specifies the starting point of enumeration. You must set this value to zero the first time this function is called. On output, this value is zero if the function succeeds. However, if the function returns zero and the GetLastError function returns ERROR_MORE_DATA, this value is used to indicate the next service entry to be read when the function is called to retrieve the additional data.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED
 | The specified handle was not opened with SC_MANAGER_ENUMERATE_SERVICE access.
ERROR_INVALID_HANDLE
 | The specified handle is invalid.
ERROR_INVALID_PARAMETER
 | A parameter that was specified is invalid.
ERROR_MORE_DATA
 | There are more service entries than would fit into the lpServices buffer. The actual number of service entries written to lpServices is returned in the lpServicesReturned parameter. The number of bytes required to get the remaining entries is returned in the pcbBytesNeeded parameter. The remaining services can be enumerated by additional calls to EnumServicesStatus with the lpResumeHandle parameter indicating the next service to read.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, EnumDependentServices, ENUM_SERVICE_STATUS, OpenSCManager


GetServiceDisplayName

The GetServiceDisplayName function obtains the display name that is associated with a particular service.

BOOL GetServiceDisplayName(
  SC_HANDLE hSCManager,  // handle to a service control manager
                         // database
  LPCTSTR lpServiceName, // the service name
  LPTSTR lpDisplayName,  // buffer to receive the service's display
                         // name
  LPDWORD lpcchBuffer    // size of display name buffer and display
                         // name
);

Parameters

hSCManager
Handle to a service control manager database, as returned by the OpenSCManager function.
lpServiceName
Pointer to a null-terminated service name string. This name is the same as the service's registry key name.
lpDisplayName
Pointer to a buffer into which the function stores the service's display name as a null-terminated string. If the function fails, this buffer will contain an empty string.
lpcchBuffer
Pointer to a DWORD that contains the size, in characters, of the buffer pointed to by lpDisplayName. When the function returns, this DWORD contains the size, in characters, of the service's display name, excluding the NULL terminator.

If the buffer pointed to by lpDisplayName is too small to contain the display name, the function stores no data into it. When the function returns, the DWORD pointed to by lpcchBuffer contains the size in characters of the service's display name, excluding the NULL terminator.

Return Values

If the functions succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

There are two names for a service: the service name and the display name. The service name is the name of the service's key in the registry. The display name is a user-friendly name that appears in the Services control panel application, and is used with the NET START command. To map the service name to the display name, use the GetServiceDisplayName function. To map the display name to the service name, use the GetServiceKeyName function.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, GetServiceKeyName, OpenSCManager


GetServiceKeyName

The GetServiceKeyName function obtains the service name that is associated with a particular service's display name.

BOOL GetServiceKeyName(
  SC_HANDLE hSCManager,  // handle to a service control manager
                         // database
  LPCTSTR lpDisplayName, // the service's display name
  LPTSTR lpServiceName,  // buffer to receive the service name
  LPDWORD lpcchBuffer    // size of service name buffer and service
                         // name
);

Parameters

hSCManager
Handle to a computer's service control manager database, as returned by OpenSCManager.
lpDisplayName
Pointer to a null-terminated service display name string.
lpServiceName
Pointer to a buffer into which the function stores the service name as a null-terminated string. If the function fails, this buffer will contain an empty string.
lpcchBuffer
Pointer to a DWORD that contains the size in characters of the buffer pointed to by the lpServiceName parameter. When the function returns, this DWORD contains the size, in characters, of the service name, excluding the NULL terminator.

If the buffer pointed to by lpServiceName is too small to contain the service name, the function stores no data in it. When the function returns, the DWORD pointed to by lpcchBuffer contains the size, in characters, of the service name, excluding the NULL terminator.

Return Values

If the functions succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

There are two names for a service: the service name and the display name. The service name is the name of the service's key in the registry. The display name is a user-friendly name that appears in the Services control panel application, and is used with the NET START command. To map the service name to the display name, use the GetServiceDisplayName function. To map the display name to the service name, use the GetServiceKeyName function.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, GetServiceDisplayName, OpenSCManager


Handler

A Handler function is an application-defined function used with the RegisterServiceCtrlHandler function. A service program uses it as the control handler function of a particular Win32-based service. The LPHANDLER_FUNCTION type defines a pointer to this function. Handler is a placeholder for the application-defined name.

VOID WINAPI Handler(
  DWORD fdwControl   // requested control code
);

Parameters

fdwControl
Specifies the requested control code. This value can be one of the standard control codes in the following table:
Value | Meaning
SERVICE_CONTROL_STOP | Requests the service to stop.
SERVICE_CONTROL_PAUSE | Requests the service to pause.
SERVICE_CONTROL_
CONTINUE 		Requests the paused service to resume.
SERVICE_CONTROL_
INTERROGATE 		Requests the service to update immediately its current status information to the service control manager.
SERVICE_CONTROL_
SHUTDOWN 		Requests the service to perform cleanup tasks, because the system is shutting down.

This value can also be a user-defined control code, as described in the following table:
Value | Meaning
Range 128 to 255. | The service defines the action associated with the control code. The hService handle must have SERVICE_USER_DEFINED_CONTROL access.

Return Values

This function does not return a value.

Remarks

When a Win32-based service is started, its ServiceMain function should immediately call the RegisterServiceCtrlHandler function to specify a Handler function to process control requests.

The control dispatcher in the main thread of a Win32-based service process invokes the control handler function for the specified service whenever it receives a control request from the service control manager. After processing the control request, the control handler must call the SetServiceStatus function to report its current status to the service control manager.

The SERVICE_CONTROL_SHUTDOWN control should only be processed by services that must absolutely clean up during shutdown, because there is an extremely limited time (about 20 seconds) available for service shutdown. After this time expires, system shutdown proceeds regardless of whether service shutdown is complete. If the service needs to take more time to shut down, it should send out STOP_PENDING status messages, along with a wait hint, so that the service controller knows how long to wait before reporting to the system that service shutdown is complete. For example, the EventLog service needs to clear a dirty bit in the files that it maintains, and the server service needs to shut down so that network connections aren't made when the system is in the shutdown state.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: User-defined.

See Also

Services Overview, Service Functions, RegisterServiceCtrlHandler, ServiceMain, SetServiceStatus


LockServiceDatabase

The LockServiceDatabase function locks the specified service control manager database.

SC_LOCK LockServiceDatabase(
  SC_HANDLE hSCManager   // handle of service control manager
                         // database
);

Parameters

hSCManager
Handle to the service control manager database. The OpenSCManager function returns this handle, which must have SC_MANAGER_LOCK access.

Return Values

If the function succeeds, the return value is a lock to the specified service control manager database.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Errors

The following error code can be set by the service control manager. Other error codes can be set by registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED | The specified handle was not opened with SC_MANAGER_LOCK access.
ERROR_INVALID_HANDLE | The specified handle is invalid.
ERROR_SERVICE_DATABASE_LOCKED | The database is locked.

Remarks

The LockServiceDatabase function tries to request ownership of the service control manager database lock. Only one process at a time can own a lock at any given time.

A lock is a protocol used by setup and configuration programs and the service control manager to serialize access to the service tree in the registry. The only time the service control manager requests ownership of the lock is when it is starting a service. Setup and configuration programs are expected to acquire ownership of a lock before using the ChangeServiceConfig or SetServiceObjectSecurity function to reconfigure a service. They should also acquire ownership of a lock before using the registry functions to reconfigure a service. The lock prevents the service control manager from starting a service while it is being reconfigured.

A call to the StartService function to start a service in a locked database fails. No other service control manager functions are affected by a lock.

The lock is held until the SC_LOCK handle is specified in a subsequent call to the UnlockServiceDatabase function. If a process that owns a lock terminates, the service control manager automatically cleans up and releases ownership of the lock.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.

See Also

Services Overview, Service Functions, ChangeServiceConfig, OpenSCManager, QueryServiceLockStatus, SetServiceObjectSecurity, StartService, UnlockServiceDatabase


NotifyBootConfigStatus

The NotifyBootConfigStatus function reports the boot status to the service control manager. It is used by boot verification programs. This function can be called only by a process running in the LocalSystem or Administrator's account.

BOOL NotifyBootConfigStatus(
  BOOL BootAcceptable   // indicates acceptability of boot
                        // configuration
);

Parameters

BootAcceptable
Specifies whether the configuration used when booting the system is acceptable. If the value is TRUE, the system saves the configuration as the last-known good configuration. If the value is FALSE, the system immediately reboots, using the previously saved last-known good configuration.

Return Values

If the BootAcceptable parameter is FALSE, the function does not return.

If the last-known good configuration was successfully saved, the return value is nonzero.

If an error occurs, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager to set parameters in the configuration registry.

Value | Meaning
ERROR_ACCESS_DENIED | The user does not have permission to perform this operation. A hard-coded DACL associated with the service control manager object determines who can perform a NotifyBootConfigStatus operation. Only the system and members of the Adminstrators group can do so.

Remarks

Saving the configuration of a running system with this function is an acceptable method for saving the last-known good configuration. If the boot configuration is unacceptable, use this function to reboot the system using the existing last-known good configuration.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.

See Also

Services Overview, Service Functions


OpenSCManager

The OpenSCManager function establishes a connection to the service control manager on the specified computer and opens the specified service control manager database.

SC_HANDLE OpenSCManager(
  LPCTSTR lpMachineName,  // pointer to machine name string
  LPCTSTR lpDatabaseName,  // pointer to database name string
  DWORD dwDesiredAccess   // type of access
);

Parameters

lpMachineName
Pointer to a null-terminated string that names the target computer. If the pointer is NULL or points to an empty string, the function connects to the service control manager on the local computer.
lpDatabaseName
Pointer to a null-terminated string that names the service control manager database to open. This parameter should be set to SERVICES_ACTIVE_DATABASE. If it is NULL, the SERVICES_ACTIVE_DATABASE database is opened by default.
dwDesiredAccess
Specifies the access to the service control manager. Before granting the requested access, the system checks the access token of the calling process against the discretionary access-control list of the security descriptor associated with the service control manager. The SC_MANAGER_CONNECT access type is implicitly specified by calling this function. In addition, any or all of the following service control manager object access types can be specified:
Type Description
SC_MANAGER_ALL_ACCESS
Includes STANDARD_RIGHTS_REQUIRED, in addition to all of the access types listed in this table.
SC_MANAGER_CONNECT
Enables connecting to the service control manager.
SC_MANAGER_CREATE_SERVICE
Enables calling of the CreateService function to create a service object and add it to the database.
SC_MANAGER_ENUMERATE_SERVICE
Enables calling of the EnumServicesStatus function to list the services that are in the database.
SC_MANAGER_LOCK
Enables calling of the LockServiceDatabase function to acquire a lock on the database.
SC_MANAGER_QUERY_LOCK_STATUS
Enables calling of the QueryServiceLockStatus function to retrieve the lock status information for the database.

The dwDesiredAccess parameter can specify any or all of the following generic access types:
Generic access | Service manager access
GENERIC_READ | Combines the following access types: STANDARD_RIGHTS_READ, SC_MANAGER_ENUMERATE_SERVICE, and SC_MANAGER_QUERY_LOCK_STATUS.
GENERIC_WRITE | Combines the following access types: STANDARD_RIGHTS_WRITE and SC_MANAGER_CREATE_SERVICE.
GENERIC_EXECUTE | Combines the following access types: STANDARD_RIGHTS_EXECUTE, SC_MANAGER_CONNECT, and SC_MANAGER_LOCK.

Return Values

If the function succeeds, the return value is a handle to the specified service control manager database.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Errors

The following error codes can be set by the SCM. Other error codes can be set by the registry functions that are called by the SCM.

Error code | Meaning
ERROR_ACCESS_DENIED | The requested access was denied.
ERROR_DATABASE_DOES_NOT_EXIST | The specified database does not exist.
ERROR_INVALID_PARAMETER | A specified parameter is invalid.

Remarks

When a process uses the OpenSCManager function to open a handle to a service control manager database, the system performs a security check before granting the requested access. All processes are permitted SC_MANAGER_CONNECT, SC_MANAGER_ENUMERATE_SERVICE, and SC_MANAGER_QUERY_LOCK_STATUS access to all service control manager databases. This enables any process to open a service control manager database handle that it can use in the OpenService, EnumServicesStatus, and QueryServiceLockStatus functions. Only processes with Administrator privileges are able to open a database handle used by the CreateService and LockServiceDatabase functions.

The returned handle is only valid for the process that called the OpenSCManager function. It can be closed by calling the CloseServiceHandle function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, CloseServiceHandle, CreateService, EnumServicesStatus, LockServiceDatabase, OpenService, QueryServiceLockStatus


OpenService

The OpenService function opens a handle to an existing service.

SC_HANDLE OpenService(
  SC_HANDLE hSCManager,  // handle to service control manager
                         // database
  LPCTSTR lpServiceName, // pointer to name of service to start
  DWORD dwDesiredAccess  // type of access to service
);

Parameters

hSCManager
Handle to the service control manager database. The OpenSCManager function returns this handle.
lpServiceName
Pointer to a null-terminated string that names the service to open. The maximum string length is 256 characters. The service control manager database preserves the case of the characters, but service name comparisons are always case insensitive. Forward-slash (/) and backslash (\) are invalid service name characters.
dwDesiredAccess
Specifies the access to the service. Before granting the requested access, the system checks the access token of the calling process against the discretionary access-control list of the security descriptor associated with the service object.

The STANDARD_RIGHTS_REQUIRED constant enables the following service object access types:
Standard rights | Description
DELETE | Enables calling of the DeleteService function to delete the service.
READ_CONTROL | Enables calling of the QueryServiceObjectSecurity function to query the security descriptor of the service object.
WRITE_DAC|WRITE_OWNER | Enables calling of the SetServiceObjectSecurity function to modify the security descriptor of the service object.

You can specify any or all of the following service object access types:
Access | Description
SERVICE_ALL_ACCESS | Includes STANDARD_RIGHTS_REQUIRED in addition to all of the access types listed in this table.
SERVICE_CHANGE_CONFIG | Enables calling of the ChangeServiceConfig function to change the service configuration.
SERVICE_ENUMERATE_DEPENDENTS | Enables calling of the EnumDependentServices function to enumerate all the services dependent on the service.
SERVICE_INTERROGATE | Enables calling of the ControlService function to ask the service to report its status immediately.
SERVICE_PAUSE_CONTINUE | Enables calling of the ControlService function to pause or continue the service.
SERVICE_QUERY_CONFIG | Enables calling of the QueryServiceConfig function to query the service configuration.
SERVICE_QUERY_STATUS | Enables calling of the QueryServiceStatus function to ask the service control manager about the status of the service.
SERVICE_START | Enables calling of the StartService function to start the service.
SERVICE_STOP | Enables calling of the ControlService function to stop the service.
SERVICE_USER_DEFINED_CONTROL | Enables calling of the ControlService function to specify a user-defined control code.

You can specify any of the following generic access types:
Generic access | Service access
GENERIC_READ | Combines the following access types: STANDARD_RIGHTS_READ, SERVICE_QUERY_CONFIG, SERVICE_QUERY_STATUS, and SERVICE_ENUMERATE_DEPENDENTS.
GENERIC_WRITE | Combines the following access types: STANDARD_RIGHTS_WRITE and SERVICE_CHANGE_CONFIG.
GENERIC_EXECUTE | Combines the following access types: STANDARD_RIGHTS_EXECUTE, SERVICE_START, SERVICE_STOP, SERVICE_PAUSE_CONTINUE, SERVICE_INTERROGATE, and SERVICE_USER_DEFINED_CONTROL.

Return Values

If the function succeeds, the return value is a handle to the service.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Errors

The following error codes can be set by the service control manager. Others can be set by the registry functions that are called by the service control manager.

Error code | Meaning
ERROR_ACCESS_DENIED | The specified service control manager database handle does not have access to the service.
ERROR_INVALID_HANDLE | The specified handle is invalid.
ERROR_INVALID_NAME | The specified service name is invalid.
ERROR_SERVICE_DOES_NOT_EXIST | The specified service does not exist.

Remarks

The returned handle is only valid for the process that called OpenService. It can be closed by calling the CloseServiceHandle function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, ChangeServiceConfig, ControlService, CreateService, DeleteService, EnumDependentServices, OpenSCManager, QueryServiceConfig, QueryServiceObjectSecurity, QueryServiceStatus, SetServiceObjectSecurity, StartService


QueryServiceConfig

The QueryServiceConfig function retrieves the configuration parameters of the specified service.

BOOL QueryServiceConfig(
  SC_HANDLE hService,  // handle of service
  LPQUERY_SERVICE_CONFIG lpServiceConfig,
                       // address of service config. structure
  DWORD cbBufSize,     // size of service configuration buffer
  LPDWORD pcbBytesNeeded   // address of variable for bytes needed
);

Parameters

hService
Handle to the service. This handle is returned by the OpenService or CreateService function, and it must have SERVICE_QUERY_CONFIG access.
lpServiceConfig
Pointer to a buffer that receives the QUERY_SERVICE_CONFIG structure in which the service configuration information is returned, plus the strings to which its members point.
cbBufSize
Specifies the size, in bytes, of the buffer pointed to by the lpServiceConfig parameter.
pcbBytesNeeded
Pointer to a variable that receives the number of bytes needed to return all the configuration information if the function fails.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes can be set by the service control manager. Others can be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED | The specified handle was not opened with SERVICE_QUERY_CONFIG access.
ERROR_INSUFFICIENT_BUFFER | There is more service configuration information than would fit into the lpServiceConfig buffer. The number of bytes required to get all the information is returned in the pcbBytesNeeded parameter. Nothing is written to the lpServiceConfig buffer.
ERROR_INVALID_HANDLE | The specified handle is invalid.

Remarks

The QueryServiceConfig function returns the service configuration information kept in the registry for a particular service. This configuration information is first set by a service control program using the CreateService function. This information may have been updated by a service configuration program using the ChangeServiceConfig function.

If the service was running when the configuration information was last changed, the information returned by QueryServiceConfig will not reflect the current configuration of the service. Instead, it will reflect the configuration of the service when it is next run. The DisplayName key is an exception to this. When the DisplayName key is changed, it takes effect immediately, regardless of whether the service is running.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, ChangeServiceConfig, CreateService, OpenService, QUERY_SERVICE_CONFIG, QueryServiceObjectSecurity, QueryServiceStatus


QueryServiceConfig2

[This is preliminary documentation and subject to change.]

The QueryServiceConfig2 function retrieves the optional configuration parameters of the specified service.

BOOL QueryServiceConfig2(
  SC_HANDLE hService,
  DWORD dwInfoLevel,
  LPBYTE lpBuffer,
  DWORD cbBufSize,
  LPDWORD pcbBytesNeeded
);

Parameters

hService
Handle to the service. This handle is returned by the OpenService or CreateService function and must have the SERVICE_CHANGE_CONFIG access right.
dwInfoLevel
Specifies the configuration information to query. This parameter can have one of the following values.
Value | Meaning
SERVICE_CONFIG_DESCRIPTION | The lpBuffer parameter is a pointer to a SERVICE_DESCRIPTION structure.
SERVICE_CONFIG_FAILURE_ACTIONS | The lpBuffer parameter is a pointer to a SERVICE_FAILURE_ACTIONS structure.

lpBuffer
Pointer to the structure in which the service configuration information is returned, plus the strings to which its members point. The format of this data depends on the value of the dwInfoLevel parameter.
cbBufSize
Specifies the size, in bytes, of the structure pointed to by the lpBuffer parameter.
pcbBytesNeeded
Pointer to a variable that receives the number of bytes needed to return the configuration information, if the function fails.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The QueryServiceConfig2 function returns the optional configuration information stored in the service control manager database for the specified service. You can change this configuration information by using the ChangeServiceConfig2 function.

You can change and query additional configuration information using the ChangeServiceConfig and QueryServiceConfig functions, respectively.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, ChangeServiceConfig, ChangeServiceConfig2, CreateService, OpenService, QueryServiceConfig, SERVICE_DESCRIPTION, SERVICE_FAILURE_ACTIONS


QueryServiceLockStatus

The QueryServiceLockStatus function retrieves the lock status of the specified service control manager database.

BOOL QueryServiceLockStatus(
  SC_HANDLE hSCManager,    // handle of svc. ctrl. mgr. database
  LPQUERY_SERVICE_LOCK_STATUS lpLockStatus,
                           // address of lock status structure
  DWORD cbBufSize,         // size of service configuration buffer
  LPDWORD pcbBytesNeeded   // address of variable for bytes needed
);

Parameters

hSCManager
Handle to the service control manager database. The OpenSCManager function returns this handle, which must have SC_MANAGER_QUERY_LOCK_STATUS access.
lpLockStatus
Pointer to a buffer that receives the QUERY_SERVICE_LOCK_STATUS structure in which the lock status of the specified database is returned, plus the strings to which its members point.
cbBufSize
Specifies the size, in bytes, of the buffer pointed to by the lpLockStatus parameter.
pcbBytesNeeded
Pointer to a variable that receives the number of bytes needed to return all the lock status information, if the function fails.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED
 | The specified handle was not opened with SC_MANAGER_QUERY_LOCK_STATUS access.
ERROR_INSUFFICIENT_BUFFER
 | There is more lock status information than would fit into the lpLockStatus buffer. The number of bytes required to get all the information is returned in the pcbBytesNeeded parameter. Nothing is written to the lpLockStatus buffer.
ERROR_INVALID_HANDLE
 | The specified handle is invalid.

Remarks

The QueryServiceLockStatus function returns a QUERY_SERVICE_LOCK_STATUS structure that indicates whether the specified database is locked. If the database is locked, the structure provides the account name of the user that owns the lock and the length of time that the lock has been held.

A process calls the LockServiceDatabase function to acquire ownership of a service control manager database lock and the UnlockServiceDatabase function to release the lock.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, LockServiceDatabase, OpenSCManager, QUERY_SERVICE_LOCK_STATUS, UnlockServiceDatabase


QueryServiceStatus

The QueryServiceStatus function retrieves the current status of the specified service.

BOOL QueryServiceStatus(
  SC_HANDLE hService,  // handle of service
  LPSERVICE_STATUS lpServiceStatus
                       // address of service status structure
);

Parameters

hService
Handle to the service. This handle is returned by the OpenService or the CreateService function, and it must have SERVICE_QUERY_STATUS access.
lpServiceStatus
Pointer to a SERVICE_STATUS structure in which the status information is returned.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED | The specified handle was not opened with SERVICE_QUERY_STATUS access.
ERROR_INVALID_HANDLE | The specified handle is invalid.

Remarks

The QueryServiceStatus function returns the most recent service status information reported to the service control manager. If the service just changed its status, it may not have updated the service control manager yet. Applications can find out the current service status by interrogating the service directly using the ControlService function with the SERVICE_CONTROL_INTERROGATE control code.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.

See Also

Services Overview, Service Functions, ControlService, CreateService, OpenService, SERVICE_STATUS, SetServiceStatus


RegisterServiceCtrlHandler

A Win32-based service calls the RegisterServiceCtrlHandler function to register a function to handle its service control requests.

SERVICE_STATUS_HANDLE RegisterServiceCtrlHandler(
  LPCTSTR lpServiceName,             // address of name of service
  LPHANDLER_FUNCTION lpHandlerProc   // address of handler function
);

Parameters

lpServiceName
Pointer to a null-terminated string that names the service run by the calling thread. This is the service name that the service control program specified in the CreateService function when creating the service.
lpHandlerProc
Pointer to the handler function to be registered. For more information, see Handler.

Return Values

If the function succeeds, the return value is a service status handle.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_INVALID_NAME | The specified service name is invalid.
ERROR_SERVICE_DOES_NOT_EXIST | The specified service does not exist.

Remarks

The ServiceMain function of a new service should immediately call the RegisterServiceCtrlHandler function to register a control handler function with the control dispatcher. This enables the control dispatcher to invoke the specified function when it receives control requests for this service. The threads of the calling process can use the service status handle returned by this function to identify the service in subsequent calls to the SetServiceStatus function.

This function must be called before the first SetServiceStatus call because it returns a service status handle for the caller to use so that no other service can inadvertently set this service status. In addition, the control handler must be in place to field control requests by the time the service specifies the controls it accepts through the SetServiceStatus function.

When the control handler function is invoked with a control request, it must call SetServiceStatus to notify the service control manager of its current status, regardless of whether the status of the service has changed.

The service status handle does not have to be closed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, CreateService, Handler, ServiceMain, SetServiceStatus


ServiceMain

A ServiceMain function is a function that a service program specifies as the entry-point function of a particular service.

The LPSERVICE_MAIN_FUNCTION type defines a pointer to this callback function. ServiceMain is a placeholder for an application-defined function name.

VOID WINAPI ServiceMain(
  DWORD dwArgc,     // number of arguments
  LPTSTR *lpszArgv  //  array of argument string pointers
);

Parameters

dwArgc
Specifies the number of arguments in the lpszArgv array.
lpszArgv
Pointer to an array of pointers that point to null-terminated argument strings. The first argument in the array is the name of the service, and subsequent arguments are any strings passed to the service by the process that called the StartService function to start the service.

Return Values

This function does not return a value.

Remarks

A service program can start one or more services. A service process has a SERVICE_TABLE_ENTRY structure for each service that it can start. The structure specifies the service name and a pointer to the ServiceMain function for that service.

When the service control manager receives a request to start a service, it starts the service process (if it is not already running). The main thread of the service process calls the StartServiceCtrlDispatcher function with a pointer to an array of SERVICE_TABLE_ENTRY structures. Then the service control manager sends a start request to the service control dispatcher for this service process. The service control dispatcher creates a new thread to execute the ServiceMain function of the service being started.

The ServiceMain function should immediately call the RegisterServiceCtrlHandler function to specify a Handler function to handle control requests. Next, it should call the SetServiceStatus function to send status information to the service control manager. After these calls, the function completes the initialization tasks of the service, and waits for the service to terminate.

A ServiceMain function does not return until its services are ready to terminate.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: User-defined.

See Also

Services Overview, Service Functions, Handler, RegisterServiceCtrlHandler, SetServiceStatus, SERVICE_TABLE_ENTRY, StartServiceCtrlDispatcher


SetServiceBits

The SetServiceBits function registers a service type with the service control manager and the Server service. The Server service can then announce the registered service type as one it currently supports. The NetServerGetInfo and NetServerEnum functions obtain a specified machine's supported service types.

A service type is represented as a set of bit flags; the SetServiceBits function sets or clears combinations of those bit flags.

BOOL SetServiceBits(
  SERVICE_STATUS_HANDLE hServiceStatus,
                    // service status handle
  DWORD dwServiceBits,
                    // service type bits to set or clear
  BOOL bSetBitsOn,  // flag to set or clear the service type bits
  BOOL bUpdateImmediately
                    // flag to announce server type immediately
);

Parameters

hServiceStatus
A handle to the information structure for a service. A service obtains the handle by calling the RegisterServiceCtrlHandler function.
dwServiceBits
A set of bit flags that specifies a service type.

Certain bit flags (0xC00F3F7B) are reserved for use by Microsoft. The SetServiceBits function fails with the error ERROR_INVALID_DATA if any of these bit flags are set in dwServiceBits. The following 18 bit flags are reserved for use by Microsoft:
Reserved Bit Flag | Value
SV_TYPE_WORKSTATION | 0x00000001
SV_TYPE_SERVER | 0x00000002
SV_TYPE_DOMAIN_CTRL | 0x00000008
SV_TYPE_DOMAIN_BAKCTRL | 0x00000010
SV_TYPE_TIME_SOURCE | 0x00000020
SV_TYPE_AFP | 0x00000040
SV_TYPE_DOMAIN_MEMBER | 0x00000100
SV_TYPE_PRINTQ_SERVER | 0x00000200
SV_TYPE_DIALIN_SERVER | 0x00000400
SV_TYPE_XENIX_SERVER | 0x00000800
SV_TYPE_SERVER_UNIX | 0x00000800
SV_TYPE_NT | 0x00001000
SV_TYPE_WFW | 0x00002000
SV_TYPE_POTENTIAL_BROWSER | 0x00010000
SV_TYPE_BACKUP_BROWSER | 0x00020000
SV_TYPE_MASTER_BROWSER | 0x00040000
SV_TYPE_DOMAIN_MASTER | 0x00080000
SV_TYPE_LOCAL_LIST_ONLY | 0x40000000
SV_TYPE_DOMAIN_ENUM | 0x80000000

Certain bit flags (0x00300084) are defined by Microsoft, but are not specifically reserved for systems software. The following are these four bit flags:
Bit Flag Constant | Value
SV_TYPE_SV_TYPE_SQLSERVER | 0x00000004
SV_TYPE_NOVELL | 0x00000080
SV_TYPE_DOMAIN_CTRL | 0x00100000
SV_TYPE_DOMAIN_BAKCTRL | 0x00200000

Certain bit flags (0x3FC0C000) are not defined by Microsoft, and their use is not coordinated by Microsoft. Developers of applications that use these bits should be aware that other applications can also use them, thus creating a conflict. The following are these 10 bit flags:
Value | Value
0x00004000 | 0x02000000
0x00008000 | 0x04000000
0x00400000 | 0x08000000
0x00800000 | 0x10000000
0x01000000 | 0x20000000

bSetBitsOn
Specifies whether the function is to set or clear the bit flags that are set in dwServiceBit. If this value is TRUE, the bits are to be set. If this value is FALSE, the bits are to be cleared.
bUpdateImmediately
Specifies whether the Server service is to perform an immediate update, announcing the new service type. If this value is TRUE, the update is to be performed immediately. If this value is FALSE, the update will not be performed immediately.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in lmserver.h.
Import Library: Use advapi32.lib.

See Also

Services Overview, Service Functions, NetServerGetInfo, NetServerEnum, RegisterServiceCtrlHandler, SetServiceStatus


SetServiceStatus

The SetServiceStatus function updates the service control manager's status information for the calling service.

BOOL SetServiceStatus(
  SERVICE_STATUS_HANDLE hServiceStatus~,
                                     // service status handle
  LPSERVICE_STATUS lpServiceStatus   // address of status structure
);

Parameters

hServiceStatus~
Specifies a handle to the service control manager's status information structure for the current service. This handle is returned by the RegisterServiceCtrlHandler function.
lpServiceStatus
Pointer to the SERVICE_STATUS structure the contains the latest status information for the calling service.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_INVALID_HANDLE | The specified handle is invalid.
ERROR_INVALID_DATA | The specified service status structure is invalid.

Remarks

A ServiceMain function first calls the RegisterServiceCtrlHandler function to get the service's SERVICE_STATUS_HANDLE. Then it immediately calls the SetServiceStatus function to notify the service control manager of its SERVICE_START_PENDING status.

When a service receives a control request, the service's Handler function must call SetServiceStatus, even if the service's status did not change. A service can also use this function at any time and by any thread of the service to notify the service control manager of status changes. Examples of such unsolicited status updates include:

  • Checkpoint updates that occur when the service is in transition from one state to another (that is, SERVICE_START_PENDING).
  • Fatal error updates that occur when the service must stop due to a recoverable error.

A service can call this function only after it has called RegisterServiceCtrlHandler to get a service status handle.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.

See Also

Services Overview, Service Functions, Handler, RegisterServiceCtrlHandler, SERVICE_STATUS, ServiceMain, SetServiceBits


StartService

The StartService function starts a service.

BOOL StartService(
  SC_HANDLE hService,            // handle of service
  DWORD dwNumServiceArgs,        // number of arguments
  LPCTSTR *lpServiceArgVectors   // array of argument strings
                                 // string pointers
);

Parameters

hService
Handle to the service. This handle is returned by the OpenService or CreateService function, and it must have SERVICE_START access.
dwNumServiceArgs
Specifies the number of argument strings in the lpServiceArgVectors array. If lpServiceArgVectors is NULL, this parameter can be zero.
lpServiceArgVectors
Pointer to an array of pointers that point to null-terminated argument strings passed to a service. Driver services do not receive these arguments. If no arguments are passed to the service being started, this parameter can be NULL. The service accesses these arguments through its ServiceMain function. The first argument (argv[0]) is the name of the service by default, followed by the arguments, if any, in the lpServiceArgVectors array.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes can be set by the service control manager. Others can be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED | The specified handle was not opened with SERVICE_START access.
ERROR_INVALID_HANDLE | The specified handle is invalid.
ERROR_PATH_NOT_FOUND | The service binary file could not be found.
ERROR_SERVICE_ALREADY_RUNNING | An instance of the service is already running.
ERROR_SERVICE_DATABASE_LOCKED | The database is locked.
ERROR_SERVICE_DEPENDENCY_DELETED | The service depends on a service that does not exist or has been marked for deletion.
ERROR_SERVICE_DEPENDENCY_FAIL | The service depends on another service that has failed to start.
ERROR_SERVICE_DISABLED | The service has been disabled.
ERROR_SERVICE_LOGON_FAILED | The service could not be logged on.
ERROR_SERVICE_MARKED_FOR_DELETE | The service has been marked for deletion.
ERROR_SERVICE_NO_THREAD | A thread could not be created for the service.
ERROR_SERVICE_REQUEST_TIMEOUT | The service did not respond to the start request in a timely fashion.

Remarks

When a driver service is started, the StartService function does not return until the device driver has finished initializing.

When a Win32-based service is started, the service control manager spawns the service process, if necessary. If the specified service shares a process with other services, the required process may already exist. The StartService function does not wait for the first status update from the new service, because it can take a while. Instead, it returns when the service control manager receives notification from the service control dispatcher that the ServiceMain thread for this service was created successfully.

The service control manager sets the following default status values before returning from StartService:

  • Current state of the service is set to SERVICE_START_PENDING.
  • Controls accepted is set to none (zero).
  • The CheckPoint value is set to zero.
  • The WaitHint time is set to 2 seconds.

The calling process can determine if the new service has finished its initialization by calling the QueryServiceStatus function periodically to query the service's status.

A service cannot call StartService during initialization. The reason is that the service control manager locks the service control database during initialization, so a call to StartService will block. Once the service reports to the service control manager that it has successfully started, it can call StartService.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, ControlService, CreateService, OpenService, QueryServiceStatus, ServiceMain


StartServiceCtrlDispatcher

The StartServiceCtrlDispatcher function connects the main thread of a service process to the service control manager, which causes the thread to be the service control dispatcher thread for the calling process.

BOOL StartServiceCtrlDispatcher(
  LPSERVICE_TABLE_ENTRY lpServiceStartTable   // address of service
                                              // table
);

Parameters

lpServiceStartTable
Pointer to an array of SERVICE_TABLE_ENTRY structures containing one entry for each service that can execute in the calling process. The members of the last entry in the table must have NULL values to designate the end of the table.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error code can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_INVALID_DATA | The specified dispatch table contains entries that are not in the proper format.
ERROR_SERVICE_ALREADY_RUNNING | Windows NT 5.0 and later: The process has already called StartServiceCtrlDispatcher. Each process can call StartServiceCtrlDispatcher only one time.

Remarks

When the service control manager starts a service process, it waits for the process to call the StartServiceCtrlDispatcher function. The main thread of a service process should make this call as soon as possible after it starts up. If StartServiceCtrlDispatcher succeeds, it connects the calling thread to the service control manager and does not return until all running services in the process have terminated. The service control manager uses this connection to send control and service start requests to the main thread of the service process. The main thread acts as a dispatcher by invoking the appropriate Handler function to handle control requests, or by creating a new thread to execute the appropriate ServiceMain function when a new service is started.

The lpServiceStartTable parameter contains an entry for each service that can run in the calling process. Each entry specifies the ServiceMain function for that service. For SERVICE_WIN32_SHARE_PROCESS services, each entry must contain the name of a service. This name is the service name that was specified by the CreateService function when the service was installed. For SERVICE_WIN32_OWN_PROCESS services, the service name in the table entry is ignored.

If a service runs in its own process, the main thread of the service process should immediately call StartServiceCtrlDispatcher. All initialization tasks are done in the service's ServiceMain function when the service is started.

If multiple services share a process and some common process-wide initialization needs to be done before any ServiceMain function is called, the main thread can do the work before calling StartServiceCtrlDispatcher, as long as it takes less than 30 seconds. Otherwise, another thread must be created to do the process-wide initialization, while the main thread calls StartServiceCtrlDispatcher and becomes the service control dispatcher. Any service-specific initialization should still be done in the individual service main functions.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Services Overview, Service Functions, ControlService, Handler, RegisterServiceCtrlHandler, ServiceMain, SERVICE_TABLE_ENTRY


UnlockServiceDatabase

The UnlockServiceDatabase function unlocks a service control manager database by releasing the specified lock.

BOOL UnlockServiceDatabase(
  SC_LOCK ScLock   // service control manager database lock to be
                   // released
);

Parameters

ScLock
Specifies a lock obtained from a previous call to the LockServiceDatabase function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_INVALID_SERVICE_LOCK | The specified lock is invalid.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.

See Also

Services Overview, Service Functions, LockServiceDatabase, QueryServiceLockStatus


Service Structures

The following structures are used with services.

ENUM_SERVICE_STATUS
QUERY_SERVICE_CONFIG
QUERY_SERVICE_LOCK_STATUS
SC_ACTION
SERVICE_DESCRIPTION
SERVICE_FAILURE_ACTIONS
SERVICE_STATUS
SERVICE_TABLE_ENTRY


ENUM_SERVICE_STATUS

The ENUM_SERVICE_STATUS structure is used by the EnumDependentServices and EnumServicesStatus functions to return the name of a service in a service control manager database and to return information about that service.

typedef struct _ENUM_SERVICE_STATUS { // ess
    LPTSTR lpServiceName;
    LPTSTR lpDisplayName;
    SERVICE_STATUS ServiceStatus;
} ENUM_SERVICE_STATUS, *LPENUM_SERVICE_STATUS;

Members

lpServiceName
Pointer to a null-terminated string that names a service in a service control manager database. The maximum string length is 256 characters. The service control manager database preserves the case of the characters, but service name comparisons are always case insensitive. A slash (/), backslash (\), comma, and space are invalid service name characters.
lpDisplayName
Pointer to a null-terminated string that is to be used by user interface programs to identify the service. This string has a maximum length of 256 characters. The name is case-preserved in the Service Control Manager. Display name comparisons are always case-insensitive.
ServiceStatus
Specifies a SERVICE_STATUS structure in which status information about the lpServiceName service is returned.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Services Overview, Service Structures, EnumDependentServices, EnumServicesStatus, SERVICE_STATUS


QUERY_SERVICE_CONFIG

The QUERY_SERVICE_CONFIG structure is used by the QueryServiceConfig function to return configuration information about an installed service.

typedef struct _QUERY_SERVICE_CONFIG { // qsc
    DWORD dwServiceType;
    DWORD dwStartType;
    DWORD dwErrorControl;
    LPTSTR lpBinaryPathName;
    LPTSTR lpLoadOrderGroup;
    DWORD dwTagId;
    LPTSTR lpDependencies;
    LPTSTR lpServiceStartName;
    LPTSTR lpDisplayName;
} QUERY_SERVICE_CONFIG, LPQUERY_SERVICE_CONFIG;

Members

dwServiceType
The value returned includes one of the following service type flags to indicate the type of service. In addition, for a SERVICE_WIN32 service, the SERVICE_INTERACTIVE_PROCESS flag might be set, indicating that the service process can interact with the desktop.
Value | Meaning
SERVICE_WIN32_OWN_PROCESS | A service type flag that indicates a Win32 service that runs in its own process.
SERVICE_WIN32_SHARE_PROCESS | A service type flag that indicates a Win32 service that shares a process with other services.
SERVICE_KERNEL_DRIVER | A service type flag that indicates a device driver.
SERVICE_FILE_SYSTEM_DRIVER | A service type flag that indicates a file system driver.
SERVICE_INTERACTIVE_PROCESS | A flag that indicates a Win32 service process that can interact with the desktop.

dwStartType
Specifies when to start the service. One of the following values is specified:
Value | Meaning
SERVICE_BOOT_START | Specifies a device driver started by the system loader. This value is valid only if the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER.
SERVICE_SYSTEM_START | Specifies a device driver started by the IoInitSystem function. This value is valid only if the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER.
SERVICE_AUTO_START | Specifies a device driver or Win32 service started by the service control manager automatically during system startup.
SERVICE_DEMAND_START | Specifies a device driver or Win32 service started by the service control manager when a process calls the StartService function.
SERVICE_DISABLED | Specifies a device driver or Win32 service that can no longer be started.

dwErrorControl
Specifies the severity of the error if this service fails to start during startup, and determines the action taken by the startup program if failure occurs. One of the following values can be specified:
Value Meaning
SERVICE_ERROR_IGNORE
The startup (boot) program logs the error but continues the startup operation.
SERVICE_ERROR_NORMAL
The startup program logs the error and displays a message box pop-up but continues the startup operation.
SERVICE_ERROR_SEVERE
The startup program logs the error. If the last-known good configuration is being started, the startup operation continues. Otherwise, the system is restarted with the last-known-good configuration.
SERVICE_ERROR_CRITICAL
The startup program logs the error, if possible. If the last-known good configuration is being started, the startup operation fails. Otherwise, the system is restarted with the last-known good configuration.

lpBinaryPathName
Pointer to a null-terminated string that contains the fully qualified path to the service binary file.
lpLoadOrderGroup
Pointer to a null-terminated string that names the load ordering group of which this service is a member. If the pointer is NULL or if it points to an empty string, the service does not belong to a group. The registry has a list of load ordering groups located at:

HKEY_LOCAL_MACHINE\System
\CurrentControlSet\Control\ServiceGroupOrder.

The startup program uses this list to load groups of services in a specified order with respect to the other groups in the list. You can place a service in a group so that another service can depend on the group.

The order in which a service starts is determined by the following criteria:

  1. The order of groups in the registry's load-ordering group list. Services in groups in the load-ordering group list are started first, followed by services in groups not in the load-ordering group list and then services that do not belong to a group.
  2. The service's dependencies listed in the lpszDependencies parameter and the dependencies of other services dependent on the service.
dwTagId
Specifies a unique tag value for this service in the group specified by the lpLoadOrderGroup parameter. A value of zero indicates that the service has not been assigned a tag. You can use a tag for ordering service startup within a load order group by specifying a tag order vector in the registry located at:

HKEY_LOCAL_MACHINE\System\CurrentControlSet
\Control\GroupOrderList

Tags are only evaluated for SERVICE_KERNEL_DRIVER and SERVICE_FILE_SYSTEM_DRIVER type services that have SERVICE_BOOT_START or SERVICE_SYSTEM_START start types.

lpDependencies
Pointer to an array of null-separated names of services or load ordering groups that must start before this service. The array is doubly null-terminated. If the pointer is NULL or if it points to an empty string, the service has no dependencies. If a group name is specified, it must be prefixed by the SC_GROUP_IDENTIFIER (defined in the WINSVC.H file) character to differentiate it from a service name, because services and service groups share the same name space. Dependency on a service means that this service can only run if the service it depends on is running. Dependency on a group means that this service can run if at least one member of the group is running after an attempt to start all members of the group.
lpServiceStartName
Pointer to a null-terminated string. If the service type is SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS, this name is the account name in the form of "DomainName\Username", which the service process will be logged on as when it runs. If the account belongs to the built-in domain, ".\Username" can be specified. If NULL is specified, the service will be logged on as the LocalSystem account.

If the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER, this name is the driver object name (that is, \FileSystem\Rdr or \Driver\Xns) which the input and output (I/O) system uses to load the device driver. If NULL is specified, the driver is run with a default object name created by the I/O system based on the service name.

lpDisplayName
Pointer to a null-terminated string that is to be used by user interface programs to identify the service. This string has a maximum length of 256 characters. The name is case-preserved in the service control manager. Display name comparisons are always case-insensitive.

Remarks

The configuration information for a service is initially specified when the service is created by a call to the CreateService function. The information can be modified by calling the ChangeServiceConfig function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Services Overview, Service Structures, ChangeServiceConfig, CreateService, QueryServiceConfig, StartService


QUERY_SERVICE_LOCK_STATUS

The QUERY_SERVICE_LOCK_STATUS structure is used by the QueryServiceLockStatus function to return information about the lock status of a service control manager database.

typedef struct _QUERY_SERVICE_LOCK_STATUS { // qsls
    DWORD fIsLocked;
    LPTSTR lpLockOwner;
    DWORD dwLockDuration;
} QUERY_SERVICE_LOCK_STATUS, * LPQUERY_SERVICE_LOCK_STATUS ;

Members

fIsLocked
Specifies whether the database is locked. If this member is nonzero, the database is locked. If it is zero, the database is unlocked.
lpLockOwner
Pointer to a null-terminated string containing the name of the user who acquired the lock.
dwLockDuration
Specifies the time, in seconds, since the lock was first acquired.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Services Overview, Service Structures, QueryServiceLockStatus


SC_ACTION

[This is preliminary documentation and subject to change.]

The SC_ACTION structure represents an action that the service control manager can perform.

typedef struct _SC_ACTION {
    SC_ACTION_TYPE  Type;
    DWORD           Delay;
} SC_ACTION, *LPSC_ACTION;

Members

Type
Specifies the action to be performed. This member can be one of the following values.
Value | Meaning
SC_ACTION_NONE | No action.
SC_ACTION_REBOOT | Reboot the computer.
SC_ACTION_RESTART | Restart the service.
SC_ACTION_RUN_COMMAND | Run a command.

Delay
Specifies the time to wait before performing the specified action, in milliseconds.

Remarks

This structure is used by the ChangeServiceConfig2 and QueryServiceConfig2 functions, in the SERVICE_FAILURE_ACTIONS structure.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.

See Also

Services Overview, Service Structures, ChangeServiceConfig2, QueryServiceConfig2, SERVICE_FAILURE_ACTIONS


SERVICE_DESCRIPTION

[This is preliminary documentation and subject to change.]

The SERVICE_DESCRIPTION structure represents a service description.

typedef struct _SERVICE_DESCRIPTION {
    LPTSTR       lpDescription;
} SERVICE_DESCRIPTION, *LPSERVICE_DESCRIPTION;

Members

lpDescription
Pointer to a description of the service. The string is limited to 1024 bytes. If this value is NULL, the description remains unchanged. If this value is an empty string (""), the current description is deleted.

Remarks

A description of NULL indicates no service description exists. The service description is NULL when the service is created.

The description is simply a comment that explains the purpose of the service. You can set the description using the ChangeServiceConfig2 function. You can retrieve the description using the QueryServiceConfig2 function. The description is also displayed by the Services snap-in.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Services Overview, Service Structures, ChangeServiceConfig2, QueryServiceConfig2


SERVICE_FAILURE_ACTIONS

The SERVICE_FAILURE_ACTIONS structure represents the action the service controller should take on each failure of a service. A service is considered failed when it terminates without reporting a status of SERVICE_STOPPED to the service controller.

typedef struct _SERVICE_FAILURE_ACTIONS {
    DWORD       dwResetPeriod;
    LPTSTR       lpRebootMsg;
    LPTSTR       lpCommand;
    DWORD       cActions;
    SC_ACTION * lpsaActions;
} SERVICE_FAILURE_ACTIONS, *LPSERVICE_FAILURE_ACTIONS;

Members

dwResetPeriod
Indicates the length of time, in seconds, after which to reset the failure count to zero if there are no failures. Specify INFINITE to indicate that this value should never be reset.
lpRebootMsg
Message to broadcast to server users before rebooting in response to the SC_ACTION_REBOOT service controller action.

If this value is NULL, the reboot message is unchanged. If the value is an empty string (""), the reboot message is deleted and no message is broadcast.

lpCommand
Command line of the process for the CreateProcess function to execute in response to the SC_ACTION_RUN_COMMAND service controller action. This process runs under the same account as the service.

If this value is NULL, the command is unchanged. If the value is an empty string (""), the command is deleted and no program is run when the service fails.

cActions
Number of elements in the lpsaActions array.

If this value is 0, but lpsaActions is not NULL, the reset period and array of failure actions are deleted.

lpsaActions
Pointer to an array of SC_ACTION structures.

If this value is NULL, the cActions and dwResetPeriod members are ignored.

Remarks

The service control manager counts the number of times each service has failed since the system booted. The count is reset to 0 if the service has not failed for dwResetPeriod seconds. When the service fails for the Nth time, the service controller performs the action specified in element [N-1] of the lpsaActions array. If N is greater than cActions, the service controller repeats the last action in the array.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Services Overview, Service Structures, CreateProcess, SC_ACTION


SERVICE_STATUS

The SERVICE_STATUS structure contains information about a service. The ControlService, EnumDependentServices, EnumServicesStatus, and QueryServiceStatus functions use this structure to return information about a service. A service uses this structure in the SetServiceStatus function to report its current status to the service control manager.

typedef struct _SERVICE_STATUS { // ss
    DWORD dwServiceType;
    DWORD dwCurrentState;
    DWORD dwControlsAccepted;
    DWORD dwWin32ExitCode;
    DWORD dwServiceSpecificExitCode;
    DWORD dwCheckPoint;
    DWORD dwWaitHint;
} SERVICE_STATUS, *LPSERVICE_STATUS;

Members

dwServiceType
The value returned includes one of the following service type flags to indicate the type of service. In addition, for a SERVICE_WIN32 service, the SERVICE_INTERACTIVE_PROCESS flag might be set, indicating that the service process can interact with the desktop.
Value | Meaning
SERVICE_WIN32_OWN_PROCESS | A service type flag that indicates a Win32 service that runs in its own process.
SERVICE_WIN32_SHARE_PROCESS | A service type flag that indicates a Win32 service that shares a process with other services.
SERVICE_KERNEL_DRIVER | A service type flag that indicates a device driver.
SERVICE_FILE_SYSTEM_DRIVER | A service type flag that indicates a file system driver.
SERVICE_INTERACTIVE_PROCESS | A flag that indicates a Win32 service process that can interact with the desktop.

dwCurrentState
Indicates the current state of the service. One of the following values is specified:
Value | Meaning
SERVICE_STOPPED | The service is not running.
SERVICE_START_PENDING | The service is starting.
SERVICE_STOP_PENDING | The service is stopping.
SERVICE_RUNNING | The service is running.
SERVICE_CONTINUE_PENDING | The service continue is pending.
SERVICE_PAUSE_PENDING | The service pause is pending.
SERVICE_PAUSED | The service is paused.

dwControlsAccepted
Specifies the control codes that the service will accept and process. A user interface process can control a service by specifying a control command in the ControlService function. By default, all services accept the SERVICE_CONTROL_INTERROGATE value. Any or all of the following flags can be specified to enable the other control codes.
Value Meaning
SERVICE_ACCEPT_STOP
The service can be stopped. This enables the SERVICE_CONTROL_STOP value.
SERVICE_ACCEPT_PAUSE_CONTINUE
The service can be paused and continued. This enables the SERVICE_CONTROL_PAUSE and SERVICE_CONTROL_CONTINUE values.
SERVICE_ACCEPT_SHUTDOWN
The service is notified when system shutdown occurs. This enables the system to send a SERVICE_CONTROL_SHUTDOWN value to the service. The ControlService function cannot send this control code.

dwWin32ExitCode
Specifies an Win32 error code that the service uses to report an error that occurs when it is starting or stopping. To return an error code specific to the service, the service must set this value to ERROR_SERVICE_SPECIFIC_ERROR to indicate that the dwServiceSpecificExitCode member contains the error code. The service should set this value to NO_ERROR when it is running and on normal termination.
dwServiceSpecificExitCode
Specifies a service specific error code that the service returns when an error occurs while the service is starting or stopping. This value is ignored unless the dwWin32ExitCode member is set to ERROR_SERVICE_SPECIFIC_ERROR.
dwCheckPoint
Specifies a value that the service increments periodically to report its progress during a lengthy start, stop, pause, or continue operation. For example, the service should increment this value as it completes each step of its initialization when it is starting up. The user interface program that invoked the operation on the service uses this value to track the progress of the service during a lengthy operation. This value is not valid and should be zero when the service does not have a start, stop, pause, or continue operation pending.
dwWaitHint
Specifies an estimate of the amount of time, in milliseconds, that the service expects a pending start, stop, pause, or continue operation to take before the service makes its next call to the SetServiceStatus function with either an incremented dwCheckPoint value or a change in dwCurrentState. If the amount of time specified by dwWaitHint passes, and dwCheckPoint has not been incremented, or dwCurrentState has not changed, the service control manager or service control program can assume that an error has occurred.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.

See Also

Services Overview, Service Structures, ControlService, EnumDependentServices, EnumServicesStatus, QueryServiceStatus, SetServiceStatus


SERVICE_TABLE_ENTRY

The SERVICE_TABLE_ENTRY structure is used by the StartServiceCtrlDispatcher function to specify the ServiceMain function for a Win32 service that can run in the calling process.

typedef struct _SERVICE_TABLE_ENTRY { // ste
    LPTSTR lpServiceName;
    LPSERVICE_MAIN_FUNCTION lpServiceProc;
} SERVICE_TABLE_ENTRY, *LPSERVICE_TABLE_ENTRY;

Members

lpServiceName
Pointer to a null-terminated string that names a service that can run in this service process. This string is ignored if the service is installed in the service control manager database as a SERVICE_WIN32_OWN_PROCESS service type. For a SERVICE_WIN32_SHARE_PROCESS service process, this string names the service that uses the ServiceMain function pointed to by the lpServiceProc member.
lpServiceProc
Pointer to a ServiceMain function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Services Overview, Service Structures, ServiceMain, StartServiceCtrlDispatcher


PE Image Helper (ImageHlp)

This overview describes the function set provided by the IMAGEHLP DLL. The ImageHlp functions allow you to work with a portable executable (PE) image. PE images are produced by a compatible Win32 linker, such as the one provided by Microsoft Developer Studio.


About ImageHlp

The ImageHlp functions are supported by the Windows NT, Windows 95, and Windows 98 operating systems. They are used mostly by programming tools, application setup utilities, and other programs that need access to the data contained in a PE image.

The following topics describe PE images and the functionality provided by the ImageHlp functions.

  • PE Format
  • Symbol Files
  • ImageHlp Functions
  • ImageHlp Structures


PE Format

Win32-based executable (image) files are structured according to the Portable Executable (PE) format. For a description of this format, see the specification included on the Microsoft Developer Network (MSDN) Library.


Symbol Files

A symbol file contains the same debugging information that an executable file would contain. However, the information is stored in a file with a .DBG extension, rather than the executable file. Therefore, you can install only the symbol files you will need during debugging. This reduces the file size of the executable, saving load time and disk storage.

To create a .DBG file, build your executable file with debug information, then use the SplitSymbols function or the Rebase tool.

The operating system dynamic-link libraries (DLL) have associated symbol files. These files are not installed during installation. To install the system symbol files, create a directory on your hard disk, and copy the files from your system installation compact disc (CD). The symbol files are located in the SUPPORT\DEBUG\I386\SYMBOLS directory tree.


ImageHlp Functions

The ImageHlp function set contains six different classes of functions:

  • general
  • image modification
  • debugger
  • image access
  • symbol handler
  • image integrity

The descriptions of these functions assume that you are familiar with the PE format and its specification.


ImageHlp General Functions

ImageHlp provides the following general helper functions:

  • ImagehlpApiVersion
  • ImagehlpApiVersionEx
  • MakeSureDirectoryPathExists
  • SearchTreeForFile


ImagehlpApiVersion

The ImagehlpApiVersion function retrieves the information about the version of ImageHlp installed on the system.

LPAPI_VERSION ImagehlpApiVersion(VOID);

Parameters

This function has no parameters.

Return Values

The return value is a pointer to an API_VERSION structure.

Remarks

Use the information in the API_VERSION structure to determine if the version of ImageHlp installed on the system is compatible with the version of ImageHlp used by the application. Although the ImageHlp functions are backwards compatible, functions that are introduced in one version are obviously not available in earlier versions.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp General Functions, API_VERSION, ImagehlpApiVersionEx


ImagehlpApiVersionEx

The ImagehlpApiVersionEx function modifies the information about the version of ImageHlp used by the application.

LPAPI_VERSION ImagehlpApiVersionEx(
  IN OUT LPAPI_VERSION AppVersion
);

Parameters

AppVersion
Pointer to an API_VERSION structure. This structure should contain valid ImageHlp version information for your application.

Return Values

The return value is a pointer to an API_VERSION structure.

Remarks

Use the ImagehlpApiVersionEx function to indicate the version of ImageHlp with which the application was built. ImageHlp uses this information to ensure compatibility. For example, consider walking through kernel-mode callback stack frames (which exist in Windows NT 4.0, where User and GDI exist in kernel mode). If you call ImagehlpApiVersionEx to set the Revision member to version 4 or later, the StackWalk function will continue through a callback stack frame. Otherwise, if you set Revision to a version earlier than 4, StackWalk will stop at the kernel transition.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp General Functions, API_VERSION, ImagehlpApiVersion


MakeSureDirectoryPathExists

The MakeSureDirectoryPathExists function creates all the directories in the specified DirPath, beginning with the root.

BOOL MakeSureDirectoryPathExists(
  IN LPSTR DirPath
);

Parameters

DirPath
Pointer to a null-terminated string that specifies a valid path name. If the final component of the path is a directory, not a filename, the string must end with a backslash (\) character.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

Each directory specified is created, if it does not already exist. If only some of the directories are created, the function will return FALSE.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp General Functions


SearchTreeForFile

The SearchTreeForFile function is used to search a directory tree for a specified file.

BOOL SearchTreeForFile(
  IN LPSTR RootPath,
  IN LPSTR InputPathName,
  OUT LPSTR OutputPathBuffer
);

Parameters

RootPath
Pointer to a null-terminated string that specifies the path where the function should begin searching for the file.
InputPathName
Pointer to a null-terminated string that specifies the file for which the function will search. You can use a partial path.
OutputPathBuffer
Pointer to a buffer that receives the full path to the file that is found. This string is not modified if the return value is FALSE.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The function searches for the file specified by the InputPathName parameter beginning at the path specified in the RootPath parameter. The maximum path depth that is allowed in the RootPath is 32 directories. When the function finds the file in the directory tree, it places the full path to the file in the buffer specified by the OutputPathBuffer parameter. The underlying file system specifies the order of the subdirectory search.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp General Functions


ImageHlp Image Modification Functions

The image modification functions allow you to change the executable image. They are mostly for use by development tools and install programs. They can be used to bind an image, compute its checksum (which is important for ensuring image integrity), change its load address, and produce symbol files.

The following are the image modification functions.

  • BindImage
  • BindImageEx
  • CheckSumMappedFile
  • MapFileAndCheckSum
  • ReBaseImage
  • RemovePrivateCvSymbolic
  • RemoveRelocations
  • SplitSymbols
  • UpdateDebugInfoFile
  • UpdateDebugInfoFileEx


BindImage

The BindImage function computes the virtual address of each imported function.

BOOL BindImage(
  IN LPSTR ImageName,
  IN LPSTR DllPath,
  IN LPSTR SymbolPath
);

Parameters

ImageName
Pointer to a null-terminated string that specifies the name of the file to be bound. This value can be a filename, a partial path, or a full path.
DllPath
Pointer to a null-terminated string that specifies the root of the search path to use if the file specified by the ImageName parameter cannot be opened.
SymbolPath
Pointer to a null-terminated string that specifies the root of the path to search for the file's corresponding symbol file.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

A call to BindImage is equivalent to the following call:

BindImageEx( 0, ImageName, DllPath, SymbolPath, NULL );

For more information, see BindImageEx .

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Image Modification Functions, BindImageEx


BindImageEx

The BindImageEx function computes the virtual address of each function that is imported.

BOOL BindImageEx(
  IN DWORD Flags,
  IN LPSTR ImageName,
  IN LPSTR DllPath,
  IN LPSTR SymbolPath,
  IN PIMAGEHLP_STATUS_ROUTINE StatusRoutine
);

Parameters

Flags
Specifies the behavior of the function. This parameter can be a combination of the following values:
Value | Meaning
BIND_NO_BOUND_IMPORTS | Do not generate a new import address table.
BIND_NO_UPDATE | Do not make any changes to the file.
BIND_ALL_IMAGES | Bind all images in the call tree for this file.

ImageName
Pointer to a null-terminated string that specifies the name of the file to be bound. This value can be a filename, a partial path, or a full path.
DllPath
Pointer to a null-terminated string that specifies the root of the search path to use if the file specified by the ImageName parameter cannot be opened.
SymbolPath
Pointer to a null-terminated string that specifies the root of the path to search for the file's corresponding symbol file.
StatusRoutine
Pointer to a status routine. The status routine is called during the progress of the image binding. For more information, see PIMAGEHLP_STATUS_ROUTINE.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The process of binding an image consists of computing the virtual address of each imported function. The computed virtual address is then saved in the importing image's Import Address Table (IAT). As a result, the image is loaded much faster, particularly if it uses many DLLs, because the system loader does not have to computer the address of each imported function.

If a corresponding symbol file can be located, its time stamp and checksum are updated.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Image Modification Functions, PIMAGEHLP_STATUS_ROUTINE


PIMAGEHLP_STATUS_ROUTINE

The PIMAGEHLP_STATUS_ROUTINE function is an application-defined callback function used with the BindImageEx function. The status routine is called during the process of the image binding.

The PIMAGEHLP_STATUS_ROUTINE type defines a pointer to this callback function. The application can define the function name.

typedef BOOL (CALLBACK *PIMAGEHLP_STATUS_ROUTINE)(
  IMAGEHLP_STATUS_REASON Reason,
  LPSTR ImageName,
  LPSTR DllName,
  ULONG Va,
  ULONG Parameter
);

Parameters

Reason
Specifies the current status of the bind operation. This parameter can be one of the following values.
Value Meaning
BindOutOfMemory
BindRvaToVaFailed
BindNoRoomInImage
BindImportModuleFailed
BindImportProcedureFailed
BindImportModule
BindImportProcedure
BindForwarder
BindForwarderNOT
BindImageModified
BindExpandFileHeaders
BindImageComplete
BindMismatchedSymbols
BindSymbolsNotUpdated

ImageName
Pointer to a null-terminated string that specifies the name of the file to be bound. This value can be a filename, a partial path, or a full path.
DllName
Pointer to a null-terminated string that specifies the name of the DLL.
Va
Specifies the computed virtual address.
Parameter
Specifies additional status information. This value depends on the value of the Reason parameter.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Image Modification Functions, BindImageEx


CheckSumMappedFile

The CheckSumMappedFile function computes the checksum of the specified image file.

PIMAGE_NT_HEADERS CheckSumMappedFile(
  IN LPVOID BaseAddress,
  IN DWORD FileLength,
  OUT LPDWORD HeaderSum,
  OUT LPDWORD CheckSum
);

Parameters

BaseAddress
Specifies the base address of the mapped file. This value is obtained by calling the MapViewOfFile function.
FileLength
Specifies the length of the file, in bytes.
HeaderSum
Pointer to a variable that receives the original checksum from the image file, or zero if there is an error.
CheckSum
Pointer to the variable that receives the computed checksum.

Return Values

If the function succeeds, the return value is a pointer to the IMAGE_NT_HEADERS structure contained in the mapped image.

If the function fails, the return value is NULL. To retrieve extended error information, call GetLastError.

Remarks

The CheckSumMappedFile function computes a new checksum for the file and returns it in the CheckSum parameter. This function is used by any application that creates or modifies an executable image. Checksums are required for Windows NT kernel mode drivers and some system DLLs. The linker computes the original checksum at link time, if you use the appropriate linker switch. For more details, see your linker documentation.

It is recommended that all images have valid checksums. It is the caller's responsibility to place the newly computed checksum into the mapped image and update the on-disk image of the file.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Image Modification Functions, MapFileAndCheckSum, MapViewOfFile


MapFileAndCheckSum

The MapFileAndCheckSum function computes the checksum of the specified file.

ULONG MapFileAndCheckSum(
  IN LPTSTR Filename,
  OUT LPDWORD HeaderSum,
  OUT LPDWORD CheckSum
);

Parameters

Filename
Pointer to a null-terminated string that specifies the filename of the file for which the checksum is to be computed.
HeaderSum
Pointer to a variable that receives the original checksum from the image file, or zero if there is an error.
CheckSum
Pointer to the variable that receives the computed checksum.

Return Values

If the function succeeds, the return value is CHECKSUM_SUCCESS.

If the function fails, the return value is one of the following:

Value | Meaning
CHECKSUM_OPEN_FAILURE | Could not open the file.
CHECKSUM_MAP_FAILURE | Could not create the file mapping for the file.
CHECKSUM_MAPVIEW_FAILURE | Could not map a view of the file.
CHECKSUM_UNICODE_FAILURE | Could not convert the filename to UNICODE.

Remarks

The MapFileAndCheckSum function computes a new checksum for the file and returns it in the CheckSum parameter. This function is used by any application that creates or modifies an executable image. Checksums are required for Windows NT kernel mode drivers and some system DLLs. The linker computes the original checksum at link time, if you use the appropriate linker switch. For more details, see your linker documentation.

It is recommended that all images have valid checksums. It is the caller's responsibility to place the newly computed checksum into the mapped image and update the on-disk image of the file.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Image Modification Functions, CheckSumMappedFile


ReBaseImage

The ReBaseImage function is used to change the load address for the specified image, which reduces the required load time for a DLL.

Alternatively, you can use the Rebase tool.

BOOL ReBaseImage(
  IN LPSTR CurrentImageName,
  IN LPSTR SymbolPath,
  IN BOOL fReBase,
  IN BOOL fRebaseSysfileOk,
  IN BOOL fGoingDown,
  IN DWORD CheckImageSize,
  OUT LPDWORD OldImageSize,
  OUT LPDWORD OldImageBase,
  OUT LPDWORD NewImageSize,
  IN OUT LPDWORD NewImageBase,
  IN DWORD TimeStamp
);

Parameters

CurrentImageName
Pointer to a null-terminated string that specifies filename of the file to be rebased.
SymbolPath
Pointer to a null-terminated string that specifies the path used to find the corresponding symbol file.
fReBase
Specifies whether the image is to be rebased. If this value is TRUE, the image is rebased. Otherwise, the image is not rebased.
fRebaseSysfileOk
Specifies whether a system image is to be rebased. If this value is TRUE, the system image is rebased. Otherwise, the system image is not rebased.
fGoingDown
Specifies whether the image should be rebased below the given base. If this value is TRUE, the image can be rebased below the given base; otherwise, it cannot.
CheckImageSize
Specifies the maximum size that the image can grow to, or zero if there is no limit.
OldImageSize
Pointer to a variable that receives the original image size.
OldImageBase
Pointer to a variable that receives the original image base.
NewImageSize
Pointer to a variable that receives the new image size after the rebase operation.
NewImageBase
Pointer to a variable that receives the new image base after the rebase operation.
TimeStamp
Specifies the new time stamp for the image. The value must be represented in the number of seconds elapsed since midnight (00:00:00), January 1, 1970, Universal Coordinated Time, according to the system clock.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The ReBaseImage function changes the desired load address for the specified image. This operation involves reading the entire image and updating all fixups, debug information, checksum, and time stamp values. You can rebase an image to reduce the required load time for its DLLs. If an application can rely on a DLL being loaded at the desired load address, then the system loader does not have to relocate the image. The image is simply loaded into the application's virtual address space and the DllMain function is called, if one is present.

A well-behaved application has its DLLs rebased so they each fall within a unique range of the virtual address space. The system DLLs are currently based in memory from 0x70000000 to 0x78000000 (0x68000000 to 0x78000000 on MIPS). Therefore, you should base your DLLs from 0x60000000 to 0x68000000. One possible scheme is to choose a base address based on the first letter of the DLL name, as shown in the following table.

First Letter | Base Address
A - C | 0x60000000
D - F | 0x61000000
G - I | 0x62000000
J - L | 0x63000000
M - O | 0x64000000
P - R | 0x65000000
S - U | 0x66000000
V - X | 0x67000000
Y - Z | 0x68000000

By using these suggestions with the ReBaseImage function, each DLL in an application can be assigned a unique base address. This process can be part of the build process or part of the final release procedure for the application.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Image Modification Functions, DllMain


RemovePrivateCvSymbolic

The RemovePrivateCvSymbolic function removes all but public information from the CodeView debug information.

BOOL RemovePrivateCvSymbolic(
  IN PCHAR DebugData,
  OUT PCHAR *NewDebugData,
  OUT LPDWORD NewDebugSize
);

Parameters

DebugData
Pointer to the CodeView debug data. This data can be found by mapping the image and searching the debug directories for debug type IMAGE_DEBUG_TYPE_CODEVIEW.
NewDebugData
Pointer to a buffer that receives the public CodeView debug information.
NewDebugSize
Pointer to a variable that receives the size of the public CodeView debug information.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The RemovePrivateCvSymbolic function removes all but public information from the CodeView debug information. Therefore, you can ship the debug symbols for an image without disclosing your data structures or other source information. The user can only get a stack trace, place breakpoints on functions, and dump memory. All but the following CodeView sections are discarded:

  • sstSegMap
  • sstSegName
  • sstOffsetMap16
  • sstOffsetMap32
  • sstModule
  • sstPublic
  • sstPublicSym
  • sstGlobalPub

It is the responsibility of the caller to free the memory pointed to by the NewDebugData parameter when he is finished.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Image Modification Functions


RemoveRelocations

The RemoveRelocations function strips relocation information from an executable image.

VOID RemoveRelocations(
  IN LPSTR ImageName
);

Parameters

ImageName
Pointer to a null-terminated string that specifies the name of the image from which to strip relocations. You must use a fully qualified path.

Return Values

None.

Remarks

The RemoveRelocations function strips relocation information from an executable image. This function exists so an image can be rebased (using the ReBaseImage function) after building and then have the relocations stripped so it will always load at that preferred load address. However, it is not recommended that you do this, because the image will not load if its preferred load address is occupied.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Image Modification Functions, ReBaseImage


SplitSymbols

The SplitSymbols function strips symbols from the specified image.

BOOL SplitSymbols(
  IN LPSTR ImageName,
  IN LPSTR SymbolsPath,
  OUT LPSTR SymbolFilePath,
  IN DWORD Flags
);

Parameters

ImageName
Pointer to a null-terminated string that specifies the name of the image from which to split symbols.
SymbolsPath
Pointer to a null-terminated string that specifies a subdirectory for storing symbols. This parameter is optional.
SymbolFilePath
Pointer to a null-terminated string that specifies the name of the generated symbol file. This file typically has a .DBG extension.
Flags
Specifies the information to be split from the image. This parameter can be zero or a combination of the following values:
Value | Meaning
SPLITSYM_EXTRACT_ALL | Usually, an image with the symbols split off will still contain a MISC debug directory with the name of the symbol file. Therefore, the debugger can still find the symbols. Using this flag removes this link. The end result is similar to using the -debug:none switch on the Microsoft linker.
SPLITSYM_REMOVE_PRIVATE | This strips off the private CodeView symbolic information when generating the symbol file. It does this by making a call to the RemovePrivateCvSymbolic function.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The SplitSymbols function should be used when stripping symbols from an image. It will create a symbol file that all Win32-compatible debuggers understand. The format is defined in WINNT.H and consists of an image header (IMAGE_SEPARATE_DEBUG_HEADER), followed by the array of section headers, the exception information (on RISC only) or FPO information (on X86 only), and all debug symbolic information from the image.

If the SymbolsPath parameter is NULL, the symbol file is stored in the directory where the image exists. Otherwise, it is stored in the subdirectory below SymbolsPath that matches the extension of the image. Using this method reduces the chances of symbol file collision. For example, the symbols for myapp.exe will be in the SymbolsPath\exe directory and the symbols for myapp.dll will be in the SymbolsPath\dll directory.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Image Modification Functions, RemovePrivateCvSymbolic


UpdateDebugInfoFile

The UpdateDebugInfoFile function takes the specified information and updates the corresponding fields in the symbol file.

BOOL UpdateDebugInfoFile(
  IN LPSTR ImageFileName,
  IN LPSTR SymbolPath,
  OUT LPSTR DebugFilePath,
  IN OUT PIMAGE_NT_HEADERS NtHeaders
);

Parameters

ImageFileName
Pointer to a null-terminated string that specifies the name of the image that is now out of date with respect to its symbol file.
SymbolPath
Pointer to a null-terminated string that specifies the path in which to look for the symbol file.
DebugFilePath
Pointer to a buffer that receives the filename of the symbol file that was updated.
NtHeaders
Pointer to an IMAGE_NT_HEADERS structure that specifies the new NT header information.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The UpdateDebugInfoFile function takes the information stored in the IMAGE_NT_HEADERS structure and updates the corresponding fields in the symbol file. Any time an image file is modified, this function should be called to keep the numbers in sync. Specifically, whenever an image checksum changes, the symbol file should be updated to match.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Image Modification Functions, UpdateDebugInfoFileEx


UpdateDebugInfoFileEx

The UpdateDebugInfoFileEx function takes the information stored in NtHeaders and updates the corresponding fields in the symbol file.

BOOL UpdateDebugInfoFileEx(
  IN LPSTR ImageFileName,
  IN LPSTR SymbolPath,
  OUT LPSTR DebugFilePath,
  IN OUT PIMAGE_NT_HEADERS NtHeaders,
  IN DWORD OldChecksum
);

Parameters

ImageFIleName
Pointer to a null-terminated string that specifies the name of the image that is now out of date with respect to its symbol file.
SymbolPath
Pointer to a null-terminated string that specifies the path in which to look for the symbol file.
DebugFilePath
The symbol file that was updated.
NtHeaders
Pointer to an IMAGE_NT_HEADERS structure that specifies the new NT header information.
OldChecksum
Specifies the original checksum value. If this value does not match the checksum that is present in the mapped image, the flags in the symbol file contain IMAGE_SEPARATE_DEBUG_MISMATCH and the last error value is set to ERROR_INVALID_DATA.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

Remarks

The UpdateDebugInfoFileEx function takes the information stored in the IMAGE_NT_HEADERS structure and updates the corresponding fields in the symbol file. Any time an image file is modified, this function should be called to keep the numbers in sync. Specifically, whenever an image checksum changes, the symbol file should be updated to match.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Image Modification Functions


ImageHlp Debugger Functions

The debugging service functions are the ImageHlp functions most suited for use by a debugger or the debugging code in an application. These functions can be used in concert with the symbol handler functions for easier use. The StackWalk function, for example, is used by the memory allocators of several applications to best track memory leaks. The functions for finding and mapping debug information can be used when the ImageHlp symbol handler functions are not needed.

  • StackWalk
  • FindDebugInfoFile
  • FindExecutableImage
  • MapDebugInformation
  • UnmapDebugInformation
  • UnDecorateSymbolName


StackWalk

The StackWalk function provides a portable method for obtaining a stack trace.

BOOL StackWalk(
  IN DWORD MachineType,
  IN HANDLE hProcess,
  IN HANDLE hThread,
  IN OUT LPSTACKFRAME StackFrame,
  IN OUT LPVOID ContextRecord,
  IN PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
  IN PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
  IN PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
  IN PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
);

Parameters

MachineType
Specifies the architecture type of the machine for which the stack trace is generated. This parameter can be one of the following values:
Value | Meaning
IMAGE_FILE_MACHINE_I386 | Intel
IMAGE_FILE_MACHINE_R4000 | MIPS
IMAGE_FILE_MACHINE_R10000 | MIPS
IMAGE_FILE_MACHINE_ALPHA | DEC Alpha
IMAGE_FILE_MACHINE_POWERPC | IBM PowerPC

hProcess
Handle to the process for which the stack trace is generated. If the caller supplies a valid callback pointer for the ReadMemoryRoutine parameter, then this value does not have to be a valid process handle. It can be a token that is unique and consistently the same for all calls to the StackWalk function. If the ImageHlp symbol handler is used with StackWalk, use the same process handles for the calls to each function.
hThread
Handle to the thread for which the stack trace is generated. If the caller supplies a valid callback pointer for the ReadMemoryRoutine parameter, then this value does not have to be a valid thread handle. It can be a token that is unique and consistently the same for all calls to the StackWalk function.
StackFrame
Pointer to a STACKFRAME structure. This structure is filled with information for the next frame, if the function call succeeds.
ContextRecord
Pointer to a CONTEXT structure. This parameter is required only when the MachineType parameter is not IMAGE_FILE_MACHINE_I386.
ReadMemoryRoutine
Pointer to a callback routine that provides memory read services. When the StackWalk function needs to read memory from the process's address space, this callback is used. If NULL is passed, then the ReadProcessMemory function is used. In this case, the hProcess parameter must be a valid process handle.
FunctionTableAccessRoutine
Pointer to a callback routine that provides access to the run-time function table for the process. For RISC machines, this function accesses the pdata table, while on X86 machines this function accesses the fpo table. This parameter is required because the StackWalk function does not have access to the process's run-time function table.

The symbol handler in ImageHlp provides functions that load and access the run-time table. If these functions are used, then SymFunctionTableAccess can be passed as a valid parameter.

GetModuleBaseRoutine
Pointer to a callback routine that provides a module base for any given virtual address. This parameter is required. The symbol handler in ImageHlp provides functions that load and maintain module information. If these functions are used, then SymGetModuleBase can be passed as a valid parameter.
TranslateAddress
Pointer to a callback routine that provides address translation for 16-bit addresses. Most, if not all, callers of StackWalk can safely pass NULL for this parameter.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The StackWalk function provides a portable method for obtaining a stack trace. This function is used by all Microsoft debuggers and tools that require stack trace facilities. Using the StackWalk function is recommended over writing your own function because of all the complexities associated with stack walking on Win32 platforms. In addition, there are compiler options that cause the stack to appear differently, depending on how the module is compiled. By using this function, your application has a portable stack trace that continues to work as the compiler and operating system change.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Debugger Functions, CONTEXT, STACKFRAME


FindDebugInfoFile

The FindDebugInfoFile function locates a symbol file.

HANDLE FindDebugInfoFile(
  IN LPSTR FileName,
  IN LPSTR SymbolPath,
  OUT LPSTR DebugFilePath
);

Parameters

FileName
Pointer to a null-terminated string that specifies the name of the symbol file that is desired. You can use a partial path.
SymbolPath
Pointer to a null-terminated string that specifies the path where symbol files are located. This can be multiple paths, with each separated by a semicolon (;).
DebugFilePath
The full path of the symbol file that is found.

Return Values

If the function succeeds, the return value is an open handle to the debug file.

If the function fails, the return value is NULL. To retrieve extended error information, call GetLastError.

Remarks

The FindDebugInfoFile function is used to locate a symbol file. This function is provided so symbol files can be located in several different directories through a single function call. The SymbolPath parameter can contain multiple paths, with each separated by a semicolon (;). When multiple paths are specified, each directory tree is searched for the symbol file. When the file is located, the search stops. Thus, be sure to specify SymbolPath with the paths in the correct order.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Debugger Functions


FindExecutableImage

The FindExecutableImage function locates an executable image file.

HANDLE FindExecutableImage(
  IN LPSTR FileName,
  IN LPSTR SymbolPath,
  OUT LPSTR ImageFilePath
);

Parameters

FileName
Pointer to a null-terminated string that specifies the name of the executable image file. You can use a partial path.
SymbolPath
Pointer to a null-terminated string that specifies the path where symbol files are located. This can be multiple paths, with each separated by a semicolon (;).
ImageFilePath
Pointer to a null-terminated string that receives the full path of the executable image file that is located.

Return Values

If the function succeeds, the return value is an open handle to the executable image file.

If the function fails, the return value is NULL. To retrieve extended error information, call GetLastError.

Remarks

The FindExecutableImage function is used to locate an executable image file. This function is provided so executable image files can be located in several different directories through a single function call. The SymbolPath parameter can contain multiple paths, with each separated by a semicolon (;). When multiple paths are specified, each directory tree is searched for the executable image file. When the file is located, the search stops. Thus, be sure to specify SymbolPath with the paths in the correct order.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Debugger Functions


MapDebugInformation

The MapDebugInformation function gains access to the debug information for an image.

PIMAGE_DEBUG_INFORMATION MapDebugInformation(
  IN HANDLE FileHandle,
  IN LPSTR FileName,
  IN LPSTR SymbolPath,
  IN DWORD ImageBase
);

Parameters

FileHandle
Handle to an open executable image, a symbol file, or NULL.
FileName
Pointer to a null-terminated string that specifies the name of an executable image file, symbol file, or NULL.
SymbolPath
Pointer to a null-terminated string that specifies the path where symbol files are located. The path can be multiple paths, each separated by a semicolon (;).
ImageBase
Specifies the base address for the image or zero.

Return Values

If the function succeeds, the return value is a pointer to an IMAGE_DEBUG_INFORMATION structure.

If the function fails, the return value is NULL. To retrieve extended error information, call GetLastError.

Remarks

The MapDebugInformation function is used to gain access to an image's debug information. The debug information is extracted from the image or the symbol file and placed into the IMAGE_DEBUG_INFORMATION structure. This structure is allocated by ImageHlp and must be deallocated by using the UnmapDebugInformation function. The memory for the structure is not in the process's default heap, so attempts to free it with a memory deallocation routine will fail.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Debugger Functions, IMAGE_DEBUG_INFORMATION, UnmapDebugInformation


UnmapDebugInformation

The UnmapDebugInformation function deallocates the memory and resources allocated by a call to the MapDebugInformation function.

BOOL UnmapDebugInformation(
  IN PIMAGE_DEBUG_INFORMATION DebugInfo
);

Parameters

DebugInfo
Pointer to an IMAGE_DEBUG_INFORMATION structure that is returned from a call to the MapDebugInformation function.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The UnmapDebugInformation function is the counterpart to the MapDebugInformation function and must be used to deallocate the memory and resources allocated by a call to the MapDebugInformation function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Debugger Functions, IMAGE_DEBUG_INFORMATION, MapDebugInformation


UnDecorateSymbolName

The UnDecorateSymbolName function undecorates decorated C++ symbol names.

DWORD UnDecorateSymbolName(
  IN LPSTR DecoratedName,
  OUT LPSTR UnDecoratedName,
  IN DWORD UndecoratedLength,
  IN DWORD Flags
);

Parameters

DecoratedName
Pointer to a null-terminated string that specifies a decorated C++ symbol name. This name can be identified by the first character of the name, which is always a question mark (?).
UnDecoratedName
Pointer to a null-terminated string that specifies the buffer that receives the undecorated name.
UndecoratedLength
Specifies the length of the UnDecoratedName buffer.
Flags
Specifies how the decorated name is undecorated. This parameter can be zero or any combination of the following values:
Value | Description
UNDNAME_COMPLETE | Enable full undecoration.
UNDNAME_NO_LEADING_UNDERSCORES | Remove leading underscores from Microsoft keywords.
UNDNAME_NO_MS_KEYWORDS | Disable expansion of Microsoft keywords.
UNDNAME_NO_FUNCTION_RETURNS | Disable expansion of return types for primary declarations.
UNDNAME_NO_ALLOCATION_MODEL | Disable expansion of the declaration model.
UNDNAME_NO_ALLOCATION_LANGUAGE | Disable expansion of the declaration language specifier.
UNDNAME_NO_MS_THISTYPE | Disable expansion of Microsoft keywords on the this type for primary declaration.
UNDNAME_NO_CV_THISTYPE | Disable expansion of CodeView modifiers on the this type for primary declaration.
UNDNAME_NO_THISTYPE | Disable all modifiers on the this type.
UNDNAME_NO_ACCESS_SPECIFIERS | Disable expansion of access specifiers for members.
UNDNAME_NO_THROW_SIGNATURES | Disable expansion of throw-signatures for functions and pointers to functions.
UNDNAME_NO_MEMBER_TYPE | Disable expansion of the static or virtual attribute of members.
UNDNAME_NO_RETURN_UDT_MODEL | Disable expansion of Microsoft model for UDT returns.
UNDNAME_32_BIT_DECODE | Undecorate 32-bit decorated names.
UNDNAME_NAME_ONLY | Crack only the name for primary declaration. Returns [scope::]name. Does expand template parameters.
UNDNAME_NO_ARGUMENTS | Do not undecorate function arguments.
UNDNAME_NO_SPECIAL_SYMS | Do not undecorate special names, such as vtable, vcall, vector, metatype, and so on.

Return Values

If the function succeeds, the return value is the number of characters in the UnDecoratedName buffer, not including the NULL terminator.

If the function fails, the return value is zero. To retrieve extended error information, call GetLastError.

Remarks

If the function fails and returns zero, the content of the UnDecoratedName buffer is undetermined.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, ImageHlp Debugger Functions


Image Access

The image access functions get access to the data in an executable image. The functions provide high-level access to the base of images and very specific access to the most common parts of an image's data.

  • ImageDirectoryEntryToData
  • ImageLoad
  • ImageNtHeader
  • ImageRvaToSection
  • ImageRvaToVa
  • ImageUnload
  • MapAndLoad
  • UnMapAndLoad
  • GetTimestampForLoadedLibrary
  • GetImageConfigInformation
  • SetImageConfigInformation
  • GetImageUnusedHeaderBytes


ImageDirectoryEntryToData

The ImageDirectoryEntryToData function obtains access to image-specific data.

PVOID ImageDirectoryEntryToData(
  IN LPVOID Base,
  IN BOOLEAN MappedAsImage,
  IN USHORT DirectoryEntry,
  OUT PULONG Size
);

Parameters

Base
Specifies the base address of the image.
MappedAsImage
Specifies how the image is mapped. If this flag is TRUE, the image is mapped by the system loader. If the flag is FALSE, the file is mapped by a call to the MapViewOfFile function.
DirectoryEntry
Specifies the index number of the desired directory entry. The value must be one of the following:
Value | Meaning
IMAGE_DIRECTORY_ENTRY_EXPORT | Export directory
IMAGE_DIRECTORY_ENTRY_IMPORT | Import directory
IMAGE_DIRECTORY_ENTRY_RESOURCE | Resource directory
IMAGE_DIRECTORY_ENTRY_EXCEPTION | Exception directory
IMAGE_DIRECTORY_ENTRY_SECURITY | Security directory
IMAGE_DIRECTORY_ENTRY_BASERELOC | Base relocation table
IMAGE_DIRECTORY_ENTRY_DEBUG | Debug directory
IMAGE_DIRECTORY_ENTRY_COPYRIGHT
IMAGE_DIRECTORY_ENTRY_GLOBALPTR | RVA of global pointer
IMAGE_DIRECTORY_ENTRY_TLS | thread local storage directory
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG | Load configuration directory
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT | Bound import directory
IMAGE_DIRECTORY_ENTRY_IAT | Import address table

Size
Specifies the size of the desired directory entry's data.

Return Values

If the function succeeds, the return value is a pointer to the directory entry's data.

If the function fails, the return value is NULL. To retrieve extended error information, call GetLastError.

Remarks

The ImageDirectoryEntryToData function is used to obtain access to image-specific data.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Access, MapViewOfFile


ImageLoad

The ImageLoad function maintains a list of loaded DLLs.

PLOADED_IMAGE ImageLoad(
  IN LPSTR DllName,
  IN LPSTR DllPath
);

Parameters

DllName
Pointer to a null-terminated string that specifies the name of the image that is loaded.
DllPath
Pointer to a null-terminated string that specifies the path used to locate the image if the name provided cannot be found. If NULL is used, then the search path rules set forth in the SearchPath function apply.

Return Values

If the function succeeds, the return value is a pointer to a LOADED_IMAGE structure.

If the function fails, the return value is NULL. To retrieve extended error information, call GetLastError.

Remarks

The ImageLoad function is used to maintain a list of loaded DLLs. If the image has already been loaded, the prior LOADED_IMAGE is returned. Otherwise, the new image is added to the list.

The LOADED_IMAGE structure must be deallocated by the ImageUnload function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Access, ImageUnload, LOADED_IMAGE


ImageNtHeader

The ImageNtHeader function locates the IMAGE_NT_HEADERS structure in a PE image and returns a pointer to the data.

PIMAGE_NT_HEADERS ImageNtHeader(
  IN LPVOID ImageBase
);

Parameters

ImageBase
Specifies the base address of an image that is mapped into memory by a call to the MapViewOfFile function.

Return Values

If the function succeeds, the return value is a pointer to an IMAGE_NT_HEADERS structure.

If the function fails, the return value is NULL. To retrieve extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Access, MapViewOfFile


ImageRvaToSection

The ImageRvaToSection function locates a relative virtual address (RVA) within the image header of a file that is mapped as a file and returns a pointer to the section table entry for that virtual address.

PIMAGE_SECTION_HEADER ImageRvaToSection(
  IN PIMAGE_NT_HEADERS NtHeaders,
  IN LPVOID Base,
  IN DWORD Rva
);

Parameters

NtHeaders
Pointer to an IMAGE_NT_HEADERS structure. This structure can be obtained by calling the ImageNtHeader function.
Base
Specifies the base address of an image that is mapped into memory through a call to MapViewOfFile.
Rva
Specifies the relative virtual address to locate.

Return Values

If the function succeeds, the return value is a pointer to an IMAGE_SECTION_HEADER structure.

If the function fails, the return value is NULL. To retrieve extended error information, call GetLastError.

Remarks

The ImageRvaToSection function locates an RVA within the image header of a file that is mapped as a file and returns a pointer to the section table entry for that virtual address.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Access, ImageNtHeader, MapViewOfFile


ImageRvaToVa

The ImageRvaToVa function locates a relative virtual address (RVA) within the image header of a file that is mapped as a file and returns the virtual address of the corresponding byte in the file.

LPVOID ImageRvaToVa(
  IN PIMAGE_NT_HEADERS NtHeaders,
  IN LPVOID Base,
  IN DWORD Rva,
  IN OUT PIMAGE_SECTION_HEADER *LastRvaSection
);

Parameters

NtHeaders
Pointer to an IMAGE_NT_HEADERS structure. This structure can be obtained by calling the ImageNtHeader function.
Base
Specifies the base address of an image that is mapped into memory through a call to the MapViewOfFile function.
Rva
Specifies the relative virtual address to locate.
LastRvaSection
Pointer to an IMAGE_SECTION_HEADER structure that specifies the last RVA section. This is an optional parameter. When specified, it points to a variable that contains the last section value used for the specified image to translate an RVA to a VA.

Return Values

If the function succeeds, the return value is the virtual address in the mapped file.

If the function fails, the return value is NULL. To retrieve extended error information, call GetLastError.

Remarks

The ImageRvaToVa function locates an RVA within the image header of a file that is mapped as a file and returns the virtual address of the corresponding byte in the file.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Access, ImageNtHeader, MapViewOfFile


ImageUnload

The ImageUnload function is used to deallocate resources from a previous call to the ImageLoad function.

BOOL ImageUnload(
  IN PLOADED_IMAGE LoadedImage
);

Parameters

LoadedImage
Pointer to a LOADED_IMAGE structure that is returned from a call to the ImageLoad function.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Access, ImageLoad, LOADED_IMAGE


MapAndLoad

The MapAndLoad function maps an image and preloads data from the mapped file.

BOOL MapAndLoad(
  IN LPSTR ImageName,
  IN LPSTR DllPath,
  OUT PLOADED_IMAGE LoadedImage,
  IN BOOL DotDll,
  IN BOOL ReadOnly
);

Parameters

ImageName
Pointer to a null-terminated string that specifies the name of the image that is loaded.
DllPath
Pointer to a null-terminated string that specifies the path used to locate the image if the name provided cannot be found. If NULL is used, then the search path rules set forth in the SearchPath function apply.
LoadedImage
Pointer to a LOADED_IMAGE structure that receives information about the image after it is loaded.
DotDll
Specifies the default extension, if the image name does not contain a file extension. If the value is TRUE, a .DLL extension is used. If the value is FALSE, then an .EXE extension is used.
ReadOnly
Specifies the access mode. If this value is TRUE, the file is mapped for read-access only. If the value is FALSE, the file is mapped for read and write access.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The MapAndLoad function maps an image and preloads data from the mapped file. The corresponding function, UnMapAndLoad, must be used to deallocate all resources that are allocated by the MapAndLoad function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Access, LOADED_IMAGE, UnMapAndLoad


UnMapAndLoad

The UnMapAndLoad function is used to deallocate all resources that are allocated by a previous call to the MapAndLoad function.

BOOL UnMapAndLoad(
  IN PLOADED_IMAGE LoadedImage
);

Parameters

LoadedImage
Pointer to a LOADED_IMAGE structure. This structure is obtained through a call to the MapAndLoad function.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The UnMapAndLoad function must be used to deallocate all resources that are allocated by a previous call to MapAndLoad. This function also writes a new checksum value into the image before the file is closed. This ensures that if a file is changed, it can be successfully loaded by the system loader.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Access, LOADED_IMAGE, MapAndLoad


GetTimestampForLoadedLibrary

The GetTimestampForLoadedLibrary function returns the timestamp of a loaded image.

DWORD GetTimestampForLoadedLibrary(
  IN LPVOID ImageBase
);

Parameters

ImageBase
Specifies the base address of an image that is mapped into memory by a call to the MapViewOfFile function.

Return Values

If the function succeeds, the return value is the time stamp from the image.

If the function fails, the return value is zero. To retrieve extended error information, call GetLastError.

Remarks

The time stamp for an image indicates the date and time that the image was created by the linker. The value is represented in the number of seconds elapsed since midnight (00:00:00), January 1, 1970, Universal Coordinated Time, according to the system clock. The time stamp can be printed using the C run-time (CRT) function ctime.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Access, MapViewOfFile


GetImageConfigInformation

The GetImageConfigInformation function locates and returns the load configuration data of an image.

BOOL GetImageConfigInformation(
  IN PLOADED_IMAGE LoadedImage,
  OUT PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation
);

Parameters

LoadedImage
Pointer to a LOADED_IMAGE structure that is returned from a call to MapAndLoad or LoadImage.
ImageConfigInformation
Pointer to an IMAGE_LOAD_CONFIG_DIRECTORY structure.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The SetImageConfigInformation function locates and changes the load configuration data of an image.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Access, IMAGE_LOAD_CONFIG_DIRECTORY, LOADED_IMAGE, SetImageConfigInformation


SetImageConfigInformation

The SetImageConfigInformation function locates and changes the load configuration data of an image.

BOOL SetImageConfigInformation(
  IN PLOADED_IMAGE LoadedImage,
  IN OUT PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation
);

Parameters

LoadedImage
Pointer to a LOADED_IMAGE structure that is returned from a call to MapAndLoad or LoadImage.
ImageConfigInformation
Pointer to an IMAGE_LOAD_CONFIG_DIRECTORY structure.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The GetImageConfigInformation function locates and returns the load configuration data of an image.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Access, GetImageConfigInformation, IMAGE_LOAD_CONFIG_DIRECTORY, LOADED_IMAGE


GetImageUnusedHeaderBytes

The GetImageUnusedHeaderBytes function returns the offset and size of the part of the PE header that is currently unused.

DWORD GetImageUnusedHeaderBytes(
  IN PLOADED_IMAGE LoadedImage,
  OUT LPDWORD SizeUnusedHeaderBytes
);

Parameters

LoadedImage
Pointer to a LOADED_IMAGE structure that is returned from a call to MapAndLoad or LoadImage.
SizeUnusedHeaderBytes
This receives the size of the image's unused header bytes.

Return Values

If the function succeeds, the return value is the offset from the base address of the first unused header byte.

If the function fails, the return value is zero. To retrieve extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Access, LOADED_IMAGE


Symbol Handler

The symbol handler functions give applications easy and portable access to the symbolic debug information of an image. These functions should be used exclusively to ensure access to symbolic information. This is necessary because these functions isolate the application from the symbol format.

These are generic, high-level functions that provide symbol access without having knowledge of the symbolic format. This frees the application from compiler, linker, and image format changes and isolates the dependency to the ImageHlp function set.

  • SymInitialize
  • SymCleanup
  • SymEnumerateModules
  • SymEnumModulesCallback
  • SymEnumerateSymbols
  • SymEnumSymbolsCallback
  • SymFunctionTableAccess
  • SymGetModuleBase
  • SymGetModuleInfo
  • SymGetOptions
  • SymGetSearchPath
  • SymGetSymFromAddr
  • SymGetSymFromName
  • SymGetSymNext
  • SymGetSymPrev
  • SymLoadModule
  • SymRegisterCallback
  • SymbolRegisteredCallback
  • SymSetOptions
  • SymSetSearchPath
  • SymUnDName
  • SymUnloadModule


SymInitialize

The SymInitialize function initializes the symbol handler for a process.

BOOL SymInitialize(
  IN HANDLE hProcess,
  IN LPSTR UserSearchPath,
  IN BOOL fInvadeProcess
);

Parameters

hProcess
Handle to the process for which symbols are to be maintained. If the application is a debugger, use the process handle for the object being debugged, otherwise use the GetCurrentProcess function to obtain the process handle.
UserSearchPath
Pointer to a null-terminated string that specifies a path, or series of paths separated by a semicolon (;), that is used to search for symbol files. If a value of NULL is used, then ImageHlp attempts to form a symbol path from the following sources:
  • Current directory
  • Environment variable _NT_SYMBOL_PATH
  • Environment variable _NT_ALTERNATE_SYMBOL_PATH
  • Environment variable SYSTEMROOT
fInvadeProcess
If this value is TRUE, ImageHlp enumerates the loaded modules for the process and effectively calls the SymLoadModule function for each module.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The SymInitialize function is used to initialize the symbol handler for a process. In the context of the symbol handler, a process is a convenient object to use when collecting symbol information. Usually, symbol handlers are used by debuggers and other tools that need to load symbols for a process being debugged.

The process handle passed to SymInitialize can be any unique value, except in the case when fInvadeProcess is TRUE. The value passed to SymInitialize must be the same value passed to all other ImageHlp symbol handler functions. It is the process handle that ImageHlp uses to identify the caller and locate the correct symbol information. You must call the SymCleanup function to deallocate all resources associated with the process for which symbols are loaded.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymLoadModule


SymCleanup

The SymCleanup function deallocates all resources associated with the process handle.

BOOL SymCleanup(
  IN HANDLE hProcess
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

This function frees all resources associated with the process handle. Failure to call this function causes memory and resource leaks in the calling application

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymInitialize


SymEnumerateModules

The SymEnumerateModules function enumerates all modules that have been loaded for the process by the SymLoadModule function.

BOOL SymEnumerateModules(
  IN HANDLE hProcess,
  IN PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,
  IN PVOID UserContext
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
EnumModulesCallback
Pointer to the enumeration callback function. This function is called once per module. For more information, see SymEnumModulesCallback.
UserContext
A user-defined value or NULL. This value is simply passed to the callback function. Normally, this parameter is used by an application to pass a pointer to a data structure that lets the callback function establish some type of context.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The SymEnumerateModules function enumerates all modules that have been loaded for the process by SymLoadModule, even if the symbol loading is deferred. The enumeration callback function is called once for each module and is passed the module information.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymEnumModulesCallback, SymInitialize, SymLoadModule


SymEnumModulesCallback

The SymEnumModulesCallback function is an application-defined callback function used with the SymEnumerateModules function. It is called once for each enumerated module, and receives the module information.

The PSYM_ENUMMODULES_CALLBACK type defines a pointer to this callback function. SymEnumModulesCallback is a placeholder for the application-defined function name.

BOOL CALLBACK SymEnumModulesCallback(
  LPSTR ModuleName,
  ULONG BaseOfDll,
  PVOID UserContext
);

Parameters

ModuleName
Pointer to a null-terminated string that specifies the name of the module.
BaseOfDll
Specifies the base address where the module is loaded into memory.
UserContext
A user-defined value specified in SymEnumerateModules, or NULL. Typically, this parameter is used by an application to pass a pointer to a data structure that lets the callback function establish some type of context.

Return Values

If the return value is TRUE, the enumeration will continue.

If the return value is FALSE, the enumeration will stop.

Remarks

The calling application is called once per module until all modules are enumerated, or until the enumeration callback function returns FALSE.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: User-defined.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymEnumerateModules


SymEnumerateSymbols

The SymEnumerateSymbols function enumerates all the symbols for a specified module.

BOOL SymEnumerateSymbols(
  IN HANDLE hProcess,
  IN DWORD BaseOfDll,
  IN PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback,
  IN PVOID UserContext
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
BaseOfDll
Specifies the base address of the module for which symbol enumeration is to take place.
EnumSymbolsCallback
Pointer to the callback function that receives the symbol information. For more information, see SymEnumSymbolsCallback.
UserContext
A user-defined value or NULL. This value is simply passed to the callback function. Normally, this parameter is used by an application to pass a pointer to a data structure that lets the callback function establish some type of context.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The SymEnumerateSymbols function enumerates all the symbols for a desired module. The module information is located by the BaseOfDll parameter. The EnumSymbolsCallback function is called once per symbol and is passed the information for each symbol.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymEnumSymbolsCallback, SymInitialize


SymEnumSymbolsCallback

The SymEnumSymbolsCallback function is an application-defined callback function used with the SymEnumerateSymbols function. It is called once for each enumerated symbol, and receives the symbol information.

The PSYM_ENUMSYMBOLS_CALLBACK type defines a pointer to this callback function. SymEnumSymbolsCallback is a placeholder for the application-defined function name.

BOOL CALLBACK SymEnumSymbolsCallback(
  LPSTR SymbolName,
  ULONG SymbolAddress,
  ULONG SymbolSize,
  PVOID UserContext
);

Parameters

SymbolName
Pointer to a null-terminated string that specifies the name of the symbol. The name can be undecorated if the SYMOPT_UNDNAME option is used with the SymSetOptions function.
SymbolAddress
Specifies the virtual address for the beginning of the symbol.
SymbolSize
Specifies the size of the symbol. The size is calculated and is actually a best-guess value. In some cases, the value can be zero.
UserContext
A user-defined value specified in SymEnumerateSymbols, or NULL. Typically, this parameter is used by an application to pass a pointer to a data structure that lets the callback function establish some type of context.

Return Values

If the function returns TRUE, the enumeration will continue.

If the function returns FALSE, the enumeration will stop.

Remarks

The calling application is called once per symbol until all the symbols are enumerated or until the enumeration callback function returns FALSE.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymEnumerateSymbols


SymFunctionTableAccess

The SymFunctionTableAccess function retrieves the function table entry for the specified address.

LPVOID SymFunctionTableAccess(
  IN HANDLE hProcess,
  IN DWORD AddrBase
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
AddrBase
Specifies the base address for which function table information is required.

Return Values

If the function succeeds, the return value is a pointer to the function table entry. The page in memory that contains the function table entry is marked as read-only. Any attempt to write to the returned pointer results in an access violation exception.

If the function fails, the return value is NULL. To retrieve extended error information, call GetLastError.

Remarks

The type of pointer returned is specific to the image from which symbols are loaded. If the image is from an Intel x86 machine, the pointer is a PFPO_DATA type. If the image is for any of the RISC platforms supported by Windows NT, the pointer is a PIMAGE_FUNCTION_ENTRY type. See the WINNT.H header file for a description of these types.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymInitialize


SymGetModuleBase

The SymGetModuleBase function retrieves the base address of the module that contains the specified address.

DWORD SymGetModuleBase(
  IN HANDLE hProcess,
  IN DWORD dwAddr
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
dwAddr
Specifies the valid virtual address that is contained in one of the modules loaded by the SymLoadModule function.

Return Value

If the function succeeds, the return value is a nonzero virtual address. The value is the base address of the module containing the address specified by the dwAddr parameter.

If the function fails, the return value is zero. To retrieve extended error information, call GetLastError.

Remarks

The module table is searched for a module that contains dwAddr. The module is located based on the load address and size of each module.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymInitialize, SymLoadModule


SymGetModuleInfo

The SymGetModuleInfo function retrieves the module information of the specified module.

BOOL SymGetModuleInfo(
  IN HANDLE hProcess,
  IN DWORD dwAddr,
  OUT PIMAGEHLP_MODULE ModuleInfo
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
dwAddr
Specifies the valid, virtual address that is contained in one of the modules loaded by the SymLoadModule function
ModuleInfo
Pointer to an IMAGEHLP_MODULE structure. The SizeOfStruct member must be set to the size of the IMAGEHLP_MODULE structure. An invalid value will result in an error.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The module table is searched for a module that contains the dwAddr. The module is located based on the load address and size of each module. If a valid module is found, the ModuleInfo parameter is filled with the information about the module.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, IMAGEHLP_MODULE, SymInitialize, SymLoadModule


SymGetOptions

The SymGetOptions function retrieves the current options mask.

DWORD SymGetOptions(VOID);

Parameters

This function has no parameters.

Return Values

The SymGetOptions function always returns the current options mask. Zero is a valid value and indicates that all options are turned off. The options values are masks that are combined using the OR operator to form a valid options value. The valid mask values are:

Value | Meaning
SYMOPT_CASE_INSENSITIVE | All symbol searches are insensitive to case.
SYMOPT_UNDNAME | All symbols are presented in undecorated form.
SYMOPT_DEFERRED_LOADS | Symbols are not loaded until a reference is made requiring the symbols be loaded. This is the fastest, most efficient way to use the symbol handler.
SYMOPT_NO_CPP | All C++ decorated symbols containing the symbol separator "::" are replaced by "__". This option exists for debuggers that cannot handle parsing real C++ symbol names.

Remarks

The options value can be changed several times while ImageHlp is in use by an application. The option change affects all future calls to the symbol handler.

Remarks

To set the current options mask, use the SymSetOptions function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler


SymGetSearchPath

The SymGetSearchPath function retrieves the search path for the specified process.

BOOL SymGetSearchPath(
  IN HANDLE hProcess,
  OUT LPSTR SearchPath,
  IN DWORD SearchPathLength
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
SearchPath
Pointer to the buffer that receives the search path.
SearchPathLength
Specifies the length in bytes of the SearchPath buffer.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The SymGetSearchPath function copies the search path for the specified process into the SearchPath buffer. If the function fails, the contents of the buffer are undefined.

To specify a search path for the process, use the SymSetSearchPath function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymInitialize, SymSetSearchPath


SymGetSymFromAddr

The SymGetSymFromAddr function locates the symbol for the specified address.

BOOL SymGetSymFromAddr(
  IN HANDLE hProcess,
  IN DWORD Address,
  OUT LPDWORD Displacement,
  IN OUT PIMAGEHLP_SYMBOL Symbol
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
Address
Specifies the address for which a symbol should be located. The address does not have to be on a symbol boundary. If the address comes after the beginning of a symbol and before the end of the symbol (the beginning of the symbol plus the symbol size), the symbol is found.
Displacement
The displacement from the beginning of the symbol, or zero.
Symbol
Pointer to an IMAGEHLP_SYMBOL structure.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The SymGetSymFromAddr function locates the symbol for a specified address. The modules are searched for the one the address belongs to. When the module is found, its symbol table is searched for a match. When the symbol is found, the symbol information is copied into the Symbol buffer provided by the caller. The caller must allocate the Symbol buffer properly and fill in the required parameters in the IMAGEHLP_SYMBOL structure before calling SymGetSymFromAddr.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, IMAGEHLP_SYMBOL, SymInitialize


SymGetSymFromName

The SymGetSymFromName function locates a symbol for the specified name.

BOOL SymGetSymFromName(
  IN HANDLE hProcess,
  IN LPSTR Name,
  OUT PIMAGEHLP_SYMBOL Symbol
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
Name
Pointer to a null-terminated string that specifies the symbol name for which a symbol is to be located.
Symbol
Pointer to an IMAGEHLP_SYMBOL structure.

Return Value

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The SymGetSymFromName function is used to locate a symbol for a specified name. The name can contain a module prefix that isolates the symbol search to a single module's symbol table.

The module prefix is in the form of "module!". The "!" character is the delimiter between the module name and the symbol name. If there is no module prefix, then the search is performed on each module's symbol table in a linear manner, beginning with the first module that is loaded.

Using the module prefix is preferable for two reasons. First, the symbol search occurs much faster. Second, when deferred symbol loading is turned on, the search causes symbols to be loaded for each module that is searched. When the symbol is found, the symbol information is copied into the Symbol buffer provided by the caller. The caller must allocate the Symbol buffer properly and fill in the required parameters in the IMAGEHLP_SYMBOL structure before calling SymGetSymFromName.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, IMAGEHLP_SYMBOL, SymInitialize


SymGetSymNext

The SymGetSymNext function retrieves the symbol information of the next symbol.

BOOL SymGetSymNext(
  IN HANDLE hProcess,
  IN OUT PIMAGEHLP_SYMBOL Symbol
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
Symbol
Pointer to an IMAGEHLP_SYMBOL structure.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The SymGetSymNext function requires that the IMAGEHLP_SYMBOL structure have valid data, presumably obtained from a call to the SymGetSymFromAddr or SymGetSymFromName function. This structure is filled with the symbol information for the next symbol in sequence by virtual address.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, IMAGEHLP_SYMBOL, SymGetSymFromAddr, SymGetSymFromName, SymGetSymPrev, SymInitialize


SymGetSymPrev

The SymGetSymPrev function retrieves the symbol information of the previous symbol.

BOOL SymGetSymPrev(
  IN HANDLE hProcess,
  IN OUT PIMAGEHLP_SYMBOL Symbol
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
Symbol
Pointer to an IMAGEHLP_SYMBOL structure.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The SymGetSymPrev function requires the IMAGEHLP_SYMBOL structure to have valid data, presumably obtained from a call to the SymGetSymFromAddr or SymGetSymFromName function. This structure is filled in with the symbol information for the previous symbol in sequence by virtual address.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, IMAGEHLP_SYMBOL, SymGetSymFromAddr, SymGetSymFromName, SymGetSymNext, SymInitialize


SymLoadModule

The SymLoadModule function loads the symbol table.

BOOL SymLoadModule(
  IN HANDLE hProcess,
  IN HANDLE hFile,
  IN LPSTR ImageName,
  IN LPSTR ModuleName,
  IN DWORD BaseOfDll,
  IN DWORD SizeOfDll
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
hFile
Handle to the file for the executable image. This argument is used mostly by debuggers, where the debugger passes the file handle obtained from a debug event. A value of NULL indicates that hFile is not used.
ImageName
Pointer to a null-terminated string that specifies the name of the executable image. This name can contain a partial path, a full path, or no path at all. If the file cannot be located by the name provided, the symbol search path is used.
ModuleName
Pointer to a null-terminated string that specifies a shortcut name for the module. If the pointer value is NULL, ImageHlp creates a name using the base name of the symbol file.
BaseOfDll
Specifies the load address of the module. If the value is zero, ImageHlp obtains the load address from the symbol file. The load address contained in the symbol file is not necessarily the actual load address. Debuggers and other applications having an actual load address should use the real load address when calling this function.
SizeOfDll
Specifies the size of the module. If the value is zero, ImageHlp obtains the size from the symbol file. The size contained in the symbol file is not necessarily the actual size. Debuggers and other applications having an actual size should use the real size when calling this function.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The symbol handler creates an entry for the module and if the deferred symbol loading option is turned off, an attempt is made to load the symbols. If deferred symbol loading is enabled, the module is marked as deferred and the symbols are not loaded until a reference is made to a symbol in the module.

To unload the symbol table, use the SymUnloadModule function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymInitialize, SymUnloadModule


SymRegisterCallback

The SymRegisterCallback function lets an application register a callback function for use by the symbol handler.

BOOL SymRegisterCallback(
  IN HANDLE hProcess,
  IN PSYMBOL_REGISTERED_CALLBACK CallbackFunction,
  IN PVOID UserContext
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
CallbackFunction
Pointer to a callback function. For more information, see SymbolRegisteredCallback.
UserContext
A user-defined value or NULL. This value is simply passed to the callback function. Normally, this parameter is used by an application to pass a pointer to a data structure that lets the callback function establish some type of context.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The SymRegisterCallback function lets an application register a callback function for use by the symbol handler. The symbol handler calls the registered callback function when there is status or progress information for the application.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymbolRegisteredCallback, SymInitialize


SymbolRegisteredCallback

The SymbolRegisteredCallback function is an application-defined callback function used with the SymRegisterCallback function. It is called by the symbol handler.

The PSYMBOL_REGISTERED_CALLBACK type defines a pointer to this callback function. SymbolRegisteredCallback is a placeholder for the application-defined function name.

BOOL CALLBACK SymbolRegisteredCallback(
  HANDLE hProcess,
  ULONG ActionCode,
  PVOID CallbackData,
  PVOID UserContext
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
ActionCode
Specifies the reason for the callback. The valid values are:
Value Meaning
CBA_DEFERRED_SYMBOL_LOAD_START
CBA_DEFERRED_SYMBOL_LOAD_COMPLETE
CBA_DEFERRED_SYMBOL_LOAD_FAILURE
CBA_SYMBOLS_UNLOADED
CBA_DUPLICATE_SYMBOL

CallbackData
Pointer to an action-specific data structure or NULL.
UserContext
A user-defined value specified in SymRegisterCallback, or NULL. Typically, this parameter is used by an application to pass a pointer to a data structure that lets the callback function establish some type of context.

Return Values

Returning the value TRUE indicates success.

Returning the value FALSE indicates failure.

Remarks

The calling application gets called through the registered callback function as a result of another call to one of ImageHlp's symbol handler functions. The calling application must be prepared for the possible side effects that this can cause. If the application has only one callback function that is being used by multiple threads, then care may be necessary to synchronize some types of data access while in the context of the callback function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: User-defined.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymRegisterCallback


SymSetOptions

The SymSetOptions function sets the options mask.

DWORD SymSetOptions(
  IN DWORD SymOptions
);

Parameters

SymOptions
Specifies the new options value. Zero is a valid value and indicates that all options are turned off. The options values are masks that are combined using the OR operator to form a valid options value. The valid mask values are:
Value | Meaning
SYMOPT_CASE_INSENSITIVE | All symbol searches are insensitive to case.
SYMOPT_UNDNAME | All symbols are presented in undecorated form.
SYMOPT_DEFERRED_LOADS | Symbols are not loaded until a reference is made requiring the symbols be loaded. This is the fastest, most efficient way to use the symbol handler.
SYMOPT_NO_CPP | All C++ decorated symbols containing the symbol separator "::" are replaced by "__". This option exists for debuggers that cannot handle parsing real C++ symbol names.

Return Values

The function returns the current options mask.

Remarks

The options value can be changed any number of times while ImageHlp is in use by an application. The option change affects all future calls to the symbol handler.

To get the current options mask, call the SymGetOptions function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymGetOptions


SymSetSearchPath

The SymSetSearchPath function sets the search path for the specified process.

BOOL SymSetSearchPath(
  IN HANDLE hProcess,
  IN LPSTR SearchPath
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
SearchPath
Specifies the search path. The string can contain multiple paths separated by a semicolon (;).

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The search path can be changed any number of times while ImageHlp is in use by an application. The change affects all future calls to the symbol handler.

To get the current search path, call the SymGetSearchPath function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymGetSearchPath, SymInitialize


SymUnDName

The SymUnDName function undecorates a decorated symbol.

BOOL SymUnDName(
  IN PIMAGEHLP_SYMBOL Symbol,
  IN LPSTR UnDecName,
  IN DWORD UnDecNameLength
);

Parameters

Symbol
Specifies the symbol to be undecorated.
UnDecName
Specifies the buffer that contains the undecorated symbol name.
UnDecNameLength
Specifies the length in bytes of the UnDecName buffer.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The UnDecName buffer contains the undecorated symbol name. However, if the buffer is too small, the name is truncated to UnDecNameLength length.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler


SymUnloadModule

The SymUnloadModule function unloads the symbol table.

BOOL SymUnloadModule(
  IN HANDLE hProcess,
  IN DWORD BaseOfDll
);

Parameters

hProcess
Handle to the process that was originally passed to the SymInitialize function.
BaseOfDll
Specifies the base address of the module that is unloaded.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Symbol Handler, SymInitialize


Image Integrity

The following functions manage the set of certificates in an image file. Routines are provided to add, remove, and query certificates. There is also a function available for obtaining the byte stream of an image file required to calculate a message digest of the image file. This is needed to create signature certificates.

Every certificate in a file has an index which can change as certificates are removed. New certificates will always be added "at the end" of the list of existing certificates. That is, they will be assigned indices that are greater than any index currently in use. In general, an application should not assume that a given certificate has the same index it had the last time it was referenced.

  • ImageGetDigestStream
  • ImageAddCertificate
  • ImageRemoveCertificate
  • ImageEnumerateCertificates
  • ImageGetCertificateData
  • ImageGetCertificateHeader


ImageGetDigestStream

The ImageGetDigestStream function returns the data to be digested from a given image file, subject to the passed DigestLevel parameter.

BOOL ImageGetDigestStream(
  IN HANDLE FileHandle,
  IN DWORD DigestLevel,
  IN PVOID Buffer,
  IN OUT PDWORD BufferLength,
  IN OUT PDWORD Context
);

Parameters

FileHandle
Handle to the image file to be modified. This handle must be opened for FILE_READ_DATA access.
DigestLevel
Specifies which aspects of the image are to be included in the returned data stream. This parameter can be one or more of the following values:
Value Meaning
DICE_PE_IMAGE_DIGEST_DEBUG_INFO
DICE_PE_IMAGE_DIGEST_RESOURCES

Buffer
Provides a pointer to a buffer for the returned data.
BufferLength
On input, this supplies the size of the passed Buffer in bytes. On output, it returns the amount of data remaining in the image. Thus, an application can pass in a BufferLength of zero to determine exactly how much space is required to retrieve all the data in a single pass.
Context
Supplies and returns cross-call context information so sequential calls can return data blocks without requiring the system to maintain state information about the operation in progress.

This parameter must be zero on the first call for accurate results.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The ImageGetDigestStream function returns the data to be digested from a given image file, subject to the passed DigestLevel parameter. The order of the bytes will be consistent for different calls, which is required to ensure that the same message digest is always produced from the retrieved byte stream.

To ensure cross-platform compatibility, all implementations of this function must behave in a consistent manner with respect to the order in which the various parts of the image file are returned.

Data should be returned in the following order:

  1. Image (executable and static data) information.
  2. Resource data.
  3. Debug information.

If any of these are not specified, the remaining parts must be returned in the same order.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity


ImageAddCertificate

The ImageAddCertificate function is used to add a DICE_CERTIFICATE to the specified file.

BOOL ImageAddCertificate(
  IN HANDLE FileHandle,
  IN PDICE_CERTIFICATE Certificate,
  OUT PDWORD Index
);

Parameters

FileHandle
Handle to the image file to be modified. This handle must be opened for FILE_READ_DATA and FILE_WRITE_DATA access.
Certificate
Specifies a buffer containing a DICE_CERTIFICATE header and all associated sections. The Length member in the certificate header will be used to determine the length of this buffer.
Index
Receives the index of the newly added certificate.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The ImageAddCertificate function adds a DICE_CERTIFICATE to the specified file. The certificate is added at the end of the existing list of certificates and is assigned an index.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity


ImageRemoveCertificate

The ImageRemoveCertificate function is used to remove the specified certificate from the given file.

BOOL ImageRemoveCertificate(
  IN HANDLE FileHandle,
  IN DWORD Index
);

Parameters

FileHandle
Handle to the image file to be modified. This handle must be opened for FILE_READ_DATA and FILE_WRITE_DATA access.
Index
Specifies the index of the certificate to be removed.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The ImageRemoveCertificate function removes the specified certificate from the given file.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity


ImageEnumerateCertificates

The ImageEnumerateCertificates function is used to return information about the certificates currently contained in an image file.

BOOL ImageEnumerateCertificates(
  IN HANDLE FileHandle,
  IN DWORD TypeFilter,
  OUT PDWORD CertificateCount,
  IN OUT PDWORD Indices OPTIONAL,
  IN OUT DWORD IndexCount OPTIONAL
);

Parameters

FileHandle
Handle to the image file to be examined. This handle must be opened for FILE_READ_DATA access.
TypeFilter
Specifies a DICE certificate section type to be used as a filter when returning certificate information. DICE_SECTION_TYPE_ANY should be passed for information on all section types present in the image.
CertificateCount
Receives the number of certificates in the image containing sections of the type specified by the TypeFilter parameter. If none are found, this parameter is zero .
Indices
Optionally provides a buffer to use to return an array of indices to the certificates containing sections of the specified type. No ordering should be assumed for the index values, nor are they guaranteed to be contiguous when DICE_SECTION_TYPE_ANY is queried.
IndexCount
Specifies the length, in double-words, of the Indices buffer. This parameter will be examined whenever Indices is present. If CertificateCount is greater than IndexCount, Indices will be filled in with the first IndexCount sections found in the image and an appropriate warning will be returned.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The ImageEnumerateCertificates function returns information about the certificates currently contained in an image file. It has filtering capabilities which allow certificates containing sections of any single type (or of any type) to be returned.

After the indices of interesting certificates are discovered, they can be passed to the ImageGetCertificateData function to obtain the actual bodies of the certificates.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity, ImageGetCertificateData


ImageGetCertificateData

The ImageGetCertificateData function is used to return a complete certificate from a file.

BOOL ImageGetCertificateData(
  IN HANDLE FileHandle,
  IN DWORD CertificateIndex,
  OUT PDICE_CERTIFICATE Certificate,
  IN OUT PDWORD RequiredLength
);

Parameters

FileHandle
Handle to the image file to be modified. This handle must be opened for FILE_READ_DATA access.
CertificateIndex
Specifies the index of the certificate to be returned.
Certificate
Specifies a buffer to receive the certificate data.
RequiredLength
On input, this parameter specifies the length of the Certificate buffer in bytes. On return, it receives the length of the certificate.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The ImageGetCertificateData function returns a complete certificate from a file.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity


ImageGetCertificateHeader

The ImageGetCertificateHeader function is used to return only the header part of the specified DICE_CERTIFICATE up to, but not including, the section offset array.

BOOL ImageGetCertificateHeader(
  IN HANDLE FileHandle,
  IN DWORD CertificateIndex,
  OUT PDICE_CERTIFICATE CertificateHeader
);

Parameters

FileHandle
Handle to the image file to be modified. This handle must be opened for FILE_READ_DATA access.
CertificateIndex
Specifies the index of the certificate whose header is to be returned.
CertificateHeader
Specifies a buffer to receive the certificate header.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

The ImageGetCertificateHeader function returns only the header part of the specified DICE_CERTIFICATE up to, but not including, the section offset array.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.
Import Library: Use imagehlp.lib.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity


ImageHlp Structures

This section describes the ImageHlp data structures. These structures are either returned through pointers or are passed to ImageHlp as function parameters.

ADDRESS
API_VERSION
IMAGE_DEBUG_INFORMATION
IMAGEHLP_DEFERRED_SYMBOL_LOAD
IMAGEHLP_DUPLICATE_SYMBOL
IMAGEHLP_MODULE
IMAGEHLP_SYMBOL
KDHELP
LOADED_IMAGE
STACKFRAME


ADDRESS

typedef struct _tagADDRESS {
    DWORD Offset;
    WORD Segment;
    ADDRESS_MODE Mode;
} ADDRESS, *LPADDRESS;

Members

Offset
Specifies either an offset into the segment, or a 32-bit virtual address. The interpretation of this value depends on the value contained in the Mode member.
Segment
Specifies the segment number. This value is used only for 16-bit addressing.
Mode
Specifies the addressing mode. This parameter can be one of the following values:

AddrMode1616
AddrMode1632
AddrModeReal
AddrModeFlat

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity


API_VERSION

The API_VERSION structure contains the ImageHlp version.

typedef struct API_VERSION {
    USHORT MajorVersion;
    USHORT MinorVersion;
    USHORT Revision;
    USHORT Reserved;
} API_VERSION, *LPAPI_VERSION;

Members

MajorVersion
Specifies the major version number.
MinorVersion
Specifies the minor version number.
Revision
Specifies the revision number.
Reserved
Reserved for use by the operating system.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity, ImageHlpApiVersion, ImageHlpApiVersionEx


IMAGE_DEBUG_INFORMATION

The IMAGE_DEBUG_INFORMATION structure contains debug information.

typedef struct _IMAGE_DEBUG_INFORMATION {
    LIST_ENTRY List;
    DWORD Size;
    PVOID MappedBase;
    USHORT Machine;
    USHORT Characteristics;
    DWORD CheckSum;
    DWORD ImageBase;
    DWORD SizeOfImage;
    DWORD NumberOfSections;
    PIMAGE_SECTION_HEADER Sections;
    DWORD ExportedNamesSize;
    LPSTR ExportedNames;
    DWORD NumberOfFunctionTableEntries;
    PIMAGE_FUNCTION_ENTRY FunctionTableEntries;
    DWORD LowestFunctionStartingAddress;
    DWORD HighestFunctionEndingAddress;
    DWORD NumberOfFpoTableEntries;
    PFPO_DATA FpoTableEntries;
    DWORD SizeOfCoffSymbols;
    PIMAGE_COFF_SYMBOLS_HEADER CoffSymbols;
    DWORD SizeOfCodeViewSymbols;
    PVOID CodeViewSymbols;
    LPSTR ImageFilePath;
    LPSTR ImageFileName;
    LPSTR DebugFilePath;
    DWORD TimeDateStamp;
    BOOL RomImage;
    PIMAGE_DEBUG_DIRECTORY DebugDirectory;
    DWORD NumberOfDebugDirectories;
    DWORD Reserved[ 3 ];
} IMAGE_DEBUG_INFORMATION, *PIMAGE_DEBUG_INFORMATION;

Members

List
Specifies the linked list pointers.
Size
Specifies the size of the memory allocated for the IMAGE_DEBUG_INFORMATION structure and all debug information.
MappedBase
Specifies the base address of the image.
Machine
Specifies the machine type. (See WINNT.H for valid values.)
Characteristics
Specifies the characteristics of the image.
CheckSum
Specifies the checksum of the image.
ImageBase
Specifies the requested base address of the image.
SizeOfImage
Specifies the size of the image.
NumberOfSections
Specifies the number of COFF section headers.
Sections
Pointer to the first COFF section header.
ExportedNamesSize
Specifies the size, in bytes, of the ExportedNames member.
ExportedNames
Pointer to a series of null-terminated strings that name all the functions exported from the image.
NumberOfFunctionTableEntries
Specifies the number of entries contained in the FunctionTableEntries member.
FunctionTableEntries
Pointer to the first function table entry.
LowestFunctionStartingAddress
Specifies the lowest function table starting address.
HighestFunctionEndingAddress
Specifies the highest function table ending address.
NumberOfFpoTableEntries
Specifies the number of entries contained in the FpoTableEntries member.
FpoTableEntries
Pointer to the first FPO entry.
SizeOfCoffSymbols
Specifies the size of the COFF symbol table.
CoffSymbols
Pointer to the COFF symbol table.
SizeOfCodeViewSymbols
Specifies the size of the CodeView symbol table.
CodeViewSymbols
Pointer to the beginning of the CodeView symbol table.
ImageFilePath
Specifies the relative path to the image filename.
ImageFileName
Specifies the image filename.
DebugFilePath
Specifies the full path to the symbol file.
TimeDateStamp
Specifies the time stamp of the image. This represents the date and time the image was created by the linker.
RomImage
This value is TRUE if the image is a ROM image.
DebugDirectory
Pointer to the first debug directory. (See WINNT.H for structure format.)
NumberOfDebugDirectories
Specifies the number of entries contained in the DebugDirectory member.
Reserved
The value in Reserved[0] contains the original executable image's section alignment. The values in Reserved[1] and Reserved[2] are undefined and reserved for use by the operating system.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity, MapDebugInformation


IMAGE_LOAD_CONFIG_DIRECTORY

The IMAGE_LOAD_CONFIG_DIRECTORY structure contains the load configuration data of an image.

typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY {
    DWORD   Characteristics;
    DWORD   TimeDateStamp;
    WORD    MajorVersion;
    WORD    MinorVersion;
    DWORD   GlobalFlagsClear;
    DWORD   GlobalFlagsSet;
    DWORD   CriticalSectionDefaultTimeout;
    DWORD   DeCommitFreeBlockThreshold;
    DWORD   DeCommitTotalFreeThreshold;
    PVOID   LockPrefixTable;
    DWORD   MaximumAllocationSize;
    DWORD   VirtualMemoryThreshold;
    DWORD   ProcessHeapFlags;
    DWORD   ProcessAffinityMask;
    WORD    CSDVersion;
    WORD    Reserved1;
    DWORD   Reserved[ 2 ];
} IMAGE_LOAD_CONFIG_DIRECTORY, *PIMAGE_LOAD_CONFIG_DIRECTORY;

Members

Characteristics
Flags indicating attributes of the file.
TimeDateStamp
Specifies the date and time stamp value. The value is represented in the number of seconds elapsed since midnight (00:00:00), January 1, 1970, Universal Coordinated Time, according to the system clock. The time stamp can be printed using the C run-time (CRT) function ctime.
MajorVersion
Major version number.
MinorVersion
Minor version number.
GlobalFlagsClear
GlobalFlagsSet
CriticalSectionDefaultTimeout
DeCommitFreeBlockThreshold
DeCommitTotalFreeThreshold
LockPrefixTable
MaximumAllocationSize
VirtualMemoryThreshold
ProcessHeapFlags
ProcessAffinityMask
CSDVersion
Reserved1
Reserved

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity, GetImageConfigInformation, SetImageConfigInformation


IMAGEHLP_DEFERRED_SYMBOL_LOAD

typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD {
    DWORD SizeOfStruct;
    DWORD BaseOfImage;
    DWORD CheckSum;
    DWORD TimeDateStamp;
    CHAR FileName[MAX_PATH];
} IMAGEHLP_DEFERRED_SYMBOL_LOAD,
    *PIMAGEHLP_DEFERRED_SYMBOL_LOAD;

Members

SizeOfStruct
Specifies the size of the structure. The caller must set this to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD).
BaseOfImage
Specifies the base virtual address where the image is loaded.
CheckSum
Specifies the computed checksum of the image. This value can be zero.
TimeDateStamp
Specifies the date and time stamp value. The value is represented in the number of seconds elapsed since midnight (00:00:00), January 1, 1970, Universal Coordinated Time, according to the system clock. The time stamp can be printed using the C run-time (CRT) function ctime.
FileName
Specifies the image name. The name may or may not contain a full path.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity


IMAGEHLP_DUPLICATE_SYMBOL

typedef struct _IMAGEHLP_DUPLICATE_SYMBOL {
    DWORD SizeOfStruct;
    DWORD NumberOfDups;
    PIMAGEHLP_SYMBOL Symbol;
    ULONG SelectedSymbol;
} IMAGEHLP_DUPLICATE_SYMBOL, *PIMAGEHLP_DUPLICATE_SYMBOL;

Members

SizeOfStruct
Specifies the size of the structure. The caller must set this to sizeof(IMAGEHLP_DUPLICATE_SYMBOL).
NumberOfDups
The number of duplicate symbols.
Symbol
Pointer to an array of symbols (IMAGEHLP_SYMBOL structures). The number of entries in the array is specified by the NumberOfDups member.
SelectedSymbol
Specifies the index into the symbol array for the selected symbol.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity, IMAGEHLP_SYMBOL


IMAGEHLP_MODULE

The IMAGEHLP_MODULE structure contains module information.

typedef struct _IMAGEHLP_MODULE {
    DWORD SizeOfStruct;
    DWORD BaseOfImage;
    DWORD ImageSize;
    DWORD TimeDateStamp;
    DWORD CheckSum;
    DWORD NumSyms;
    SYM_TYPE SymType;
    CHAR ModuleName[32];
    CHAR ImageName[256];
    CHAR LoadedImageName[256];
} IMAGEHLP_MODULE, *PIMAGEHLP_MODULE;

Members

SizeOfStruct
Specifies the size of the structure. The caller must set this to sizeof(IMAGEHLP_MODULE).
BaseOfImage
Specifies the base virtual address where the image is loaded.
ImageSize
Specifies the size of the image.
TimeDateStamp
Specifies the date and time stamp value. The value is represented in the number of seconds elapsed since midnight (00:00:00), January 1, 1970, Universal Coordinated Time, according to the system clock. The time stamp can be printed using the C run-time (CRT) function ctime.
CheckSum
Specifies the computed checksum of the image. This value can be zero.
NumSyms
Specifies the number of symbols in the symbol table.
SymType
Specifies the type of symbols that are loaded. This parameter can be one of the following values:
Value | Meaning
SymNone | No symbols are loaded.
SymCoff | COFF symbols.
SymCv | CodeView symbols.
SymPdb | PDB symbols. (Actually CodeView stored in a PDB file.)
SymExport | Symbols generated from a DLL's export table.
SymDeferred | ImageHlp has not yet attempted to load symbols.

ModuleName
Specifies the module name.
ImageName
Specifies the image name. The name may or may not contain a full path.
LoadedImageName
Specifies the full path and filename from which symbols were loaded.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity, SymGetModuleInfo


IMAGEHLP_SYMBOL

The IMAGEHLP_SYMBOL structure contains symbol information.

typedef struct _IMAGEHLP_SYMBOL {
    DWORD SizeOfStruct;
    DWORD Address;
    DWORD Size;
    DWORD Flags;
    DWORD MaxNameLength;
    CHAR Name[1];
} IMAGEHLP_SYMBOL, *PIMAGEHLP_SYMBOL;

Members

SizeOfStruct
Specifies the size of the structure, in bytes. The caller must set this parameter to sizeof(IMAGEHLP_SYMBOL).
Address
Specifies the virtual address for the symbol.
Size
Specifies the size of the symbol. This value is a best guess and can be zero.
Flags
Specifies additional information about the symbol. This parameter can be one of the following:
Value Meaning
SYMF_OMAP_GENERATED
SYMF_OMAP_MODIFIED

MaxNameLength
The caller must set this value to the maximum length of the string that the Name member can contain. Because symbol names can vary in length, this data structure is allocated by the caller. This member is used so ImageHlp knows how much memory is available for use by the symbol name.
Name
A null-terminated string specifying either the decorated or undecorated symbol name. If the buffer is not large enough for the complete symbol, then the name is truncated to MaxNameLength characters.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity, SymGetSymFromAddr, SymGetSymFromName


KDHELP

typedef struct _KDHELP {
    DWORD Thread;
    DWORD ThCallbackStack;
    DWORD NextCallback;
    DWORD FramePointer;
    DWORD KiCallUserMode;
    DWORD KeUserCallbackDispatcher;
} KDHELP, *PKDHELP;

Members

Thread
Specifies the address of the kernel thread object, as provided in the WAIT_STATE_CHANGE packet.
ThCallbackStack
Specifies the offset in the thread object to the pointer to the current callback frame in the kernel stack.
NextCallback
Specifies the address of the next callback frame.
FramePointer
Specifies the address of the saved frame pointer, if applicable.
KiCallUserMode
Specifies the address of the kernel function that calls out to user mode.
KeUserCallbackDispatcher
Specifies the address of the user mode dispatcher function.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity


LOADED_IMAGE

The LOADED_IMAGE structure contains information about the loaded image.

typedef struct _LOADED_IMAGE {
    LPSTR ModuleName;
    HANDLE hFile;
    PUCHAR MappedAddress;
    PIMAGE_NT_HEADERS FileHeader;
    PIMAGE_SECTION_HEADER LastRvaSection;
    ULONG NumberOfSections;
    PIMAGE_SECTION_HEADER Sections;
    ULONG Characteristics;
    BOOLEAN fSystemImage;
    BOOLEAN fDOSImage;
    LIST_ENTRY Links;
    ULONG SizeOfImage;
} LOADED_IMAGE, *PLOADED_IMAGE;

Members

ModuleName
Pointer to a null-terminated string that specifies the filename of the mapped file.
hFile
Handle to the mapped file.
MappedAddress
Specifies the base address of the mapped file.
FileHeader
Pointer to the NT headers.
LastRvaSection
Pointer to the first COFF section header.
NumberOfSections
Specifies the count of the COFF section headers.
Sections
Pointer to the first COFF section header.
Characteristics
Specifies the image characteristics value.
fSystemImage
This value is TRUE if the image is a kernel mode executable image.
fDOSImage
This value is TRUE if the image is a 16-bit executable image.
Links
Specifies the list of loaded images.
SizeOfImage
Specifies the size of the image.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity, ImageLoad, MapAndLoad


STACKFRAME

The STACKFRAME structure represents a stack frame.

typedef struct _tagSTACKFRAME {
    ADDRESS AddrPC;
    ADDRESS AddrReturn;
    ADDRESS AddrFrame;
    ADDRESS AddrStack;
    LPVOID FuncTableEntry;
    DWORD Params[4];
    BOOL Far;
    BOOL Virtual;
    DWORD Reserved[3];
    KDHELP KdHelp;
} STACKFRAME, *LPSTACKFRAME;

Members

AddrPC
Specifies the program counter.
AddrReturn
Specifies the return address.
AddrFrame
Specifies the frame pointer.
AddrStack
Specifies the stack pointer.
FuncTableEntry
The pointer to pdata, fpo, or NULL.
Params
The possible arguments to the function.
Far
This member is TRUE if this is a WOW far call.
Virtual
This member is TRUE if this is a virtual frame.
Reserved
Used internally by the StackWalk function.
KdHelp
The helper data for walking kernel callback frames.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Windows CE: Unsupported.
Header: Declared in imagehlp.h.

See Also

PE Image Helper (ImageHlp) Overview, Image Integrity, StackWalk


Communications

A communications resource is a physical or logical device that provides a single bidirectional, asynchronous data stream. Serial ports, parallel ports, fax machines, and modems are examples of communications resources. For each communications resource, there is a service provider, consisting of a library or driver, that enables applications to access the resource.


About Communications

The file input and output (I/O) functions (CreateFile, CloseHandle, ReadFile, ReadFileEx, WriteFile, and WriteFileEx) provide the basic interface for opening and closing a communications resource handle and for performing read and write operations. The Microsoft® Win32® API also includes a set of communications functions that provide access to communications resources. This overview describes the use of file I/O and communications functions, which enable applications to perform the following tasks:

  • Open a handle to a specified communications resource.
  • Set and query the configuration of a serial communications resource.
  • Read from or write to a serial communications resource.
  • Monitor a specified set of events that might occur for a given serial communications resource.
  • Send a control command to the device driver associated with a specified communications resource, causing the driver to execute an extended function.


Communications Resource Handles

A process uses the CreateFile function to open a handle to a communications resource. For example, specifying COM1 opens a handle to a serial port, and LPT1 opens a handle to a parallel port. If the specified resource is currently being used by another process, CreateFile fails. Any thread of the process can use the handle returned by CreateFile to identify the resource in any of the functions that access the resource.

When using CreateFile to open a handle directly to a device, an application must use the special characters " \\ .\" to identify the device. For example, to open a handle to drive A, specify " \\ .\a:" for the lpszName parameter of CreateFile. The calling process can use the handle in the DeviceIoControl function to send control codes to the device.

When the process calls CreateFile to open a communications resource, it specifies the following attributes:

  • What type of read-write access exists for the specified resource.
  • Whether the handle can be inherited by child processes.
  • Whether the handle can be used in overlapped (asynchronous) I/O operations. (For a description of overlapped operations, see Synchronization.)

When the process uses CreateFile to open a communications resource, it must specify certain values for the following parameters:

  • The fdwShareMode parameter must be zero, opening the resource for exclusive access.
  • The fdwCreate parameter must specify the OPEN_EXISTING flag.
  • The hTemplateFile parameter must be NULL.


Modification of Communications Resource Settings

When the CreateFile function opens a handle to a serial communications resource, the system initializes and configures the resource according to the values set up the last time the resource was opened. Preserving the previous settings enables the user to retain the settings specified through an mode command when the device is reopened. The values inherited from the previous open operation include the configuration settings of the device control block (a DCB structure) and the time-out values used in I/O operations. If the device has never been opened, it is configured with the system defaults.

To determine the initial configuration of a serial communications resource, a process calls the GetCommState function, which fills in a serial port DCB structure with the current configuration settings. To modify this configuration, a process specifies a DCB structure in a call to the SetCommState function.

Members of the DCB structure specify the configuration settings such as the baud rate, the number of data bits per byte, and the number of stop bits per byte. Other DCB members specify special characters and enable parity checking and flow control. When a process needs to modify only a few of these configuration settings, it should first call GetCommState to fill in a DCB structure with the current configuration. Then the process can adjust the important values in the DCB structure and reconfigure the device by calling SetCommState and specifying the modified DCB structure. This procedure ensures that the unmodified members of the DCB structure contain appropriate values. For example, a common error is to configure a device with a DCB structure in which the structure's XonChar member is equal to the XoffChar member.

The BuildCommDCB function provides another way to modify a DCB structure. BuildCommDCB uses a string with the same form as the command-line arguments of the mode command to specify the baud rate, parity scheme, number of stop bits, and number of data bits. The remaining members of DCB are not changed by this function, except that the appropriate members are set to disable XON/XOFF and hardware flow control. BuildCommDCB only modifies a DCB structure; it does not reconfigure the device.

A process can reconfigure a communications resource by using the GetCommProperties function to get information from a device driver about the configuration settings that it supports. The process can use this information to avoid specifying a configuration that is not supported.

The SetCommState function reconfigures the communications resource, but it does not affect the internal output and input buffers of the specified driver. The buffers are not flushed, and pending read and write operations are not terminated prematurely.

A process reinitializes a communications resource by using the SetupComm function, which performs the following tasks:

  • Terminates pending read and write operations, even if they have not been completed.
  • Discards unread characters and frees the internal output and input buffers of the driver associated with the specified resource.
  • Reallocates the internal output and input buffers.

A process is not required to call SetupComm. If it does not, the resource's driver initializes the device with the default settings the first time that the communications resource handle is used.


Communications Resource Configuration

The COMMCONFIG structure defines the configuration of a communications resource, serial or otherwise. The format of the structure varies depending on the type of communications resource (the provider subtype). The first few structure members are common to all communications resources; additional members are defined for specific provider subtypes. Specific service providers may extend the COMMCONFIG structure as well.

An application can get and set the configuration of a communications resource by using the GetCommConfig and SetCommConfig functions. When opened, a communications resource is initialized using the default configuration for its provider subtype. To get and set the default configuration for a provider subtype, use the GetDefaultCommConfig and SetDefaultCommConfig functions.

To prompt the user for configuration information, use the CommConfigDialog function. This function displays a dialog box defined by the service provider and fills in a COMMCONFIG structure based on user input.


Modem Configuration

Modem configuration functions enable you to configure a modem before making a connection. An application can set modem options and determine the features of a modem without using commands specific to any modem device. Following are the general features an application may set before making a call:

  • Primary mode of operation (synchronous, asynchronous, and whether error control is enabled).
  • V.42 error control (defined by CCITT recommendation V.42), including specific parameters. CCITT stands for the International Telegraph and Telephone Consultative Committee.
  • V.42bis (defined by CCITT recommendation V.42bis) and MNP5 data compression.
  • Time-out options, including call setup, inactivity, and buffered data delivery.

Before setting a modem's configuration, an application should determine the capabilities of the modem device by using the GetCommProperties function. This function fills in a COMMPROP structure. This structure contains both a general portion, which applies to all communications devices, and a portion that is specific to each provider subtype. For modem devices, the provider-specific portion of the COMMPROP structure is a MODEMDEVCAPS structure.

An application can get and set the current configuration of a modem by using the GetCommConfig and SetCommConfig functions, both of which use a COMMCONFIG structure. This structure contains both a general portion, which applies to all communications devices, and a portion that is specific to each provider subtype. For modem devices, the provider-specific portion of the COMMCONFIG structure is a MODEMSETTINGS structure.

After configuring a modem, an application can use the Telephony Application Programming Interface (TAPI) to actually establish a connection.

The modem configuration functions do not provide for long-term management and maintenance of a modem. Modem service providers should supply modem configuration dialog boxes for this purpose.


Read and Write Operations

The Win32 API supports both synchronous and asynchronous (overlapped) file I/O operations on serial communications resources. Overlapped operations enable the calling thread to perform other tasks while the operation executes in the background. A thread uses the ReadFile or ReadFileEx function to read from a communications resource, and the WriteFile or WriteFileEx function to write to a communications resource. ReadFile and WriteFile can be performed synchronously or asynchronously. ReadFileEx and WriteFileEx can only be performed asynchronously.

The behavior of these read and write functions is affected by whether the function is executed as an overlapped operation, whether the time-out parameters are associated with the handle, and whether flow control parameters are associated with the handle.

A thread can also write to a communications resource by using the TransmitCommChar function, which transmits a specified character ahead of any pending data in the output buffer. This function is useful for transmitting a high priority signal character to the receiving system. Transmission of the high priority character is still subject to flow control and write time-outs, and the operation is performed synchronously.

A thread can use the PurgeComm function to discard all characters in a device's output or input buffer. PurgeComm can also terminate pending read or write operations, even if the operations have not been completed. If a thread uses PurgeComm to flush an output buffer, the deleted characters are not transmitted. To empty the output buffer while ensuring that the contents are transmitted, a thread can call the FlushFileBuffers function (a synchronous operation). Note, however, that FlushFileBuffers is subject to flow control but not to write time-outs, and it will not return until all pending write operations have been transmitted.


Overlapped Operations

Overlapped operations enable a thread to execute a time-consuming I/O operation in the background, leaving the thread free to perform other tasks. To enable overlapped I/O operations on a communications resource, the thread must specify the FILE_FLAG_OVERLAPPED flag in the CreateFile function when the handle is opened. To execute the ReadFile or WriteFile function as an overlapped operation, the calling thread must specify a pointer to an OVERLAPPED structure.The OVERLAPPED structure must contain a handle to a manual-reset (not an auto-reset) event object. The system sets the state of the event object to not-signaled when a call to the I/O function returns before the operation has been completed. The system sets the state of the event object to signaled when the operation has been completed. The thread uses a wait function to check the current state of the event object or to wait for its state to be signaled.

The ReadFileEx and WriteFileEx functions can be performed only as overlapped operations. The calling thread specifies a pointer to the FileIOCompletionRoutine function, which is executed when the overlapped operation is completed. The completion routine is executed only if the calling thread performs an alertable operation.

For more information about event objects, wait functions, alertable waits, and completion routines, see Synchronization.


Time-Outs

A handle to a communications resource has an associated set of time-out parameters that affect the behavior of read and write operations. Time-outs can cause a ReadFile, ReadFileEx, WriteFile, or WriteFileEx operation to conclude when a time-out interval elapses, even though the specified number of characters have not been read or written. It is not treated as an error when a time-out occurs during a read or write operation (that is, the read or write function's return value indicates success). The count of bytes actually read or written is reported by ReadFile or WriteFile (or by the GetOverlappedResult or FileIOCompletionRoutine function, if the I/O was performed as an overlapped operation).

When an application opens a communications resource, the system sets the resource's time-out values to the values in effect when the resource was last used. If the communications resource has never been opened, the system sets the time-out values to some default value. In either case, an application should always determine the current time-out values after opening the resource, and then explicitly set them to meet its requirements. To determine the current time-out values of a communications resource, use the GetCommTimeouts function. To change the time-out values, use the SetCommTimeouts function.

Two types of time-outs are enabled by the time-out parameters. An interval time-out occurs when the time between the receipt of any two characters exceeds a specified number of milliseconds. Timing starts when the first character is received and is restarted when each new character is received. A total time-out occurs when the total amount of time consumed by a read operation exceeds a calculated number of milliseconds. Timing starts immediately when the I/O operation begins. Write operations support only total time-outs. Read operations support both interval and total time-outs, which can be used separately or combined.

The time, in milliseconds, of the total time-out period for a read or write operation is calculated by using the multiplier and constant values from the COMMTIMEOUTS structure specified in the GetCommTimeouts or SetCommTimeouts function. The following formula is used:

Timeout = (MULTIPLIER * number_of_bytes) + CONSTANT

Using both a multiplier and a constant enables the total time-out period to vary, depending on the amount of data being requested. An application can use only the constant by setting the multiplier to zero, or use only the multiplier by setting the constant to zero. If both the constant and multiplier are zero, total time-out is not used.

If all read time-out parameters are zero, read time-outs are not used, and a read operation is not complete until the requested number of bytes have been read or an error occurs. Similarly, if all write time-out parameters are zero, a write operation is not completed until the requested number of bytes have been written or an error occurs.

If the read interval time-out parameter is the MAXDWORD value and both read total time-out parameters are zero, a read operation is completed immediately after reading whatever characters are available in the input buffer, even if it is empty.

Interval timing forces a read operation to return when there is a lull in reception. A process using interval time-outs can set a fairly short interval parameter, so it can respond quickly to small, isolated bursts of one or a few characters, yet it can still collect large buffers of characters with a single call when data is received in a steady stream.

Time-outs for a write operation can be useful when transmission is blocked by some kind of flow control or when the SetCommBreak function has been called to suspend character transmission.

The following table summarizes the behavior of read operations based on the values specified for total and interval time-outs.

Total | Interval | Behavior
0 | 0 | Returns when the buffer is completely filled. Time-outs are not used.
T | 0 | Returns when the buffer is completely filled or when T milliseconds have elapsed since the beginning of the operation.
0 | Y | Returns when the buffer is completely filled or when Y milliseconds have elapsed between the receipt of any two characters. Timing does not begin until the first character is received.
T | Y | Returns when the buffer is completely filled or when either type of time-out occurs.

Note, however, that timing is relative to the system controlling the physical device. For a remote device such as a modem, the timing is relative to the server system to which the modem is attached. Any network propagation delay is not factored in. For example, a client application might specify a total time-out that computes to be 500 milliseconds. When 500 milliseconds have elapsed at the server, a time-out error is returned to the client. If there is a 50 milliseconds network propagation delay, the client will not be notified of the time-out until approximately 50 milliseconds after the time-out actually occurred.

The time-out parameters affect the behavior of overlapped read and write operations on a communications device. With overlapped I/O, the ReadFile, WriteFile, ReadFileEx, or WriteFileEx function can return before the operation has been completed. The time-out parameters can determine when the operation has been completed.


Communications Errors

There are other circumstances where a read or write operation can be completed with fewer than the requested number of characters, even though a time-out has not occurred. Following are some examples:

  • Some drivers support the use of special characters, which complete a read operation immediately with only the characters that have been read up to the point when they are received.
  • The PurgeComm function can be called to prematurely terminate pending read or write operations. This function can also delete the contents of the output or input buffers, or both.
  • If a communications error occurs during a read or write operation, all I/O operations on the communications resource are terminated. Break conditions, parity errors, or framing errors are examples of such errors. When an error occurs, the process must call the ClearCommError function to clear the error flag before it can begin additional I/O operations. ClearCommError reports the specific error that occurred and the current status of the device.


Communications Events

A process can monitor a set of events that occur in a communications resource. For example, an application can use event monitoring to determine when the CTS (clear-to-send) and DSR (data-set-ready) signals change state.

A process can monitor events on a given communications resource by using the SetCommMask function to create an event mask. To determine the current event mask for a communications resource, a process can use the GetCommMask function. The following values specify events that can be monitored.

Value | Meaning
EV_BREAK | A break was detected on input.
EV_CTS | The CTS (clear-to-send) signal changed state.
EV_DSR | The DSR (data-set-ready) signal changed state.
EV_ERR | A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
EV_RING | A ring indicator was detected.
EV_RLSD | The RLSD (receive-line-signal-detect) signal changed state.
EV_RXCHAR | A character was received and placed in the input buffer.
EV_RXFLAG | The event character was received and placed in the input buffer. The event character is specified in the device's DCB structure, which is applied to a serial port by using the SetCommState function.
EV_TXEMPTY | The last character in the output buffer was sent.

After a set of events is specified, a process uses the WaitCommEvent function to wait for one of the events to occur. WaitCommEvent can be used synchronously or as an overlapped operation. For additional information about executing a function as an overlapped operation, see Synchronization.

When one of the events specified in the event mask occurs, the process completes the wait operation and sets an event mask variable to indicate the type of event detected. If the SetCommMask is called for a communications resource while a wait is pending for that resource, WaitCommEvent returns an error.

The WaitCommEvent function detects events that have occurred since the last call to SetCommMask or WaitCommEvent. For example, if you specify the EV_RXCHAR event as a wait-satisfying event, a call to WaitCommEvent will be satisfied if there are characters in the driver's input buffer that have arrived since the last call to WaitCommEvent or SetCommMask. Thus, given the following pseudo-code, any characters received between T1 and T2 will satisfy the next call to WaitCommEvent.

while (we_care)
{
    WaitCommEvent(args)

T1: // Read bytes
    // Process bytes

T2:
}

When monitoring an event that occurs when a signal (CTS, DSR, and so on) changes state, WaitCommEvent reports the change, but not the current state. To query the current state of the CTS (clear-to-send), DSR (data-set-ready), RLSD (receive-line-signal-detect), and ring indicator signals, a process can use the GetCommModemStatus function.


Extended Functions

Some communications functions can be called for a device by using the EscapeCommFunction function. This function sends a code to direct the device to execute an extended function. For example, an application can suspend character transmission with the SETBREAK code and resume transmission with the CLRBREAK code. These particular operations can also be started by calling the SetCommBreak and ClearCommBreak functions. EscapeCommFunction can also be used to implement manual modem control. For example, the CLRDTR and SETDTR codes can be used to implement manual DTR (data-terminal-ready) flow control. Note, however, that an error occurs if a process uses EscapeCommFunction to manipulate the DTR line when the device has been configured to enable DTR handshaking, or the RTS (request-to-send) line if RTS handshaking is enabled.

The DeviceIoControl function enables a process to send an extended function code directly to a specified device driver, causing the device to perform a given operation. DeviceIoControl gives a device associated with a communications resource capabilities not supported by the standard serial communications functions. It enables an application to configure a device using parameters unique to that device as well as to call any device-specific functions.


Using the Communications Functions

  • Configuring a communications resource
  • Monitoring communications events


Configuring a Communications Resource

The following example opens a handle to COM1 and fills in a DCB structure with the current configuration. The DCB structure is then modified and used to reconfigure the device.

DCB dcb;
HANDLE hCom;
DWORD dwError;
BOOL fSuccess;

hCom = CreateFile( "COM1",
    GENERIC_READ | GENERIC_WRITE,
    0,    // comm devices must be opened w/exclusive-access
    NULL, // no security attributes
    OPEN_EXISTING, // comm devices must use OPEN_EXISTING
    0,    // not overlapped I/O
    NULL  // hTemplate must be NULL for comm devices
    );

if (hCom == INVALID_HANDLE_VALUE)
{
    dwError = GetLastError();

    // handle error
}

// Omit the call to SetupComm to use the default queue sizes.
// Get the current configuration.

fSuccess = GetCommState(hCom, &dcb);

if (!fSuccess)
{
    // Handle the error.
}

// Fill in the DCB: baud=9600, 8 data bits, no parity, 1 stop bit.

dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;

fSuccess = SetCommState(hCom, &dcb);

if (!fSuccess)
{
    // Handle the error.
}


Monitoring Communications Events

The following example code opens the serial port for overlapped I/O, creates an event mask to monitor CTS and DSR signals, and then waits for an event to occur. The WaitCommEvent function should be executed as an overlapped operation so the other threads of the process cannot perform I/O operations during the wait.

HANDLE hCom;
OVERLAPPED o;
BOOL fSuccess;
DWORD dwEvtMask;

hCom = CreateFile( "COM1",
    GENERIC_READ | GENERIC_WRITE,
    0,    // exclusive access
    NULL, // no security attributes
    OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED,
    NULL
    );

if (hCom == INVALID_HANDLE_VALUE)
{
    // Handle the error.
}

// Set the event mask.

fSuccess = SetCommMask(hCom, EV_CTS | EV_DSR);

if (!fSuccess)
{
    // Handle the error.
}

// Create an event object for use in WaitCommEvent.

o.hEvent = CreateEvent(
    NULL,   // no security attributes
    FALSE,  // auto reset event
    FALSE,  // not signaled
    NULL    // no name
    );

assert(o.hEvent);

if (WaitCommEvent(hCom, &dwEvtMask, &o))
{
    if (dwEvtMask & EV_DSR)
    {
         // To do.
    }

    if (dwEvtMask & EV_CTS)
    {
         // To do.
    }
}


Communication Reference

The following elements are used with communications devices.

  • Communication Functions
  • Communication Structures


Communication Functions

The following functions are used with communications devices.

BuildCommDCB
BuildCommDCBAndTimeouts
ClearCommBreak
ClearCommError
CommConfigDialog
EscapeCommFunction
GetCommConfig
GetCommMask
GetCommModemStatus
GetCommProperties
GetCommState
GetCommTimeouts
GetDefaultCommConfig
PurgeComm
SetCommBreak
SetCommConfig
SetCommMask
SetCommState
SetCommTimeouts
SetDefaultCommConfig
SetupComm
TransmitCommChar
WaitCommEvent


BuildCommDCB

The BuildCommDCB function fills a specified DCB structure with values specified in a device-control string. The device-control string uses the syntax of the mode command.

BOOL BuildCommDCB(
  LPCTSTR lpDef,  // pointer to device-control string
  LPDCB lpDCB     // pointer to device-control block
);

Parameters

lpDef
Pointer to a null-terminated string that specifies device-control information. The string must have the same form as the mode command's command-line arguments. For example, the following string specifies a baud rate of 1200, no parity, 8 data bits, and 1 stop bit:
baud=1200 parity=N data=8 stop=1

The device name is ignored if it is included in the string, but it must specify a valid device, as follows:

COM1: baud=1200 parity=N data=8 stop=1

For further information on mode command syntax, refer to the end-user documentation for your operating system.

lpDCB
Pointer to a DCB structure to be filled in.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The BuildCommDCB function adjusts only those members of the DCB structure that are specifically affected by the lpDef parameter, with the following exceptions:

  • If the specified baud rate is 110, the function sets the stop bits to 2 to remain compatible with the system's mode command.
  • By default, BuildCommDCB disables XON/XOFF and hardware flow control. To enable flow control, you must explicitly set the appropriate members of the DCB structure.

The BuildCommDCB function only fills in the members of the DCB structure. To apply these settings to a serial port, use the SetCommState function.

There are older and newer forms of the mode command syntax. The BuildCommDCB function supports both forms. However, you cannot mix the two forms together.

The newer form of the mode command syntax lets you explicitly set the values of the flow control members of the DCB structure. If you use an older form of the mode syntax, the BuildCommDCB function sets the flow control members of the DCB structure, as follows:

  • For a string such as 96,n,8,1 or any other older-form mode string that doesn't end with an x or a p:

    fInX, fOutX,fOutXDsrFlow,and fOutXCtsFlow are all set to FALSE

    fDtrControl is set to DTR_CONTROL_ENABLE

    fRtsControl is set to RTS_CONTROL_ENABLE

  • For a string such as 96,n,8,1,x or any other older-form mode string that finishes with an x:

    fInX, fOutX are both set to TRUE

    fOutXDsrFlow,fOutXCtsFlow are both set to FALSE.

    fDtrControl is set to DTR_CONTROL_ENABLE

    fRtsControl is set to RTS_CONTROL_ENABLE

  • For a string such as 96,n,8,1,p or any other older-form mode string that finishes with a p:

    fInX, fOutX are both set to FALSE

    fOutXDsrFlow,fOutXCtsFlow are both set to TRUE.

    fDtrControl is set to DTR_CONTROL_HANDSHAKE

    fRtsControl is set to RTS_CONTROL_HANDSHAKE

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Communications Overview, Communication Functions, DCB, SetCommState


BuildCommDCBAndTimeouts

The BuildCommDCBAndTimeouts function translates a device-definition string into appropriate device-control block codes and then places these codes into a device control block. The function can also set up time-out values, including the possibility of no time-outs, for a device; the function's behavior in this regard varies based on the contents of the device-definition string.

BOOL BuildCommDCBAndTimeouts(
  LPCTSTR lpDef,                  // pointer to device-control string
  LPDCB lpDCB,                    // pointer to device-control block
  LPCOMMTIMEOUTS  lpCommTimeouts  // pointer to comm time-out structure
);

Parameters

lpDef
Pointer to a null-terminated string that specifies device-control information for the device. The function takes this string, parses it, and then sets appropriate values in the DCB structure pointed to by lpDCB.
lpDCB
Pointer to a DCB structure that the function fills with information from the device-control information string pointed to by lpDef. This DCB structure defines the control settings for a communications device.
lpCommTimeouts
Pointer to a COMMTIMEOUTS structure that the function can use to set device time-out values.

The BuildCommDcbAndTimeouts function modifies its time-out setting behavior based on the presence or absence of a "TO=xxx" substring in the string specified by lpDef:

  • If that string contains the substring "TO=ON", the function sets up total read and write time-out values for the device based on the time-out structure pointed to by lpCommTimeouts.
  • If that string contains the substring "TO=OFF", the function sets up the device with no time-outs.
  • If that string contains neither of the aforementioned "TO=xxx" substrings, the function ignores the time-out structure pointed to by lpCommTimeouts. The time-out structure will not be accessed.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Communications Overview, Communication Functions, BuildCommDCB, COMMTIMEOUTS, DCB, GetCommTimeouts, SetCommTimeouts


ClearCommBreak

The ClearCommBreak function restores character transmission for a specified communications device and places the transmission line in a nonbreak state.

BOOL ClearCommBreak(
  HANDLE hFile   // handle to communications device
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A communications device is placed in a break state by the SetCommBreak or EscapeCommFunction function. Character transmission is then suspended until the break state is cleared by calling ClearCommBreak.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, ClearCommError, CreateFile, EscapeCommFunction, SetCommBreak


ClearCommError

The ClearCommError function retrieves information about a communications error and reports the current status of a communications device. The function is called when a communications error occurs, and it clears the device's error flag to enable additional input and output (I/O) operations.

BOOL ClearCommError(
  HANDLE hFile,     // handle to communications device
  LPDWORD lpErrors, // pointer to variable to receive error codes
  LPCOMSTAT lpStat  // pointer to buffer for communications status
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.
lpErrors
Pointer to a 32-bit variable to be filled with a mask indicating the type of error. This parameter can be one or more of the following error codes:
Value | Meaning
CE_BREAK | The hardware detected a break condition.
CE_DNS | Windows 95 and Windows 98: A parallel device is not selected.
CE_FRAME | The hardware detected a framing error.
CE_IOE | An I/O error occurred during communications with the device.
CE_MODE | The requested mode is not supported, or the hFile parameter is invalid. If this value is specified, it is the only valid error.
CE_OOP | Windows 95 and Windows 98: A parallel device signaled that it is out of paper.
CE_OVERRUN | A character-buffer overrun has occurred. The next character is lost.
CE_PTO | Windows 95 and Windows 98: A time-out occurred on a parallel device.
CE_RXOVER | An input buffer overflow has occurred. There is either no room in the input buffer, or a character was received after the end-of-file (EOF) character.
CE_RXPARITY | The hardware detected a parity error.
CE_TXFULL | The application tried to transmit a character, but the output buffer was full.

lpStat
Pointer to a COMSTAT structure in which the device's status information is returned. If lpStat is NULL, no status information is returned.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If a communications port has been set up with a TRUE value for the fAbortOnError member of the setup DCB structure, the communications software will terminate all read and write operations on the communications port when a communications error occurs. No new read or write operations will be accepted until the application acknowledges the communications error by calling the ClearCommError function.

The ClearCommError function fills the status buffer pointed to by the lpStat parameter with the current status of the communications device specified by the hFile parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, ClearCommBreak, COMSTAT, CreateFile, DCB


CommConfigDialog

The CommConfigDialog function displays a driver-supplied configuration dialog box.

BOOL CommConfigDialog(
  LPTSTR lpszName,   // pointer to device name string
  HWND hWnd,         // handle to window
  LPCOMMCONFIG lpCC  // pointer to comm configuration structure
);

Parameters

lpszName
Pointer to a null-terminated string specifying the name of the device for which a dialog box should be displayed.
hWnd
Handle to the window that owns the dialog box. This parameter can be any valid window handle, or it should be NULL if the dialog box is to have no owner.
lpCC
Pointer to a COMMCONFIG structure. This structure contains initial settings for the dialog box before the call, and changed values after the call.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The CommConfigDialog function requires a dynamic-link library (DLL) provided by the communications hardware vendor.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Communications Overview, Communication Functions, COMMCONFIG


EscapeCommFunction

The EscapeCommFunction function directs a specified communications device to perform an extended function.

BOOL EscapeCommFunction(
  HANDLE hFile,  // handle to communications device
  DWORD dwFunc   // extended function to perform
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.
dwFunc
Specifies the code of the extended function to perform. This parameter can be one of the following values:
Value | Meaning
CLRDTR | Clears the DTR (data-terminal-ready) signal.
CLRRTS | Clears the RTS (request-to-send) signal.
SETDTR | Sends the DTR (data-terminal-ready) signal.
SETRTS | Sends the RTS (request-to-send) signal.
SETXOFF | Causes transmission to act as if an XOFF character has been received.
SETXON | Causes transmission to act as if an XON character has been received.
SETBREAK | Suspends character transmission and places the transmission line in a break state until the ClearCommBreak function is called (or EscapeCommFunction is called with the CLRBREAK extended function code). The SETBREAK extended function code is identical to the SetCommBreak function. Note that this extended function does not flush data that has not been transmitted.
CLRBREAK | Restores character transmission and places the transmission line in a nonbreak state. The CLRBREAK extended function code is identical to the ClearCommBreak function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows CE: Windows CE supports the following additional flags for the dwFunc parameter:

SETIR
Sets the serial port in IR mode.
CLRIR
Sets port into normal serial mode.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, ClearCommBreak, CreateFile, SetCommBreak


GetCommConfig

The GetCommConfig function gets the current configuration of a communications device.

BOOL GetCommConfig(
  HANDLE hCommDev,    // handle to communications service
  LPCOMMCONFIG lpCC,  // pointer to comm configuration structure
  LPDWORD lpdwSize    // pointer to size of buffer
);

Parameters

hCommDev
Handle to the open communications device.
lpCC
Pointer to the buffer that receives the COMMCONFIG structure.
lpdwSize
Pointer to a 32-bit variable that specifies the size, in bytes, of the buffer pointed to by lpCC. When the function returns, the variable contains the number of bytes copied if the function succeeds, or the number of bytes required if the buffer was too small.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, use the GetLastError function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, SetCommConfig, COMMCONFIG


GetCommMask

The GetCommMask function retrieves the value of the event mask for a specified communications device.

BOOL GetCommMask(
  HANDLE hFile,      // handle to communications device
  LPDWORD lpEvtMask  // pointer to variable to get event mask
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.
lpEvtMask
Pointer to the 32-bit variable to be filled with a mask of events that are currently enabled. This parameter can be one or more of the following values:
Value | Meaning
EV_BREAK | A break was detected on input.
EV_CTS | The CTS (clear-to-send) signal changed state.
EV_DSR | The DSR (data-set-ready) signal changed state.
EV_ERR | A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
EV_EVENT1 | An event of the first provider-specific type occured.
EV_EVENT2 | An event of the second provider-specific type occured.
EV_PERR | A printer error occured.
EV_RING | A ring indicator was detected.
EV_RLSD | The RLSD (receive-line-signal-detect) signal changed state.
EV_RX80FULL | The receive buffer is 80 percent full.
EV_RXCHAR | A character was received and placed in the input buffer.
EV_RXFLAG | The event character was received and placed in the input buffer. The event character is specified in the device's DCB structure, which is applied to a serial port by using the SetCommState function.
EV_TXEMPTY | The last character in the output buffer was sent.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The GetCommMask function uses a 32-bit mask variable to indicate the set of events that can be monitored for a particular communications resource. A handle to the communications resource can be specified in a call to the WaitCommEvent function, which waits for one of the events to occur. To modify the event mask of a communications resource, use the SetCommMask function.

Windows CE: Windows CE does not support the following values for the lpEvtMask parameter:

EV_EVENT1

EV_EVENT2

EV_RX80FULL

EV_PERR

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, CreateFile, DCB, SetCommMask, WaitCommEvent,


GetCommModemStatus

The GetCommModemStatus function retrieves modem control-register values.

BOOL GetCommModemStatus(
  HANDLE hFile,        // handle to communications device
  LPDWORD lpModemStat  // pointer to control-register values
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.
lpModemStat
Pointer to a 32-bit variable that specifies the current state of the modem control-register values. This parameter can be a combination of the following values:
Value | Meaning
MS_CTS_ON | The CTS (clear-to-send) signal is on.
MS_DSR_ON | The DSR (data-set-ready) signal is on.
MS_RING_ON | The ring indicator signal is on.
MS_RLSD_ON | The RLSD (receive-line-signal-detect) signal is on.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The GetCommModemStatus function is useful when you are using the WaitCommEvent function to monitor the CTS, RLSD, DSR, or ring indicator signals. To detect when these signals change state, use WaitCommEvent and then use GetCommModemStatus to determine the state after a change occurs.

The function fails if the hardware does not support the control-register values.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, CreateFile, WaitCommEvent


GetCommProperties

The GetCommProperties function fills a buffer with information about the communications properties for a specified communications device.

BOOL GetCommProperties(
  HANDLE hFile,           // handle to comm device
  LPCOMMPROP lpCommProp   // pointer to comm properties structure
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.
lpCommProp
Pointer to a COMMPROP structure in which the communications properties information is returned. This information can be used in subsequent calls to the SetCommState, SetCommTimeouts, or SetupComm function to configure the communications device.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The GetCommProperties function returns information from a device driver about the configuration settings that are supported by the driver.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, COMMPROP, CreateFile, SetCommState, SetCommTimeouts, SetupComm


GetCommState

The GetCommState function fills in a device-control block (a DCB structure) with the current control settings for a specified communications device.

BOOL GetCommState(
  HANDLE hFile,  // handle to communications device
  LPDCB lpDCB    // pointer to device-control block structure
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.
lpDCB
Pointer to the DCB structure in which the control settings information is returned.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, CreateFile, DCB, SetCommState


GetCommTimeouts

The GetCommTimeouts function retrieves the time-out parameters for all read and write operations on a specified communications device.

BOOL GetCommTimeouts(
  HANDLE hFile,                  // handle to comm device
  LPCOMMTIMEOUTS lpCommTimeouts  // pointer to comm time-outs structure
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.
lpCommTimeouts
Pointer to a COMMTIMEOUTS structure in which the time-out information is returned.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

For more information about time-out values for communications devices, see the SetCommTimeouts function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, CreateFile, COMMTIMEOUTS, SetCommTimeouts


GetDefaultCommConfig

The GetDefaultCommConfig function gets the default configuration for a communications device.

BOOL GetDefaultCommConfig(
  LPCSTR lpszName,    // pointer to device name string
  LPCOMMCONFIG lpCC,  // pointer to buffer that receives structure
  LPDWORD lpdwSize    // pointer to size of buffer
);

Parameters

lpszName
Pointer to a null-terminated string specifying the name of the device.
lpCC
Pointer to the buffer that receives the COMMCONFIG structure.
lpdwSize
Pointer to a 32-bit variable that specifies the size, in bytes, of the buffer pointed to by lpCC. Upon return, the variable contains the number of bytes copied if the function succeeds, or the number of bytes required if the buffer was too small.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, use the GetLastError function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Communications Overview, Communication Functions, SetDefaultCommConfig, COMMCONFIG


PurgeComm

The PurgeComm function can discard all characters from the output or input buffer of a specified communications resource. It can also terminate pending read or write operations on the resource.

BOOL PurgeComm(
  HANDLE hFile,  // handle to communications resource
  DWORD dwFlags  // action to perform
);

Parameters

hFile
Handle to the communications resource. The CreateFile function returns this handle.
dwFlags
Specifies the action to take. This parameter can be a combination of the following values:
Value | Meaning
PURGE_TXABORT | Terminates all outstanding overlapped write operations and returns immediately, even if the write operations have not been completed.
PURGE_RXABORT | Terminates all outstanding overlapped read operations and returns immediately, even if the read operations have not been completed.
PURGE_TXCLEAR | Clears the output buffer (if the device driver has one).
PURGE_RXCLEAR | Clears the input buffer (if the device driver has one).

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If a thread uses PurgeComm to flush an output buffer, the deleted characters are not transmitted. To empty the output buffer while ensuring that the contents are transmitted, call the FlushFileBuffers function (a synchronous operation). Note, however, that FlushFileBuffers is subject to flow control but not to write time-outs, and it will not return until all pending write operations have been transmitted.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, CreateFile


SetCommBreak

The SetCommBreak function suspends character transmission for a specified communications device and places the transmission line in a break state until the ClearCommBreak function is called.

BOOL SetCommBreak(
  HANDLE hFile   // handle to communications device
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, ClearCommBreak, CreateFile


SetCommConfig

The SetCommConfig function sets the current configuration of a communications device.

BOOL SetCommConfig(
  HANDLE hCommDev,    // handle to comm device
  LPCOMMCONFIG lpCC,  // pointer to comm configuration services
  DWORD dwSize        // size of structure
);

Parameters

hCommDev
Handle to the open communications device.
lpCC
Pointer to a COMMCONFIG structure.
dwSize
Specifies the size, in bytes, of the structure pointed to by lpCC.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, GetCommConfig, COMMCONFIG


SetCommMask

The SetCommMask function specifies a set of events to be monitored for a communications device.

BOOL SetCommMask(
  HANDLE hFile,    // handle to communications device
  DWORD dwEvtMask  // mask that identifies enabled events
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.
dwEvtMask
Specifies the events to be enabled. A value of zero disables all events. This parameter can be a combination of the following values:
Value | Meaning
EV_BREAK | A break was detected on input.
EV_CTS | The CTS (clear-to-send) signal changed state.
EV_DSR | The DSR (data-set-ready) signal changed state.
EV_ERR | A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
EV_RING | A ring indicator was detected.
EV_RLSD | The RLSD (receive-line-signal-detect) signal changed state.
EV_RXCHAR | A character was received and placed in the input buffer.
EV_RXFLAG | The event character was received and placed in the input buffer. The event character is specified in the device's DCB structure, which is applied to a serial port by using the SetCommState function.
EV_TXEMPTY | The last character in the output buffer was sent.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The SetCommMask function specifies the set of events that can be monitored for a particular communications resource. A handle to the communications resource can be specified in a call to the WaitCommEvent function, which waits for one of the events to occur. To get the current event mask of a communications resource, use the GetCommMask function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, CreateFile, DCB, GetCommMask, SetCommState, WaitCommEvent


SetCommState

The SetCommState function configures a communications device according to the specifications in a device-control block (a DCB structure). The function reinitializes all hardware and control settings, but it does not empty output or input queues.

BOOL SetCommState(
  HANDLE hFile,  // handle to communications device
  LPDCB lpDCB    // pointer to device-control block structure
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.
lpDCB
Pointer to a DCB structure containing the configuration information for the specified communications device.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The SetCommState function uses a DCB structure to specify the desired configuration. The GetCommState function returns the current configuration.

To set only a few members of the DCB structure, you should modify a DCB structure that has been filled in by a call to GetCommState. This ensures that the other members of the DCB structure have appropriate values.

The SetCommState function fails if the XonChar member of the DCB structure is equal to the XoffChar member.

When SetCommState is used to configure the 8250, the following restrictions apply to the values for the DCB structure's ByteSize and StopBits members:

  • The number of data bits must be 5 to 8 bits.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, BuildCommDCB, CreateFile, DCB, GetCommState


SetCommTimeouts

The SetCommTimeouts function sets the time-out parameters for all read and write operations on a specified communications device.

BOOL SetCommTimeouts(
  HANDLE hFile,                  // handle to comm device
  LPCOMMTIMEOUTS lpCommTimeouts  // pointer to comm time-out structure
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.
lpCommTimeouts
Pointer to a COMMTIMEOUTS structure that contains the new time-out values.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, COMMTIMEOUTS, GetCommTimeouts, ReadFile, ReadFileEx, WriteFile, WriteFileEx


SetDefaultCommConfig

The SetDefaultCommConfig function sets the default configuration for a communications device.

BOOL SetDefaultCommConfig(
  LPCSTR lpszName,    // pointer to device name string
  LPCOMMCONFIG lpCC,  // pointer to structure
  DWORD dwSize        // size of structure
);

Parameters

lpszName
Pointer to a null-terminated string specifying the name of the device.
lpCC
Pointer to a COMMCONFIG structure.
dwSize
Specifies the size, in bytes, of the structure pointed to by lpCC.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Communications Overview, Communication Functions, GetDefaultCommConfig, COMMCONFIG


SetupComm

The SetupComm function initializes the communications parameters for a specified communications device.

BOOL SetupComm(
  HANDLE hFile,     // handle to communications device
  DWORD dwInQueue,  // size of input buffer
  DWORD dwOutQueue  // size of output buffer
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.
dwInQueue
Specifies the recommended size, in bytes, of the device's internal input buffer.
dwOutQueue
Specifies the recommended size, in bytes, of the device's internal output buffer.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

After a process uses the CreateFile function to open a handle to a communications device, it can call SetupComm to set the communications parameters for the device. If it does not set them, the device uses the default parameters when the first call to another communications function occurs.

The dwInQueue and dwOutQueue parameters specify the recommended sizes for the internal buffers used by the driver for the specified device. For example, YMODEM protocol packets are slightly larger than 1024 bytes. Therefore, a recommended buffer size might be 1200 bytes for YMODEM communications. For Ethernet-based communications, a recommended buffer size might be 1600 bytes, which is slightly larger than a single Ethernet frame.

The device driver receives the recommended buffer sizes, but is free to use any input and output (I/O) buffering scheme, as long as it provides reasonable performance and data is not lost due to overrun (except under extreme circumstances). For example, the function can succeed even though the driver does not allocate a buffer, as long as some other portion of the system provides equivalent functionality.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, CreateFile, SetCommState


TransmitCommChar

The TransmitCommChar function transmits a specified character ahead of any pending data in the output buffer of the specified communications device.

BOOL TransmitCommChar(
  HANDLE hFile,  // handle to communications device
  char cChar     // character to transmit
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.
cChar
Specifies the character to be transmitted.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The TransmitCommChar function is useful for sending an interrupt character (such as a ctrl+c) to a host system.

If the device is not transmitting, TransmitCommChar cannot be called repeatedly. Once TransmitCommChar places a character in the output buffer, the character must be transmitted before the function can be called again. If the previous character has not yet been sent, TransmitCommChar returns an error.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, CreateFile, WaitCommEvent


WaitCommEvent

The WaitCommEvent function waits for an event to occur for a specified communications device. The set of events that are monitored by this function is contained in the event mask associated with the device handle.

BOOL WaitCommEvent(
  HANDLE hFile,                // handle to communications device
  LPDWORD lpEvtMask,           // pointer to variable to receive event
  LPOVERLAPPED lpOverlapped,   // pointer to overlapped structure
);

Parameters

hFile
Handle to the communications device. The CreateFile function returns this handle.
lpEvtMask
Pointer to a 32-bit variable that receives a mask indicating the type of event that occurred. If an error occurs, the value is zero; otherwise, it is one of the following values:
Value | Meaning
EV_BREAK | A break was detected on input.
EV_CTS | The CTS (clear-to-send) signal changed state.
EV_DSR | The DSR (data-set-ready) signal changed state.
EV_ERR | A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY.
EV_RING | A ring indicator was detected.
EV_RLSD | The RLSD (receive-line-signal-detect) signal changed state.
EV_RXCHAR | A character was received and placed in the input buffer.
EV_RXFLAG | The event character was received and placed in the input buffer. The event character is specified in the device's DCB structure, which is applied to a serial port by using the SetCommState function.
EV_TXEMPTY | The last character in the output buffer was sent.

lpOverlapped
Pointer to an OVERLAPPED structure. This structure is required if hFile was opened with FILE_FLAG_OVERLAPPED.

If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the operation is complete.

If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, WaitCommEvent is performed as an overlapped operation. In this case, the OVERLAPPED structure must contain a handle to a manual-reset event object (created by using the CreateEvent function).

If hFile handle was not opened with FILE_FLAG_OVERLAPPED, WaitCommEvent does not return until one of the specified events or an error occurs.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The WaitCommEvent function monitors a set of events for a specified communications resource. To set and query the current event mask of a communications resource, use the SetCommMask and GetCommMask functions.

If the overlapped operation cannot be completed immediately, the function returns FALSE and the GetLastError function returns ERROR_IO_PENDING, indicating that the operation is executing in the background. When this happens, the system sets the hEvent member of the OVERLAPPED structure to the not-signaled state before WaitCommEvent returns, and then it sets it to the signaled state when one of the specified events or an error occurs. The calling process can use one of the wait functions to determine the event object's state and then use the GetOverlappedResult function to determine the results of the WaitCommEvent operation. GetOverlappedResult reports the success or failure of the operation, and the variable pointed to by the lpEvtMask parameter is set to indicate the event that occurred.

If a process attempts to change the device handle's event mask by using the SetCommMask function while an overlapped WaitCommEvent operation is in progress, WaitCommEvent returns immediately. The variable pointed to by the lpEvtMask parameter is set to zero.

Windows CE: Windows CE supports an additional flag for the lpEvtMask parameter:

EV_POWER
Power event, which is generated whenever the device is powered on.

The WaitCommEvent function cannot be performed as an overlapped operation. The lpOverlapped parameter is not supported and is ignored. It should be set to NULL before calling WaitCommEvent.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Communications Overview, Communication Functions, CreateFile, DCB, GetCommMask, GetOverlappedResult, OVERLAPPED, SetCommMask, SetCommState


Communication Structures

The following structures are used with communications devices.

COMMCONFIG
COMMPROP
COMMTIMEOUTS
COMSTAT
DCB
MODEMDEVCAPS
MODEMSETTINGS


COMMCONFIG

The COMMCONFIG structure contains information about the configuration state of a communications device.

typedef struct _COMM_CONFIG {
    DWORD dwSize;             // size of structure
    WORD  wVersion;           // version of structure
    WORD  wReserved;          // reserved
    DCB   dcb;                // device-control block
    DWORD dwProviderSubType;  // type of provider-specific data
    DWORD dwProviderOffset;   // offset of provider-specific data
    DWORD dwProviderSize;     // size of provider-specific data
    WCHAR wcProviderData[1];  // provider-specific data
} COMMCONFIG, *LPCOMMCONFIG;

Members

dwSize
Specifies the size, in bytes, of the COMMCONFIG structure.
wVersion
Specifies the version number of the COMMCONFIG structure. This parameter can be 1. The version of the provider-specific structure should be included in the wcProviderData member.
wReserved
Reserved; do not use.
dcb
Specifies a device-control block (DCB) structure for RS-232 serial devices. A DCB structure is always present regardless of the port driver subtype specified in the device's COMMPROP structure.
dwProviderSubType
Identifies the type of communications provider, and thus the format of the provider-specific data. For a list of communications provider types, see the description of the COMMPROP structure.
dwProviderOffset
Specifies the offset, in bytes, of the provider-specific data relative to the beginning of the structure. This member is zero if there is no provider-specific data.
dwProviderSize
Specifies the size, in bytes, of the provider-specific data.
wcProviderData
Contains the provider-specific data, if any. This member may be of any size or may be omitted. Because the COMMCONFIG structure may be expanded in the future, applications should use the dwProviderOffset member to determine the location of this member.

Remarks

If the provider subtype is PST_RS232 or PST_PARALLELPORT the wcProviderData member is omitted. If the provider subtype is PST_MODEM, the wcProviderData member contains a MODEMSETTINGS structure.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Communications Overview, Communication Structures, DCB, COMMPROP, GetCommProperties, MODEMSETTINGS


COMMPROP

The COMMPROP structure is used by the GetCommProperties function to return information about a given communications driver.

typedef struct _COMMPROP {
    WORD  wPacketLength;       // packet size, in bytes
    WORD  wPacketVersion;      // packet version
    DWORD dwServiceMask;       // services implemented
    DWORD dwReserved1;         // reserved
    DWORD dwMaxTxQueue;        // max Tx bufsize, in bytes
    DWORD dwMaxRxQueue;        // max Rx bufsize, in bytes
    DWORD dwMaxBaud;           // max baud rate, in bps
    DWORD dwProvSubType;       // specific provider type
    DWORD dwProvCapabilities;  // capabilities supported
    DWORD dwSettableParams;    // changeable parameters
    DWORD dwSettableBaud;      // allowable baud rates
    WORD  wSettableData;       // allowable byte sizes
    WORD  wSettableStopParity; // stop bits/parity allowed
    DWORD dwCurrentTxQueue;    // Tx buffer size, in bytes
    DWORD dwCurrentRxQueue;    // Rx buffer size, in bytes
    DWORD dwProvSpec1;         // provider-specific data
    DWORD dwProvSpec2;         // provider-specific data
    WCHAR wcProvChar[1];       // provider-specific data
} COMMPROP;

Members

wPacketLength
Specifies the size, in bytes, of the entire data packet, regardless of the amount of data requested.
wPacketVersion
Specifies the version of the structure.
dwServiceMask
Specifies a bitmask indicating which services are implemented by this provider. The SP_SERIALCOMM value is always specified for communications providers, including modem providers.
dwReserved1
Reserved; do not use.
dwMaxTxQueue
Specifies the maximum size, in bytes, of the driver's internal output buffer. A value of zero indicates that no maximum value is imposed by the serial provider.
dwMaxRxQueue
Specifies the maximum size, in bytes, of the driver's internal input buffer. A value of zero indicates that no maximum value is imposed by the serial provider.
dwMaxBaud
Specifies the maximum allowable baud rate, in bits per second (bps). This member can be one of the following values:
Value | Meaning
BAUD_075 | 75 bps
BAUD_110 | 110 bps
BAUD_134_5 | 134.5 bps
BAUD_150 | 150 bps
BAUD_300 | 300 bps
BAUD_600 | 600 bps
BAUD_1200 | 1200 bps
BAUD_1800 | 1800 bps
BAUD_2400 | 2400 bps
BAUD_4800 | 4800 bps
BAUD_7200 | 7200 bps
BAUD_9600 | 9600 bps
BAUD_14400 | 14400 bps
BAUD_19200 | 19200 bps
BAUD_38400 | 38400 bps
BAUD_56K | 56K bps
BAUD_57600 | 57600 bps
BAUD_115200 | 115200 bps
BAUD_128K | 128K bps
BAUD_USER | Programmable baud rates available

dwProvSubType
Specifies the specific communications provider type:
Value | Meaning
PST_FAX | FAX device
PST_LAT | LAT protocol
PST_MODEM | Modem device
PST_NETWORK_BRIDGE | Unspecified network bridge
PST_PARALLELPORT | Parallel port
PST_RS232 | RS-232 serial port
PST_RS422 | RS-422 port
PST_RS423 | RS-423 port
PST_RS449 | RS-449 port
PST_SCANNER | Scanner device
PST_TCPIP_TELNET | TCP/IP Telnet® protocol
PST_UNSPECIFIED | Unspecified
PST_X25 | X.25 standards

dwProvCapabilities
Specifies a bitmask indicating the capabilities offered by the provider. This member can be one of the following values:
Value | Meaning
PCF_16BITMODE | Special 16-bit mode supported
PCF_DTRDSR | DTR (data-terminal-ready)/DSR (data-set-ready) supported
PCF_INTTIMEOUTS | Interval time-outs supported
PCF_PARITY_CHECK | Parity checking supported
PCF_RLSD | RLSD (receive-line-signal-detect) supported
PCF_RTSCTS | RTS (request-to-send)/CTS (clear-to-send) supported
PCF_SETXCHAR | Settable XON/XOFF supported
PCF_SPECIALCHARS | Special character support provided
PCF_TOTALTIMEOUTS | Total (elapsed) time-outs supported
PCF_XONXOFF | XON/XOFF flow control supported

dwSettableParams
Specifies a bitmask indicating the communications parameter that can be changed. This member can be one of the following values:
Value | Meaning
SP_BAUD | Baud rate
SP_DATABITS | Data bits
SP_HANDSHAKING | Handshaking (flow control)
SP_PARITY | Parity
SP_PARITY_CHECK | Parity checking
SP_RLSD | RLSD (receive-line-signal-detect)
SP_STOPBITS | Stop bits

dwSettableBaud
Specifies a bitmask indicating the baud rates that can be used. For values, see the dwMaxBaud member.
wSettableData
Specifies a bitmask indicating the number of data bits that can be set. This member can be one of the following values:
Value | Meaning
DATABITS_5 | 5 data bits
DATABITS_6 | 6 data bits
DATABITS_7 | 7 data bits
DATABITS_8 | 8 data bits
DATABITS_16 | 16 data bits
DATABITS_16X | Special wide path through serial hardware lines

wSettableStopParity
Specifies a bitmask indicating the stop bit and parity settings that can be selected. This member can be one of the following values:
Value | Meaning
STOPBITS_10 | 1 stop bit
STOPBITS_15 | 1.5 stop bits
STOPBITS_20 | 2 stop bits
PARITY_NONE | No parity
PARITY_ODD | Odd parity
PARITY_EVEN | Even parity
PARITY_MARK | Mark parity
PARITY_SPACE | Space parity

dwCurrentTxQueue
Specifies the size, in bytes, of the driver's internal output buffer. A value of zero indicates that the value is unavailable.
dwCurrentRxQueue
Specifies the size, in bytes, of the driver's internal input buffer. A value of zero indicates that the value is unavailable.
dwProvSpec1
Specifies provider-specific data. Applications should ignore this member unless they have detailed information about the format of the data required by the provider.

Set this member to COMMPROP_INITIALIZED before calling the GetCommProperties function to indicate that the wPacketLength member is already valid.

dwProvSpec2
Specifies provider-specific data. Applications should ignore this member unless they have detailed information about the format of the data required by the provider.
wcProvChar
Specifies provider-specific data. Applications should ignore this member unless they have detailed information about the format of the data required by the provider.

Remarks

The contents of the dwProvSpec1, dwProvSpec2, and wcProvChar members depend on the provider subtype (specified by the dwProvSubType member).

If the provider subtype is PST_MODEM, these members are used as follows:

Value | Meaning
dwProvSpec1 | Not used.
dwProvSpec2 | Not used.
wcProvChar | Contains a MODEMDEVCAPS structure.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.

See Also

Communications Overview, Communication Structures, GetCommProperties


COMMTIMEOUTS

The COMMTIMEOUTS structure is used in the SetCommTimeouts and GetCommTimeouts functions to set and query the time-out parameters for a communications device. The parameters determine the behavior of ReadFile, WriteFile, ReadFileEx, and WriteFileEx operations on the device.

typedef struct _COMMTIMEOUTS {
    DWORD ReadIntervalTimeout;
    DWORD ReadTotalTimeoutMultiplier;
    DWORD ReadTotalTimeoutConstant;
    DWORD WriteTotalTimeoutMultiplier;
    DWORD WriteTotalTimeoutConstant;
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

Members

ReadIntervalTimeout
Specifies the maximum time, in milliseconds, allowed to elapse between the arrival of two characters on the communications line. During a ReadFile operation, the time period begins when the first character is received. If the interval between the arrival of any two characters exceeds this amount, the ReadFile operation is completed and any buffered data is returned. A value of zero indicates that interval time-outs are not used.

A value of MAXDWORD, combined with zero values for both the ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members, specifies that the read operation is to return immediately with the characters that have already been received, even if no characters have been received.

ReadTotalTimeoutMultiplier
Specifies the multiplier, in milliseconds, used to calculate the total time-out period for read operations. For each read operation, this value is multiplied by the requested number of bytes to be read.
ReadTotalTimeoutConstant
Specifies the constant, in milliseconds, used to calculate the total time-out period for read operations. For each read operation, this value is added to the product of the ReadTotalTimeoutMultiplier member and the requested number of bytes.

A value of zero for both the ReadTotalTimeoutMultiplier and ReadTotalTimeoutConstant members indicates that total time-outs are not used for read operations.

WriteTotalTimeoutMultiplier
Specifies the multiplier, in milliseconds, used to calculate the total time-out period for write operations. For each write operation, this value is multiplied by the number of bytes to be written.
WriteTotalTimeoutConstant
Specifies the constant, in milliseconds, used to calculate the total time-out period for write operations. For each write operation, this value is added to the product of the WriteTotalTimeoutMultiplier member and the number of bytes to be written.

A value of zero for both the WriteTotalTimeoutMultiplier and WriteTotalTimeoutConstant members indicates that total time-outs are not used for write operations.

Remarks

If an application sets ReadIntervalTimeout and ReadTotalTimeoutMultiplier to MAXDWORD and sets ReadTotalTimeoutConstant to a value greater than zero and less than MAXDWORD, one of the following occurs when the ReadFile function is called:

  • If there are any characters in the input buffer, ReadFile returns immediately with the characters in the buffer.
  • If there are no characters in the input buffer, ReadFile waits until a character arrives and then returns immediately.
  • If no character arrives within the time specified by ReadTotalTimeoutConstant, ReadFile times out.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.

See Also

Communications Overview, Communication Structures, GetCommTimeouts, ReadFile, ReadFileEx, SetCommTimeouts, WriteFile, WriteFileEx


COMSTAT

The COMSTAT structure contains information about a communications device. This structure is filled by the ClearCommError function.

typedef struct _COMSTAT {
    DWORD fCtsHold : 1;   // Tx waiting for CTS signal
    DWORD fDsrHold : 1;   // Tx waiting for DSR signal
    DWORD fRlsdHold : 1;  // Tx waiting for RLSD signal
    DWORD fXoffHold : 1;  // Tx waiting, XOFF char received
    DWORD fXoffSent : 1;  // Tx waiting, XOFF char sent
    DWORD fEof : 1;       // EOF character sent
    DWORD fTxim : 1;      // character waiting for Tx
    DWORD fReserved : 25; // reserved
    DWORD cbInQue;        // bytes in input buffer
    DWORD cbOutQue;       // bytes in output buffer
} COMSTAT, *LPCOMSTAT;

Members

fCtsHold
Specifies whether transmission is waiting for the CTS (clear-to-send) signal to be sent. If this member is TRUE, transmission is waiting.
fDsrHold
Specifies whether transmission is waiting for the DSR (data-set-ready) signal to be sent. If this member is TRUE, transmission is waiting.
fRlsdHold
Specifies whether transmission is waiting for the RLSD (receive-line-signal-detect) signal to be sent. If this member is TRUE, transmission is waiting.
fXoffHold
Specifies whether transmission is waiting because the XOFF character was received. If this member is TRUE, transmission is waiting.
fXoffSent
Specifies whether transmission is waiting because the XOFF character was transmitted. If this member is TRUE, transmission is waiting. Transmission halts when the XOFF character is transmitted to a system that takes the next character as XON, regardless of the actual character.
fEof
Specifies whether the end-of-file (EOF) character has been received. If this member is TRUE, the EOF character has been received.
fTxim
If this member is TRUE, there is a character queued for transmission that has come to the communications device by way of the TransmitCommChar function. The communications device transmits such a character ahead of other characters in the device's output buffer.
fReserved
Reserved; do not use.
cbInQue
Specifies the number of bytes received by the serial provider but not yet read by a ReadFile operation.
cbOutQue
Specifies the number of bytes of user data remaining to be transmitted for all write operations. This value will be zero for a nonoverlapped write.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.

See Also

Communications Overview, Communication Structures, ClearCommError, ReadFile, TransmitCommChar


DCB

The DCB structure defines the control setting for a serial communications device.

typedef struct _DCB { // dcb
    DWORD DCBlength;           // sizeof(DCB)
    DWORD BaudRate;            // current baud rate
    DWORD fBinary: 1;          // binary mode, no EOF check
    DWORD fParity: 1;          // enable parity checking
    DWORD fOutxCtsFlow:1;      // CTS output flow control
    DWORD fOutxDsrFlow:1;      // DSR output flow control
    DWORD fDtrControl:2;       // DTR flow control type
    DWORD fDsrSensitivity:1;   // DSR sensitivity
    DWORD fTXContinueOnXoff:1; // XOFF continues Tx
    DWORD fOutX: 1;            // XON/XOFF out flow control
    DWORD fInX: 1;             // XON/XOFF in flow control
    DWORD fErrorChar: 1;       // enable error replacement
    DWORD fNull: 1;            // enable null stripping
    DWORD fRtsControl:2;       // RTS flow control
    DWORD fAbortOnError:1;     // abort reads/writes on error
    DWORD fDummy2:17;          // reserved
    WORD wReserved;            // not currently used
    WORD XonLim;               // transmit XON threshold
    WORD XoffLim;              // transmit XOFF threshold
    BYTE ByteSize;             // number of bits/byte, 4-8
    BYTE Parity;               // 0-4=no,odd,even,mark,space
    BYTE StopBits;             // 0,1,2 = 1, 1.5, 2
    char XonChar;              // Tx and Rx XON character
    char XoffChar;             // Tx and Rx XOFF character
    char ErrorChar;            // error replacement character
    char EofChar;              // end of input character
    char EvtChar;              // received event character
    WORD wReserved1;           // reserved; do not use
} DCB;

Members

DCBlength
Specifies the length, in bytes, of the DCB structure.
BaudRate
Specifies the baud rate at which the communications device operates. This member can be an actual baud rate value, or one of the following baud rate indexes:
CBR_110 | CBR_19200
CBR_300 | CBR_38400
CBR_600 | CBR_56000
CBR_1200 | CBR_57600
CBR_2400 | CBR_115200
CBR_4800 | CBR_128000
CBR_9600 | CBR_256000
CBR_14400

fBinary
Specifies whether binary mode is enabled. The Win32 API does not support nonbinary mode transfers, so this member must be TRUE. Using FALSE will not work.
fParity
Specifies whether parity checking is enabled. If this member is TRUE, parity checking is performed and errors are reported.
fOutxCtsFlow
Specifies whether the CTS (clear-to-send) signal is monitored for output flow control. If this member is TRUE and CTS is turned off, output is suspended until CTS is sent again.
fOutxDsrFlow
Specifies whether the DSR (data-set-ready) signal is monitored for output flow control. If this member is TRUE and DSR is turned off, output is suspended until DSR is sent again.
fDtrControl
Specifies the DTR (data-terminal-ready) flow control. This member can be one of the following values:
Value | Meaning
DTR_CONTROL_DISABLE | Disables the DTR line when the device is opened and leaves it disabled.
DTR_CONTROL_ENABLE | Enables the DTR line when the device is opened and leaves it on.
DTR_CONTROL_HANDSHAKE | Enables DTR handshaking. If handshaking is enabled, it is an error for the application to adjust the line by using the EscapeCommFunction function.

fDsrSensitivity
Specifies whether the communications driver is sensitive to the state of the DSR signal. If this member is TRUE, the driver ignores any bytes received, unless the DSR modem input line is high.
fTXContinueOnXoff
Specifies whether transmission stops when the input buffer is full and the driver has transmitted the XoffChar character. If this member is TRUE, transmission continues after the input buffer has come within XoffLim bytes of being full and the driver has transmitted the XoffChar character to stop receiving bytes. If this member is FALSE, transmission does not continue until the input buffer is within XonLim bytes of being empty and the driver has transmitted the XonChar character to resume reception.
fOutX
Specifies whether XON/XOFF flow control is used during transmission. If this member is TRUE, transmission stops when the XoffChar character is received and starts again when the XonChar character is received.
fInX
Specifies whether XON/XOFF flow control is used during reception. If this member is TRUE, the XoffChar character is sent when the input buffer comes within XoffLim bytes of being full, and the XonChar character is sent when the input buffer comes within XonLim bytes of being empty.
fErrorChar
Specifies whether bytes received with parity errors are replaced with the character specified by the ErrorChar member. If this member is TRUE and the fParity member is TRUE, replacement occurs.
fNull
Specifies whether null bytes are discarded. If this member is TRUE, null bytes are discarded when received.
fRtsControl
Specifies the RTS (request-to-send) flow control. If this value is zero, the default is RTS_CONTROL_HANDSHAKE. This member can be one of the following values:
Value | Meaning
RTS_CONTROL_DISABLE | Disables the RTS line when the device is opened and leaves it disabled.
RTS_CONTROL_ENABLE | Enables the RTS line when the device is opened and leaves it on.
RTS_CONTROL_HANDSHAKE | Enables RTS handshaking. The driver raises the RTS line when the "type-ahead" (input) buffer is less than one-half full and lowers the RTS line when the buffer is more than three-quarters full. If handshaking is enabled, it is an error for the application to adjust the line by using the EscapeCommFunction function.
RTS_CONTROL_TOGGLE | Specifies that the RTS line will be high if bytes are available for transmission. After all buffered bytes have been sent, the RTS line will be low.

fAbortOnError
Specifies whether read and write operations are terminated if an error occurs. If this member is TRUE, the driver terminates all read and write operations with an error status if an error occurs. The driver will not accept any further communications operations until the application has acknowledged the error by calling the ClearCommError function.
fDummy2
Reserved; do not use.
wReserved
Not used; must be set to zero.
XonLim
Specifies the minimum number of bytes allowed in the input buffer before the XON character is sent.
XoffLim
Specifies the maximum number of bytes allowed in the input buffer before the XOFF character is sent. The maximum number of bytes allowed is calculated by subtracting this value from the size, in bytes, of the input buffer.
ByteSize
Specifies the number of bits in the bytes transmitted and received.
Parity
Specifies the parity scheme to be used. This member can be one of the following values:
Value | Meaning
EVENPARITY | Even
MARKPARITY | Mark
NOPARITY | No parity
ODDPARITY | Odd
SPACEPARITY | Space

StopBits
Specifies the number of stop bits to be used. This member can be one of the following values:
Value | Meaning
ONESTOPBIT | 1 stop bit
ONE5STOPBITS | 1.5 stop bits
TWOSTOPBITS | 2 stop bits

XonChar
Specifies the value of the XON character for both transmission and reception.
XoffChar
Specifies the value of the XOFF character for both transmission and reception.
ErrorChar
Specifies the value of the character used to replace bytes received with a parity error.
EofChar
Specifies the value of the character used to signal the end of data.
EvtChar
Specifies the value of the character used to signal an event.
wReserved1
Reserved; do not use.

Remarks

When a DCB structure is used to configure the 8250, the following restrictions apply to the values specified for the ByteSize and StopBits members:

  • The number of data bits must be 5 to 8 bits.
  • The use of 5 data bits with 2 stop bits is an invalid combination, as is 6, 7, or 8 data bits with 1.5 stop bits.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.

See Also

Communications Overview, Communication Structures, BuildCommDCB, ClearCommError, EscapeCommFunction, GetCommState, SetCommState


MODEMDEVCAPS

The MODEMDEVCAPS structure contains information about the capabilities of a modem.

typedef struct modemdevcaps_tag {
    DWORD dwActualSize;            // size of returned data, in bytes
    DWORD dwRequiredSize;          // total size of structure
    DWORD dwDevSpecificOffset;     // offset of provider-defined data
    DWORD dwDevSpecificSize;       // size of provider-defined data
    DWORD dwModemProviderVersion;     // provider version number
    DWORD dwModemManufacturerOffset;  // offset of manufacturer name
    DWORD dwModemManufacturerSize;    // length of manufacturer name
    DWORD dwModemModelOffset;         // offset of model name
    DWORD dwModemModelSize;           // length of model name
    DWORD dwModemVersionOffset;       // offset of version name
    DWORD dwModemVersionSize;         // length of version name
    DWORD dwDialOptions;              // bitmap of supported values
    DWORD dwCallSetupFailTimer;       // maximum in seconds
    DWORD dwInactivityTimeout;        // maximum in tenths of seconds
    DWORD dwSpeakerVolume;            // bitmap of supported values
    DWORD dwSpeakerMode;              // bitmap of supported values
    DWORD dwModemOptions;             // bitmap of supported values
    DWORD dwMaxDTERate;               // maximum value in bit/s
    DWORD dwMaxDCERate;               // maximum value in bit/s
    BYTE abVariablePortion [1];       // variable-length data
} MODEMDEVCAPS, *PMODEMDEVCAPS, *LPMODEMDEVCAPS;

Members

dwActualSize
Specifies the size, in bytes, of the data actually returned to the application. This member may be less than the dwRequiredSize member, if an application did not allocate enough space for the variable-length portion of the structure.
dwRequiredSize
Specifies the number of bytes required for the entire MODEMDEVCAPS structure, including the variable-length portion.
dwDevSpecificOffset
Specifies the offset of the provider-defined portion of the structure, in bytes relative to the beginning of the structure.
dwDevSpecificSize
Specifies the size of the provider-defined portion of the structure, in bytes.
dwModemProviderVersion
Specifies the version of the service provider. The format and use of this member depends on the service provider.
dwModemManufacturerOffset
Specifies the offset of a text string that contains the name of the modem manufacturer. The offset is specified in bytes relative to the beginning of the structure.
dwModemManufacturerSize
Specifies the length of the modem manufacturer name, in bytes. The string is not null-terminated.
dwModemModelOffset
Specifies the offset of a text string that contains the model of the modem. The offset is specified in bytes relative to the beginning of the structure.
dwModemModelSize
Specifies the length of the model name, in bytes. The string is not null-terminated.
dwModemVersionOffset
Specifies the offset of a text string that gives the version and revision of the attached modem, if the provider could determine the information. The offset is specified in bytes relative to the beginning of the structure.
dwModemVersionSize
Specifies the length of the modem version string, in bytes. The string is not null-terminated.
dwDialOptions
Specifies dialing options that are supported by the modem device. This member can be zero or more of the following values:
Value | Meaning
DIALOPTION_DIALBILLING | Specifies that the modem supports waiting for billing tone (bong).
DIALOPTION_DIALQUIET | Specifies that the modem supports waiting for quiet.
DIALOPTION_DIALDIALTONE | Specifies that the modem supports waiting for a dial tone.

dwCallSetupFailTimer
Specifies the maximum call setup timeout supported by the modem, in seconds. This is the largest value that can be specified for the corresponding member of the MODEMSETTINGS structure.
dwInactivityTimeout
Specifies the maximum inactivity timeout supported by the modem, in tenths of seconds. This is the largest value that can be specified for the corresponding member of the MODEMSETTINGS structure.
dwSpeakerVolume
Specifies the speaker volume settings supported by the modem. This member can be zero or more of the following values:
Value | Meaning
MDMVOLFLAG_LOW | The modem supports low (MDMVOL_LOW) volume.
MDMVOLFLAG_MEDIUM | The modem supports medium (MDMVOL_MEDIUM) volume.
MDMVOLFLAG_HIGH | The modem supports high (MDMVOL_HIGH) volume.

dwSpeakerMode
Specifies the speaker mode settings supported by the modem. This member can be zero or more of the following values:
Value | Meaning
MDMSPKRFLAG_OFF | The modem supports the MDMSPKR_OFF speaker mode.
MDMSPKRFLAG_DIAL | The modem supports the MDMSPKR_DIAL speaker mode.
MDMSPKRFLAG_ON | The modem supports the MDMSPKR_ON speaker mode.
MDMSPKRFLAG_CALLSETUP | The modem supports the MDMSPKR_CALLSETUP speaker mode.

dwModemOptions
Specifies supported modem options. This member can be zero or more of the following values:
MDM_BLIND_DIAL | MDM_FLOWCONTROL_SOFT
MDM_CCITT_OVERRIDE | MDM_FORCED_EC
MDM_CELLULAR | MDM_SPEED_ADJUST
MDM_COMPRESSION | MDM_TONE_DIAL
MDM_ERROR_CONTROL | MDM_V23_OVERRIDE
MDM_FLOWCONTROL_HARD

When MODEMDEVCAPS is used to set modem options, as part of the MODEMSETTINGS structure, these values are used as follows:

Value | Meaning
MDM_CCITT_OVERRIDE | When set, CCITT modulations are enabled for V.21 and V.22 or V.23. When clear, bell modulations are enabled for 103 and 212A.
MDM_V23_OVERRIDE | When set, CCITT modulations are enabled for V.23. When clear, CCITT modulations are enabled for V.21 and V.22.

For V.23 to be set, both MDM_CCITT_OVERRIDE and MDM_V23_OVERRIDE must be set.

dwMaxDTERate
Maximum DTE rate in bits per second.
dwMaxDCERate
Maximum DCE rate in bits per second.
abVariablePortion
Contains variable-length information, including strings and any provider-defined information.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in mcx.h.

See Also

Communications Overview, Communication Structures, MODEMSETTINGS


MODEMSETTINGS

The MODEMSETTINGS structure contains information about a modem's configuration.

typedef struct modemsettings_tag {
    DWORD dwActualSize;            // size of returned data, in bytes
    DWORD dwRequiredSize;          // total size of structure
    DWORD dwDevSpecificOffset;     // offset of provider-defined data
    DWORD dwDevSpecificSize;       // size of provider-defined data

    // Static local options (read/write)
    DWORD dwCallSetupFailTimer;      // call setup timeout, in seconds
    DWORD dwInactivityTimeout;       // timeout, in tenths of seconds
    DWORD dwSpeakerVolume;           // speaker volume level
    DWORD dwSpeakerMode;             // speaker mode
    DWORD dwPreferredModemOptions;   // preferred options

    // negotiated options (read only) for current or last call
    DWORD dwNegotiatedModemOptions;  // bitmap specifying options
    DWORD dwNegotiatedDCERate;       // DCE rate, in bits per second

    // Variable portion for proprietary expansion
    BYTE  abVariablePortion[1];      // variable-length data
} MODEMSETTINGS, *PMODEMSETTINGS, *LPMODEMSETTINGS;

Members

dwActualSize
Specifies the size, in bytes, of the data actually returned to the application. This member may be less than the dwRequiredSize member if an application did not allocate enough space for the variable-length portion of the structure.
dwRequiredSize
Specifies the number of bytes required for the entire MODEMDEVCAPS structure, including the variable-length portion.
dwDevSpecificOffset
Specifies the offset of the provider-defined portion of the structure, in bytes relative to the beginning of the structure.
dwDevSpecificSize
Specifies the size of the provider-defined portion of the structure, in bytes.
dwCallSetupFailTimer
Specifies the maximum number of seconds the modem should wait, after dialing is completed, for an indication that a modem-to-modem connection has been established. If a connection is not established in this interval, the call is assumed to have failed. This member is equivalent to register S7 in Hayes® compatible modems.
dwInactivityTimeout
Specifies the maximum number of seconds of inactivity allowed after a connection is established. If no data is either transmitted or received for this period of time, the call is automatically terminated. This time-out is used to avoid excessive long distance charges or online service charges if an application unexpectedly locks up or the user leaves.
dwSpeakerVolume
Specifies the volume level of the monitor speaker when the speaker is on. This member can be one of the following values:
Value | Meaning
MDMVOL_LOW | Low volume.
MDMVOL_MEDIUM | Medium volume.
MDMVOL_HIGH | High volume.

The MODEMDEVCAPS structure specifies the speaker volumes a modem supports. Actual volumes are hardware-specific.

dwSpeakerMode
Specifies when the speaker should be on. This member can be one of the following values:
Value | Meaning
MDMSPKR_OFF | The speaker is always off.
MDMSPKR_CALLSETUP | The speaker is on until a connection is established.
MDMSPKR_ON | The speaker is always on.
MDMSPKR_DIAL | The speaker is on until a connection is established, except that it is off while the modem is actually dialing.

dwPreferredModemOptions
Specifies the modem options requested by the application. The local and remote modems negotiate modem options during call setup; this member specifies the initial negotiating position of the local modem.

The dwModemOptions member of the MODEMDEVCAPSstructure specifies the modem options supported by the local modem. For a list of modem options, see the description of the MODEMDEVCAPS structure.

dwNegotiatedModemOptions
Specifies the modem options that are actually in effect. This member is filled in after a connection is established and the local and remote modems negotiate modem options.

The dwModemOptions member of the MODEMDEVCAPS structure specifies the modem options supported by the local modem. For a list of modem options, see the description of the MODEMDEVCAPS structure.

dwNegotiatedDCERate
Specifies the DCE rate that is in effect. This member is filled in after a connection is established and the local and remote modems negotiate modem modulations.
abVariablePortion
Contains provider-defined information, if any.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in mcx.h.

See Also

Communications Overview, Communication Structures, MODEMDEVCAPS


Consoles and Character-Mode Support

Microsoft® Windows® and Microsoft® Windows NT® provide consoles that manage input and output (I/O) for character-mode applications (applications that do not provide their own graphical user interface).

This overview describes support for character-mode applications.


About Character-Mode Support

Consoles provide high-level support for simple character-mode applications that interact with the user by using functions that read from standard input and write to standard output or standard error. Consoles also provide sophisticated low-level support that gives direct access to a console's screen buffer and that enables applications to receive extended input information (such as mouse input).


Consoles

A console is an interface that provides I/O to character-mode applications. This processor-independent mechanism makes it easy to port existing character-mode applications or to create new character-mode tools and applications.

A console consists of an input buffer and one or more screen buffers. The input buffer contains a queue of input records, each of which contains information about an input event. The input queue always includes key-press and key-release events. It can also include mouse events (pointer movements and button presses and releases) and events during which user actions affect the size of the active screen buffer. A screen buffer is a two-dimensional array of character and color data for output in a console window.

The console functions enable different levels of access to a console. The high-level console I/O functions enable an application to read from standard input to retrieve keyboard input stored in a console's input buffer. The functions also enable an application to write to standard output or standard error to display text in the console's screen buffer. The high-level functions also support redirection of standard handles and control of console modes for different I/O functionality. The low-level console I/O functions enable applications to receive detailed input about keyboard and mouse events, as well as events involving user interactions with the console window. The low-level functions also enable greater control of output to the screen.


Creation of a Console

The system creates a new console when it starts a console process, a character-mode process whose entry point is the main function. For example, the system creates a new console when it starts the command processor. When the command processor starts a new console process, the user can specify whether the system creates a new console for the new process or whether it inherits the command processor's console. A process can create a console by using one of the following methods:

  • A graphical user interface (GUI) or console process that is not currently attached to a console can use the AllocConsole function to create a new console.
  • A GUI or console process can use the CreateProcess function to create a new console process and specify a flag to tell the system to create a new console.

Typically, a process uses AllocConsole to create a console when an error occurs requiring interaction with the user. For example, a GUI process can create a console when an error occurs that prevents it from using its normal graphical interface, or a console process that does not normally interact with the user can create a console when an error makes it necessary. The process that calls AllocConsole must not be attached to an existing console. GUI processes are not attached to any console when they are created. A console process is not attached to a console if the DETACHED_PROCESS flag was specified in a call to CreateProcess when the process was created. A process can use the FreeConsole function to detach itself from an inherited console or from a console created by AllocConsole.

A process can also create a console by specifying the CREATE_NEW_CONSOLE flag in a call to CreateProcess. This method creates a new console that is accessible to the child process but not to the parent process. Separate consoles enable both parent and child processes to interact with the user without conflict. If this flag is not specified when a console process is created, both processes are attached to the same console, and there is no guarantee that the correct process will receive the input intended for it. Applications can prevent confusion by creating child processes that do not inherit handles of the input buffer, or by enabling only one child process at a time to inherit an input buffer handle while preventing the parent process from reading console input until the child has finished.

Creating a new console results in a new console window, as well as separate I/O screen buffers. The process associated with the new console uses the GetStdHandle function to get the handles of the new console's input and screen buffers. These handles enable the process to access the console.

When a process uses CreateProcess, it can specify a STARTUPINFO structure, whose members control the characteristics of the first new console (if any) created for the child process. The STARTUPINFO structure specified in the call to CreateProcess affects a console created if the CREATE_NEW_CONSOLE flag is specified. It also affects a console created if the child process subsequently uses AllocConsole. The following console characteristics can be specified:

  • The size, in character cells, and the location, in screen pixel coordinates, of the new console window
  • The size, in character cells, of the new console's screen buffer
  • The text and background color attributes of the new console's screen buffer
  • The name appearing in the title bar of the new console's window

The system uses default values if the STARTUPINFO values are not specified. A child process can use the GetStartupInfo function to determine the values in its STARTUPINFO structure.

A process cannot change the location of its console window on the screen, but the following console functions are available to set or retrieve the other properties specified in the STARTUPINFO structure.

Function | Description
GetConsoleScreenBufferInfo | Retrieves the window size, screen buffer size, and color attributes.
SetConsoleWindowInfo | Changes the size of the console window.
SetConsoleScreenBufferSize | Changes the size of the screen buffer.
SetConsoleTextAttribute | Sets the color attributes.
SetConsoleTitle | Sets the console window title.
GetConsoleTitle | Retrieves the console window title.


Closing a Console

A process can use the FreeConsole function to detach itself from its console. If other processes share the console, the console is not destroyed, but the process that called FreeConsole cannot refer to it. After calling FreeConsole, the process can use AllocConsole to create a new console.

A console is closed when the last process attached to it terminates or calls FreeConsole.


Console Handles

A console process uses handles to access the input and screen buffers of its console. A process can use the GetStdHandle, CreateFile, or CreateConsoleScreenBuffer function to open one of these handles.

The GetStdHandle function provides a mechanism for retrieving the standard input (STDIN), standard output (STDOUT), and standard error (STDERR) handles associated with a process. During console creation, the system creates these handles. Initially, STDIN is a handle to the console's input buffer, and STDOUT and STDERR are handles of the console's active screen buffer. However, the SetStdHandle function can redirect the standard handles by changing the handle associated with STDIN, STDOUT, or STDERR. Because the parent's standard handles are inherited by any child process, subsequent calls to GetStdHandle return the redirected handle. A handle returned by GetStdHandle may, therefore, refer to something other than console I/O. For example, before creating a child process, a parent process can use SetStdHandle to set a pipe handle to be the STDIN handle that is inherited by the child process. When the child process calls GetStdHandle, it gets the pipe handle. This means that the parent process can control the standard handles of the child process. The handles returned by GetStdHandle have GENERIC_READ | GENERIC_WRITE access unless SetStdHandle has been used to set the standard handle to have lesser access.

The value of the handles returned by GetStdHandle will not be 0, 1, and 2, so the standard predefined stream constants in the STDIO.H header file (STDIN, STDOUT, and STDERR) cannot be used in functions that require a console handle.

The CreateFile function enables a process to get a handle to its console's input buffer and active screen buffer, even if STDIN and STDOUT have been redirected. To open a handle to a console's input buffer, specify the CONIN$ value in a call to CreateFile. Specify the CONOUT$ value in a call to CreateFile to open a handle to a console's active screen buffer. CreateFile enables you to specify the read-write access of the handle that it returns.

The CreateConsoleScreenBuffer function creates a new screen buffer and returns a handle, which can be used in any function that accepts a handle to console output. The new screen buffer is not active until its handle is specified in a call to the SetConsoleActiveScreenBuffer function. Note that changing the active screen buffer does not affect the handle returned by GetStdHandle. Similarly, using SetStdHandle to change the STDOUT handle does not affect the active screen buffer.

Console handles returned by CreateFile and CreateConsoleScreenBuffer can be used in any of the console functions that require a handle to a console's input buffer or of a console screen buffer. Handles returned by GetStdHandle can be used by the console functions if they have not been redirected to refer to something other than console I/O. If a standard handle has been redirected to refer to a file or a pipe, however, the handle can only be used by the ReadFile and WriteFile functions.

A process can use the DuplicateHandle function to create a duplicate console handle that has different access or inheritability from the original handle. Note, however, that a process can create a duplicate console handle only for its own use. This differs from other handle types (such as file, pipe, or mutex objects), for which DuplicateHandle can create a duplicate that is valid for a different process.

To close a console handle, a process can use the CloseHandle function.


Console Input Buffer

Each console has an input buffer that contains a queue of input event records. When a console's window has the keyboard focus, a console formats each input event (such as a single keystroke, a movement of the mouse, or a mouse-button click) as an input record that it places in the console's input buffer.

Applications can access a console's input buffer indirectly by using the high-level console I/O functions, or directly by using the low-level console I/O functions. The high-level input functions filter and process the data in the input buffer, returning only a stream of input characters. The low-level input functions enable applications to read input records directly from a console's input buffer, or to place input records into the input buffer.

An input record is a structure containing information about the type of event that occurred (keyboard, mouse, window resizing, focus, or menu event) as well as specific details about the event. The EventType member in an INPUT_RECORD structure indicates which type of event is contained in the record.

Focus and menu events are placed in a console's input buffer for internal use by the system and should be ignored by applications.

Keyboard Events

Keyboard events are generated when any key is pressed or released; this includes control keys. However, the alt key has special meaning to the system when pressed and released without being combined with another character, and it is not passed through to the application. Also, the ctrl+c key combination is not passed through if the input handle is in processed mode.

If the input event is a keystroke, the Event member in INPUT_RECORD is a KEY_EVENT_RECORD structure containing the following information:

  • A Boolean value indicating whether the key was pressed or released.
  • A repeat count that can be greater than one when a key is held down.
  • The virtual-key code, identifying the given key in a device-independent manner.
  • The virtual-scan code, indicating the device-dependent value generated by the keyboard hardware.
  • The translated Unicode™ or ANSI character.
  • A flag variable indicating the state of the control keys (the alt, ctrl, shift, num lock, scroll lock, and caps lock keys) and indicating whether an enhanced key was pressed. Enhanced keys for the IBM® 101-key and 102-key keyboards are the ins, del, home, end, page up, page down, and arrow keys in the clusters to the left of the numeric keypad and the divide (/) and enter keys in the numeric keypad.

Mouse Events

Mouse events are generated whenever the user moves the mouse or presses or releases one of the mouse buttons. Mouse events are placed in the input buffer only if the following conditions are met:

  • The console input mode is set to ENABLE_MOUSE_INPUT (the default mode).
  • The console window has the keyboard focus.
  • The mouse pointer is within the borders of the console's window.

If the input event is a mouse event, the Event member in INPUT_RECORD is a MOUSE_EVENT_RECORD structure containing the following information:

  • The coordinates of the mouse pointer in terms of the character-cell row and column in the screen buffer's coordinate system.
  • A flag variable indicating the state of the mouse buttons.
  • A flag variable indicating the state of the control keys (alt, ctrl, shift, num lock, scroll lock, and caps lock) and indicating whether an enhanced key was pressed. Enhanced keys for the IBM 101-key and 102-key keyboards are the ins, del, home, end, page up, page down, and arrow keys in the clusters to the left of the numeric keypad and the divide (/) and enter keys in the numeric keypad.
  • A flag variable indicating whether the event was a normal button-press or button-release event, a mouse movement event, or the second click of a double-click event.

Note The mouse position coordinates are in terms of the screen buffer, not the console window. The screen buffer may have been scrolled with respect to the window, so the upper left corner of the window is not necessarily the (0,0) coordinate of the screen buffer. To determine the coordinates of the mouse relative to the coordinate system of the window, subtract the window origin coordinates from the mouse position coordinates. Use the GetConsoleScreenBufferInfo function to determine the window origin coordinates.

The dwButtonState member of the MOUSE_EVENT_RECORD structure has a bit corresponding to each mouse button. The bit is 1 if the button is down and 0 if the button is up. A button-release event is detected by a 0 value for the dwEventFlags member of MOUSE_EVENT_RECORD and a change in a button's bit from 1 to 0. The GetNumberOfConsoleMouseButtons function retrieves the number of buttons on the mouse.

Buffer-Resizing Events

A console window's menu enables the user to change the size of the active screen buffer; this change generates a buffer-resizing event. Buffer-resizing events are placed in the input buffer if the console's input mode is set to ENABLE_WINDOW_INPUT (that is, the default mode is disabled).

If the input event is a buffer-resizing event, the Event member of INPUT_RECORD is a WINDOW_BUFFER_SIZE_RECORD structure containing the new size of the screen buffer, expressed in character-cell columns and rows.

If the user reduces the size of the screen buffer, any data in the discarded portion of the buffer is lost.

Changes to the screen buffer size as a result of application calls to the SetConsoleScreenBufferSize function are not generated as buffer-resizing events.


Console Screen Buffers

A screen buffer is a two-dimensional array of character and color data for output in a console window. A console can have multiple screen buffers. The active screen buffer is the one that is displayed on the screen.

The system creates a screen buffer whenever it creates a new console. A process can use the CreateConsoleScreenBuffer function to create additional screen buffers for its console. A new screen buffer is not active until its handle is specified in a call to the SetConsoleActiveScreenBuffer function. However, screen buffers can be accessed for reading and writing whether they are active or inactive.

Each screen buffer has its own two-dimensional array of character information records. The data for each character is stored in a CHAR_INFO structure that specifies the Unicode or ANSI character and the foreground and background colors in which that character is displayed.

A number of properties associated with a screen buffer can be set independently for each screen buffer. This means that changing the active screen buffer can have a dramatic effect on the appearance of the console window. The properties associated with a screen buffer include:

  • Screen buffer size, in character rows and columns.
  • Text attributes (foreground and background colors for displaying text to be written by the WriteFile or WriteConsole function).
  • Window size and location (the rectangular region of the screen buffer that is displayed in the console window).
  • Cursor position, appearance, and visibility.
  • Output modes (ENABLE_PROCESSED_OUTPUT and ENABLE_WRAP_AT_EOL_OUTPUT). For more information about console output modes, see High-Level Console Modes.

When a screen buffer is created, it contains blanks. Its cursor is visible and positioned at the buffer's origin (0,0), and the window is positioned with its upper left corner at the buffer's origin. The size of the screen buffer, the window size, the text attributes, and the appearance of the cursor are determined by the user or by the system defaults. To retrieve the current values of the various properties associated with the screen buffer, use the GetConsoleScreenBufferInfo, GetConsoleCursorInfo, and GetConsoleMode functions.

Applications that change any of the screen buffer properties should either create their own screen buffer or save the state of the inherited screen buffer during startup and restore it at exit.


Window and Screen Buffer Size

The size of a screen buffer is expressed in terms of a coordinate grid based on character cells. The width is the number of character cells in each row, and the height is the number of rows. Associated with each screen buffer is a window that determines the size and location of the rectangular portion of the screen buffer displayed in the console window. A screen buffer's window is defined by specifying the character-cell coordinates of the upper left and lower right cells of the window's rectangle.

A screen buffer can be any size, limited only by available memory. The dimensions of a screen buffer's window cannot exceed the corresponding dimensions of either the screen buffer or the maximum window that can fit on the screen based on the current font size (controlled exclusively by the user).

The GetConsoleScreenBufferInfo function returns the following information about a screen buffer and its window:

  • The current size of the screen buffer
  • The current location of the window
  • The maximum size of the window given the current screen buffer size, the current font size, and the screen size

The GetLargestConsoleWindowSize function returns the maximum size of a console's window based on the current font and screen sizes. This size differs from the maximum window size returned by GetConsoleScreenBufferInfo in that the screen buffer size is ignored.

To change a screen buffer's size, use the SetConsoleScreenBufferSize function. This function fails if either dimension of the specified size is less than the corresponding dimension of the console's window.

To change the size or location of a screen buffer's window, use the SetConsoleWindowInfo function. This function fails if the specified window-corner coordinates exceed the limits of the screen buffer or the screen. Changing the window size of the active screen buffer changes the size of the console window displayed on the screen.

A process can change its console's input mode to enable window input so that the process is able to receive input when the user changes the screen buffer size. If an application enables window input, it can use GetConsoleScreenBufferInfo to retrieve window and screen buffer size at startup. This information can then be used to determine the way data is displayed in the window. If the user changes the screen buffer size, the application can respond by changing the way data is displayed. For example, an application can adjust the way text wraps at the end of the line if the number of characters per row changes. If an application does not enable window input, it must either use the inherited window and screen buffer sizes, or set them to the desired size during startup and restore the inherited sizes at exit. For additional information about window input mode, see Low-Level Console Modes.


Scrolling the Screen Buffer

The console window displays a portion of the active screen buffer. Each screen buffer maintains its own current window rectangle that specifies the coordinates of the upper left and lower right character cells to be displayed in the console window. To determine the current window rectangle of a screen buffer, use GetConsoleScreenBufferInfo. When a screen buffer is created, the upper left corner of its window is at the upper left corner of the screen buffer at (0,0).

The window rectangle can change to display different parts of the screen buffer. The window rectangle of a screen buffer can change in the following situations:

  • When SetConsoleWindowInfo is called to specify a new window rectangle, it scrolls the view of the screen buffer by changing the position of the window rectangle without changing the size of the window. For examples of scrolling the window's contents, see Scrolling a Screen Buffer's Window.

  • When using the WriteFile function to write to a screen buffer with wrap at end-of-line (EOL) output mode enabled, the window rectangle shifts automatically, so the cursor is always displayed.
  • When the SetConsoleCursorPosition function specifies a new cursor position that is outside the boundaries of the current window rectangle, the window rectangle shifts automatically to display the cursor.
  • When the user changes the size of the console window or uses the window's scroll bars, the window rectangle of the active screen buffer can change. This change is not reported as a window resizing event in the input buffer.

In each of these situations, the window rectangle shifts to display a different part of the screen buffer, but the contents of the screen buffer remain in the same position. The following situations can cause the screen buffer's contents to shift:

  • When the ScrollConsoleScreenBuffer function is called, a rectangular block is copied from one part of a screen buffer to another.
  • When using WriteFile to write to a screen buffer with wrap at EOL output mode enabled, the screen buffer's contents scroll automatically when the end of the screen buffer is encountered. This scrolling discards the top row of the screen buffer.

ScrollConsoleScreenBuffer specifies the screen buffer rectangle that is moved and the new upper left coordinates to which the rectangle is copied. This function can scroll a portion or the entire contents of the screen buffer.

The illustration shows a ScrollConsoleScreenBuffer operation that scrolls the entire contents of the screen buffer up by several rows. The contents of the top rows are discarded, and the bottom rows are filled with a specified character and color.

The effects of ScrollConsoleScreenBuffer can be limited by specifying an optional clipping rectangle so that the contents of the screen buffer outside the clipping rectangle are unchanged. The effect of clipping is to create a subwindow (the clipping rectangle) whose contents are scrolled without affecting the rest of the screen buffer. For an example that uses ScrollConsoleScreenBuffer, see Scrolling a Screen Buffer's Contents.

Cursor Appearance and Position

A screen buffer's cursor can be visible or hidden. When it is visible, its appearance can vary, ranging from from completely filling a character cell to appearing as a horizontal line at the bottom of the cell. To retrieve information about the appearance and visibility of the cursor, use the GetConsoleCursorInfo function. This function reports whether the cursor is visible and describes the appearance of the cursor as the percentage of a character cell that it fills. To set the appearance and visibility of the cursor, use the SetConsoleCursorInfo function.

Characters written by the high-level console I/O functions are written at the current cursor location, advancing the cursor to the next location. To determine the current cursor position in the coordinate system of a screen buffer, use GetConsoleScreenBufferInfo. You can use SetConsoleCursorPosition to set the cursor position and, thereby, control the placement of text that is written or echoed by the high-level I/O functions. If you move the cursor, text at the new cursor location is overwritten.

The position, appearance, and visibility of the cursor are set independently for each screen buffer.

Screen Buffer Color Attributes

Each screen buffer character cell stores the color attributes for the colors used in drawing the text and background of that cell. An application can set the color data for each character cell individually, storing the data in the Attributes member of the CHAR_INFO structure for each cell.

The current text attributes of each screen buffer determine the foreground (text) and background colors of characters subsequently written or echoed by the high-level functions. An application can use GetConsoleScreenBufferInfo to determine the current text attributes of a screen buffer and the SetConsoleTextAttribute function to set the text attributes. Changing a screen buffer's text attributes does not affect the display of characters previously written. These text attributes do not affect characters written by the low-level console I/O functions (such as the WriteConsoleOutput or WriteConsoleOutputCharacter function) which either explicitly specify the attributes for each cell that is written or leave the attributes unchanged at the written positions.

The following attribute constants are defined in the WINCON.H header file:

  • FOREGROUND_BLUE
  • FOREGROUND_GREEN
  • FOREGROUND_RED
  • FOREGROUND_INTENSITY
  • BACKGROUND_BLUE
  • BACKGROUND_GREEN
  • BACKGROUND_RED
  • BACKGROUND_INTENSITY

The foreground attributes specify the text color, and the background attributes specify the color used to fill the cell's background. An application can combine the constants to achieve different colors. For example, the following combination results in bright cyan text on a blue background.

FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE

If no background constant is specified, the background is black, and if no foreground constant is specified, the text is black. For example, the following combination produces black text on a white background.

BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED


Input and Output Methods

The Win32 API provides two very different approaches to console I/O, the choice of which depends on how much flexibility and control an application needs. The high-level approach enables simple character stream I/O, but it limits access to a console's input and screen buffers. The low-level approach requires that developers write more code and choose among a greater range of functions, but it also gives an application more flexibility.

An application can use the file I/O functions, ReadFile and WriteFile, and the console functions, ReadConsole and WriteConsole, for high-level I/O that provides indirect access to a console's input and screen buffers. The high-level input functions filter and process the data in a console's input buffer to return input as a stream of characters, discarding mouse and buffer-resizing input. Similarly, the high-level output functions write a stream of characters that are displayed at the current cursor location in a screen buffer. An application controls the way these functions work by setting a console's I/O modes.

The low-level I/O functions provide direct access to a console's input and screen buffers, enabling an application to access mouse and buffer-resizing input events and extended information for keyboard events. Low-level output functions enable an application to read from or write to a specified number of consecutive character cells in a screen buffer, or to read or write to rectangular blocks of character cells at a specified location in a screen buffer. A console's input modes affect low-level input by enabling the application to determine whether mouse and buffer-resizing events are placed in the input buffer. A console's output modes have no effect on low-level output.

The high-level and low-level I/O methods are not mutually exclusive, and an application can use any combination of these functions. Typically, however, an application uses one approach or the other exclusively.

The sections that follow describe in detail the console modes and the high-level and low-level I/O functions.


Console Modes

Associated with each console input buffer are a set of input modes that affects input operations. Similarly, each console screen buffer has a set of output modes that affects output operations. The input modes can be divided into two groups: those that affect the high-level input functions and those that affect the low-level input functions. The output modes only affect applications that use the high-level output functions.

The GetConsoleMode function reports the current input mode of a console's input buffer or the current output mode of a screen buffer. The SetConsoleMode function sets the current mode of either a console input buffer or a screen buffer. If a console has multiple screen buffers, the output modes of each can be different. An application can change I/O modes at any time. For more information about the console modes that affect high-level and low-level I/O operations, see High-Level Console Modes and Low-Level Console Modes.


High-Level Console I/O

The high-level I/O functions provide a simple way to read a stream of characters from console input or to write a stream of characters to console output. A high-level read operation gets input characters from a console's input buffer and stores them in a specified buffer. A high-level write operation takes characters from a specified buffer and writes them to a screen buffer at the current cursor location, advancing the cursor as each character is written.

High-level I/O gives you a choice between the ReadFile and WriteFile functions and the ReadConsole and WriteConsole functions. They are identical, except for two important differences. The console functions support the use of either Unicode characters or the ANSI character set; the file I/O functions do not support Unicode. Also, the file I/O functions can be used to access files, pipes, and serial communications devices; the console functions can only be used with console handles. This distinction is important if an application relies on standard handles that may have been redirected.

When using either set of high-level functions, an application can control the text and background colors used to display characters subsequently written to a screen buffer. An application can also use the console modes that affect high-level console I/O to enable or disable the following properties:

  • Echoing of keyboard input to the active screen buffer
  • Line input, in which a read operation does not return until the enter key is pressed
  • Automatic processing of keyboard input to handle carriage returns, ctrl+c, and other input details
  • Automatic processing of output to handle line wrapping, carriage returns, backspaces, and other output details


High-Level Console Modes

The behavior of the high-level console functions is affected by the console input and output modes. All of the following console input modes are enabled for a console's input buffer when a console is created:

  • Line input mode
  • Processed input mode
  • Echo input mode

Both of the following console output modes are enabled for a console screen buffer when it is created:

  • Processed output mode
  • Wrapping at EOL output mode

All three input modes, along with processed output mode, are designed to work together. It is best to either enable or disable all of these modes as a group. When all are enabled, the application is said to be in "cooked" mode, which means that most of the processing is handled for the application. When all are disabled, the application is in "raw" mode, which means that input is unfiltered and any processing is left to the application.

An application can use the GetConsoleMode function to determine the current mode of a console's input buffer or screen buffer. You can enable or disable any of these modes by using the following values in the SetConsoleMode function. Note that setting the output mode of one screen buffer does not affect the output mode of other screen buffers.

Mode | Description
ENABLE_PROCESSED_INPUT
 | Used with a console input handle to cause the system to process any system editing or control key input rather than returning it as input in the read operation's buffer. If line input is also enabled, backspaces and carriage returns are handled correctly. A backspace causes the cursor to move back one space without affecting the character at the cursor position. A carriage return is converted to carriage return – linefeed character combination. If echo input mode is enabled and the output should reflect system editing, processed output must be enabled for the active screen buffer. If processed input is enabled, the ctrl+c key combination is passed on to the appropriate handler regardless of whether line input is enabled. For more information about control handlers, see Console Control Handlers.
ENABLE_LINE_INPUT
 | Used with a console input handle to cause the ReadFile and ReadConsole functions to return when the enter key is pressed. If line input mode is disabled, the functions return when one or more characters are available in the input buffer.
ENABLE_ECHO_INPUT
 | Used with a console input handle to cause keyboard input read by the ReadFile or ReadConsole function to be echoed to the active screen buffer. Characters are echoed only if the process that calls ReadFile or ReadConsole has an open handle to the active screen buffer. Echo mode cannot be enabled unless line input is also enabled. The output mode of the active screen buffer affects the way echoed input is displayed.
ENABLE_PROCESSED_OUTPUT
 | Used with a console screen buffer handle to cause the system to perform the appropriate action for ANSI control characters that are written to a screen buffer. The backspace, tab, bell, carriage return, and linefeed characters are processed. A tab character moves the cursor to the next tab stop, which occurs every eight characters. A bell character sounds a short tone.
ENABLE_WRAP_AT_EOL_OUTPUT
 | Used with a console screen buffer handle to cause the current output position (cursor position) to move to the first column in the next row (line) when the end of the current row is reached. If the bottom of the window region is reached, the window origin is moved down one row. This movement has the effect of scrolling the contents of the window up one row. If the bottom of the screen buffer is reached, the contents of the screen buffer are scrolled up one row, and the top row of the screen buffer is discarded. If this mode is disabled, the last character in the row is overwritten with any subsequent characters.


High-Level Console Input and Output Functions

The ReadFile and WriteFile functions, or the ReadConsole and WriteConsole functions, enable an application to read console input and write console output as a stream of characters. ReadConsole and WriteConsole behave exactly like ReadFile and WriteFile except that they can be used either as wide-character functions (in which text arguments must use Unicode) or as ANSI functions (in which text arguments must use characters from the Windows character set). Applications that need to maintain a single set of sources to support either Unicode or the ANSI character set should use ReadConsole and WriteConsole.

ReadConsole and WriteConsole can only be used with console handles; ReadFile and WriteFile can be used with other handles (such as files or pipes). ReadConsole and WriteConsole fail if used with a standard handle that has been redirected and is no longer a console handle.

To get keyboard input, a process can use ReadFile or ReadConsole with a handle to the console's input buffer, or it can use ReadFile to read input from a file or a pipe if STDIN has been redirected. These functions only return keyboard events that can be translated into ANSI characters (or Unicode characters in the case of ReadConsole). The input that can be returned includes control key combinations. The functions do not return keyboard events involving the function keys or arrow keys. Input events generated by mouse, window, focus, or menu input are discarded.

If line input mode is enabled (the default mode), ReadFile and ReadConsole do not return to the calling application until the enter key is pressed. If line input mode is disabled, the functions do not return until at least one character is available. In either mode, all available characters are read until either no more keys are available or the specified number of characters has been read. Unread characters are buffered until the next read operation. The functions report the total number of characters actually read. If echo input mode is enabled, characters read by these functions are written to the active screen buffer at the current cursor position.

A process can use WriteFile or WriteConsole to write to either an active or inactive screen buffer, or it can use WriteFile to write to a file or a pipe if STDOUT has been redirected. Processed output mode and wrap at EOL output mode control the way characters are written or echoed to a screen buffer.

Characters written by WriteFile or WriteConsole, or echoed by ReadFile or ReadConsole, are inserted in a screen buffer at the current cursor position. As each character is written, the cursor position advances to the next character cell; however, the behavior at the end of a row depends on the screen buffer's wrap at EOL output mode. An application can use the GetConsoleScreenBufferInfo function to determine the current cursor position and the SetConsoleCursorPosition function to set the cursor position.

For an example that uses the high-level console I/O functions, see Using the High-Level Input and Output Functions.


Low-Level Console I/O

The low-level console I/O functions expand an application's control over console I/O by enabling direct access to a console's input and screen buffers. These functions enable an application to perform the following tasks:

  • Receive input about mouse and buffer-resizing events
  • Receive extended information about keyboard input events
  • Write input records to the input buffer
  • Read input records without removing them from the input buffer
  • Determine the number of pending events in the input buffer
  • Flush the input buffer
  • Read and write strings of Unicode or ANSI characters at a specified location in a screen buffer
  • Read and write strings of text and background color attributes at a specified screen buffer location
  • Read and write rectangular blocks of character and color data at a specified screen buffer location
  • Write a single Unicode or ANSI character, or a text and background color attribute combination, to a specified number of consecutive cells beginning at a specified screen buffer location


Low-Level Console Modes

The types of input events reported in a console's input buffer depend on the console's mouse and window input modes. The console's processed input mode determines how the system handles the ctrl+c key combination. To set or retrieve the state of a console's input modes, an application can specify a console input buffer handle in a call to the SetConsoleMode or GetConsoleMode function. The following modes are used with console input handles.

Mode | Description
ENABLE_MOUSE_INPUT
 | Controls whether mouse events are reported in the input buffer. By default, mouse input is enabled and window input is disabled. Changing either of these modes affects only input that occurs after the mode is set; pending mouse or window events in the input buffer are not flushed. The mouse pointer is displayed regardless of the mouse mode.
ENABLE_WINDOW_INPUT
 | Controls whether buffer-resizing events are reported in the input buffer. By default, mouse input is enabled and window input is disabled. Changing either of these modes affects only input that occurs after the mode is set; pending mouse or window events in the input buffer are not flushed. The mouse pointer is displayed regardless of the mouse mode.
ENABLE_PROCESSED_INPUT
 | Controls the processing of input for applications using the high-level console I/O functions. However, if processed input mode is enabled, the ctrl+c key combination is not reported in the console's input buffer. Instead, it is passed on to the appropriate control handler function. For more information about control handlers, see Console Control Handlers.

The output modes of a screen buffer do not affect the behavior of the low-level output functions.


Low-Level Console Input Functions

A console's input buffer contains input records that can include information about keyboard, mouse, buffer-resizing, focus, and menu events. The low-level functions provide direct access to the input buffer, unlike the high-level functions that filter and process the input buffer's data, discarding all but keyboard input.

The Win32 API provides five low-level functions for accessing a console's input buffer:

  • ReadConsoleInput
  • PeekConsoleInput
  • GetNumberOfConsoleInputEvents
  • WriteConsoleInput
  • FlushConsoleInputBuffer

The ReadConsoleInput, PeekConsoleInput, and WriteConsoleInput functions use the INPUT_RECORD structure to read from or write to an input buffer.

Following are descriptions of the low-level console input functions.

Function | Description
ReadConsoleInput | Reads and removes input records from an input buffer. The function does not return until at least one record is available to be read. Then all available records are transferred to the buffer of the calling process until either no more records are available or the specified number of records has been read. Unread records remain in the input buffer for the next read operation. The function reports the total number of records that have been read. For an example that uses ReadConsoleInput, see Reading Input Buffer Events.
PeekConsoleInput | Reads without removing the pending input records in an input buffer. All available records up to the specified number are copied into the buffer of the calling process. If no records are available, the function returns immediately. The function reports the total number of records that have been read.
GetNumberOfConsoleInputEvents | Determines the number of unread input records in an input buffer.
WriteConsoleInput | Places input records into the input buffer behind any pending records in the buffer. The input buffer grows dynamically, if necessary, to hold as many records as are written. To use this function, the specified input buffer handle must have GENERIC_WRITE access.
FlushConsoleInputBuffer | Discards all unread events in the input buffer. To use this function, the specified input buffer handle must have GENERIC_WRITE access.

A thread of an application's process can perform a wait operation to wait for input to be available in an input buffer. To initiate a wait operation, specify a handle to the input buffer in a call to any of the wait functions. These functions can return when the state of one or more objects is signaled. The state of a console input handle becomes signaled when there are unread records in its input buffer. The state is reset to nonsignaled when the input buffer becomes empty. If there is no input available, the calling thread enters an efficient wait state, consuming very little processor time while waiting for the conditions of the wait operation to be satisfied.


Low-Level Console Output Functions

The low-level console output functions provide direct access to the character cells of a screen buffer. One set of functions reads from or writes to consecutive cells beginning at any location in the screen buffer. Another set of functions reads from or writes to rectangular blocks of cells.

The following functions read from or write to a specified number of consecutive character cells in a screen buffer, beginning with a specified cell.

Function | Description
ReadConsoleOutputCharacter
 | Copies a string of Unicode or ANSI characters from a screen buffer.
WriteConsoleOutputCharacter
 | Writes a string of Unicode or ANSI characters to a screen buffer.
ReadConsoleOutputAttribute
 | Copies a string of text and background color attributes from a screen buffer.
WriteConsoleOutputAttribute
 | Writes a string of text and background color attributes to a screen buffer.
FillConsoleOutputCharacter
 | Writes a single Unicode or ANSI character to a specified number of consecutive cells in a screen buffer.
FillConsoleOutputAttribute
 | Writes a text and background color attribute combination to a specified number of consecutive cells in a screen buffer.

For all of these functions, when the last cell of a row is encountered, reading or writing wraps around to the first cell of the next row. When the end of the last row of the screen buffer is encountered, the write functions discard all unwritten characters or attributes, and the read functions report the number of characters or attributes actually written..

The following functions read from or write to rectangular blocks of character cells at a specified location in a screen buffer.

Function | Description
ReadConsoleOutput
 | Copies character and color data from a specified block of screen buffer cells into a given block in a destination buffer.
WriteConsoleOutput
 | Writes character and color data to a specified block of screen buffer cells from a given block in a source buffer.

These functions treat screen buffers and source or destination buffers as two-dimensional arrays of CHAR_INFO structures (containing character and color attribute data for each cell). The functions specify the width and height, in character cells, of the source or destination buffer, and the pointer to the buffer is treated as a pointer to the origin cell (0,0) of the two-dimensional array. The functions use a SMALL_RECT structure to specify which rectangle to access in the screen buffer, and the coordinates of the upper left cell in the source or destination buffer determine the location of the corresponding rectangle in that buffer.

These functions automatically clip the specified screen buffer rectangle to fit within the boundaries of the screen buffer. For example, if the rectangle specifies lower right coordinates that are (column 100, row 50) and the screen buffer is only 80 columns wide, the coordinates are clipped so that they are (column 79, row 50). Similarly, this adjusted rectangle is again clipped to fit within the boundaries of the source or destination buffer. The screen buffer coordinates of the actual rectangle that was read from or written to are specified. For an example that uses these functions, see Reading and Writing Blocks of Characters and Attributes.

The illustration shows a ReadConsoleOutput operation where clipping occurs when the block is read from the screen buffer, and again when the block is copied into the destination buffer. The function reports the actual screen buffer rectangle that it copied from.


Console Code Pages

A code page is a mapping of 256 character codes to individual characters. Different code pages include different special characters, typically customized for a language or a group of languages.

Associated with each console are two code pages: one for input and one for output. A console uses its input code page to translate keyboard input into the corresponding character value. It uses its output code page to translate the character values written by the various output functions into the images displayed in the console window. An application can use the SetConsoleCP and GetConsoleCP functions to set and retrieve a console's input code pages and the SetConsoleOutputCP and GetConsoleOutputCP functions to set and retrieve its output code pages.

The identifiers of the code pages available on the local computer are stored in the registry under the following key.

%HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage%

For information about using the registry functions to determine the available code pages, see Registry.

For more information about code pages, see String Manipulation.


Console Control Handlers

Each console process has its own list of control handler functions that are called by the system when the process receives a ctrl+c, ctrl+break, or ctrl+close signal. Initially, the list of control handlers for each process contains only a default handler function that calls the ExitProcess function. A console process can add or remove additional HandlerRoutine functions by calling the SetConsoleCtrlHandler function. This function does not affect the lists of control handlers for other processes. When a console process receives any of the control signals, it calls the handler functions on a last-registered, first-called basis until one of the handlers returns TRUE. If none of the handlers returns TRUE, the default handler is called.

The function's dwCtrlType parameter identifies which control signal was received, and the return value indicates whether the signal was handled.

For an example of a control handler function, see Registering a Control Handler Function.


CTRL+C and CTRL+BREAK Signals

The ctrl+c and ctrl+break key combinations receive special handling by console processes. By default, when a console window has the keyboard focus, ctrl+c or ctrl+break is treated as a signal (SIGINT or SIGBREAK) and not as keyboard input. By default, these signals are passed to all console processes that are attached to the console, causing the system to call the control handler function or functions associated with these processes. Detached processes (GUI processes or console processes started with the DETACHED_PROCESS or CREATE_NEW_CONSOLE flag) are not affected.

ctrl+break is always treated as a signal, but an application can change the default ctrl+c behavior in two ways that prevent the handler functions from being called:

  • The SetConsoleMode function can disable the ENABLE_PROCESSED_INPUT input mode for a console's input buffer, so ctrl+c is reported as keyboard input rather than as a signal.
  • Windows NT: When SetConsoleCtrlHandler is called with NULL and TRUE values for its parameters, the calling process ignores ctrl+c signals. Normal ctrl+c processing is restored by calling SetConsoleCtrlHandler with NULL and FALSE values. This attribute of ignoring or not ignoring ctrl+c signals is inherited by child processes, but it can be enabled or disabled by any process without affecting existing processes.


CTRL+CLOSE Signal

The system generates a ctrl+close signal when the user closes a console. All processes attached to the console receive the signal, giving each process an opportunity to clean up before termination. When a process receives this signal, the handler function can take one of the following actions after performing any cleanup operations:

  • Call ExitProcess to terminate the process.
  • Return FALSE. If none of the registered handler functions returns TRUE, the default handler terminates the process.
  • Return TRUE. In this case, no other handler functions are called, and a pop-up dialog box asks the user whether to terminate the process. If the user chooses not to terminate the process, the system does not close the console until the process finally terminates.


Console Process Groups

When a process uses the CreateProcess function to create a new console process, it can specify the CREATE_NEW_PROCESS_GROUP flag to make the new process the root process of a console process group. The process group includes all processes that are descendants of the root process.

A process can use the GenerateConsoleCtrlEvent function to send a ctrl+c or ctrl+break signal to all processes in a console process group. The signal is only received by those processes in the group that are attached to the same console as the process that called GenerateConsoleCtrlEvent.


Using the Console

  • Using the high-level input and output functions
  • Writing characters or colors to consecutive cells
  • Reading and writing blocks of characters and attributes
  • Reading input buffer events
  • Scrolling a screen buffer's window
  • Scrolling a screen buffer's contents
  • Registering a control handler function
  • Console application issues


Using the High-Level Input and Output Functions

The following example uses the high-level console I/O functions for console I/O. For more information about the high-level console I/O functions, see High-Level Console I/O.

The example assumes that the default I/O modes are in effect initially for the first calls to the ReadFile and WriteFile functions. Then the input mode is changed to turn off line input mode and echo input mode for the second calls to ReadFile and WriteFile. The SetConsoleTextAttribute function is used to set the colors in which subsequently written text will be displayed. Before exiting, the program restores the original console input mode and color attributes.

The example's NewLine function is used when line input mode is disabled. It handles carriage returns by moving the cursor position to the first cell of the next row. If the cursor is already in the last row of the screen buffer, the contents of the screen buffer are scrolled up one line. For an example that illustrates the use of the ScrollConsoleScreenBuffer function to scroll a screen buffer, see Scrolling a Screen Buffer's Contents.

#include <windows.h>

void NewLine(void);
void ScrollScreenBuffer(HANDLE, INT);

HANDLE hStdout, hStdin;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;

void main(void)
{
    LPSTR lpszPrompt1 = "Type something and press Enter:\n";
    LPSTR lpszPrompt2 = "Type any key: ";
    CHAR chBuffer[256];
    DWORD cRead, cWritten, fdwMode, fdwOldMode;
    WORD wOldColorAttrs;

    // Get handles to STDIN and STDOUT.

    hStdin = GetStdHandle(STD_INPUT_HANDLE);
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    if (hStdin == INVALID_HANDLE_VALUE ||
        hStdout == INVALID_HANDLE_VALUE)
    {
        MyErrorExit("GetStdHandle");
    }

    // Save the current text colors.

    if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
        MyErrorExit("GetConsoleScreenBufferInfo");

    wOldColorAttrs = csbiInfo.wAttributes;

    // Set the text attr. to draw red text on black background.

    if (! SetConsoleTextAttribute(hStdout, FOREGROUND_RED))
        MyErrorExit("SetConsoleTextAttribute");

    // Write to STDOUT and read from STDIN by using the default
    // modes. Input is echoed automatically, and ReadFile
    // does not return until a carriage return is typed.
    //
    // The default input modes are line, processed, and echo.
    // The default output modes are processed and wrap at EOL.

    while (1)
    {
        if (! WriteFile(
            hStdout,              // output handle
            lpszPrompt1,          // prompt string
            lstrlen(lpszPrompt1), // string length
            &cWritten,            // bytes written
            NULL) )               // not overlapped
        break;
        if (! ReadFile(
            hStdin,    // input handle
            chBuffer,  // buffer to read into
            255,       // size of buffer
            &cRead,    // actual bytes read
            NULL) )    // not overlapped
        break;
        if (chBuffer[0] == 'q') break;
    }

    // Turn off the line input mode, and echo the input mode.

    if (! GetConsoleMode(hStdin, &fdwOldMode))
        MyErrorExit("GetConsoleMode");

    fdwMode = fdwOldMode &
        ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
    if (! SetConsoleMode(hStdin, fdwMode))
        MyErrorExit("SetConsoleMode");

    // Prompt for input.

    if (! WriteFile(
        hStdout,              // output handle
        lpszPrompt2,          // prompt string
        lstrlen(lpszPrompt2), // string length
        &cWritten,            // bytes written
        NULL) )               // not overlapped
    MyErrorExit("WriteFile");

    // Without line and echo input modes, ReadFile returns
    // when any input is available. Carriage returns must
    // be handled, and WriteFile is used to echo input.

    while (1)
    {
        if (! ReadFile(hStdin, chBuffer, 1, &cRead, NULL))
            break;
        if (chBuffer[0] == '\r')
            NewLine();
        else if (! WriteFile(hStdout, chBuffer, cRead,
            &cWritten, NULL)) break;
        if (chBuffer[0] == 'q') break;
    }

    // Restore the original console mode.

    if (! SetConsoleMode(hStdin, fdwOldMode))
        MyErrorExit("SetConsoleMode");

    // Restore the original text colors.

    if (! SetConsoleTextAttribute(hStdout, wOldColorAttrs))
        MyErrorExit("SetConsoleTextAttribute");
}

// The NewLine function handles carriage returns when the processed
// input mode is disabled. It gets the current cursor position
// and resets it to the first cell of the next row.

void NewLine(void)
{
    if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
        MyErrorExit("GetConsoleScreenBufferInfo");
    csbiInfo.dwCursorPosition.X = 0;

    // If it is the last line in the screen buffer, scroll
    // the buffer up.

    if ((csbiInfo.dwSize.Y-1) == csbiInfo.dwCursorPosition.Y)
    {
        ScrollScreenBuffer(hStdout, 1);
    }

    // Otherwise, advance the cursor to the next line.

    else csbiInfo.dwCursorPosition.Y += 1;

    if (! SetConsoleCursorPosition(hStdout,
        csbiInfo.dwCursorPosition))
    {
        MyErrorExit("SetConsoleCursorPosition");
    }
}


Writing Characters or Colors to Consecutive Cells

Characters or color attributes can be written to specified character cells in a screen buffer. The following example uses the WriteConsoleOutputCharacter function to write a string of characters beginning at the upper left corner of a screen buffer. Then the example uses the WriteConsoleOutputAttribute function to write a string of color attributes to the first 51 cells of the same row. The coord parameter for both functions specifies the character cell in the screen buffer at which writing begins. The location in the console window where these characters or colors appear depends on the current window rectangle of the screen buffer. For additional information about the relationship between a screen buffer and its windows, see Window and Screen Buffer Size and Scrolling the Screen Buffer.

HANDLE hOutput;
    LPTSTR lpszString = "Character String";
    DWORD cWritten;
    BOOL fSuccess;
    COORD coord;
    WORD wColors[3], wColor;
    CHAR chFillChar;

// Write a string of characters to a screen buffer.

    coord.X = 0;            // start at first cell
    coord.Y = 0;            //   of first row
    fSuccess = WriteConsoleOutputCharacter(
        hOutput,              // screen buffer handle
        lpszString,           // pointer to source string
        lstrlen(lpszString),  // length of string
        coord,                // first cell to write to
        &cWritten);           // actual number written
    if (! fSuccess)
        MyErrorExit("WriteConsoleOutputCharacter");

// Write a string of colors to a screen buffer.

    wColors[0] = BACKGROUND_RED;
    wColors[1] = BACKGROUND_RED |     // white background
                 BACKGROUND_GREEN |
                 BACKGROUND_BLUE;
    wColors[2] = BACKGROUND_BLUE;

    for (;fSuccess && coord.X < 50; coord.X += 3)
    {
        fSuccess = WriteConsoleOutputAttribute(
            hOutput,          // screen buffer handle
            wColors,          // pointer to source string
            3,                // length of string
            coord,            // first cell to write to
            &cWritten);       // actual number written
    }
    if (! fSuccess)
        MyErrorExit("WriteConsoleOutputAttribute");

The same character or color attribute can be written to a specified number of consecutive screen buffer cells beginning at a specified location. The following example uses the FillConsoleOutputCharacter function to clear a 80-by-50-character screen buffer, and then it uses the FillConsoleOutputAttribute function to set the color attributes of the same cells.

// Fill an 80-by-50-character screen buffer with the space character.

    coord.X = 0;            // start at first cell
    coord.Y = 0;            //   of first row
    chFillChar = ' ';

    fSuccess = FillConsoleOutputCharacter(
        hStdout,          // screen buffer handle
        chFillChar,       // fill with spaces
        80*50,            // number of cells to fill
        coord,            // first cell to write to
        &cWritten);       // actual number written

    if (! fSuccess)
        MyErrorExit("FillConsoleOutputCharacter");

// Set 80-by-50-character screen buffer colors to white text on red.

    wColor = BACKGROUND_RED |
             FOREGROUND_RED |
             FOREGROUND_GREEN |
             FOREGROUND_BLUE;

    fSuccess = FillConsoleOutputAttribute(
        hStdout,          // screen buffer handle
        wColor,           // color to fill with
        80*50,            // number of cells to fill
        coord,            // first cell to write to
        &cWritten);       // actual number written

    if (! fSuccess)
        MyErrorExit("FillConsoleOutputAttribute");


Reading and Writing Blocks of Characters and Attributes

The ReadConsoleOutput function copies a rectangular block of character and color attribute data from a console screen buffer into a destination buffer. The function treats the destination buffer as a two-dimensional array of CHAR_INFO structures. Similarly, the WriteConsoleOutput function copies a rectangular block of character and color attribute data from a source buffer to a console screen buffer. For more information about reading from or writing to rectangular blocks of screen buffer cells, see Input and Output Methods.

The following example uses the CreateConsoleScreenBuffer function to create a new screen buffer. After the SetConsoleActiveScreenBuffer function makes this the active screen buffer, a block of characters and color attributes is copied from the top two rows of the SDTOUT screen buffer into a temporary buffer. The data is then copied from the temporary buffer into the new active screen buffer. When the application is finished using the new screen buffer, it calls SetConsoleActiveScreenBuffer to restore the original STDOUT screen buffer.

#include <windows.h>

VOID main(void)
{
    HANDLE hStdout, hNewScreenBuffer;
    SMALL_RECT srctReadRect;
    SMALL_RECT srctWriteRect;
    CHAR_INFO chiBuffer[160]; // [2][80];
    COORD coordBufSize;
    COORD coordBufCoord;
    BOOL fSuccess;

    // Get a handle to the STDOUT screen buffer to copy from and
    // create a new screen buffer to copy to.

    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    hNewScreenBuffer = CreateConsoleScreenBuffer(
       GENERIC_READ |           // read-write access
       GENERIC_WRITE,
       0,                       // not shared
       NULL,                    // no security attributes
       CONSOLE_TEXTMODE_BUFFER, // must be TEXTMODE
       NULL);                   // reserved; must be NULL
    if (hStdout == INVALID_HANDLE_VALUE ||
            hNewScreenBuffer == INVALID_HANDLE_VALUE)
    {
        MyErrorExit("CreateConsoleScreenBuffer");
    }

    // Make the new screen buffer the active screen buffer.

    if (! SetConsoleActiveScreenBuffer(hNewScreenBuffer) )
        MyErrorExit("SetConsoleActiveScreenBuffer");

    // Set the source rectangle.

    srctReadRect.Top = 0;    // top left: row 0, col 0
    srctReadRect.Left = 0;
    srctReadRect.Bottom = 1; // bot. right: row 1, col 79
    srctReadRect.Right = 79;

    // The temporary buffer size is 2 rows x 80 columns.

    coordBufSize.Y = 2;
    coordBufSize.X = 80;

    // The top left destination cell of the temporary buffer is
    // row 0, col 0.

    coordBufCoord.X = 0;
    coordBufCoord.Y = 0;

    // Copy the block from the screen buffer to the temp. buffer.

    fSuccess = ReadConsoleOutput(
       hStdout,        // screen buffer to read from
       chiBuffer,      // buffer to copy into
       coordBufSize,   // col-row size of chiBuffer
       coordBufCoord,  // top left dest. cell in chiBuffer
       &srctReadRect); // screen buffer source rectangle
    if (! fSuccess)
        MyErrorExit("ReadConsoleOutput");

    // Set the destination rectangle.

    srctWriteRect.Top = 10;    // top lt: row 10, col 0
    srctWriteRect.Left = 0;
    srctWriteRect.Bottom = 11; // bot. rt: row 11, col 79
    srctWriteRect.Right = 79;

    // Copy from the temporary buffer to the new screen buffer.

    fSuccess = WriteConsoleOutput(
        hNewScreenBuffer, // screen buffer to write to
        chiBuffer,        // buffer to copy from
        coordBufSize,     // col-row size of chiBuffer
        coordBufCoord,    // top left src cell in chiBuffer
        &srctWriteRect);  // dest. screen buffer rectangle
    if (! fSuccess)
        MyErrorExit("WriteConsoleOutput");
    Sleep(10000);

    // Restore the original active screen buffer.

    if (! SetConsoleActiveScreenBuffer(hStdout))
        MyErrorExit("SetConsoleActiveScreenBuffer");

}


Reading Input Buffer Events

The ReadConsoleInput function can be used to directly access a console's input buffer. When a console is created, mouse input is enabled and window input is disabled. To ensure that the process receives all types of events, this example uses the SetConsoleMode function to enable window and mouse input. Then it goes into a loop that reads and handles console input events.

VOID MouseEventProc(MOUSE_EVENT_RECORD);
VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD);
VOID KeyEventProc(KEY_EVENT_RECORD);
VOID GetInputEvents(VOID);

DWORD main(VOID)
{
    HANDLE hStdin;
    DWORD cNumRead, fdwMode, fdwSaveOldMode, i;
    INPUT_RECORD irInBuf[128];

    // Get the standard input handle.

    hStdin = GetStdHandle(STD_INPUT_HANDLE);
    if (hStdin == INVALID_HANDLE_VALUE)
        MyErrorExit("GetStdHandle");

    // Save the current input mode, to be restored on exit.

    if (! GetConsoleMode(hStdin, &fdwSaveOldMode) )
        MyErrorExit("GetConsoleMode");

    // Enable the window and mouse input events.

    fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
    if (! SetConsoleMode(hStdin, fdwMode) )
        MyErrorExit("SetConsoleMode");

    // Loop to read and handle the input events.

    while (1)
    {

        // Wait for the events.

        if (! ReadConsoleInput(
                hStdin,      // input buffer handle
                irInBuf,     // buffer to read into
                128,         // size of read buffer
                &cNumRead) ) // number of records read
            MyErrorExit("ReadConsoleInput");

        // Dispatch the events to the appropriate handler.

        for (i = 0; i < cNumRead; i++)
        {
            switch(irInBuf[i].EventType)
            {
                case KEY_EVENT: // keyboard input
                    KeyEventProc(irInBuf[i].Event.KeyEvent);
                    break;

                case MOUSE_EVENT: // mouse input
                    MouseEventProc(irInBuf[i].Event.MouseEvent);
                    break;

                case WINDOW_BUFFER_SIZE_EVENT: // scrn buf. resizing
                    ResizeEventProc(
                        irInBuf[i].Event.WindowBufferSizeEvent);
                    break;

                case FOCUS_EVENT:  // disregard focus events

                case MENU_EVENT:   // disregard menu events
                    break;

                default:
                    MyErrorExit("unknown event type");
                    break;
            }
        }
    }

    return 0;
}


Scrolling a Screen Buffer's Window

The SetConsoleWindowInfo function can be used to scroll the contents of a screen buffer in the console window. This function can also change the window size. The function can either specify the new upper left and lower right corners of the screen buffer's window as absolute screen buffer coordinates or specify the changes from the current window coordinates. The function fails if the specified window coordinates are outside the boundaries of the screen buffer.

The following example scrolls the view of the screen buffer up one row by modifying the absolute window coordinates returned by the GetConsoleScreenBufferInfo function.

HANDLE hStdout;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
SMALL_RECT srctWindow;

hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

// Get the current screen buffer size and window position.

if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
    MyErrorExit("GetConsoleScreenBufferInfo");

// Set srctWindow to the current window size and location.

srctWindow = csbiInfo.srWindow;

// If window is not at the screen buffer top, move it up one line.

if ( srctWindow.Top > 0 )
{
    srctWindow.Top -= 1;      // move top up by one row
    srctWindow.Bottom -= 1;   // move bottom up by one row

    if (! SetConsoleWindowInfo(
               hStdout,      // screen buffer handle
               TRUE,         // absolute coordinates
               &srctWindow)) // specifies new location
        MyErrorExit("SetConsoleWindowInfo");
}

The same scrolling can be done by specifying changes in the window coordinates.

// Get the current screen buffer window position.

if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
    MyErrorExit("GetConsoleScreenBufferInfo");

// If window is not at the screen buffer top, move it up one line.

if (csbiInfo.srWindow.Top > 0)
{
    srctWindow.Top = -1;      // move top up by one row
    srctWindow.Bottom = -1;   // move bottom up by one row
    srctWindow.Left = 0;      // no change
    srctWindow.Right = 0;     // no change

    if (! SetConsoleWindowInfo(
               hStdout,      // screen buffer handle
               FALSE,        // deltas, not absolute
               &srctWindow)) // specifies new location
    {
        MyErrorExit("SetConsoleWindowInfo");
    }
}


Scrolling a Screen Buffer's Contents

The ScrollConsoleScreenBuffer function moves a block of character cells from one part of a screen buffer to another part of the same screen buffer. The function specifies the upper left and lower right cells of the source rectangle to be moved and the destination coordinates of the new location for the upper left cell. The character and color data in the source cells is moved to the new location, and any cells left empty by the move are filled in with a specified character and color. If a clipping rectangle is specified, the cells outside of it are left unchanged.

ScrollConsoleScreenBuffer can be used to delete a line by specifying coordinates of the first cell in the line as the destination coordinates and specifying a scrolling rectangle that includes all the rows below the line.

The following example shows the use of a clipping rectangle to scroll only the bottom 15 rows of the screen buffer. The rows in the specified rectangle are scrolled up one line at a time, and the top row of the block is discarded. The contents of the screen buffer outside the clipping rectangle are left unchanged.

HANDLE hStdout;
BOOL fSuccess;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
SMALL_RECT srctScrollRect, srctClipRect;
CHAR_INFO chiFill;
COORD coordDest;

hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

if (hStdout == INVALID_HANDLE_VALUE)
    MyErrorExit("GetStdHandle");

// Get the screen buffer size.

fSuccess = GetConsoleScreenBufferInfo(hStdout, &csbiInfo);

if (! fSuccess)
    MyErrorExit("GetConsoleScreenBufferInfo");

// The scrolling rectangle is the bottom 15 rows of the
// screen buffer.

srctScrollRect.Top = csbiInfo.dwSize.Y - 16;
srctScrollRect.Bottom = csbiInfo.dwSize.Y - 1;
srctScrollRect.Left = 0;
srctScrollRect.Right = csbiInfo.dwSize.X - 1;

// The destination for the scroll rectangle is one row up.

coordDest.X = 0;
coordDest.Y = csbiInfo.dwSize.Y - 17;

// The clipping rectangle is the same as the scrolling rectangle.
// The destination row is left unchanged.

srctClipRect = srctScrollRect;

// Fill the bottom row with green blanks.

chiFill.Attributes = BACKGROUND_GREEN | FOREGROUND_RED;
chiFill.Char.AsciiChar = ' ';

// Scroll up one line.

fSuccess = ScrollConsoleScreenBuffer(
    hStdout,         // screen buffer handle
    &srctScrollRect, // scrolling rectangle
    &srctClipRect,   // clipping rectangle
    coordDest,       // top left destination cell
    &chiFill);       // fill character and color


Registering a Control Handler Function

This section shows an example of the SetConsoleCtrlHandler function that is used to install a control handler.

When a ctrl+c signal is received, the control handler returns TRUE, indicating that it has handled the signal. Doing this prevents other control handlers from being called.

When a CTRL_CLOSE_EVENT signal is received, the control handler returns TRUE, causing the system to display a dialog box that gives the user the choice of terminating the process and closing the console or allowing the process to continue execution. If the user chooses not to terminate the process, the system closes the console when the process finally terminates.

When a ctrl+break, CTRL_LOGOFF_EVENT, or CTRL_SHUTDOWN_EVENT signal is received, the control handler returns FALSE. Doing this causes the signal to be passed to the next control handler function. If no other control handlers have been registered or none of the registered handlers returns TRUE, the default handler will be used, resulting in the process being terminated.

BOOL CtrlHandler(DWORD fdwCtrlType)
{
    switch (fdwCtrlType)
    {
        // Handle the CTRL+C signal.

        case CTRL_C_EVENT:

            Beep(1000, 1000);
            return TRUE;

        // CTRL+CLOSE: confirm that the user wants to exit.

        case CTRL_CLOSE_EVENT:

            return TRUE;

        // Pass other signals to the next handler.

        case CTRL_BREAK_EVENT:

        case CTRL_LOGOFF_EVENT:

        case CTRL_SHUTDOWN_EVENT:

        default:

            return FALSE;
    }
}

void main(void)
{
    BOOL fSuccess;

    fSuccess = SetConsoleCtrlHandler(
        (PHANDLER_ROUTINE) CtrlHandler,  // handler function
        TRUE);                           // add to list
    if (! fSuccess)
        MyErrorExit("Could not set control handler");
}


Console Application Issues

The 8-bit console functions use the OEM code page. All other functions use the ANSI code page by default. This means that strings returned by the console functions may not be processed correctly by the other functions and vice versa. For example, if FindFirstFileA returns a string that contains certain extended ANSI characters, WriteConsoleA will not display the string properly.

The best long-term solution for a console application is to use Unicode. Barring that solution, a console application should use the SetFileApisToOEM function. That function changes relevant file functions so that they produce OEM character set strings rather than ANSI character set strings.

The following are the file functions:

_lopen GetDriveType LoadLibrary
CopyFile GetFileAttributes LoadLibraryEx
CreateDirectory GetFullPathName MoveFile
CreateFile GetModuleFileName MoveFileEx
CreateProcess GetModuleHandle OpenFile
DeleteFile GetSystemDirectory RemoveDirectory
FindFirstFile GetTempFileName SearchPath
FindNextFile GetTempPath SetCurrentDirectory
GetCurrentDirectory GetVolumeInformation SetFileAttributes
GetDiskFreeSpace GetWindowsDirectory

When dealing with command lines, a console application should obtain the command line in Unicode form and convert it to OEM form, using the relevant character-to-OEM functions. Note, also, that argv uses the ANSI character set.


Console Reference

The following elements are associated with accessing a console.

  • Console Functions
  • Console Structures


Console Functions

The following functions used to access a console.

AllocConsole
CreateConsoleScreenBuffer
FillConsoleOutputAttribute
FillConsoleOutputCharacter
FlushConsoleInputBuffer
FreeConsole
GenerateConsoleCtrlEvent
GetConsoleCP
GetConsoleCursorInfo
GetConsoleMode
GetConsoleOutputCP
GetConsoleScreenBufferInfo
GetConsoleTitle
GetLargestConsoleWindowSize
GetNumberOfConsoleInputEvents
GetNumberOfConsoleMouseButtons
GetStdHandle
HandlerRoutine
PeekConsoleInput
ReadConsole
ReadConsoleInput
ReadConsoleOutput
ReadConsoleOutputAttribute
ReadConsoleOutputCharacter
ScrollConsoleScreenBuffer
SetConsoleActiveScreenBuffer
SetConsoleCP
SetConsoleCtrlHandler
SetConsoleCursorInfo
SetConsoleCursorPosition
SetConsoleMode
SetConsoleOutputCP
SetConsoleScreenBufferSize
SetConsoleTextAttribute
SetConsoleTitle
SetConsoleWindowInfo
SetStdHandle
WriteConsole
WriteConsoleInput
WriteConsoleOutput
WriteConsoleOutputAttribute
WriteConsoleOutputCharacter


AllocConsole

The AllocConsole function allocates a new console for the calling process.

BOOL AllocConsole(VOID)

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A process can be associated with only one console, so the AllocConsole function fails if the calling process already has a console. A process can use the FreeConsole function to detach itself from its current console, and then it can call AllocConsole to create a new console. If the calling process creates a child process, the child inherits the new console.

AllocConsole also sets up standard input, standard output, and standard error handles for the new console. The standard input handle is a handle to the console's input buffer, and the standard output and standard error handles are handles to the console's screen buffer. To retrieve these handles, use the GetStdHandle function.

This function is primarily used by graphics applications to create a console window. Graphics applications are initialized without a console. Console applications are normally initialized with a console, unless they are created as detached processes (by calling the CreateProcess function with the DETACHED_PROCESS flag).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, CreateProcess, FreeConsole, GetStdHandle


CreateConsoleScreenBuffer

The CreateConsoleScreenBuffer function creates a console screen buffer and returns a handle to it.

HANDLE CreateConsoleScreenBuffer(
  DWORD dwDesiredAccess,  // access flag
  DWORD dwShareMode,      // buffer share mode
  LPSECURITY_ATTRIBUTES *lpSecurityAttributes,
                          // pointer to security attributes
  DWORD dwFlags,          // type of buffer to create
  LPVOID lpScreenBufferData   // reserved
);

Parameters

dwDesiredAccess
Specifies the desired access to the console screen buffer. This parameter can be one or both of the following values:
Value | Meaning
GENERIC_READ | Requests read access to the console screen buffer, enabling the process to read data from the buffer.
GENERIC_WRITE | Requests write access to the console screen buffer, enabling the process to write data to the buffer.

dwShareMode
Specifies how this console screen buffer can be shared. This parameter can be zero, indicating that the buffer cannot be shared, or it can be one or both of the following two values:
Value | Meaning
FILE_SHARE_READ | Other open operations can be performed on the console screen buffer for read access.
FILE_SHARE_WRITE | Other open operations can be performed on the console screen buffer for write access.

lpSecurityAttributes
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpSecurityAttributes is NULL, the handle cannot be inherited.

Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new console screen buffer. If lpSecurityAttributes is NULL, the console screen buffer gets a default security descriptor.

dwFlags
Specifies the type of console screen buffer to create. The only currently supported screen buffer type is CONSOLE_TEXTMODE_BUFFER.
lpScreenBufferData
Reserved for possible future use; should be NULL.

Return Values

If the function succeeds, the return value is a handle to the new console screen buffer.

If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.

Remarks

A console can have multiple screen buffers but only one active screen buffer. Inactive screen buffers can be accessed for reading and writing, but only the active screen buffer is displayed. To make the new screen buffer the active screen buffer, use the SetConsoleActiveScreenBuffer function.

The calling process can use the returned handle in any function that requires a handle to a console screen buffer, subject to the limitations of access specified by the dwDesiredAccess parameter.

The calling process can use the DuplicateHandle function to create a duplicate screen buffer handle that has different access or inheritability from the original handle. However, DuplicateHandle cannot be used to create a duplicate that is valid for a different process (except through inheritance).

To close the screen buffer handle, use the CloseHandle function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, CloseHandle, DuplicateHandle, GetConsoleScreenBufferInfo, SECURITY_ATTRIBUTES, SetConsoleActiveScreenBuffer, SetConsoleScreenBufferSize


FillConsoleOutputAttribute

The FillConsoleOutputAttribute function sets the text and background color attributes for a specified number of character cells, beginning at the specified coordinates in a screen buffer.

BOOL FillConsoleOutputAttribute(
  HANDLE hConsoleOutput,  // handle to screen buffer
  WORD wAttribute,        // color attribute to write
  DWORD nLength,          // number of character cells to write to
  COORD dwWriteCoord,     // x- and y-coordinates of first cell
  LPDWORD lpNumberOfAttrsWritten
                          // pointer to number of cells written to
);

Parameters

hConsoleOutput
Handle to a screen buffer. The handle must have GENERIC_WRITE access.
wAttribute
Specifies the foreground and background color attributes to write to the screen buffer. Any combination of the following values can be specified: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following combination of values produces white text on a black background:
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
nLength
Specifies the number of character cells to be set to the specified color attributes.
dwWriteCoord
Specifies a COORD structure containing the screen buffer coordinates of the first cell whose attributes are to be set.
lpNumberOfAttrsWritten
Pointer to the variable that receives the number of character cells whose attributes were actually set.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the number of character cells whose attributes are to be set extends beyond the end of the specified row in the screen buffer, the cells of the next row are set. If the number of cells to write to extends beyond the end of the screen buffer, the cells are written up to the end of the screen buffer.

The character values at the positions written to are not changed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, COORD, FillConsoleOutputCharacter, SetConsoleTextAttribute, WriteConsoleOutputAttribute


FillConsoleOutputCharacter

The FillConsoleOutputCharacter function writes a character to the screen buffer a specified number of times, beginning at the specified coordinates.

BOOL FillConsoleOutputCharacter(
  HANDLE hConsoleOutput,  // handle to screen buffer
  TCHAR cCharacter,       // character to write
  DWORD nLength,          // number of character cells to write to
  COORD dwWriteCoord,     // x- and y-coordinates of first cell
  LPDWORD lpNumberOfCharsWritten
                          // pointer to number of cells written to
);

Parameters

hConsoleOutput
Handle to a screen buffer. The handle must have GENERIC_WRITE access.
cCharacter
Specifies the character to write to the screen buffer.
nLength
Specifies the number of character cells to write the character to.
dwWriteCoord
Specifies a COORD structure containing the screen buffer coordinates of the first cell to write the character to.
lpNumberOfCharsWritten
Pointer to the variable that receives the number of characters actually written to the screen buffer.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the number of characters to write to extends beyond the end of the specified row in the screen buffer, characters are written to the next row. If the number of characters to write to extends beyond the end of the screen buffer, the characters are written up to the end of the screen buffer.

The attribute values at the positions written are not changed.

Windows NT: This function uses either Unicode characters or 8-bit characters from the console's current code page. The console's code page defaults initially to the system's OEM code page. To change the console's code page, use the SetConsoleCP or SetConsoleOutputCP functions, or use the chcp or mode con cp select= commands.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Consoles and Character-Mode Support Overview, Console Functions, COORD, FillConsoleOutputAttribute, SetConsoleCP, SetConsoleOutputCP, WriteConsoleOutputCharacter


FlushConsoleInputBuffer

The FlushConsoleInputBuffer function flushes the console input buffer. All input records currently in the input buffer are discarded.

BOOL FlushConsoleInputBuffer(
  HANDLE hConsoleInput   // handle to console input buffer
);

Parameters

hConsoleInput
Handle to the console input buffer. The handle must have GENERIC_WRITE access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, GetNumberOfConsoleInputEvents, PeekConsoleInput, ReadConsoleInput, WriteConsoleInput


FreeConsole

The FreeConsole function detaches the calling process from its console.

BOOL FreeConsole(VOID)

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If other processes share the console, the console is not destroyed, but the calling process cannot refer to it.

A process can use FreeConsole to detach itself from its current console, and then it can call the AllocConsole function to create a new console.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, AllocConsole


GenerateConsoleCtrlEvent

The GenerateConsoleCtrlEvent function sends a specified signal to a console process group that shares the console associated with the calling process.

BOOL GenerateConsoleCtrlEvent(
  DWORD dwCtrlEvent,       // signal to generate
  DWORD dwProcessGroupId   // process group to get signal
);

Parameters

dwCtrlEvent
Specifies the type of signal to generate. One of the following values is specified:
Value | Meaning
CTRL_C_EVENT | Generates a ctrl+c signal.
CTRL_BREAK_EVENT | Generates a ctrl+break signal.

dwProcessGroupId
Specifies the identifier of the process group that receives the signal. A process group is created when the CREATE_NEW_PROCESS_GROUP flag is specified in a call to the CreateProcess function. The process identifier of the new process is also the process group identifier of a new process group. The process group includes all processes that are descendants of the root process. Only those processes in the group that share the same console as the calling process receive the signal. In other words, if a process in the group creates a new console, that process does not receive the signal, nor do its descendants.

If this parameter is zero, the signal is generated in all processes that share the console of the calling process.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

GenerateConsoleCtrlEvent causes the control handler functions of processes in the target group to be called. All console processes have a default handler function that calls the ExitProcess function. A console process can use the SetConsoleCtrlHandler function to install or remove other handler functions.

SetConsoleCtrlHandler can also enable an inheritable attribute that causes the calling process to ignore ctrl+c signals. If GenerateConsoleCtrlEvent sends a ctrl+c signal to a process for which this attribute is enabled, the handler functions for that process are not called. ctrl+break signals always cause the handler functions to be called.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, CreateProcess, ExitProcess, SetConsoleCtrlHandler


GetConsoleCP

Windows NT: The GetConsoleCP function returns the identity of the input code page used by the console associated with the calling process. A console uses its input code page to translate keyboard input into the corresponding character value.

Windows 95: On Japanese and Korean implementations of Windows 95, the GetConsoleCP function returns the VM code page, because the OEM code page can be either 437 or DBCS. On all other implementations of Windows 95, the GetConsoleCP function returns the OEM code page.

UINT GetConsoleCP(VOID)

Parameters

This function has no parameters.

Return Values

The return value is a code that identifies the code page.

Remarks

A code page maps 256 character codes to individual characters. Different code pages include different special characters, typically customized for a language or a group of languages.

To set a console's input code page, use the SetConsoleCP function. To set and query a console's output code page, use the SetConsoleOutputCP and GetConsoleOutputCP functions.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, GetConsoleOutputCP, SetConsoleCP, SetConsoleOutputCP


GetConsoleCursorInfo

The GetConsoleCursorInfo function retrieves information about the size and visibility of the cursor for the specified console screen buffer.

BOOL GetConsoleCursorInfo(
  HANDLE hConsoleOutput,  // handle to console screen buffer
  PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
                          // address of cursor information
);

Parameters

hConsoleOutput
Handle to a console screen buffer. The handle must have GENERIC_READ access.
lpConsoleCursorInfo
Pointer to a CONSOLE_CURSOR_INFO structure in which information about the console's cursor is returned.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, CONSOLE_CURSOR_INFO, SetConsoleCursorInfo


GetConsoleMode

The GetConsoleMode function reports the current input mode of a console's input buffer or the current output mode of a console screen buffer.

BOOL GetConsoleMode(
  HANDLE hConsoleHandle,
                   // handle to console input or screen buffer
  LPDWORD lpMode   // current mode flags
);

Parameters

hConsoleHandle
Handle to a console input buffer or a screen buffer. The handle must have GENERIC_READ access.
lpMode
Pointer to a 32-bit variable that indicates the current mode of the specified buffer.

If the hConsoleHandle parameter is an input handle, the mode can be a combination of the following values. When a console is created, all input modes except ENABLE_WINDOW_INPUT are enabled by default.
Value | Meaning
ENABLE_LINE_INPUT | The ReadFile or ReadConsole function returns only when a carriage return character is read. If this mode is disabled, the functions return when one or more characters are available.
ENABLE_ECHO_INPUT | Characters read by the ReadFile or ReadConsole function are written to the active screen buffer as they are read. This mode can be used only if the ENABLE_LINE_INPUT mode is also enabled.
ENABLE_PROCESSED_INPUT | ctrl+c is processed by the system and is not placed in the input buffer. If the input buffer is being read by ReadFile or ReadConsole, other control keys are processed by the system and are not returned in the ReadFile or ReadConsole buffer. If the ENABLE_LINE_INPUT mode is also enabled, backspace, carriage return, and linefeed characters are handled by the system.
ENABLE_WINDOW_INPUT | User interactions that change the size of the console screen buffer are reported in the console's input buffer. Information about these events can be read from the input buffer by applications using the ReadConsoleInput function, but not by those using ReadFile or ReadConsole.
ENABLE_MOUSE_INPUT | If the mouse pointer is within the borders of the console window and the window has the keyboard focus, mouse events generated by mouse movement and button presses are placed in the input buffer. These events are discarded by ReadFile or ReadConsole, even when this mode is enabled.

If the hConsoleHandle parameter is a screen buffer handle, the mode can be a combination of the following values. When a screen buffer is created, both output modes are enabled by default.
Value | Meaning
ENABLE_PROCESSED_OUTPUT | Characters written by the WriteFile or WriteConsole function or echoed by the ReadFile or ReadConsole function are parsed for ASCII control sequences, and the correct action is performed. Backspace, tab, bell, carriage return, and linefeed characters are processed.
ENABLE_WRAP_AT_EOL_OUTPUT | When writing with WriteFile or WriteConsole or echoing with ReadFile or ReadConsole, the cursor moves to the beginning of the next row when it reaches the end of the current row. This causes the rows displayed in the console window to scroll up automatically when the cursor advances beyond the last row in the window. It also causes the contents of the screen buffer to scroll up (discarding the top row of the screen buffer) when the cursor advances beyond the last row in the screen buffer. If this mode is disabled, the last character in the row is overwritten with any subsequent characters.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A console consists of an input buffer and one or more screen buffers. The mode of a console buffer determines how the console behaves during input or output (I/O) operations. One set of flag constants is used with input handles, and another set is used with screen buffer (output) handles. Setting the output modes of one screen buffer does not affect the output modes of other screen buffers.

The ENABLE_LINE_INPUT and ENABLE_ECHO_INPUT modes only affect processes that use ReadFile or ReadConsole to read from the console's input buffer. Similarly, the ENABLE_PROCESSED_INPUT mode primarily affects ReadFile and ReadConsole users, except that it also determines whether ctrl+c input is reported in the input buffer (to be read by the ReadConsoleInput function) or is passed to a function defined by the application.

The ENABLE_WINDOW_INPUT and ENABLE_MOUSE_INPUT modes determine whether user interactions involving window resizing and mouse actions are reported in the input buffer or discarded. These events can be read by ReadConsoleInput, but they are always filtered by ReadFile and ReadConsole.

The ENABLE_PROCESSED_OUTPUT and ENABLE_WRAP_AT_EOL_OUTPUT modes only affect processes using ReadFile or ReadConsole and WriteFile or WriteConsole.

To change a console's I/O modes, call SetConsoleMode function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, ReadConsole, ReadConsoleInput, ReadFile, SetConsoleMode, WriteConsole, WriteFile


GetConsoleOutputCP

Windows NT: The GetConsoleOutputCP function returns the identity of the output code page used by the console associated with the calling process. A console uses its output code page to translate the character values written by the various output functions into the images displayed in the console window.

Windows 95: On Japanese and Korean implementations of Windows 95, the GetConsoleOutputCP function returns the VM code page, because the OEM code page can be either 437 or DBCS. On all other implementations of Windows 95, the GetConsoleOutputCP function returns the OEM code page.

UINT GetConsoleOutputCP(VOID)

Parameters

This function has no parameters.

Return Values

The return value is a code that identifies the code page.

Remarks

A code page maps 256 character codes to individual characters. Different code pages include different special characters, typically customized for a language or a group of languages.

To set a console's output code page, use the SetConsoleOutputCP function. To set and query a console's input code page, use the SetConsoleCP and GetConsoleCP functions.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, GetConsoleCP, SetConsoleCP, SetConsoleOutputCP


GetConsoleScreenBufferInfo

The GetConsoleScreenBufferInfo function retrieves information about the specified console screen buffer.

BOOL GetConsoleScreenBufferInfo(
  HANDLE hConsoleOutput,  // handle to console screen buffer
  PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
                          // address of screen buffer info.
);

Parameters

hConsoleOutput
Handle to a console screen buffer. The handle must have GENERIC_READ access.
lpConsoleScreenBufferInfo
Pointer to a CONSOLE_SCREEN_BUFFER_INFO structure in which the screen buffer information is returned.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The rectangle returned in the srWindow member of the CONSOLE_SCREEN_BUFFER_INFO structure can be modified and then passed to the SetConsoleWindowInfo function to scroll the screen buffer in the window, to change the size of the window, or both.

All coordinates returned in the CONSOLE_SCREEN_BUFFER_INFO structure are in character-cell coordinates, where the origin (0, 0) is at the upper-left corner of the screen buffer.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, CONSOLE_SCREEN_BUFFER_INFO, GetLargestConsoleWindowSize, SetConsoleCursorPosition, SetConsoleScreenBufferSize, SetConsoleWindowInfo


GetConsoleTitle

The GetConsoleTitle function retrieves the title bar string for the current console window.

DWORD GetConsoleTitle(
  LPTSTR lpConsoleTitle,  // address of buffer for title
  DWORD nSize             // size of the buffer
);

Parameters

lpConsoleTitle
Pointer to a buffer that receives a null-terminated string containing the text that appears in the title bar of the console window.
nSize
Specifies the size, in characters, of the buffer pointed to by the lpConsoleTitle parameter.

Return Values

If the function succeeds, the return value is the length, in characters, of the string copied to the buffer.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

To set the title bar string for a console window, use the SetConsoleTitle function.

Windows NT: This function uses either Unicode characters or 8-bit characters from the console's current code page. The console's code page defaults initially to the system's OEM code page. To change the console's code page, use the SetConsoleCP or SetConsoleOutputCP functions, or use the chcp or mode con cp select= commands.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Consoles and Character-Mode Support Overview, Console Functions, SetConsoleCP, SetConsoleOutputCP, SetConsoleTitle


GetLargestConsoleWindowSize

The GetLargestConsoleWindowSize function returns the size of the largest possible console window, based on the current font and the size of the display.

COORD GetLargestConsoleWindowSize(
  HANDLE hConsoleOutput   // handle to console screen buffer
);

Parameters

hConsoleOutput
Handle to a console screen buffer.

Return Values

If the function succeeds, the return value is a COORD structure that specifies the number of character cell rows (X member) and columns (Y member) in the largest possible console window. Otherwise, the members of the structure are zero.

To get extended error information, call GetLastError.

Remarks

The function does not take into consideration the size of the screen buffer, which means that the window size returned may be larger than the size of the screen buffer. The GetConsoleScreenBufferInfo function can be used to determine the maximum size of the console window, given the current screen buffer size, the current font, and the display size.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, COORD, GetConsoleScreenBufferInfo, SetConsoleWindowInfo


GetNumberOfConsoleInputEvents

The GetNumberOfConsoleInputEvents function retrieves the number of unread input records in the console's input buffer.

BOOL GetNumberOfConsoleInputEvents(
  HANDLE hConsoleInput,       // handle to console input buffer
  LPDWORD lpcNumberOfEvents   // address for number of events
);

Parameters

hConsoleInput
Handle to the console input buffer. The handle must have GENERIC_READ access.
lpcNumberOfEvents
Pointer to a 32-bit variable that receives the number of unread input records in the console's input buffer.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The GetNumberOfConsoleInputEvents function reports the total number of unread input records in the input buffer, including keyboard, mouse, and window-resizing input records. Processes using the ReadFile or ReadConsole function can only read keyboard input. Processes using the ReadConsoleInput function can read all types of input records.

A process can specify a console input buffer handle in one of the wait functions to determine when there is unread console input. When the input buffer is not empty, the state of a console input buffer handle is signaled.

To read input records from a console input buffer without affecting the number of unread records, use the PeekConsoleInput function. To discard all unread records in a console's input buffer, use the FlushConsoleInputBuffer function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, FlushConsoleInputBuffer, PeekConsoleInput, ReadConsole, ReadConsoleInput, ReadFile


GetNumberOfConsoleMouseButtons

The GetNumberOfConsoleMouseButtons function retrieves the number of buttons on the mouse used by the current console.

BOOL GetNumberOfConsoleMouseButtons(
  LPDWORD lpNumberOfMouseButtons   // address of number of buttons
);

Parameters

lpNumberOfMouseButtons
Pointer to a 32-bit variable that receives the number of mouse buttons.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

When a console receives mouse input, an INPUT_RECORD structure containing a MOUSE_EVENT_RECORD structure is placed in the console's input buffer. The dwButtonState member of MOUSE_EVENT_RECORD has a bit indicating the state of each mouse button. The bit is 1 if the button is down and 0 if the button is up. To determine the number of bits that are significant, use GetNumberOfConsoleMouseButtons.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, ReadConsoleInput, INPUT_RECORD, MOUSE_EVENT_RECORD


GetStdHandle

The GetStdHandle function returns a handle for the standard input, standard output, or standard error device.

HANDLE GetStdHandle(
  DWORD nStdHandle   // input, output, or error device
);

Parameters

nStdHandle
Specifies the device for which to return the handle. This parameter can have one of the following values:
Value | Meaning
STD_INPUT_HANDLE | Standard input handle
STD_OUTPUT_HANDLE | Standard output handle
STD_ERROR_HANDLE | Standard error handle

Return Values

If the function succeeds, the return value is a handle to the specified device.

If the function fails, the return value is the INVALID_HANDLE_VALUE flag. To get extended error information, call GetLastError.

Remarks

Handles returned by GetStdHandle can be used by applications that need to read from or write to the console. When a console is created, the standard input handle is a handle to the console's input buffer, and the standard output and standard error handles are handles of the console's active screen buffer. These handles can be used by the ReadFile and WriteFile functions, or by any of the console functions that access the console input buffer or a screen buffer (for example, the ReadConsoleInput, WriteConsole, or GetConsoleScreenBufferInfo functions).

All handles returned by this function have GENERIC_READ and GENERIC_WRITE access unless the SetStdHandle function has been used to set a standard handle to be some handle with a lesser access.

The standard handles of a process may be redirected by a call to SetStdHandle, in which case GetStdHandle returns the redirected handle. If the standard handles have been redirected, you can specify the CONIN$ value in a call to the CreateFile function to get a handle to a console's input buffer. Similarly, you can specify the CONOUT$ value to get a handle to a console's active screen buffer.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, CreateFile, GetConsoleScreenBufferInfo, ReadConsoleInput, ReadFile, SetStdHandle, WriteConsole, WriteFile


HandlerRoutine

A HandlerRoutine function is an application-defined function used with the SetConsoleCtrlHandler function. A console process uses this function to handle control signals received by the process. The PHANDLER_ROUTINE type defines a pointer to this callback function. HandlerRoutine is a placeholder for the application-defined function name.

BOOL WINAPI HandlerRoutine(
  DWORD dwCtrlType   //  control signal type
);

Parameters

dwCtrlType
Indicates the type of control signal received by the handler. This value is one of the following:
Signal | Description
CTRL_C_EVENT | A CTRL+c signal was received, either from keyboard input or from a signal generated by the GenerateConsoleCtrlEvent function.
CTRL_BREAK_EVENT | A CTRL+BREAK signal was received, either from keyboard input or from a signal generated by GenerateConsoleCtrlEvent.
CTRL_CLOSE_EVENT | A signal that the system sends to all processes attached to a console when the user closes the console (either by choosing the Close command from the console window's System menu, or by choosing the End Task command from the Task List).
CTRL_LOGOFF_EVENT | A signal that the system sends to all console processes when a user is logging off. This signal does not indicate which user is logging off, so no assumptions can be made.
CTRL_SHUTDOWN_EVENT | A signal that the system sends to all console processes when the system is shutting down.

Return Values

If the function handles the control signal, it should return TRUE. If it returns FALSE, the next handler function in the list of handlers for this process is used.

Remarks

Each console process has its own list of HandlerRoutine functions. Initially, this list contains only a default handler function that calls ExitProcess. A console process adds or removes additional handler functions by calling the SetConsoleCtrlHandler function, which does not affect the list of handler functions for other processes. When a console process receives any of the control signals, its handler functions are called on a last-registered, first-called basis until one of the handlers returns TRUE. If none of the handlers returns TRUE, the default handler is called.

The CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT signals give the process an opportunity to clean up before termination. A HandlerRoutine called to handle any of these signals can do one of the following after performing any cleanup operations:

  • Call the ExitProcess function to terminate the process.
  • Return FALSE. If none of the registered handler functions returns TRUE, the default handler terminates the process.
  • Return TRUE. In this case, no other handler functions are called, and the system displays a pop-up dialog box that asks the user whether to terminate the process. The system also displays the dialog box if the process does not respond within a certain time-out period (5 seconds for CTRL_CLOSE_EVENT, and 20 seconds for CTRL_LOGOFF_EVENT and CTRL_SHUTDOWN_EVENT).

A process can use the SetProcessShutdownParameters function to prevent the CTRL_LOGOFF_EVENT and CTRL_SHUTDOWN_EVENT dialog box from being displayed. In this case, the system just terminates the process when a HandlerRoutine returns TRUE or when the time-out period elapses.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: User-defined.

See Also

Consoles and Character-Mode Support Overview, Console Functions, ExitProcess, GenerateConsoleCtrlEvent, GetProcessShutdownParameters, SetConsoleCtrlHandler, SetProcessShutdownParameters


PeekConsoleInput

The PeekConsoleInput function reads data from the specified console input buffer without removing it from the buffer.

BOOL PeekConsoleInput(
  HANDLE hConsoleInput,  // handle to a console input buffer
  PINPUT_RECORD lpBuffer,  // pointer to the buffer for peek data
  DWORD nLength,         // number of records to read
  LPDWORD lpNumberOfEventsRead
                         // pointer to number of records read
);

Parameters

hConsoleInput
Handle to the input buffer. The handle must have GENERIC_READ access.
lpBuffer
Pointer to an INPUT_RECORD buffer that receives the input buffer data.
nLength
Specifies the size, in records, of the buffer pointed to by the lpBuffer parameter.
lpNumberOfEventsRead
Pointer to a 32-bit variable that receives the number of input records read.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the number of records requested exceeds the number of records available in the buffer, the number available is read. If no data is available, the function returns immediately.

Windows NT: This function uses either Unicode characters or 8-bit characters from the console's current code page. The console's code page defaults initially to the system's OEM code page. To change the console's code page, use the SetConsoleCP or SetConsoleOutputCP functions, or use the chcp or mode con cp select= commands.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Consoles and Character-Mode Support Overview, Console Functions, INPUT_RECORD, ReadConsoleInput, SetConsoleCP, SetConsoleOutputCP, WriteConsoleInput


ReadConsole

The ReadConsole function reads character input from the console input buffer and removes it from the buffer.

BOOL ReadConsole(
  HANDLE hConsoleInput,        // handle to a console input buffer
  LPVOID lpBuffer,             // address of buffer to receive data
  DWORD nNumberOfCharsToRead,  // number of characters to read
  LPDWORD lpNumberOfCharsRead,  // address of number of characters
                                // read
  LPVOID lpReserved            // reserved
);

Parameters

hConsoleInput
Handle to the console input buffer. The handle must have GENERIC_READ access.
lpBuffer
Pointer to a buffer that receives the data read from the console input buffer.
nNumberOfCharsToRead
Specifies the number of characters to read. Because the function can read either 2-byte Unicode or 1-byte ANSI characters, the size of the buffer pointed to by the lpBuffer parameter should be at least nNumberOfCharsToRead * sizeof(TCHAR).
lpNumberOfCharsRead
Pointer to a 32-bit variable that receives the number of characters actually read.
lpReserved
Reserved; must be NULL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

ReadConsole reads keyboard input from a console's input buffer. It behaves like the ReadFile function, except that it can read in either Unicode (wide-character) or ANSI mode. To have applications that maintain a single set of sources compatible with both modes, use ReadConsole rather than ReadFile. Although ReadConsole can only be used with a console input buffer handle, ReadFile can be used with other handles (such as files or pipes). ReadConsole fails if used with a standard handle that has been redirected to be something other than a console handle.

All of the input modes that affect the behavior of ReadFile have the same effect on ReadConsole. To retrieve and set the input modes of a console input buffer, use the GetConsoleMode and SetConsoleMode functions.

If the input buffer contains input events other than keyboard events (such as mouse events or window-resizing events), they are discarded. Those events can only be read by using the ReadConsoleInput function.

Windows NT: This function uses either Unicode characters or 8-bit characters from the console's current code page. The console's code page defaults initially to the system's OEM code page. To change the console's code page, use the SetConsoleCP or SetConsoleOutputCP functions, or use the chcp or mode con cp select= commands.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Consoles and Character-Mode Support Overview, Console Functions, GetConsoleMode, ReadConsoleInput, ReadFile, SetConsoleCP, SetConsoleMode, SetConsoleOutputCP, WriteConsole


ReadConsoleInput

The ReadConsoleInput function reads data from a console input buffer and removes it from the buffer.

BOOL ReadConsoleInput(
  HANDLE hConsoleInput,  // handle to a console input buffer
  PINPUT_RECORD lpBuffer,  // address of the buffer for read data
  DWORD nLength,         // number of records to read
  LPDWORD lpNumberOfEventsRead
                         // address of number of records read
);

Parameters

hConsoleInput
Handle to the input buffer. The handle must have GENERIC_READ access.
lpBuffer
Pointer to an INPUT_RECORD buffer that receives the input buffer data.
nLength
Specifies the size, in input records, of the buffer pointed to by the lpBuffer parameter.
lpNumberOfEventsRead
Pointer to a 32-bit variable that receives the number of input records read.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the number of records requested in the nLength parameter exceeds the number of records available in the buffer, the number available is read. The function does not return until at least one input record has been read.

A process can specify a console input buffer handle in one of the wait functions to determine when there is unread console input. When the input buffer is not empty, the state of a console input buffer handle is signaled.

To determine the number of unread input records in a console's input buffer, use the GetNumberOfConsoleInputEvents function. To read input records from a console input buffer without affecting the number of unread records, use the PeekConsoleInput function. To discard all unread records in a console's input buffer, use the FlushConsoleInputBuffer function.

Windows NT: This function uses either Unicode characters or 8-bit characters from the console's current code page. The console's code page defaults initially to the system's OEM code page. To change the console's code page, use the SetConsoleCP or SetConsoleOutputCP functions, or use the chcp or mode con cp select= commands.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Consoles and Character-Mode Support Overview, Console Functions, FlushConsoleInputBuffer, GetNumberOfConsoleInputEvents, INPUT_RECORD, PeekConsoleInput, ReadConsole, ReadFile, SetConsoleCP, SetConsoleOutputCP, WriteConsoleInput


ReadConsoleOutput

The ReadConsoleOutput function reads character and color attribute data from a rectangular block of character cells in a console screen buffer, and the function writes the data to a rectangular block at a specified location in the destination buffer.

BOOL ReadConsoleOutput(
  HANDLE hConsoleOutput,  // handle to a console screen buffer
  PCHAR_INFO lpBuffer,    // address of buffer that receives data
  COORD dwBufferSize,     // column-row size of destination buffer
  COORD dwBufferCoord,    // upper-left cell to write to
  PSMALL_RECT lpReadRegion   // address of rectangle to read from
);

Parameters

hConsoleOutput
Handle to the screen buffer. The handle must have GENERIC_READ access.
lpBuffer
Pointer to a destination buffer that receives the data read from the screen buffer. This pointer is treated as the origin of a two-dimensional array of CHAR_INFO structures whose size is specified by the dwBufferSize parameter.
dwBufferSize
Specifies the size, in character cells, of the lpBuffer parameter. The X member of the COORD structure is the number of columns; the Y member is the number of rows.
dwBufferCoord
Specifies the coordinates of the upper-left cell in the lpBuffer parameter that receives the data read from the screen buffer. The X member of the COORD structure is the column, and the Y member is the row.
lpReadRegion
Pointer to a SMALL_RECT structure. On input, the structure members specify the upper-left and lower-right coordinates of the screen buffer rectangle from which the function is to read. On output, the structure members specify the actual rectangle that the function copied from.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

ReadConsoleOutput treats the screen buffer and the destination buffer as two-dimensional arrays (columns and rows of character cells). The rectangle pointed to by the lpReadRegion parameter specifies the size and location of the block to be read from the screen buffer. A destination rectangle of the same size is located with its upper-left cell at the coordinates of the dwBufferCoord parameter in the lpBuffer array. Data read from the cells in the screen buffer source rectangle is copied to the corresponding cells in the destination buffer. If the corresponding cell is outside the boundaries of the destination buffer rectangle (whose dimensions are specified by the dwBufferSize parameter), the data is not copied.

Cells in the destination buffer corresponding to coordinates that are not within the boundaries of the screen buffer are left unchanged. In other words, these are the cells for which no screen buffer data is available to be read.

Before ReadConsoleOutput returns, it sets the members of the structure pointed to by the lpReadRegion parameter to the actual screen buffer rectangle whose cells were copied into the destination buffer. This rectangle reflects the cells in the source rectangle for which there existed a corresponding cell in the destination buffer, because ReadConsoleOutput clips the dimensions of the source rectangle to fit the boundaries of the screen buffer.

If the rectangle specified by lpReadRegion lies completely outside the boundaries of the screen buffer, or if the corresponding rectangle is positioned completely outside the boundaries of the destination buffer, no data is copied. In this case, the function returns with the members of the structure pointed to by the lpReadRegion parameter set such that the Right member is less than the Left, or the Bottom member is less than the Top. To determine the size of the screen buffer, use the GetConsoleScreenBufferInfo function.

The ReadConsoleOutput function has no effect on the screen buffer's cursor position. The contents of the screen buffer are not changed by the function.

Windows NT: This function uses either Unicode characters or 8-bit characters from the console's current code page. The console's code page defaults initially to the system's OEM code page. To change the console's code page, use the SetConsoleCP or SetConsoleOutputCP functions, or use the chcp or mode con cp select= commands.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Consoles and Character-Mode Support Overview, Console Functions, CHAR_INFO, COORD, ReadConsoleOutputAttribute, ReadConsoleOutputCharacter, SetConsoleCP, SetConsoleOutputCP, SMALL_RECT, WriteConsoleOutput


ReadConsoleOutputAttribute

The ReadConsoleOutputAttribute function copies a specified number of foreground and background color attributes from consecutive cells of a console screen buffer, beginning at a specified location.

BOOL ReadConsoleOutputAttribute(
  HANDLE hConsoleOutput,
                      // handle to a console screen buffer
  LPWORD lpAttribute, // address of buffer to receive attributes
  DWORD nLength,      // number of character cells to read from
  COORD dwReadCoord,  // coordinates of first cell to read from
  LPDWORD lpNumberOfAttrsRead
                      // address of number of cells read from
);

Parameters

hConsoleOutput
Handle to a console screen buffer. The handle must have GENERIC_READ access.
lpAttribute
Pointer to a buffer that receives the attributes read from the screen buffer.
nLength
Specifies the number of screen buffer character cells from which to read. The size of the buffer pointed to by the lpAttribute parameter should be nLength * sizeof(WORD).
dwReadCoord
Specifies the coordinates of the first cell in the screen buffer from which to read. The X member of the COORD structure is the column, and the Y member is the row.
lpNumberOfAttrsRead
Pointer to a 32-bit variable that receives the number of attributes actually read.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the number of attributes to be read from extends beyond the end of the specified screen buffer row, attributes are read from the next row. If the number of attributes to be read from extends beyond the end of the screen buffer, attributes up to the end of the screen buffer are read.

Each attribute specifies the foreground (text) and background colors in which that character cell is drawn. The attribute values are some combination of the following values: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following combination of values produces red text on a white background:

FOREGROUND_RED | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, COORD, ReadConsoleOutput, ReadConsoleOutputCharacter, WriteConsoleOutput, WriteConsoleOutputAttribute, WriteConsoleOutputCharacter


ReadConsoleOutputCharacter

The ReadConsoleOutputCharacter function copies a number of characters from consecutive cells of a console screen buffer, beginning at a specified location.

BOOL ReadConsoleOutputCharacter(
  HANDLE hConsoleOutput,
                      // handle to a console screen buffer
  LPTSTR lpCharacter, // address of buffer to receive characters
  DWORD nLength,      // number of character cells to read from
  COORD dwReadCoord,  // coordinates of first cell to read from
  LPDWORD lpNumberOfCharsRead
                      // address of number of cells read from
);

Parameters

hConsoleOutput
Handle to a console screen buffer. The handle must have GENERIC_READ access.
lpCharacter
Pointer to a buffer that receives the characters read from the screen buffer.
nLength
Specifies the number of screen buffer character cells from which to read. The size of the buffer pointed to by the lpCharacter parameter should be nLength * sizeof(TCHAR).
dwReadCoord
Specifies the coordinates of the first cell in the screen buffer from which to read. The X member of the COORD structure is the column, and the Y member is the row.
lpNumberOfCharsRead
Pointer to a 32-bit variable that receives the number of characters actually read.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the number of characters to be read from extends beyond the end of the specified screen buffer row, characters are read from the next row. If the number of characters to be read from extends beyond the end of the screen buffer, characters up to the end of the screen buffer are read.

Windows NT: This function uses either Unicode characters or 8-bit characters from the console's current code page. The console's code page defaults initially to the system's OEM code page. To change the console's code page, use the SetConsoleCP or SetConsoleOutputCP functions, or use the chcp or mode con cp select= commands.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Consoles and Character-Mode Support Overview, Console Functions, COORD, ReadConsoleOutput, ReadConsoleOutputAttribute, SetConsoleCP, SetConsoleOutputCP, WriteConsoleOutput, WriteConsoleOutputAttribute, WriteConsoleOutputCharacter


ScrollConsoleScreenBuffer

The ScrollConsoleScreenBuffer function moves a block of data in a screen buffer. The effects of the move can be limited by specifying a clipping rectangle, so the contents of the screen buffer outside the clipping rectangle are unchanged.

BOOL ScrollConsoleScreenBuffer(
  HANDLE hConsoleOutput,  // handle to a console screen buffer
  CONST SMALL_RECT *lpScrollRectangle,
                          // address of screen buffer rect. to move
  CONST SMALL_RECT *lpClipRectangle,
                          // address of affected screen buffer rect.
  COORD dwDestinationOrigin,  // new location of screen buffer rect.
  CONST CHAR_INFO *lpFill   // address of fill character and color
);

Parameters

hConsoleOutput
Handle to a console screen buffer. The handle must have GENERIC_WRITE access.
lpScrollRectangle
Pointer to a SMALL_RECT structure whose members specify the upper-left and lower-right coordinates of the screen buffer rectangle to be moved.
lpClipRectangle
Pointer to a SMALL_RECT structure whose members specify the upper-left and lower-right coordinates of the screen buffer rectangle that is affected by the scrolling. This pointer can be NULL.
dwDestinationOrigin
Specifies the upper-left corner of the new location of the lpScrollRectangle contents.
lpFill
Pointer to a CHAR_INFO structure that specifies the character and color attributes to be used in filling the cells within the intersection of lpScrollRectangle and lpClipRectangle that were left empty as a result of the move.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

ScrollConsoleScreenBuffer copies the contents of a rectangular region of a screen buffer, specified by the lpScrollRectangle parameter, to another area of the screen buffer. The target rectangle has the same dimensions as the lpScrollRectangle rectangle with its upper-left corner at the coordinates specified by the dwDestinationOrigin parameter. Those parts of lpScrollRectangle that do not overlap with the target rectangle are filled in with the character and color attributes specified by the lpFill parameter.

The clipping rectangle applies to changes made in both the lpScrollRectangle rectangle and the target rectangle. For example, if the clipping rectangle does not include a region that would have been filled by the contents of lpFill, the original contents of the region are left unchanged.

If the scroll or target regions extend beyond the dimensions of the screen buffer, they are clipped. For example, if lpScrollRectangle is the region contained by (0,0) and (19,19) and dwDestinationOrigin is (10,15), the target rectangle is the region contained by (10,15) and (29,34). However, if the screen buffer is 50 characters wide and 30 characters high, the target rectangle is clipped to (10,15) and (29,29). Changes to the screen buffer are also clipped according to lpClipRectangle, if the parameter specifies a SMALL_RECT structure. If the clipping rectangle is specified as (0,0) and (49,19), only the changes that occur in that region of the screen buffer are made.

Windows NT: This function uses either Unicode characters or 8-bit characters from the console's current code page. The console's code page defaults initially to the system's OEM code page. To change the console's code page, use the SetConsoleCP or SetConsoleOutputCP functions, or use the chcp or mode con cp select= commands.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Consoles and Character-Mode Support Overview, Console Functions, CHAR_INFO, SetConsoleCP, SetConsoleOutputCP, SetConsoleWindowInfo, SMALL_RECT


SetConsoleActiveScreenBuffer

The SetConsoleActiveScreenBuffer function sets the specified screen buffer to be the currently displayed console screen buffer.

BOOL SetConsoleActiveScreenBuffer(
  HANDLE hConsoleOutput   // handle to console screen buffer
);

Parameters

hConsoleOutput
Handle to a console screen buffer.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A console can have multiple screen buffers. SetConsoleActiveScreenBuffer determines which one is displayed. You can write to an inactive screen buffer and then use SetConsoleActiveScreenBuffer to display the buffer's contents.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, CreateConsoleScreenBuffer


SetConsoleCP

The SetConsoleCP function sets the input code page used by the console associated with the calling process. A console uses its input code page to translate keyboard input into the corresponding character value.

BOOL SetConsoleCP(
  UINT wCodePageID   // code page to set
);

Parameters

wCodePageID
Specifies the identifier of the code page to set. The identifiers of the code pages available on the local computer are stored in the registry under the following key.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A code page maps 256 character codes to individual characters. Different code pages include different special characters, typically customized for a language or a group of languages.

To determine a console's current input code page, use the GetConsoleCP function. To set and retrieve a console's output code page, use the SetConsoleOutputCP and GetConsoleOutputCP functions.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, GetConsoleCP, GetConsoleOutputCP, SetConsoleOutputCP


SetConsoleCtrlHandler

The SetConsoleCtrlHandler function adds or removes an application-defined HandlerRoutine function from the list of handler functions for the calling process.

Windows NT: If no handler function is specified, the function sets an inheritable attribute that determines whether the calling process ignores ctrl+c signals.

BOOL SetConsoleCtrlHandler(
  PHANDLER_ROUTINE HandlerRoutine,  // address of handler function
  BOOL Add                          // handler to add or remove
);

Parameters

HandlerRoutine
Pointer to the application-defined HandlerRoutine function to add or remove.

Windows NT: This parameter can be NULL.

Add
Specifies whether to add or remove the function pointed to by the HandlerRoutine parameter from the handler list. If this parameter is TRUE, the handler is added; if it is FALSE, the handler is removed.

Windows NT: If the HandlerRoutine parameter is NULL, a TRUE value causes the calling process to ignore ctrl+c input, and a FALSE value restores normal processing of ctrl+c input. This attribute of ignoring or processing ctrl+c is inherited by child processes.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Each console process has its own list of application-defined HandlerRoutine functions that handle ctrl+c and ctrl+break signals. The handler functions also handle signals generated by the system when the user closes the console, logs off, or shuts down the system. Initially, the handler list for each process contains only a default handler function that calls the ExitProcess function. A console process adds or removes additional handler functions by calling the SetConsoleCtrlHandler function, which does not affect the list of handler functions for other processes. When a console process receives any of the control signals, its handler functions are called on a last-registered, first-called basis until one of the handlers returns TRUE. If none of the handlers returns TRUE, the default handler is called.

For console processes, the ctrl+c and ctrl+break key combinations are typically treated as signals (CTRL_C_EVENT and CTRL_C_BREAK_EVENT). When a console window with the keyboard focus receives ctrl+c or ctrl+break, the signal is typically passed to all processes sharing that console.

ctrl+break is always treated as a signal, but typical ctrl+c behavior can be changed in three ways that prevent the handler functions from being called:

  • The SetConsoleMode function can disable the ENABLE_PROCESSED_INPUT mode for a console's input buffer, so ctrl+c is reported as keyboard input rather than as a signal.
  • Windows NT: Calling SetConsoleCtrlHandler with the NULL and TRUE arguments causes the calling process to ignore ctrl+c signals. This attribute is inherited by child processes, but it can be enabled or disabled by any process without affecting existing processes.
  • If a console process is being debugged and ctrl+c signals have not been disabled, the kernel generates a DBG_CONTROL_C exception. This exception is raised only for the benefit of the debugger, and an application should never use an exception handler to deal with it. If the debugger handles the exception, an application will not notice the ctrl+c, with one exception: alertable waits will terminate. If the debugger passes the exception on unhandled, ctrl+c is passed to the console process and treated as a signal, as previously discussed.

A console process can use the GenerateConsoleCtrlEvent function to send a ctrl+c or ctrl+break signal to a console process group.

The system generates CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT signals when the user closes the console, logs off, or shuts down the system so that the process has an opportunity to clean up before termination. Console functions, or any C run-time functions that call console functions, may not work reliably during processing of any of the three signals mentioned previously. The reason is that some or all of the internal console cleanup routines may have been called before executing the process signal handler.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, ExitProcess, GenerateConsoleCtrlEvent, GetConsoleMode, HandlerRoutine, SetConsoleMode


SetConsoleCursorInfo

The SetConsoleCursorInfo function sets the size and visibility of the cursor for the specified console screen buffer.

BOOL SetConsoleCursorInfo(
  HANDLE hConsoleOutput,  // handle to console screen buffer
  CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
                          // address of cursor information
);

Parameters

hConsoleOutput
Handle to a console screen buffer. The handle must have GENERIC_WRITE access.
lpConsoleCursorInfo
Pointer to a CONSOLE_CURSOR_INFO structure containing the new specifications for the screen buffer's cursor.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

When a screen buffer's cursor is visible, its appearance can vary, ranging from completely filling a character cell to showing up as a horizontal line at the bottom of the cell. The dwSize member of the CONSOLE_CURSOR_INFO structure specifies the percentage of a character cell that is filled by the cursor. If this member is less than 1 or greater than 100, SetConsoleCursorInfo fails.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, CONSOLE_CURSOR_INFO, GetConsoleCursorInfo, SetConsoleCursorPosition


SetConsoleCursorPosition

The SetConsoleCursorPosition function sets the cursor position in the specified console screen buffer.

BOOL SetConsoleCursorPosition(
  HANDLE hConsoleOutput,  // handle to console screen buffer
  COORD dwCursorPosition   // new cursor position coordinates
);

Parameters

hConsoleOutput
Handle to a console screen buffer. The handle must have GENERIC_WRITE access.
dwCursorPosition
Specifies a COORD structure containing the new cursor position. The coordinates are the column and row of a screen buffer character cell. The coordinates must be within the boundaries of the screen buffer.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The cursor position determines where characters written by the WriteFile or WriteConsole function, or echoed by the ReadFile or ReadConsole function, are displayed. To determine the current position of the cursor, use the GetConsoleScreenBufferInfo function.

If the new cursor position is not within the boundaries of the screen buffer's window, the window origin changes to make the cursor visible.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, GetConsoleCursorInfo, GetConsoleScreenBufferInfo, ReadConsole, ReadFile, SetConsoleCursorInfo, WriteConsole, WriteFile


SetConsoleMode

The SetConsoleMode function sets the input mode of a console's input buffer or the output mode of a console screen buffer.

BOOL SetConsoleMode(
  HANDLE hConsoleHandle,
                 // handle to console input or screen buffer
  DWORD dwMode   // input or output mode to set
);

Parameters

hConsoleHandle
Handle to a console input buffer or a screen buffer. The handle must have GENERIC_WRITE access.
dwMode
Specifies the input or output mode to set. If the hConsoleHandle parameter is an input handle, the mode can be a combination of the following values. When a console is created, all input modes except ENABLE_WINDOW_INPUT are enabled by default.
Value | Meaning
ENABLE_LINE_INPUT | The ReadFile or ReadConsole function returns only when a carriage return character is read. If this mode is disabled, the functions return when one or more characters are available.
ENABLE_ECHO_INPUT | Characters read by the ReadFile or ReadConsole function are written to the active screen buffer as they are read. This mode can be used only if the ENABLE_LINE_INPUT mode is also enabled.
ENABLE_PROCESSED_INPUT | ctrl+c is processed by the system and is not placed in the input buffer. If the input buffer is being read by ReadFile or ReadConsole, other control keys are processed by the system and are not returned in the ReadFile or ReadConsole buffer. If the ENABLE_LINE_INPUT mode is also enabled, backspace, carriage return, and linefeed characters are handled by the system.
ENABLE_WINDOW_INPUT | User interactions that change the size of the console screen buffer are reported in the console's input buffer. Information about these events can be read from the input buffer by applications using the ReadConsoleInput function, but not by those using ReadFile or ReadConsole.
ENABLE_MOUSE_INPUT | If the mouse pointer is within the borders of the console window and the window has the keyboard focus, mouse events generated by mouse movement and button presses are placed in the input buffer. These events are discarded by ReadFile or ReadConsole, even when this mode is enabled.

If the hConsoleHandle parameter is a screen buffer handle, the mode can be a combination of the following values. When a screen buffer is created, both output modes are enabled by default.
Value | Meaning
ENABLE_PROCESSED_OUTPUT | Characters written by the WriteFile or WriteConsole function or echoed by the ReadFile or ReadConsole function are examined for ASCII control sequences and the correct action is performed. Backspace, tab, bell, carriage return, and linefeed characters are processed.
ENABLE_WRAP_AT_EOL_OUTPUT | When writing with WriteFile or WriteConsole or echoing with ReadFile or ReadConsole, the cursor moves to the beginning of the next row when it reaches the end of the current row. This causes the rows displayed in the console window to scroll up automatically when the cursor advances beyond the last row in the window. It also causes the contents of the screen buffer to scroll up (discarding the top row of the screen buffer) when the cursor advances beyond the last row in the screen buffer. If this mode is disabled, the last character in the row is overwritten with any subsequent characters.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A console consists of an input buffer and one or more screen buffers. The mode of a console buffer determines how the console behaves during input and output (I/O) operations. One set of flag constants is used with input handles, and another set is used with screen buffer (output) handles. Setting the output modes of one screen buffer does not affect the output modes of other screen buffers.

The ENABLE_LINE_INPUT and ENABLE_ECHO_INPUT modes only affect processes that use ReadFile or ReadConsole to read from the console's input buffer. Similarly, the ENABLE_PROCESSED_INPUT mode primarily affects ReadFile and ReadConsole users, except that it also determines whether ctrl+c input is reported in the input buffer (to be read by the ReadConsoleInput function) or is passed to a HandlerRoutine function defined by the application.

The ENABLE_WINDOW_INPUT and ENABLE_MOUSE_INPUT modes determine whether user interactions involving window resizing and mouse actions are reported in the input buffer or discarded. These events can be read by ReadConsoleInput, but they are always filtered by ReadFile and ReadConsole.

The ENABLE_PROCESSED_OUTPUT and ENABLE_WRAP_AT_EOL_OUTPUT modes only affect processes using ReadFile or ReadConsole and WriteFile or WriteConsole.

To determine the current mode of a console input buffer or a screen buffer, use the GetConsoleMode function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, GetConsoleMode, HandlerRoutine, ReadConsole, ReadConsoleInput, ReadFile, WriteConsole, WriteFile


SetConsoleOutputCP

The SetConsoleOutputCP function sets the output code page used by the console associated with the calling process. A console uses its output code page to translate the character values written by the various output functions into the images displayed in the console window.

BOOL SetConsoleOutputCP(
  UINT wCodePageID   // code page to set
);

Parameters

wCodePageID
Specifies the identifier of the code page to set. The identifiers of the code pages available on the local computer are stored in the registry under the following key.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A code page maps 256 character codes to individual characters. Different code pages include different special characters, typically customized for a language or a group of languages.

To determine a console's current output code page, use the GetConsoleOutputCP function. To set and retrieve a console's input code page, use the SetConsoleCP and GetConsoleCP functions.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, GetConsoleCP, GetConsoleOutputCP, SetConsoleCP


SetConsoleScreenBufferSize

The SetConsoleScreenBufferSize function changes the size of the specified console screen buffer.

BOOL SetConsoleScreenBufferSize(
  HANDLE hConsoleOutput,  // handle to console screen buffer
  COORD dwSize            // new size in character rows and cols.
);

Parameters

hConsoleOutput
Handle to a console screen buffer. The handle must have GENERIC_WRITE access.
dwSize
Specifies a COORD structure containing the new size, in rows and columns, of the screen buffer. The specified width and height cannot be less than the width and height of the screen buffer's window. The specified dimensions also cannot be less than the minimum size allowed by the system. This minimum depends on the current font size for the console (selected by the user) and the SM_CXMIN and SM_CYMIN values returned by the GetSystemMetrics function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, COORD, GetConsoleScreenBufferInfo, SetConsoleWindowInfo


SetConsoleTextAttribute

The SetConsoleTextAttribute function sets the foreground (text) and background color attributes of characters written to the screen buffer by the WriteFile or WriteConsole function, or echoed by the ReadFile or ReadConsole function. This function affects only text written after the function call.

BOOL SetConsoleTextAttribute(
  HANDLE hConsoleOutput,  // handle to console screen buffer
  WORD wAttributes        // text and background colors
);

Parameters

hConsoleOutput
Handle to a console screen buffer. The handle must have GENERIC_READ access.
wAttributes
Specifies the foreground and background color attributes. Any combination of the following values can be specified: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following combination of values produces white text on a black background:
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

To determine the current color attributes of a screen buffer, call the GetConsoleScreenBufferInfo function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, GetConsoleScreenBufferInfo, ReadConsole, ReadFile, WriteConsole, WriteFile


SetConsoleTitle

The SetConsoleTitle function sets the title bar string for the current console window.

BOOL SetConsoleTitle(
  LPCTSTR lpConsoleTitle   // address of new title
);

Parameters

lpConsoleTitle
Pointer to a null-terminated string that contains the string to appear in the title bar of the console window.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows NT: This function uses either Unicode characters or 8-bit characters from the console's current code page. The console's code page defaults initially to the system's OEM code page. To change the console's code page, use the SetConsoleCP or SetConsoleOutputCP functions, or use the chcp or mode con cp select= commands.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Consoles and Character-Mode Support Overview, Console Functions, GetConsoleTitle, SetConsoleCP, SetConsoleOutputCP


SetConsoleWindowInfo

The SetConsoleWindowInfo function sets the current size and position of a console screen buffer's window.

BOOL SetConsoleWindowInfo(
  HANDLE hConsoleOutput,  // handle to console screen buffer
  BOOL bAbsolute,         // coordinate type flag
  CONST SMALL_RECT *lpConsoleWindow
                          // address of new window rectangle
);

Parameters

hConsoleOutput
Handle to a console screen buffer. The handle must have GENERIC_WRITE access.
bAbsolute
Specifies how the coordinates in the structure pointed to by the lpConsoleWindow parameter are used. If bAbsolute is TRUE, the coordinates specify the new upper-left and lower-right corners of the window. If it is FALSE, the coordinates are offsets to the current window-corner coordinates.
lpConsoleWindow
Pointer to a SMALL_RECT structure that contains values that determine the new upper-left and lower-right corners of the window.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The function fails if the specified window rectangle extends beyond the boundaries of the screen buffer. This means that the Top and Left members of the lpConsoleWindow rectangle (or the calculated top and left coordinates, if bAbsolute is FALSE) cannot be less than zero. Similarly, the Bottom and Right members (or the calculated bottom and right coordinates) cannot be greater than (screen buffer height – 1) and (screen buffer width – 1), respectively. The function also fails if the Right member (or calculated right coordinate) is less than or equal to the Left member (or calculated left coordinate) or if the Bottom member (or calculated bottom coordinate) is less than or equal to the Top member (or calculated top coordinate).

For consoles with more than one screen buffer, changing the window location for one screen buffer does not affect the window locations of the other screen buffers.

To determine the current size and position of a screen buffer's window, use the GetConsoleScreenBufferInfo function. This function also returns the maximum size of the window, given the current screen buffer size, the current font size, and the screen size. The GetLargestConsoleWindowSize function returns the maximum window size given the current font and screen sizes, but it does not consider the size of the screen buffer.

SetConsoleWindowInfo can be used to scroll the contents of the screen buffer by shifting the position of the window rectangle without changing its size.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, GetConsoleScreenBufferInfo, GetLargestConsoleWindowSize, SMALL_RECT, ScrollConsoleScreenBuffer


SetStdHandle

The SetStdHandle function is used to set the handle for the standard input, standard output, or standard error device. The specified handle can be used by subsequent calls to the GetStdHandle function to refer to the input, output, or error device.

BOOL SetStdHandle(
  DWORD nStdHandle,  // input, output, or error device
  HANDLE hHandle     // handle to be a standard handle
);

Parameters

nStdHandle
Specifies the handle to be set. This parameter can have one of the following values:
Value | Meaning
STD_INPUT_HANDLE | Standard input handle
STD_OUTPUT_HANDLE | Standard output handle
STD_ERROR_HANDLE | Standard error handle

hHandle
Supplies the handle to store as standard input, standard output, or standard error.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The standard handles of a process may have been redirected by a call to SetStdHandle, in which case GetStdHandle will return the redirected handle. If the standard handles have been redirected, you can specify the CONIN$ value in a call to the CreateFile function to get a handle to a console's input buffer. Similarly, you can specify the CONOUT$ value to get a handle to the console's active screen buffer.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, CreateFile, GetStdHandle


WriteConsole

The WriteConsole function writes a character string to a console screen buffer beginning at the current cursor location.

BOOL WriteConsole(
  HANDLE hConsoleOutput, // handle to a console screen buffer
  CONST VOID *lpBuffer,  // pointer to buffer to write from
  DWORD nNumberOfCharsToWrite,
                         // number of characters to write
  LPDWORD lpNumberOfCharsWritten,
                         // pointer to number of characters written
  LPVOID lpReserved      // reserved
);

Parameters

hConsoleOutput
Handle to the console screen buffer to be written to. The handle must have GENERIC_WRITE access.
lpBuffer
Pointer to a buffer that contains characters to be written to the screen buffer.
nNumberOfCharsToWrite
Specifies the number of characters to write.
lpNumberOfCharsWritten
Pointer to a 32-bit variable that receives the number of characters actually written.
lpReserved
Reserved; must be NULL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

WriteConsole writes characters to a console screen buffer. It behaves like the WriteFile function, except it can write in either Unicode (wide-character) or ANSI mode. To create an application that maintains a single set of sources compatible with both modes, use WriteConsole rather than WriteFile. Although WriteConsole can be used only with a console screen buffer handle, WriteFile can be used with other handles (such as files or pipes). WriteConsole fails if used with a standard handle that has been redirected to be something other than a console handle.

Although an application can use WriteConsole in ANSI mode to write ANSI characters, consoles do not support ANSI escape sequences. However, some Win32 functions provide equivalent functionality: for example, SetCursorPos, SetConsoleTextAttribute, and GetConsoleCursorInfo.

WriteConsole writes characters to the screen buffer at the current cursor position. The cursor position advances as characters are written. The SetConsoleCursorPosition function sets the current cursor position.

Characters are written using the foreground and background color attributes associated with the screen buffer. The SetConsoleTextAttribute function changes these colors. To determine the current color attributes and the current cursor position, use GetConsoleScreenBufferInfo.

All of the input modes that affect the behavior of WriteFile have the same effect on WriteConsole. To retrieve and set the output modes of a console screen buffer, use the GetConsoleMode and SetConsoleMode functions.

Windows NT: This function uses either Unicode characters or 8-bit characters from the console's current code page. The console's code page defaults initially to the system's OEM code page. To change the console's code page, use the SetConsoleCP or SetConsoleOutputCP functions, or use the chcp or mode con cp select= commands.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Consoles and Character-Mode Support Overview, Console Functions, GetConsoleCursorInfo, GetConsoleMode, GetConsoleScreenBufferInfo, ReadConsole, SetConsoleCP, SetConsoleCursorPosition, SetConsoleMode, SetConsoleOutputCP, SetConsoleTextAttribute, SetCursorPos, WriteFile


WriteConsoleInput

The WriteConsoleInput function writes data directly to the console input buffer.

BOOL WriteConsoleInput(
  HANDLE hConsoleInput,  // handle to a console input buffer
  CONST INPUT_RECORD *lpBuffer,
                         // pointer to the buffer for write data
  DWORD nLength,         // number of records to write
  LPDWORD lpNumberOfEventsWritten
                         // pointer to number of records written
);

Parameters

hConsoleInput
Handle to the input buffer. The handle must have GENERIC_WRITE access.
lpBuffer
Pointer to an INPUT_RECORD buffer containing data to be written to the input buffer.
nLength
Specifies the number of input records to be written.
lpNumberOfEventsWritten
Pointer to a 32-bit variable that receives the number of input records actually written.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

WriteConsoleInput places input records into the input buffer behind any pending events in the buffer. The input buffer grows dynamically, if necessary, to hold as many events as are written.

Windows NT: This function uses either Unicode characters or 8-bit characters from the console's current code page. The console's code page defaults initially to the system's OEM code page. To change the console's code page, use the SetConsoleCP or SetConsoleOutputCP functions, or use the chcp or mode con cp select= commands.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Consoles and Character-Mode Support Overview, Console Functions, INPUT_RECORD, PeekConsoleInput, ReadConsoleInput, SetConsoleCP, SetConsoleOutputCP


WriteConsoleOutput

The WriteConsoleOutput function writes character and color attribute data to a specified rectangular block of character cells in a console screen buffer. The data to be written is taken from a correspondingly sized rectangular block at a specified location in the source buffer.

BOOL WriteConsoleOutput(
  HANDLE hConsoleOutput,  // handle to a console screen buffer
  CONST CHAR_INFO *lpBuffer,  // pointer to buffer with data to write
  COORD dwBufferSize,     // column-row size of source buffer
  COORD dwBufferCoord,    // upper-left cell to write from
  PSMALL_RECT lpWriteRegion   // pointer to rectangle to write to
);

Parameters

hConsoleOutput
Handle to the screen buffer. The handle must have GENERIC_WRITE access.
lpBuffer
Pointer to a source buffer that contains the data to be written to the screen buffer. This pointer is treated as the origin of a two-dimensional array of CHAR_INFO structures whose size is specified by the dwBufferSize parameter.
dwBufferSize
Specifies the size, in character cells, of the buffer pointed to by the lpBuffer parameter. The X member of the COORD structure is the number of columns; the Y member is the number of rows.
dwBufferCoord
Specifies the coordinates of the upper-left cell in the buffer pointed to by the lpBuffer parameter to write data from. The X member of the COORD structure is the column, and the Y member is the row.
lpWriteRegion
Pointer to a SMALL_RECT structure. On input, the structure members specify the upper-left and lower-right coordinates of the screen buffer rectangle to write to. On output, the structure members specify the actual rectangle that was written to.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

WriteConsoleOutput treats the source buffer and the destination screen buffer as two-dimensional arrays (columns and rows of character cells). The rectangle pointed to by the lpWriteRegion parameter specifies the size and location of the block to be written to in the screen buffer. A rectangle of the same size is located with its upper-left cell at the coordinates of the dwBufferCoord parameter in the lpBuffer array. Data from the cells that are in the intersection of this rectangle and the source buffer rectangle (whose dimensions are specified by the dwBufferSize parameter) is written to the destination rectangle.

Cells in the destination rectangle whose corresponding source location are outside the boundaries of the source buffer rectangle are left unaffected by the write operation. In other words, these are the cells for which no data is available to be written.

Before WriteConsoleOutput returns, it sets the members of lpWriteRegion to the actual screen buffer rectangle affected by the write operation. This rectangle reflects the cells in the destination rectangle for which there existed a corresponding cell in the source buffer, because WriteConsoleOutput clips the dimensions of the destination rectangle to the boundaries of the screen buffer.

If the rectangle specified by lpWriteRegion lies completely outside the boundaries of the screen buffer, or if the corresponding rectangle is positioned completely outside the boundaries of the source buffer, no data is written. In this case, the function returns with the members of the structure pointed to by the lpWriteRegion parameter set such that the Right member is less than the Left, or the Bottom member is less than the Top. To determine the size of the screen buffer, use the GetConsoleScreenBufferInfo function.

WriteConsoleOutput has no effect on the cursor position.

Windows NT: This function uses either Unicode characters or 8-bit characters from the console's current code page. The console's code page defaults initially to the system's OEM code page. To change the console's code page, use the SetConsoleCP or SetConsoleOutputCP functions, or use the chcp or mode con cp select= commands.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Consoles and Character-Mode Support Overview, Console Functions, CHAR_INFO, COORD, GetConsoleScreenBufferInfo, ReadConsoleOutput, ReadConsoleOutputAttribute, ReadConsoleOutputCharacter, SetConsoleCP, SetConsoleOutputCP, SMALL_RECT, WriteConsoleOutputAttribute, WriteConsoleOutputCharacter


WriteConsoleOutputAttribute

The WriteConsoleOutputAttribute function copies a number of foreground and background color attributes to consecutive cells of a console screen buffer, beginning at a specified location.

BOOL WriteConsoleOutputAttribute(
  HANDLE hConsoleOutput,  // handle to a console screen buffer
  CONST WORD *lpAttribute,  // pointer to buffer to write attributes
                            // from
  DWORD nLength,          // number of character cells to write to
  COORD wWriteCoord,      // coordinates of first cell to write to
  LPDWORD lpNumberOfAttrsWritten
                          // pointer to number of cells written to
);

Parameters

hConsoleOutput
Handle to the screen buffer. The handle must have GENERIC_WRITE access.
lpAttribute
Pointer to a buffer that contains the attributes to write to the screen buffer.
nLength
Specifies the number of screen buffer character cells to write to.
dwWriteCoord
Specifies the column and row coordinates of the first cell in the screen buffer to write to.
lpNumberOfAttrsWritten
Pointer to a 32-bit variable that receives the number of attributes actually written to the screen buffer.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the number of attributes to be written to extends beyond the end of the specified row in the screen buffer, attributes are written to the next row. If the number of attributes to be written to extends beyond the end of the screen buffer, the attributes are written up to the end of the screen buffer.

The character values at the positions written to are not changed.

Each attribute specifies the foreground (text) and background colors in which that character cell is drawn. The attribute values are some combination of the following values: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following combination of values produces red text on a white background:

FOREGROUND_RED | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.

See Also

Consoles and Character-Mode Support Overview, Console Functions, ReadConsoleOutput, ReadConsoleOutputAttribute, ReadConsoleOutputCharacter, WriteConsoleOutput, WriteConsoleOutputCharacter


WriteConsoleOutputCharacter

The WriteConsoleOutputCharacter function copies a number of characters to consecutive cells of a console screen buffer, beginning at a specified location.

BOOL WriteConsoleOutputCharacter(
  HANDLE hConsoleOutput,  // handle to a console screen buffer
  LPCTSTR lpCharacter,    // pointer to buffer to write characters
                          // from
  DWORD nLength,          // number of character cells to write to
  COORD dwWriteCoord,     // coordinates of first cell to write to
  LPDWORD lpNumberOfCharsWritten
                          // pointer to number of cells written to
);

Parameters

hConsoleOutput
Handle to the screen buffer. The handle must have GENERIC_WRITE access.
lpCharacter
Pointer to a buffer that contains the characters to write to the screen buffer.
nLength
Specifies the number of screen buffer character cells to write to.
dwWriteCoord
Specifies the column and row coordinates of the first cell in the screen buffer to write to.
lpNumberOfCharsWritten
Pointer to a 32-bit variable that receives the number of characters actually written.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the number of characters to be written to extends beyond the end of the specified row in the screen buffer, characters are written to the next row. If the number of characters to be written to extends beyond the end of the screen buffer, characters are written up to the end of the screen buffer.

The attribute values at the positions written to are not changed.

Windows NT: This function uses either Unicode characters or 8-bit characters from the console's current code page. The console's code page defaults initially to the system's OEM code page. To change the console's code page, use the SetConsoleCP or SetConsoleOutputCP functions, or use the chcp or mode con cp select= commands.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Consoles and Character-Mode Support Overview, Console Functions, ReadConsoleOutput, ReadConsoleOutputAttribute, ReadConsoleOutputCharacter, SetConsoleCP, SetConsoleOutputCP, WriteConsoleOutput, WriteConsoleOutputAttribute


Console Structures

The following structures are used to access a console.

CHAR_INFO
CONSOLE_CURSOR_INFO
CONSOLE_SCREEN_BUFFER_INFO
COORD
FOCUS_EVENT_RECORD
INPUT_RECORD
KEY_EVENT_RECORD
MENU_EVENT_RECORD
MOUSE_EVENT_RECORD
SMALL_RECT
WINDOW_BUFFER_SIZE_RECORD


CHAR_INFO

The CHAR_INFO structure specifies the Unicode or ANSI character and the foreground (text) and background color attributes of a screen buffer character cell. This structure is used by console functions to read from and write to a console screen buffer.

typedef struct _CHAR_INFO { // chi
    union {                /* Unicode or ANSI character  */
        WCHAR UnicodeChar;
        CHAR AsciiChar;
    } Char;
    WORD Attributes;       // text and background colors
} CHAR_INFO, *PCHAR_INFO;

Members

Char
Specifies either the Unicode (wide-character) or ANSI character of a screen buffer character cell, depending on whether the Unicode or ANSI version of the function is used.
Attributes
Specifies the foreground (text) and background colors in which a screen buffer character cell is drawn. This member can be zero, or it can be any combination of the following values:
BACKGROUND_BLUE | FOREGROUND_BLUE
BACKGROUND_GREEN | FOREGROUND_GREEN
BACKGROUND_RED | FOREGROUND_RED
BACKGROUND_INTENSITY | FOREGROUND_INTENSITY

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.

See Also

Consoles and Character-Mode Support Overview, Console Structures, ReadConsoleOutput, ScrollConsoleScreenBuffer, WriteConsoleOutput


CONSOLE_CURSOR_INFO

The CONSOLE_CURSOR_INFO structure contains information about the console cursor.

typedef struct _CONSOLE_CURSOR_INFO { // cci
    DWORD  dwSize;
    BOOL   bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

Members

dwSize
Specifies a number between 1 and 100, indicating the percentage of the character cell that is filled by the cursor. The cursor appearance varies, ranging from completely filling the cell to showing up as a horizontal line at the bottom of the cell.
bVisible
Specifies the visibility of the cursor. If the cursor is visible, this member is TRUE.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.

See Also

Consoles and Character-Mode Support Overview, Console Structures, GetConsoleCursorInfo, SetConsoleCursorInfo


CONSOLE_SCREEN_BUFFER_INFO

The CONSOLE_SCREEN_BUFFER_INFO structure contains information about a console screen buffer.

typedef struct _CONSOLE_SCREEN_BUFFER_INFO { // csbi
    COORD      dwSize;
    COORD      dwCursorPosition;
    WORD       wAttributes;
    SMALL_RECT srWindow;
    COORD      dwMaximumWindowSize;
} CONSOLE_SCREEN_BUFFER_INFO ;

Members

dwSize
Specifies the size, in character columns and rows, of the screen buffer.
dwCursorPosition
Specifies the column and row coordinates of the cursor in the screen buffer.
wAttributes
Specifies the foreground (text) and background color attributes to be used for characters that are written to a screen buffer by the WriteFile and WriteConsole functions, or echoed to a screen buffer by the ReadFile and ReadConsole functions. The attribute values are some combination of the following values: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following combination of values produces red text on a white background:

FOREGROUND_RED | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
srWindow
Specifies a SMALL_RECT structure that contains the screen buffer coordinates of the upper-left and lower-right corners of the display window.
dwMaximumWindowSize
Specifies the maximum size of the console window, given the current screen buffer size and font and the screen size.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.

See Also

Consoles and Character-Mode Support Overview, Console Structures, GetConsoleScreenBufferInfo, ReadConsole, ReadFile, SMALL_RECT, WriteConsole, WriteFile


COORD

The COORD structure defines the coordinates of a character cell in a console screen buffer. The origin of the coordinate system (0,0) is at the top, left cell of the buffer.

typedef struct _COORD { // coord.
    SHORT X;      // horizontal coordinate
    SHORT Y;      // vertical coordinate
} COORD;

Members

X
Horizontal or column value.
Y
Vertical or row value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.

See Also

Consoles and Character-Mode Support Overview, Console Structures


FOCUS_EVENT_RECORD

The FOCUS_EVENT_RECORD structure is used to report focus events in a console INPUT_RECORD structure. These events are used internally and should be ignored.

typedef struct _FOCUS_EVENT_RECORD { // fer
    BOOL bSetFocus;
} FOCUS_EVENT_RECORD;

Members

bSetFocus
Used internally.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.

See Also

Consoles and Character-Mode Support Overview, Console Structures, INPUT_RECORD


INPUT_RECORD

The INPUT_RECORD structure is used to report input events in the console input buffer. These records can be read from the input buffer by using the ReadConsoleInput or PeekConsoleInput function, or written to the input buffer by using the WriteConsoleInput function.

typedef struct _INPUT_RECORD { // ir
    WORD EventType;
    union {
        KEY_EVENT_RECORD KeyEvent;
        MOUSE_EVENT_RECORD MouseEvent;
        WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
        MENU_EVENT_RECORD MenuEvent;
        FOCUS_EVENT_RECORD FocusEvent;
    } Event;
} INPUT_RECORD;

Members

EventType
Handle to the type of input event and the event record stored in the Event member.

This member can have one of the following values:
Value Meaning
KEY_EVENT
The Event member contains a KEY_EVENT_RECORD structure with information about a keyboard event.
MOUSE_EVENT
The Event member contains a MOUSE_EVENT_RECORD structure with information about a mouse movement or button press event.
WINDOW_BUFFER_SIZE_EVENT
The Event member contains a WINDOW_BUFFER_SIZE_RECORD structure with information about the new size of the screen buffer.
MENU_EVENT
The Event member contains a MENU_EVENT_RECORD structure. These events are used internally and should be ignored.
FOCUS_EVENT
The Event member contains a FOCUS_EVENT_RECORD structure. These events are used internally and should be ignored.

Event
Contains a KEY_EVENT_RECORD, MOUSE_EVENT_RECORD, WINDOW_BUFFER_SIZE_RECORD, MENU_EVENT_RECORD, or FOCUS_EVENT_RECORD structure, depending on the event type specified by the EventType member.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.

See Also

Consoles and Character-Mode Support Overview, Console Structures, FOCUS_EVENT_RECORD, KEY_EVENT_RECORD, MENU_EVENT_RECORD, MOUSE_EVENT_RECORD, PeekConsoleInput, ReadConsoleInput, WriteConsoleInput


KEY_EVENT_RECORD

The KEY_EVENT_RECORD structure is used to report keyboard input events in a console INPUT_RECORD structure.

typedef struct _KEY_EVENT_RECORD { // ker
    BOOL bKeyDown;
    WORD wRepeatCount;
    WORD wVirtualKeyCode;
    WORD wVirtualScanCode;
    union {
        WCHAR UnicodeChar;
        CHAR  AsciiChar;
    } uChar;
    DWORD dwControlKeyState;
} KEY_EVENT_RECORD;

Members

bKeyDown
Specifies TRUE if the key is being pressed, FALSE if the key is being released.
wRepeatCount
Specifies a count indicating that a key is being held down. For example, when a key is held down, you might get five events with this member equal to 1, one event with this member equal to 5, or multiple events with this member greater than or equal to 1.
wVirtualKeyCode
Specifies the virtual-key code that identifies the given key in a device-independent manner.
wVirtualScanCode
Specifies the virtual scan code of the given key that represents the device-dependent value generated by the keyboard hardware.
uChar
Specifies the translated Unicode or ASCII character, depending on whether the wide-character (Unicode) or ANSI version of the ReadConsoleInput function was used.
dwControlKeyState
Indicates the state of the control keys. This member can be a combination of the following values:
Value | Meaning
CAPSLOCK_ON | The caps lock light is on.
ENHANCED_KEY | The key is enhanced.
LEFT_ALT_PRESSED | The left alt key is pressed.
LEFT_CTRL_PRESSED | The left ctrl key is pressed.
NUMLOCK_ON | The num lock light is on.
RIGHT_ALT_PRESSED | The right alt key is pressed.
RIGHT_CTRL_PRESSED | The right ctrl key is pressed.
SCROLLLOCK_ON | The scroll lock light is on.
SHIFT_PRESSED | The shift key is pressed.

Remarks

Enhanced keys for the IBM® 101- and 102-key keyboards are the ins, del, home, end, page up, page down, and direction keys in the clusters to the left of the keypad; and the divide (/) and enter keys in the keypad.

Keyboard input events are generated when any key, including control keys, is pressed or released. However, the alt key when pressed and released without combining with another character, has special meaning to the system and is not passed through to the application. Also, the ctrl+c key combination is not passed through if the input handle is in processed mode (ENABLE_PROCESSED_INPUT).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.

See Also

Consoles and Character-Mode Support Overview, Console Structures, PeekConsoleInput, ReadConsoleInput, WriteConsoleInput, INPUT_RECORD


MENU_EVENT_RECORD

The MENU_EVENT_RECORD structure reports menu events in a console INPUT_RECORD structure. These events are used internally and should be ignored.

typedef struct _MENU_EVENT_RECORD { // mer
    UINT dwCommandId;
} MENU_EVENT_RECORD, *PMENU_EVENT_RECORD;

Members

dwCommandId
Used internally.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.

See Also

Consoles and Character-Mode Support Overview, Console Structures, INPUT_RECORD


MOUSE_EVENT_RECORD

The MOUSE_EVENT_RECORD structure is used in a console INPUT_RECORD structure to report mouse input events.

typedef struct _MOUSE_EVENT_RECORD { // mer
    COORD dwMousePosition;
    DWORD dwButtonState;
    DWORD dwControlKeyState;
    DWORD dwEventFlags;
} MOUSE_EVENT_RECORD;

Members

dwMousePosition
Specifies the location of the cursor in terms of the screen buffer's character-cell coordinates.
dwButtonState
Indicates the status of the mouse buttons. The least significant bit corresponds to the leftmost mouse button. The next least significant bit corresponds to the rightmost mouse button. The next bit indicates the next-to-leftmost mouse button. The bits then correspond left to right to the mouse buttons. A bit is 1 if the button was pressed.

The following constants are defined for the first five mouse buttons:

FROM_LEFT_1ST_BUTTON_PRESSED
RIGHTMOST_BUTTON_PRESSED
FROM_LEFT_2ND_BUTTON_PRESSED
FROM_LEFT_3RD_BUTTON_PRESSED
FROM_LEFT_4TH_BUTTON_PRESSED

dwControlKeyState
Indicates the state of the control keys. This member can be a combination of the following values:
Value | Meaning
RIGHT_ALT_PRESSED | The right alt key is pressed.
LEFT_ALT_PRESSED | The left alt key is pressed.
RIGHT_CTRL_PRESSED | The right ctrl key is pressed.
LEFT_CTRL_PRESSED | The left ctrl key is pressed.
CAPSLOCK_ON | The caps lock light is on.
ENHANCED_KEY | The key is enhanced.
NUMLOCK_ON | The num lock light is on.
SCROLLLOCK_ON | The scroll lock light is on.
SHIFT_PRESSED | The shift key is pressed.

dwEventFlags
Indicates the type of mouse event. If this value is zero, it indicates a mouse button being pressed or released. Otherwise, the value is one of the following:
Value | Meaning
DOUBLE_CLICK | The second click (button press) of a double-click occurred. The first click is returned as a regular button-press event.
MOUSE_MOVED | A change in mouse position occurred.
MOUSE_WHEELED | The mouse wheel was rolled.

Remarks

Mouse events are placed in the input buffer when the console is in mouse mode (ENABLE_MOUSE_INPUT).

Mouse events are generated whenever the user moves the mouse, or presses or releases one of the mouse buttons. Mouse events are placed in a console's input buffer only when the console group has the keyboard focus and the cursor is within the borders of the console's window.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.

See Also

Consoles and Character-Mode Support Overview, Console Structures, INPUT_RECORD, PeekConsoleInput, ReadConsoleInput, WriteConsoleInput


SMALL_RECT

The SMALL_RECT structure defines the coordinates of the upper left and lower right corners of a rectangle.

typedef struct _SMALL_RECT { // srct
    SHORT Left;
    SHORT Top;
    SHORT Right;
    SHORT Bottom;
} SMALL_RECT;

Members

Left
Specifies the x-coordinate of the upper left corner of the rectangle.
Top
Specifies the y-coordinate of the upper left corner of the rectangle.
Right
Specifies the x-coordinate of the lower right corner of the rectangle.
Bottom
Specifies the y-coordinate of the lower right corner of the rectangle.

Remarks

This structure is used by console functions to specify rectangular areas of console screen buffers, where the coordinates specify the rows and columns of screen-buffer character cells.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.

See Also

Consoles and Character-Mode Support Overview, Console Structures, RECT, RECTL


WINDOW_BUFFER_SIZE_RECORD

The WINDOW_BUFFER_SIZE_RECORD structure is used in a console INPUT_RECORD structure to report changes in the size of the screen buffer.

typedef struct _WINDOW_BUFFER_SIZE_RECORD { // wbsr
    COORD dwSize;
} WINDOW_BUFFER_SIZE_RECORD;

Members

dwSize
Specifies the new size of the screen buffer, in character cell columns and rows.

Remarks

Buffer size events are placed in the input buffer when the console is in window-aware mode (ENABLE_WINDOW_INPUT).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wincon.h.

See Also

Consoles and Character-Mode Support Overview, Console Structures, INPUT_RECORD, ReadConsoleInput


Data Decompression Library

This overview describes concepts relating to data compression and describes the decompression functions in LZEXPAND.DLL.


About the Data Decompression Library

Typically, an application calls functions in LZEXPAND.DLL to decompress data previously compressed by using the Microsoft® File Compression Utility (COMPRESS.EXE).


Data Compression

Data compression reduces the size of a file by minimizing redundant data. In a text file, redundant data can be frequently occurring characters, such as the space character, or common vowels, such as the letters e and a; it can also be frequently occurring character strings. Data compression creates a compressed version of a file by minimizing this redundant data.

Each type of data-compression algorithm minimizes redundant data in a unique manner. For example, the Huffman encoding algorithm assigns a code to characters in a file based on how frequently those characters occur. Another compression algorithm, called run-length encoding, generates a two-part value for repeated characters: the first part specifies the number of times the character is repeated, and the second part identifies the character. Another compression algorithm, known as the Lempel-Ziv algorithm, converts variable-length strings into fixed-length codes that consume less space than the original strings.

To compress large applications or data files, run COMPRESS.EXE from the command line. COMPRESS.EXE uses the Lempel-Ziv compression algorithm.


Data Decompression

Applications can call the functions in LZEXPAND.DLL to decompress files compressed by using COMPRESS.EXE. The functions can also process uncompressed files without attempting to decompress them.

The following table describes each function found in LZEXPAND.DLL.

Function | Purpose
CopyLZFile | This function is obsolete. It is provided to simplify porting of 16-bit Windows-based applications. Win32-based applications should use the LZCopy function.
GetExpandedName | Retrieves the original name of a compressed file, if the /r option was used during compression of the file.
LZClose | Closes a file that was opened when the application called the LZOpenFile function.
LZCopy | Copies a source file to a destination file. If the source file is compressed, this function creates a decompressed destination file. If the source file is not compressed, this function duplicates the original file. This function is intended for single-file copy operations.
LZDone | This function is obsolete and should not be used in Win32-based applications. It is provided to simplify porting of 16-bit Windows-based applications.
LZInit | Creates structures used for decompressing files.
LZOpenFile | Opens a file and returns a handle that identifies it.
LZRead | Reads a specified number of bytes from a file. If the file is compressed, this function decompresses the bytes before copying them to the destination buffer.
LZSeek | Positions the file pointer within the decompressed image of a compressed file. The application calls this function to position the pointer before calling the LZRead function.
LZStart | This function is obsolete and should not be used in Win32-based applications. It is provided to simplify porting of 16-bit Windows-based applications.


Using the Data Decompression Library

Functions in LZEXPAND.DLL can be used to decompress single or multiple files. They can also be used to decompress compressed files a portion at a time.

  • Decompressing a single file
  • Decompressing multiple files
  • Reading bytes from compressed files


Decompressing a Single File

An application can decompress a single compressed file by performing the following tasks.

  1. Open the source file by calling the LZOpenFile function.
  2. Open the destination file by calling LZOpenFile.
  3. Copy the source file to the destination file by calling the LZCopy function and passing the handles returned by LZOpenFile.
  4. Close the files by calling the LZClose function.


Decompressing Multiple Files

An application can decompress multiple files by performing the following tasks.

  1. Open the source files by calling the LZOpenFile function.
  2. Open the destination files by calling LZOpenFile.
  3. Copy the source files to the destination files by calling the LZCopy function.
  4. Close the files by calling the LZClose function.


Reading Bytes from Compressed Files

In addition to decompressing a complete file in a single operation, an application can decompress a compressed file a portion at a time by using the LZSeek and LZRead functions. These functions are particularly useful when it is necessary to extract parts of large files. For example, a font manufacturer may have compressed files containing font metrics in addition to character data. To use the information in these files, an application would need to decompress the file; however, most applications would use only part of the file at any particular time. To get information about font metrics, the application would extract data from the header. To get information from the text, the application would reposition the file pointer by calling LZSeek and extract character data by calling LZRead.


Data Decompression Library Reference

The following elements are used to decompress files.

  • Data Decompression Library Functions


Data Decompression Library Functions

The following functions are used to decompress files.

GetExpandedName
LZClose
LZCopy
LZInit
LZOpenFile
LZRead
LZSeek

Obsolete Functions

CopyLZFile
LZDone
LZStart


CopyLZFile

The CopyLZFile function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. For Win32-based applications, use the LZCopy function.

See Also

Data Decompression Library Overview, Data Decompression Library Functions


GetExpandedName

The GetExpandedName function retrieves the original name of a compressed file, if the file was compressed by using the Microsoft File Compression Utility (COMPRESS.EXE) and the /r option was specified.

INT GetExpandedName(
  LPTSTR lpszSource,  // address of name of compressed file
  LPTSTR lpszBuffer   // address of buffer for original filename
);

Parameters

lpszSource
Pointer to a string that specifies the name of a compressed file.
lpszBuffer
Pointer to a buffer that receives the name of the compressed file.

Return Values

If the function succeeds, the return value is 1.

If the function fails, the return value is LZERROR_BADVALUE. There is no extended error information for this function; do not call GetLastError.

Note GetExpandedName calls neither SetLastError nor SetLastErrorEx; thus, its failure does not affect a thread's last-error code.

Remarks

The contents of the buffer pointed to by the lpszBuffer parameter is the original filename if the file was compressed by using the /r option. If the /r option was not used, this function duplicates the name in the lpszSource parameter into the lpszBuffer buffer.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lzexpand.h.
Import Library: Use lz32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Data Decompression Library Overview, Data Decompression Library Functions


LZClose

The LZClose function closes a file that was opened by using the LZOpenFile function.

VOID LZClose(
  INT hFile   // LZ file handle identifying file to be closed
);

Parameters

hFile
Handle to the source file to be closed.

Return Values

This function does not return a value.

Remarks

The handle identifying the file must be retrieved by calling the LZOpenFile function. If the handle is retrieved by calling the CreateFile or OpenFile function, an error occurs.

If the file is compressed by using the Microsoft File Compression Utility (COMPRESS.EXE) and opened by using LZOpenFile, LZClose frees any global heap space that was allocated to expand the file.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lzexpand.h.
Import Library: Use lz32.lib.

See Also

Data Decompression Library Overview, Data Decompression Library Functions, CreateFile, LZOpenFile, OpenFile


LZCopy

The LZCopy function copies a source file to a destination file. If the source file is compressed with the Microsoft File Compression Utility (COMPRESS.EXE), this function creates a decompressed destination file. If the source file is not compressed, this function duplicates the original file.

LONG LZCopy(
  INT hfSource,  // LZ file handle identifying source file
  INT hfDest     // LZ file handle identifying destination file
);

Parameters

hfSource
Handle to the source file.
hfDest
Handle to the destination file.

Return Values

If the function succeeds, the return value specifies the size, in bytes, of the destination file.

If the function fails, the return value is an LZERROR_* code. These codes have values less than zero. Note that LZCopy calls neither SetLastError nor SetLastErrorEx; thus, its failure does not affect a thread's last-error code.

Here is a list of the LZERROR_* codes that LZCopy can return upon failure:

Value | Meaning
LZERROR_BADINHANDLE | The handle identifying the source file is not valid. The file cannot be read.
LZERROR_BADOUTHANDLE | The handle identifying the destination file is not valid. The file cannot be written.
LZERROR_GLOBALLOC | The maximum number of open compressed files has been exceeded or local memory cannot be allocated.
LZERROR_GLOBLOCK | The LZ file handle cannot be locked down.
LZERROR_READ | The source file format is not valid.

There is no extended error information for this function; do not call GetLastError.

Remarks

The handles identifying the source and destination files must be retrieved by calling the LZInit or LZOpenFile function.

The preferred function to use for copying files is LZCopy. The CopyLZFile function is provided for compatibility with 16-bit versions of Windows.

If the function succeeds, the file identified by the hfDest parameter is always uncompressed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lzexpand.h.
Import Library: Use lz32.lib.

See Also

Data Decompression Library Overview, Data Decompression Library Functions, CopyLZFile, LZInit, LZOpenFile


LZDone

The LZDone function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. Win32-based applications should use the LZOpenFile function.

See Also

Data Decompression Library Overview, Data Decompression Library Functions


LZInit

The LZInit function allocates memory for the internal data structures required to decompress files, and then creates and initializes them.

INT LZInit(
  INT hfSource   // handle to source file
);

Parameters

hfSource
Handle to the source file.

Return Values

If the function succeeds, the return value is a new LZ file handle.

If the function fails, the return value is an LZERROR_* code. These codes have values less than zero. Note that LZInit calls neither SetLastError nor SetLastErrorEx; thus, its failure does not affect a thread's last-error code.

Here is a list of the LZERROR_* codes that LZInit can return upon failure:

Value | Meaning
LZERROR_BADINHANDLE | The handle identifying the source file is not valid. The file cannot be read.
LZERROR_GLOBALLOC | The maximum number of open compressed files has been exceeded or local memory cannot be allocated.
LZERROR_GLOBLOCK | The LZ file handle cannot be locked down.
LZERROR_UNKNOWNALG | The file is compressed with an unrecognized compression algorithm.

There is no extended error information for this function; do not call GetLastError.

Remarks

A maximum of 16 compressed files can be open at any given time. Similarly, a maximum of 16 uncompressed files can be open at any given time. An application should be careful to close the handle returned by LZInit when it is done using the file; otherwise, the application can inadvertently hit the 16-file limit.

The handle this function returns is compatible only with the functions in LZEXPAND.DLL; it should not be used for other file operations.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lzexpand.h.
Import Library: Use lz32.lib.

See Also

Data Decompression Library Overview, Data Decompression Library Functions


LZOpenFile

The LZOpenFile function creates, opens, reopens, or deletes the specified file.

INT LZOpenFile(
  LPTSTR lpFileName,       // address of name of file to be opened
  LPOFSTRUCT lpReOpenBuf,  // address of open file structure
  WORD wStyle              // action to take
);

Parameters

lpFileName
Pointer to a string that specifies the name of a file.
lpReOpenBuf
Pointer to the OFSTRUCT structure that is to receive information about the file when the file is first opened. The structure can be used in subsequent calls to the LZOpenFile function to refer to the open file.

The szPathName member of this structure contains characters from the original equipment manufacturer (OEM) character set.

wStyle
Specifies the action to take. This parameter can be a combination of the following values:
Value | Meaning
OF_CANCEL | Ignored. In the Win32-based application programming interface (API), the OF_PROMPT style produces a dialog box containing a Cancel button.
OF_CREATE | Directs LZOpenFile to create a new file. If the file already exists, it is truncated to zero length.
OF_DELETE | Deletes the file.
OF_EXIST | Opens the file and then closes it to test for a file's existence.
OF_PARSE | Fills the OFSTRUCT structure but carries out no other action.
OF_PROMPT | Displays a dialog box if the requested file does not exist. The dialog box informs the user that the system cannot find the file, and it contains Retry and Cancel buttons. Clicking the Cancel button directs LZOpenFile to return a file not found error message.
OF_READ | Opens the file for reading only.
OF_READWRITE | Opens the file for reading and writing.
OF_REOPEN | Opens the file using information in the reopen buffer.
OF_SHARE_DENY_NONE | Opens the file without denying other processes read or write access to the file. LZOpenFile fails if the file has been opened in compatibility mode by any other process.
OF_SHARE_DENY_READ | Opens the file and denies other processes read access to the file. LZOpenFile fails if the file has been opened in compatibility mode or has been opened for read access by any other process.
OF_SHARE_DENY_WRITE | Opens the file and denies other processes write access to the file. LZOpenFile fails if the file has been opened in compatibility mode or has been opened for write access by any other process.
OF_SHARE_EXCLUSIVE | Opens the file in exclusive mode, denying other processes both read and write access to the file. LZOpenFile fails if the file has been opened in any other mode for read or write access, even by the current process.
OF_WRITE | Opens the file for writing only.

Return Values

If the function succeeds and the value specified by the wStyle parameter is not OF_READ, the return value is a handle identifying the file. If the file is compressed and opened with wStyle set to OF_READ, the return value is a special file handle.

If the function fails, the return value is an LZERROR_* code. These codes have values less than zero. There is no extended error information for this function; do not call GetLastError.

Note LZOpenFile calls neither SetLastError nor SetLastErrorEx; thus, its failure does not affect a thread's last-error code.

Here is a list of the LZERROR_* codes that LZOpenFile can return upon failure:

Value | Meaning
LZERROR_BADINHANDLE | The handle identifying the source file is not valid. The file cannot be read.
LZERROR_GLOBALLOC | The maximum number of open compressed files has been exceeded or local memory cannot be allocated.

Remarks

If the wStyle parameter is the OF_READ flag (or OF_READ and any of the OF_SHARE_ flags) and the file is compressed, LZOpenFile calls the LZInit function, which performs the required initialization for the decompression operations.

The handle this function returns is compatible only with the functions in LZEXPAND.DLL; it should not be used for other file operations.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lzexpand.h.
Import Library: Use lz32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Data Decompression Library Overview, Data Decompression Library Functions, LZClose, LZInit, LZRead


LZRead

The LZRead function reads (at most) the specified number of bytes from a file and copies them into a buffer.

INT LZRead(
  INT hFile,       // LZ file handle to file
  LPSTR lpBuffer,  // address of buffer for bytes
  INT cbRead       // count of bytes
);

Parameters

hFile
Handle to the source file.
lpBuffer
Pointer to a buffer that receives the bytes read from the file.
cbRead
Specifies the count of bytes to be read.

Return Values

If the function succeeds, the return value specifies the number of bytes read.

If the function fails, the return value is an LZERROR_* code. These codes have values less than zero. Note that LZRead calls neither SetLastError nor SetLastErrorEx; thus, its failure does not affect a thread's last-error code.

Here is a list of the LZERROR_* codes that LZRead can return upon failure:

Value | Meaning
LZERROR_BADINHANDLE | The handle identifying the source file is not valid. The file cannot be read.
LZERROR_BADOUTHANDLE | The handle identifying the destination file is not valid. The file cannot be written.
LZERROR_BADVALUE | One of the input parameters is not valid.
LZERROR_GLOBALLOC | The maximum number of open compressed files has been exceeded or local memory cannot be allocated.
LZERROR_GLOBLOCK | The LZ file handle cannot be locked down.
LZERROR_READ | The source file format is not valid.
LZERROR_WRITE | There is insufficient space for the output file.

There is no extended error information for this function; do not call GetLastError.

Remarks

The handle identifying the file must be retrieved by calling either the LZInit or LZOpenFile function.

If the file is compressed, LZRead emulates the _lread function on an expanded image of the file and copies the bytes of data into the specified buffer.

Applications must call the LZOpenFile, LZSeek, and LZRead functions instead of the OpenFile, _llseek, and _lread functions.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lzexpand.h.
Import Library: Use lz32.lib.

See Also

Data Decompression Library Overview, Data Decompression Library Functions, LZInit, LZOpenFile, LZSeek


LZSeek

The LZSeek function moves a file pointer a number of bytes from a starting position.

LONG LZSeek(
  INT hFile,     // handle to source file
  LONG lOffset,  // number of bytes to move
  INT iOrigin    // starting position
);

Parameters

hFile
Handle to the source file.
lOffset
Specifies the number of bytes by which to move the file pointer.
iOrigin
Specifies the starting position of the pointer. This parameter must be one of the following values:
Value | Meaning
0 | Moves the file pointer lOffset bytes from the beginning of the file.
1 | Moves the file pointer lOffset bytes from the current position.
2 | Moves the file pointer lOffset bytes from the end of the file.

Return Values

If the function succeeds, the return value specifies the offset from the beginning of the file to the new pointer position.

If the function fails, the return value is an LZERROR_* code. These codes have values less than zero. Note that LZSeek calls neither SetLastError nor SetLastErrorEx; thus, its failure does not affect a thread's last-error code.

Upon failure, LZSeek can return the following LZERROR_* codes:

Value | Meaning
LZERROR_BADINHANDLE | The handle identifying the source file is not valid. The file cannot be read.
LZERROR_BADVALUE | One of the parameters is outside the range of acceptable values.
LZERROR_GLOBLOCK | The LZ file handle cannot be locked down.

There is no extended error information for this function; do not call GetLastError.

Remarks

The handle identified by the hFile parameter must be retrieved by calling either the LZInit or LZOpenFile function.

If the file is compressed, LZSeek emulates the _llseek function on an expanded image of the file.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lzexpand.h.
Import Library: Use lz32.lib.

See Also

Data Decompression Library Overview, Data Decompression Library Functions, LZInit, LZOpenFile


LZStart

The LZStart function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. Win32-based applications should use the LZCopy function.

See Also

Data Decompression Library Overview, Data Decompression Library Functions


File Systems

Win32®-based applications rely on file systems to store and retrieve information on mass storage devices. File systems provide the underlying support that applications need to create and access files and directories on the individual volumes associated with the devices.

Each file system consists of one or more drivers and supporting dynamic-link libraries that define the data formats and features of the file system. These determine the conventions used for filenames, the level of security and recoverability available, and the general performance of input and output (I/O) operations.


About File Systems

Depending on the configuration of a computer, a Win32®-based application may have access to volumes managed by any of the following file systems:

  • NTFS file system
  • FAT file system
  • Protected-mode FAT file system

Because the different volumes your application connects to can be managed by different file systems, it is important to understand the differences between file systems and to prepare your application to work effectively with all file systems. Before you access files and directories on a given volume, you should determine the capabilities of the file system by using the GetVolumeInformation function. This function returns values that you can use to adapt your application to work effectively with the file system.

In general, you should avoid using static buffers for filenames and paths. Instead, use the values returned by GetVolumeInformation to allocate buffers as you need them. If you must use static buffers, reserve 256 characters for filenames and 260 characters for paths.


The NTFS File System

NTFS File System

Microsoft® Windows NT® provides support for the NTFS file system. This file system supports object-oriented applications by treating all files as objects with user- and system-defined attributes. NTFS provides all the capabilities of the FAT file system without many of its limitations. Accessing files under NTFS is often faster than accessing similar files under the FAT file system.

NTFS also includes features not present in FAT, such as security, Unicode filenames, automatic creation of MS-DOS® aliases, multiple data streams, and unique functionality specific to the POSIX subsystem. For more information about security, see Access Control. For more information about Unicode, see Unicode and Character Sets.

NTFS filenames can be any practical length (up to 255 characters). There is no requirement that NTFS filenames have extensions; however, many applications still create and use them. For more information, see Filename Conventions.

The following features are supported on NTFS:

  • File Compression
  • File Encryption
  • Disk Quotas
  • Sparse Files
  • Reparse Points


File System Recovery

NTFS is a fully recoverable file system. It is designed to restore consistency to a disk after a CPU failure, system crash, or I/O error. NTFS allows the operating system to recover without your having to use disk-checking utilities. However, NTFS provides some disk utilities in case recovery fails or corruption occurs outside the control of the file system.


File Compression

Windows NT 3.51 and later support file compression on an individual file basis for NTFS volumes. The following topics discuss NTFS file compression:

  • Compression Attribute
  • Compression State
  • Obtaining the Size of a Compressed File


Compression Attribute

On NTFS volumes, each file and directory has a compression attribute. Other file systems may also implement a compression attribute for individual files and directories.

You can determine whether a file system supports a compression attribute for files and directories by calling the GetVolumeInformation function and examining the FS_FILE_COMPRESSION bit flag.

Use the GetFileAttributes or GetFileAttributesEx function to determine the compression attribute of a file or directory.

If a file's compression attribute is set, all of the data in the file is compressed. If the attribute is clear, none of the data in the file is compressed. There is no partially compressed state. The compression attribute is a simple Boolean indicator of compression state.

A directory's compression attribute provides a default compression attribute for newly created files and subdirectories. When you call CreateFile or CreateDirectory to create a new file or directory, the new file or directory inherits the compression attribute of its parent directory.


Compression State

Each file and directory on a volume that supports compression for individual files and directories has a compression state.

Whereas the compression attribute of a file or directory indicates simply whether the file or directory is compressed or not compressed, the compression state also specifies the format of any compressed data.

Use the FSCTL_GET_COMPRESSION DeviceIoControl operation to determine the compression state of a file or directory.

Compression state is encoded as a 16-bit value. A compression state value of COMPRESSION_FORMAT_NONE indicates that a file is not compressed. A value of COMPRESSION_FORMAT_DEFAULT indicates that a file is compressed, using the default compression format. Any other value indicates that a file is compressed, using the compression format specified by the compression state value.

Use the FSCTL_SET_COMPRESSION DeviceIoControl operation to set the compression state of a file or directory. This operation also sets the compression attribute of the file or directory.

Setting the compression state of a file to a nonzero value compresses the file, using the compression format encoded by the compression state value. Setting a file's compression state to zero decompresses the file. These are synchronous operations. The file is compressed or decompressed immediately when you set its compression state.

Setting a directory's compression state does not cause any immediate compression or decompression. Instead, setting a directory's compression state sets a default compression state that will be given to all newly created files and subdirectories.


Obtaining the Size of a Compressed File

Use the GetCompressedFileSize function to obtain the compressed size of a file. If the file is compressed, its compressed size will be less than its uncompressed size. Use the GetFileSize).function to determine the uncompressed size of a file.


File Encryption

[This is preliminary documentation and subject to change.]

Windows NT version 5.0 and later support the Encrypted File System (EFS), which provides cryptographic protection of files on NTFS volumes. EFS provides file encryption on an individual file basis using a public-key system. The following topics discuss NTFS file encryption:

  • Encrypting Files
  • Backing up Encrypted Files

Note EFS encryption and NTFS file compression are mutually exclusive; you cannot compress an encrypted file. However, encrypted files tend to be compressed already, due the nature of cryptographic algorithms.


Encrypting Files

[This is preliminary documentation and subject to change.]

You can determine whether a file system supports file encryption for files and directories by calling the GetVolumeInformation function and examining the FILE_SUPPORTS_ENCRYPTION bit flag.

To encrypt a file, use the EncryptFile function. All data streams in the file are encrypted. If the file is already encrypted, EncryptFile does nothing but return a nonzero value, which indicates success. If the file is compressed, EncryptFile will decompress the file before encrypting it.

To decrypt an encrypted file, use the DecryptFile function. If the file is not encrypted, DecryptFile does nothing but return a nonzero value indicating success.


Backing Up Encrypted Files

[This is preliminary documentation and subject to change.]

Because backup operators typically do not have access to users' cryptographic keys, operators cannot encrypt and decrypt users' files. Therefore, backup operators must use raw mode to perform backup and restore operations on encrypted files. When reading in raw mode, the system returns the data in all streams as a single stream of encrypted bytes. When writing in raw mode, the caller must return the stream of encrypted bytes exactly as it was read. EFS reconstructs the encrypted file.

Raw file data does not contain security or property set information for the file. Backup operators must obtain and back up this information separately for encrypted files. Neither the security nor the property set information is encrypted, so it may be read and written as for any other file.

A backup application performing operations on an encrypted file must first call the OpenRaw function to get a system-defined context block. This context block is used as a parameter to the other raw-mode backup functions. To back up the file, make a single call to the ReadRaw function, providing the context block and a pointer to an export callback function. The system calls the callback function with blocks of file data until all data has been processed.

Restoring an encrypted file is similar to backing it up. To restore the file, make a single call to the WriteRaw function, providing the context block and a pointer to an import callback function. The system calls the callback function, and the application fills in file data until all data has been processed.

The OpenRaw, ReadRaw, and WriteRaw function parameters also include an application-defined context block. You can use this block for internal tracking of information, such as the file handle and the current offset in the file.

When the operation is complete call the CloseRaw function to free allocated system resources and close the file.


Disk Quotas

[This is preliminary documentation and subject to change.]

NTFS version 5.0 and later support disk quotas, which allow administrators to control the amount of data that each user can store on an NTFS volume. Administrators can optionally configure the system to log an event when users are near their quota, and to deny further disk space to users who exceed their quota. Administrators can also generate reports and use the event monitor to track quota issues.

You can determine whether a file system supports disk quotas by calling the GetVolumeInformation function and examining the FILE_VOLUME_QUOTAS bit flag.

The following topics discuss disk quotas.

  • Disk Quotas and Free Space
  • Disk Quota Limits
  • Disk Quota States
  • Administering Disk Quotas
  • Disk Quota Interfaces


Disk Quotas and Free Space

[This is preliminary documentation and subject to change.]

Disk quotas are transparent to the user. When a user asks how much space is free on a disk, Windows NT reports only the available quota allowance the user has available. If the user exceeds this allowance, Windows NT returns the same error it would return to indicate that the disk was full.

To obtain more free disk space after exceeding the quota allowance, the user must do one of the following:

  • Delete some files.
  • Have another user claim ownership of some files.
  • Have the administrator increase the quota allowance.

Programs that need to retrieve the actual amount of free disk space can call the GetDiskFreeSpaceEx function and look at the TotalNumberOfFreeBytes parameter.


Disk Quota Limits

[This is preliminary documentation and subject to change.]

The disk space used by each file is charged directly to the user who owns the file. The owner of a file is identified by the security identifier (SID) in the security information for the file. The total disk space charged to a user is the sum of the length of all data streams. In other words, property set streams and resident user data streams affect the user's quota. Compressing or decompressing files does not affect the disk space reported for the files. Therefore, quota settings on one volume can be compared to settings on another volume.

The following are the types of disk quota limits.

  • Warning threshold. You can configure the system to generate a system logfile entry when the disk space charged to the user exceeds this value.
  • Hard quota. You can configure the system to generate a system logfile entry when the disk space charged to the user exceeds this value. You can also configure the system to deny additional disk space to the user when the disk space charged to the user exceeds this value.

NTFS automatically creates a user quota entry when a user first writes to the volume. Entries that are created automatically are assigned the default warning threshold and hard quota limit values for the volume.


Disk Quota States

[This is preliminary documentation and subject to change.]

The administrator can turn quota enforcement on and off. There are three quota states, as shown in the following table.

State | Description
Quota disabled | Quota usage changes are not tracked, but the quota limits are not removed. In this state, performance is not affected by disk quotas. This is the default state.
Quota tracked | Quota usage changes are tracked, but quota limits are not enforced. In this state, no quota violation events are generated and no file operations fail because of disk quota violations.
Quota enforced | Quota usage changes are tracked and quota limits are enforced.


Administering Disk Quotas

[This is preliminary documentation and subject to change.]

The administrator can set quotas for specific users on a volume. The administrator can also set default quotas for the volume. A new user on the volume receives the default quota unless the administrator established a quota specifically for that user.

The administrator can query the level of quota tracking, the default quota limits, and the per-owner quota information. The per-user quota information contains the user's hard quota limit, warning threshold, and the quota usage.


Disk Quota Interfaces

[This is preliminary documentation and subject to change.]

The following interfaces are used with disk quotas:

  • IDiskQuotaControl
  • IDiskQuotaEvents
  • IDiskQuotaUser
  • IDiskQuotaUserBatch
  • IEnumDiskQuotaUsers


Sparse Files

[This is preliminary documentation and subject to change.]

A very large file without a lot of data is said to contain a sparse data set. Applications that use sparse data sets include image processors and high-speed databases. In versions of NTFS prior to version 5.0, the portions of the file that did not contain useful data occupied valuable disk space.

The file compression introduced in NTFS 3.51 is a partial solution to the problem. The portions of the file that do not contain useful data are set to zero, and file compression compacts the non-data portions. However, file compression has its own drawbacks. Access time may increase due to data compression and decompression.

NTFS 5.0 introduces another solution, called a sparse file. When the sparse file facilities are used, the system does not allocate hard drive space to a file except in regions where it contains something other than zeros. The default data value of a sparse file is zero.


Sparse File Operations

[This is preliminary documentation and subject to change.]

You can determine whether a file system supports sparse files by calling the GetVolumeInformation function and examining the FILE_SUPPORTS_SPARSE_FILES bit flag.

Most applications are not aware of sparse-files and will not create sparse files. The fact that an application is reading a sparse file is transparent to the application. An application that is aware of sparse-files should determine whether its data set is suitable to be kept in a sparse file. After that determination is made, the application must explicitly declare a file as sparse, using the FSCTL_SET_SPARSE operation.

After an application has set a file to be sparse, the application can use the FSCTL_SET_ZERO_DATA operation to set a region of the file to zero. In addition, the application can use the FSCTL_QUERY_ALLOCATED_RANGES operation to speed searches for nonzero data in the sparse file.

When you perform a write operation (with a function or operation other than FSCTL_SET_ZERO_DATA) whose data consists nothing but zeros, zeros will be written to the disk for the entire length of the write. To zero out a range of the file and maintain sparseness, use FSCTL_SET_ZERO_DATA.

A sparse aware application may also set an existing file to be sparse. If an application sets an existing file to be sparse, it should then scan the file for regions which contain zeros, and use FSCTL_SET_ZERO_DATA to reset those regions, and possibly deallocate some physical disk storage. An application upgraded to sparse file awareness should perform this conversion.

When you perform a read operation from a zeroed-out portion of a sparse file may not read from the hard drive. Instead, the system recognizes that the portion of the file to be read contains zeros, and it returns a buffer full of zeros without actually reading from the disk.

As with any other file, the system can write data to or read data from any position in a sparse file. Nonzero data being written to a previously zeroed portion of the file may result in allocation of disk space. Zeros being written over nonzero data (with FSCTL_SET_ZERO_DATA) may result in a deallocation of disk space.

Note It is up to the application to maintain sparseness by writing zeros with FSCTL_SET_ZERO_DATA.

Note Defragmenting tools which handle compressed files on NTFS file systems will correctly handle sparse files on NTFS 5.0 volumes.


Obtaining the Size of a Sparse File

[This is preliminary documentation and subject to change.]

Use the GetCompressedFileSize function to obtain the actual size allocated on disk for a sparse file. This total does not include the size of the regions which were deallocated because they were filled with zeroes. Use the GetFileSize function to determine the total size of a file, including the size of the sparse regions that were deallocated.


Sparse Files and Disk Quota

[This is preliminary documentation and subject to change.]

A sparse file affects user quotas by the nominal size of the file, not the actual allocated amount of disk space. That is, creating a 50-MB file with all zero bytes consumes 50 MB of that user's quota. This means that as the user writes data to the sparse file, he need not worry about exceeding his hard quota limit, because he has already been charged for the space. System administrators should not count on the size of a sparse file remaining small. Therefore they should not grant their users hard quota limits that exceed the physical space available, despite the use of sparse files.


Reparse Points

[This is preliminary documentation and subject to change.]

On an NTFS version 5.0 volume, a file or directory can contain a reparse point, which is a collection of user-defined data. The format of this data is understood by the application which stores the data, and a file system filter, which you install to interpret the data and process the file. When an application sets a reparse point, it stores this data, plus a reparse tag, which uniquely identifies the data it is storing. When the file system opens a file with a reparse point, it attempts to find the file system filter associated with the data format identified by the reparse tag. If such a file system filter is found, the filter processes the file as directed by the reparse data. If no such file system filter is found, the file open operation fails.

For example, in Windows NT 5.0, reparse points are used to implement NTFS links and the Microsoft Hierarchical Storage Management (HSM) Server. HSM Server uses an administrator-defined set of rules to move infrequently used files to long term storage, such as tape or CD-ROM. It uses reparse points to store information about the file in the file system. This information is stored in a stub file that contains a reparse point whose data points to the device where the actual file is now located. The file system filter can use this information to retrieve the file.

The following topics discuss reparse points:

  • Reparse Point Tags
  • Reparse Point Operations
  • Reparse Points and File Operations
  • Reparse Point Restrictions


Reparse Point Tags

[This is preliminary documentation and subject to change.]

Each reparse point has an identifier tag so that you can efficiently differentiate between the different types of reparse points, without having to examine the user-defined data in the reparse point. Windows NT has a set of predefined tags and a range of tags reserved for Microsoft. If you use any of the reserved tags when setting a reparse point, the operation will fail. Tags not included in these ranges are not reserved are available for you to use in your application. In a future beta release, it will be possible for you to create a unique tag to identify your reparse points.

When you set a reparse point, you must tag the data to be placed in the reparse point. After the reparse point has been established, a new set operation fails if the tag for the new data does not match the tag for the existing data. If the tags match, the set operation overwrites the existing reparse point.

Tag Contents

Reparse tags are stored as a ULONG value. The bits define certain attributes, as shown in the following diagram.

3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  +-+-+-+-------------------------+-------------------------------+
  |M|L|N|   Reserved bits         |           Tag Value           |
  +-+-+-+-------------------------+-------------------------------+

The low 16 bits are used to determine the kind of reparse point. The high 16 bits have 13 bits reserved for future use, and three bits that denote specific attributes of the tags and entities represented by the reparse point. The following table describes these bits.

Bit | Description
M | Microsoft bit. If this bit is set, the tag is owned by Microsoft. All other tags must use zero for this bit.
L | High-latency bit. If this bit is set, the system is expected to be slow to retrieve the first byte of data. The application should display some indication to the user that the operation is in progress.
N | Name surrogate bit. If this bit is set, the file represents another named entity in the system.


Reparse Point Operations

[This is preliminary documentation and subject to change.]

You can determine whether a file system supports reparse points by calling the GetVolumeInformation function and examining the FILE_SUPPORTS_REPARSE_POINTS bit flag.

You can set, modify, obtain, and remove reparse points by using the DeviceIoControl function. The following table describes the reparse point operations that you can perform using DeviceIoControl.

Operation | Description
FSCTL_SET_REPARSE_POINT | Allows the calling program to set a new reparse point, or to modify an existing one.
FSCTL_GET_REPARSE_POINT | Obtains the information stored in an existing reparse point.
FSCTL_DELETE_REPARSE_POINT | Removes an existing reparse point.

If you are modifying, getting, or deleting a reparse point, you must specify the same reparse tag in the operation that is contained in the file. Otherwise, the operation will fail with the error ERROR_REPARSE_ATTRIBUTE_CONFLICT.

To determine whether a file contains a reparse point, use the GetFileAttributes function. If the file has an associated reparse point, the FILE_ATTRIBUTE_REPARSE_POINT attribute is set.

To overwrite an existing reparse point without already having a handle to the file, call CreateFile with the FILE_OPEN_REPARSE_POINT flag. This flag allows you to open the file whether or not the corresponding file system filter is installed and working correctly.


Reparse Points and File Operations

[This is preliminary documentation and subject to change.]

Reparse points enable new behavior that you should be aware of when writing applications that manipulate files. For example, backup applications should specify BACKUP_REPARSE_DATA in the WIN32_STREAM_ID structure when backing up files with reparse points. Virus detection applications should search for the reparse points that indicate linked files and a files that were moved to long-term storage.


Reparse Point Restrictions

[This is preliminary documentation and subject to change.]

The following restrictions apply to reparse points.

  • Reparse points can be established for a directory, but the directory must be empty. Otherwise, NTFS fails to establish the reparse point. In addition, you cannot create directories or files in directory that contains a reparse point. .
  • Reparse points and extended attributes are mutually exclusive. NTFS cannot create a reparse point when the file contains extended attributes, and it cannot create extended attributes on a file that contains a reparse point.
  • Reparse point data cannot exceed 16 kilobytes. Setting a reparse point fails if the amount of data to be placed in the reparse point exceeds this limit.


FAT File System

The File Allocation Table (FAT) file system organizes data on fixed disks and floppy disks. The distinguishing feature of the FAT file system is its filename convention. The filename convention consists of a filename (up to eight characters), a separating period (.), and a filename extension (up to three characters).

The main advantage of FAT volumes is that they are accessible by MS-DOS, Microsoft® Windows®, and OS/2 systems. FAT is also the only file system currently supported on floppy disks and other removable media.

Valid FAT filenames have the following form:

[[drive:]][[directory\]]filename[[.extension]]

The drive parameter must name an existing drive and can be any letter from A through Z. The drive letter must be followed by a colon (:).

The directory parameter specifies the directory that contains the file's directory entry. This value must be followed by a backslash (\) to separate it from the filename. If the specified directory is not in the current directory, directory must include the names of all directories in the file's path, separated by backslashes. The root directory is specified by using a backslash at the beginning of the name. For example, if the directory ABCD is in the directory SAMPLE and SAMPLE is in the root directory, the correct directory specification is \SAMPLE\ABCD. A directory name consists of any combination of up to eight letters, digits, or the following special characters:

$ % ' – _ @ { } ~ ` ! # ( )

A directory name can also have an extension that is any combination of up to three letters, digits, or special characters, preceded by a period (.).

The filename and extension parameters specify the file. Filename can be any combination of up to eight letters, digits, or the special characters previously listed; extension can be any combination of up to three letters, digits, or special characters, all preceded by a period. Filename can also include embedded (preceded and followed by one or more letters, digits, or special characters just noted) spaces. For example, the string "disk 1" is a valid value for filename.

FAT volumes do not distinguish between uppercase and lowercase letters.


Protected-Mode FAT File System

The protected-mode FAT file system organizes data on fixed and floppy disks. Protected-mode FAT is compatible with the FAT file system, using file allocation tables and directory entries to store information about the contents of a disk. Protected-mode FAT also supports long filenames, storing these names and other information such as the date and time the file was last accessed in the FAT structures.

Protected-mode FAT allows filenames of up to 255 characters, including the terminating null character. This is similar to NTFS, which allows filenames of up to 256 characters.

Protected-mode FAT allows paths of up to 260 characters, including the terminating null character.


File System Reference

The following functions, interfaces, and structures are used with file systems.

  • File System Functions
  • File System Interfaces
  • File System Structures


File System Functions

The following functions are used with file systems.

CloseRaw
CreateHardLink
DecryptFile
EncryptFile
ExportCallback
GetCompressedFileSize
GetVolumeInformation
ImportCallback
OpenRaw
ReadRaw
WriteRaw


CloseRaw

[This is preliminary documentation and subject to change.]

The CloseRaw function signals the completion of a backup or restore operation.

VOID CloseRaw(
  PVOID pvContext
);

Parameters

pvContext
Pointer to a system-defined context block. The context block is returned by the OpenRaw function.

Return Values

This function does not return a value.

Remarks

The CloseRaw function frees allocated system resources and closes the file.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File Systems Overview, File System Functions, OpenRaw, ReadRaw, WriteRaw


CreateHardLink

[This is preliminary documentation and subject to change.]

The CreateHardLink function establishes an NTFS hard link between an existing file and a new file. An NTFS hard link is similar to a POSIX hard link.

BOOL CreateHardLink(
  LPCTSTR lpFileName,
  LPCTSTR lpExistingFileName,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes
);

Parameters

lpFileName
Pointer to the name of the new file to be opened.
lpExistingFileName
Pointer to the name of the existing file to be linked to the new file.
lpSecurityAttributes
Pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new file and determines whether child processes can inherit the returned handle. If lpSecurityAttributes is NULL, the object receives a default security descriptor and the handle cannot be inherited.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

You can use hard links to provide multiple names for the same underlying file. Hard links synchronize updates to the underlying file. Therefore, modifications performed on the existing file are also performed on the new file to which it is linked.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File Systems Overview, File System Functions, SECURITY_ATTRIBUTES


DecryptFile

[This is preliminary documentation and subject to change.]

The DecryptFile function decrypts a file or directory that was encrypted using the EncryptFile function.

BOOL DecryptFile(
  LPCTSTR lpFileName,
  DWORD dwReserved
);

Parameters

lpFileName
Pointer to a null-terminated string that specifies the name of the file to decrypt.

The caller must have FILE_READ_DATA, FILE_WRITE_DATA, FILE_READ_ATTRIBUTES, FILE_WRITE_ATTRIBUTES, and SYNCHRONIZE access to the file.

dwReserved
Reserved; must be 0.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The DecryptFile function requires exclusive access to the file being decrypted, and will fail if another process is using the file. If the file is not encrypted, DecryptFile simply returns a nonzero value, which indicates success.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File Systems Overview, File System Functions, EncryptFile


EncryptFile

[This is preliminary documentation and subject to change.]

The EncryptFile function encrypts a file or directory. All data streams in a file are encrypted. All new files created in an encrypted directory are encrypted.

BOOL EncryptFile(
  LPCTSTR lpFileName
);

Parameters

lpFileName
Pointer to a null-terminated string that specifies the name of the file or directory to encrypt.

The caller must have FILE_READ_DATA, FILE_WRITE_DATA, FILE_READ_ATTRIBUTES, FILE_WRITE_ATTRIBUTES, and SYNCHRONIZE access to the file.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The EncryptFile function requires exclusive access to the file being encrypted, and will fail another process is using the file.

If the file is already encrypted, EncryptFile simply returns a nonzero value, which indicates success. If the file is compressed, EncryptFile will decompress the file before encrypting it.

To decrypt an encrypted file, use the DecryptFile function.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File Systems Overview, File System Functions, DecryptFile


ExportCallback

The ExportCallback function is an application-defined callback function used with the ReadRaw function. The system calls ExportCallback with blocks of file data. ExportCallback can write the data to another file or another storage media. The system will continue to send data until ExportCallback has received all data for processing.

The PFE_EXPORT_FUNC type defines a pointer to this callback function. ExportCallback is a placeholder for the application-defined function name.

DWORD ExportCallback(
  PBYTE pbData,
  PVOID pvCallbackContext,
  PULONG ulLength
);

Parameters

pbData
Pointer to a block of data to be backed up.
pvCallbackContext
Pointer to an application-defined context block.
ulLength
Specifies the length, in bytes, of the data pointed to by the pbData parameter.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. To get a generic description of the error, use FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag.

Remarks

You can use the application-defined context block for internal tracking of information, such as the file handle and the current offset in the file.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: User-defined.

See Also

File Systems Overview, File System Functions, ReadRaw


GetCompressedFileSize

The GetCompressedFileSize function obtains the actual number of bytes of disk storage used to store a specified file. If the file is located on a volume that supports compression, and the file is compressed, the value obtained is the compressed size of the specified file. If the file is located on a volume that supports sparse files, and the file is a sparse file, the value obtained is the sparse size of the specified file.

If the file is not located on a volume that supports compression or sparse files, or if the file is not compressed or a sparse file, the value obtained is the actual file size, the same as the value returned by a call to GetFileSize.

DWORD GetCompressedFileSize(
  LPCTSTR lpFileName,     // pointer to name of file
  LPDWORD lpFileSizeHigh  // pointer to DWORD to receive high-order
                          // doubleword of file size
);

Parameters

lpFileName
Pointer to a null-terminated string that specifies the name of the file.
lpFileSizeHigh
Pointer to a DWORD variable that the function sets to the high-order doubleword of the compressed file size. The function's return value is the low-order doubleword of the compressed file size.

This parameter can be NULL if the high-order doubleword of the compressed file size is not needed. Files less than 4 gigabytes in size do not need the high-order doubleword.

Return Values

If the function succeeds, the return value is the low-order doubleword of the actual number of bytes of disk storage used to store the specified file, and if lpFileSizeHigh is non-NULL, the function puts the high-order doubleword of that actual value into the DWORD pointed to by that parameter. This is the compressed file size for compressed files, the actual file size for noncompressed files.

If the function fails, and lpFileSizeHigh is NULL, the return value is 0xFFFFFFFF. To get extended error information, call GetLastError.

If the function fails, and lpFileSizeHigh is non-NULL, the return value is 0xFFFFFFFF, and GetLastError returns a value other than NO_ERROR.

Remarks

Calling the GetCompressedFileSize function with the name of a nonseeking device, such as a pipe or a communications device, has no meaning.

Note that if the return value is 0xFFFFFFFF and lpFileSizeHigh is non-NULL, an application must call GetLastError to determine whether the function has succeeded or failed.

An application can determine whether a volume is compressed by calling GetVolumeInformation, then checking the status of the FS_VOL_IS_COMPRESSED flag in the DWORD value pointed to by that function's lpFileSystemFlags parameter.

An application can determine whether a file is compressed by implementing the following pseudocode:

call GetVolumeInformation on the file's volume
if the file's volume is compressed
    call GetCompressedFileSize on the file
    call GetFileSize on the file
    if the sizes don't match
        the file is compressed

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File Systems Overview, File System Functions, GetFileSize, GetVolumeInformation


GetVolumeInformation

The GetVolumeInformation function returns information about a file system and volume whose root directory is specified.

BOOL GetVolumeInformation(
  LPCTSTR lpRootPathName,        // address of root directory of the
                                 // file system
  LPTSTR lpVolumeNameBuffer,     // address of name of the volume
  DWORD nVolumeNameSize,         // length of lpVolumeNameBuffer
  LPDWORD lpVolumeSerialNumber,  // address of volume serial number
  LPDWORD lpMaximumComponentLength,
                                 // address of system's maximum
                                 // filename length
  LPDWORD lpFileSystemFlags,     // address of file system flags
  LPTSTR lpFileSystemNameBuffer, // address of name of file system
  DWORD nFileSystemNameSize      // length of lpFileSystemNameBuffer
);

Parameters

lpRootPathName
Pointer to a string that contains the root directory of the volume to be described. If this parameter is NULL, the root of the current directory is used. If this parameter is a UNC name, you must follow it with an additional backslash. For example, you would specify \\MyServer\MyShare as \\MyServer\MyShare\.
lpVolumeNameBuffer
Pointer to a buffer that receives the name of the specified volume.
nVolumeNameSize
Specifies the length, in characters, of the volume name buffer. This parameter is ignored if the volume name buffer is not supplied.
lpVolumeSerialNumber
Pointer to a variable that receives the volume serial number. This parameter can be NULL if the serial number is not required.
lpMaximumComponentLength
Pointer to a doubleword value that receives the maximum length, in characters, of a filename component supported by the specified file system. A filename component is that portion of a filename between backslashes.

The value stored in variable pointed to by *lpMaximumComponentLength is used to indicate that long names are supported by the specified file system. For example, for a FAT file system supporting long names, the function stores the value 255, rather than the previous 8.3 indicator. Long names can also be supported on systems that use the NTFS file system.

lpFileSystemFlags
Pointer to a doubleword that receives flags associated with the specified file system. This parameter can be any combination of the following flags, however, FS_FILE_COMPRESSION and FS_VOL_IS_COMPRESSED are mutually exclusive.
Value | Meaning
FS_CASE_IS_PRESERVED | The file system preserves the case of filenames when it places a name on disk.
FS_CASE_SENSITIVE | The file system supports case-sensitive filenames.
FS_UNICODE_STORED_ON_DISK | The file system supports Unicode in filenames as they appear on disk.
FS_PERSISTENT_ACLS | The file system preserves and enforces ACLs. For example, NTFS preserves and enforces ACLs, and FAT does not.
FS_FILE_COMPRESSION | The file system supports file-based compression.
FS_VOL_IS_COMPRESSED | The specified volume is a compressed volume; for example, a DoubleSpace volume.
FILE_SUPPORTS_ENCRYPTION | The file system supports the Encrypted File System (EFS).
FILE_SUPPORTS_OBJECT_IDS | The file system supports object identifiers.
FILE_SUPPORTS_REPARSE_POINTS | The file system supports reparse points.
FILE_SUPPORTS_SPARSE_FILES | The file system supports sparse files.
FILE_VOLUME_QUOTAS | The file system supports disk quotas.

lpFileSystemNameBuffer
Pointer to a buffer that receives the name of the file system (such as FAT or NTFS).
nFileSystemNameSize
Specifies the length, in characters, of the file system name buffer. This parameter is ignored if the file system name buffer is not supplied.

Return Values

If all the requested information is retrieved, the return value is nonzero.

If not all the requested information is retrieved, the return value is zero. To get extended error information, call GetLastError.

Remarks

If you are attempting to obtain information about a floppy drive that does not have a floppy disk or a CD-ROM drive that does not have a compact disc, the system displays a message box asking the user to insert a floppy disk or a compact disc, respectively. To prevent the system from displaying this message box, call the SetErrorMode function with SEM_FAILCRITICALERRORS.

The FS_VOL_IS_COMPRESSED flag is the only indicator of volume-based compression. The file system name is not altered to indicate compression. This flag comes back set on a DoubleSpace volume, for example. With volume-based compression, an entire volume is either compressed or not compressed.

The FS_FILE_COMPRESSION flag indicates whether a file system supports file-based compression. With file-based compression, individual files can be compressed or not compressed.

The FS_FILE_COMPRESSION and FS_VOL_IS_COMPRESSED flags are mutually exclusive; both bits cannot come back set.

The maximum component length value, stored in the DWORD variable pointed to by lpMaximumComponentLength, is the only indicator that a volume supports longer-than-normal FAT (or other file system) file names. The file system name is not altered to indicate support for long file names.

The GetCompressedFileSize function obtains the compressed size of a file. The GetFileAttributes function can determine whether an individual file is compressed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File Systems Overview, File System Functions, GetCompressedFileSize, GetFileAttributes, SetErrorMode, SetVolumeLabel


ImportCallback

The ImportCallback function is an application-defined callback function used with the WriteRaw function. The system calls ImportCallback to retrieve blocks of file data. ImportCallback reads the data from its current location and sends it to the system, until the system has received all data for processing.

The PFE_IMPORT_FUNC type defines a pointer to this callback function. ImportCallback is a placeholder for the application-defined function name.

DWORD ImportCallback(
  PBYTE pbData,
  PVOID pvCallbackContext,
  ULONG ulLength
);

Parameters

pbData
Pointer to a block of data to be restored.
pvCallbackContext
Pointer to an application-defined context block.
ulLength
Specifies the length, in bytes, of the data pointed to by the pbData parameter. When the function returns, this parameter contains the length, in bytes, of the data written to pbData.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. To get a generic description of the error, use FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag.

Remarks

The system calls the ImportCallback function until the callback function indicates there is no more data to restore. To indicate that there is no more data can be restored, set *ulLength to 0 and use a return code of ERROR_SUCCESS.

You can use the application-defined context block for internal tracking of information, such as the file handle and the current offset in the file.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: User-defined.

See Also

File Systems Overview, File System Functions, WriteRaw


OpenRaw

[This is preliminary documentation and subject to change.]

The OpenRaw function opens the specified encrypted file for a backup (export) operation or opens the file for a restore (import) operation.

DWORD OpenRaw(
  LPCTSTR lpFileName,
  ULONG ulFlags,
  PVOID *pvContext
);

Parameters

lpFileName
Pointer to a null-terminated string that specifies the name of the file to open.
ulFlags
Specifies file attributes. This parameter may be one or more of the following values.
Value | Meaning
0 | The file is being opened for export (backup). This is the default option.
CREATE_FOR_IMPORT | The file is being opened for import (restore).

pvContext
Pointer that receives a system-defined context block that must be used in subsequent calls to the ReadRaw, WriteRaw, or CloseRaw function.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

To back up an encrypted file, call OpenRaw to open the file, then call ReadRaw. When the operation is completed, call CloseRaw.

To restore an encrypted file, call OpenRaw specifying CREATE_FOR_IMPORT in the ulFlags parameter, then call WriteRaw. When the operation is completed, call CloseRaw.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File Systems Overview, File System Functions, CloseRaw, ReadRaw, WriteRaw


ReadRaw

[This is preliminary documentation and subject to change.]

The ReadRaw function is used to back up (export) encrypted files.

DWORD ReadRaw(
  PFE_EXPORT_FUNC pfExportCallback,
  PVOID pvCallbackContext,
  PVOID pvContext
);

Parameters

pfExportCallback
Pointer to the export callback function. The system passes blocks of data to the callback function until the callback function has processed all the data. For more information, see ExportCallback.
pvCallbackContext
Pointer to an application-defined context block.
pvContext
Pointer to a system-defined context block. The context block is returned by the OpenRaw function.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. To get a generic description of the error, use FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag.

Remarks

A call to ReadRaw must be preceded by a successful call to OpenRaw. When the read operation is finished, call the CloseRaw function to free allocated resources and close the file.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File Systems Overview, File System Functions, CloseRaw, ExportCallback, OpenRaw, WriteRaw


WriteRaw

[This is preliminary documentation and subject to change.]

The WriteRaw function is used for restore (import) operations on an encrypted file.

DWORD WriteRaw(
  PFE_IMPORT_FUNC pfImportCallback,
  PVOID pvCallbackContext,
  PVOID pvContext
);

Parameters

pfImportCallback
Pointer to the import callback function. The system passes blocks of data to the callback function until the callback function has processed all the data. For more information, see ImportCallback.
pvCallbackContext
Pointer to an application-defined context block.
pvContext
Pointer to a system-defined context block. The context block is returned by the OpenRaw function.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. To get a generic description of the error. use FormatMessage with the FORMAT_MESSAGE_FROM_SYSTEM flag.

Remarks

A call to WriteRaw must be preceded by a successful call to OpenRaw, specifying CREATE_FOR_IMPORT in the ulFlags parameter. When the write operation is finished, call the CloseRaw function to free allocated resources and close the file.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File Systems Overview, File System Functions, CloseRaw, ImportCallback, OpenRaw, ReadRaw


File System Interfaces

The following interfaces are used with file systems.

IDiskQuotaControl
IDiskQuotaEvents
IDiskQuotaUser
IDiskQuotaUserBatch
IEnumDiskQuotaUsers


IDiskQuotaControl

The IDiskQuotaControl interface provides methods for controlling the disk quota facilities of a single NTFS volume. The client can query and set volume-specific quota attributes through IDiskQuotaControl. The client can also enumerate all per-user quota entries on the volume. A client instantiates this interface by calling the CoCreateInstance function using the class identifier CLSID_DiskQuotaControl.

Virtual function table

IUnknown Methods

QueryInterface
AddRef
Release

IDiskQuotaControl Methods

Initialize
SetQuotaState
GetQuotaState
SetQuotaLogFlags
GetQuotaLogFlags
SetDefaultQuotaThreshold
GetDefaultQuotaThreshold
GetDefaultQuotaThresholdText
SetDefaultQuotaLimit
GetDefaultQuotaLimit
GetDefaultQuotaLimitText
AddUserSid
AddUserName
DeleteUser
FindUserSid
FindUserName
CreateEnumUsers
CreateUserBatch
InvalidateSidNameCache
GiveUserNameResolutionPriority
ShutdownNameResolution

Remarks

The disk quota control object also implements the IConnectionPointContainer interface to service the IDiskQuotaEvents interface.

See Also

File Systems Overview, File System Interfaces


IDiskQuotaControl::AddUserName

[This is preliminary documentation and subject to change.]

Adds a new quota entry on the volume for the specified user. The user is identified by domain and account name.

HRESULT AddUserName(
  LPWSTR pszDomain,
  LPWSTR pszName,
  DWORD fNameResolution,
  PDISKQUOTA_USER *ppUser
);

Parameters

pszDomain
Pointer to the user's domain name string.
pszName
Pointer to the user's account name string. If pszDomain points to an empty string, pszName must point to a fully qualified "Domain\Account" string.
fNameResolution
Indicates how the user account information is to be obtained. The volume's quota information identifies users by SID. The user account information (such as domain name, account name, and full name) must be obtained from the network domain controller, or the local computer if it is not on a network. This parameter can be one of the following values.
Value | Meaning
DISKQUOTA_USERNAME_RESOLVE_NONE | Do not resolve user account information.
DISKQUOTA_USERNAME_RESOLVE_SYNC | Resolve user account information synchronously. AddUserName returns when the information is resolved. If the information exists in the disk quota SID cache, it is returned immediately. Otherwise, the method must locate the information. This can take several seconds.
DISKQUOTA_USERNAME_RESOLVE_ASYNC | Resolve user account information asynchronously. AddUserName returns immediately. The caller must implement the IDiskQuotaEvents interface to receive notification when the information is available. If the information was cached during a previous request, notification occurs as soon as the object is serviced. Otherwise, the method obtains the information from the network domain controller, then notifies IDiskQuotaEvents.

ppUser
Pointer to receive the IDiskQuotaUser interface pointer to the newly created quota user object.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_OUTOFMEMORY | Insufficient memory.
S_FALSE | User already exists. Not added.
E_POINTER | Pointer parameter was NULL.
DQC_E_USER_UNKNOWN | The specified user is unknown.

Remarks

The NTFS file system automatically creates a user quota entry when a user first writes to the volume. Entries that are created automatically are assigned the default warning threshold and hard quota limit values for the volume. This method allows you to create a user quota entry before a user has written information to the volume. Therefore, you can pre-assign a warning threshold or hard quota limit value different than the volume default settings.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::AddUserSid

[This is preliminary documentation and subject to change.]

Adds a new quota entry on the volume for the specified user. The user is identified by security identifier (SID).

HRESULT AddUserSid(
  PSID pUserSid,
  DWORD fNameResolution,
  PDISKQUOTA_USER *ppUser
);

Parameters

pUserSid
Pointer to a buffer containing the user's SID.
fNameResolution
Indicates how the user account information is to be obtained. The volume's quota information identifies users by SID. The user account information (such as domain name, account name, and full name) must be obtained from the network domain controller, or the local computer if it is not on a network. This parameter can be one of the following values.
Value | Meaning
DISKQUOTA_USERNAME_RESOLVE_NONE | Do not resolve user account information.
DISKQUOTA_USERNAME_RESOLVE_SYNC | Resolve user account information synchronously. AddUserSid returns when the information is resolved. If the information exists in the disk quota SID cache, it is returned immediately. Otherwise, the method must locate the information. This can take several seconds.
DISKQUOTA_USERNAME_RESOLVE_ASYNC | Resolve user account information asynchronously. AddUserSid returns immediately. The caller must implement the IDiskQuotaEvents interface to receive notification when the information is available. If the information was cached during a previous request, notification occurs as soon as the object is serviced. Otherwise, the method obtains the information from the network domain controller, then notifies IDiskQuotaEvents.

ppUser
Pointer to receive the IDiskQuotaUser interface pointer to the newly created quota user object.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_OUTOFMEMORY | Insufficient memory.
S_FALSE | User already exists. Not added.
E_POINTER | Pointer parameter was NULL.
DQC_E_USER_UNKNOWN | The specified user is unknown.

Remarks

The NTFS file system automatically creates a user quota entry when a user first writes to the volume. Entries that are created automatically are assigned the default warning threshold and hard quota limit values for the volume. This method allows you to create a user quota entry before a user has written information to the volume. Therefore, you can pre-assign a warning threshold or hard quota limit value different than the volume default settings.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::CreateEnumUsers

[This is preliminary documentation and subject to change.]

Creates an enumerator object for enumerating quota users on the volume. The newly created object implements the IEnumDiskQuotaUsers interface.

HRESULT CreateEnumUsers(
  PSID *rgpUserSids,
  DWORD cpSids,
  DWORD fNameResolution,
  PENUM_DISKQUOTA_USERS *ppEnum
);

Parameters

rgpUserSids
Array of security identifier (SID) pointers representing the user objects to be included in the enumeration. If this value is NULL, all user entries are enumerated.
cpSids
Number of items in the rgpUserSids array. Ignored if rgpUserSids is NULL.
fNameResolution
Indicates how the user account information is to be obtained. The volume's quota information identifies users by SID. The user account information (such as domain name, account name, and full name) must be obtained from the network domain controller, or the local computer if it is not on a network. This parameter can be one of the following values.
Value | Meaning
DISKQUOTA_USERNAME_RESOLVE_NONE | Do not resolve user account information.
DISKQUOTA_USERNAME_RESOLVE_SYNC | Resolve user account information synchronously. The IEnumDiskQuotaUsers::Next method returns when the information is resolved. If the information exists in the disk quota SID cache, it is returned immediately. Otherwise, the method must locate the information. This can take several seconds.
DISKQUOTA_USERNAME_RESOLVE_ASYNC | Resolve user account information asynchronously. The IEnumDiskQuotaUsers::Next method returns immediately. The caller must implement the IDiskQuotaEvents interface to receive notification when the information is available. If the information was cached during a previous request, notification occurs as soon as the object is serviced. Otherwise, the method obtains the information from the network domain controller, then notifies IDiskQuotaEvents.

ppEnum
Pointer to a pointer to the IEnumDiskQuotaUsers enumerator.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_POINTER | The ppEnum parameter is NULL.
E_OUTOFMEMORY | Insufficient memory.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::CreateUserBatch

[This is preliminary documentation and subject to change.]

Creates a batching object for optimizing updates to the quota settings of multiple users simultaneously.

HRESULT CreateUserBatch(
  PDISKQUOTA_USER_BATCH *ppBatch
);

Parameters

ppBatch
Pointer to receive the IDiskQuotaUserBatch interface pointer.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_POINTER | The ppBatch parameter is NULL.
E_OUTOFMEMORY | Insufficient memory to create the object.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::DeleteUser

[This is preliminary documentation and subject to change.]

Removes a user entry from the volume quota information file, if the user's charged quota amount is zero bytes.

HRESULT DeleteUser(
  PDISKQUOTA_USER pUser
);

Parameters

pUser
Pointer to the IDiskQuotaUser interface of the user whose quota record is marked for deletion.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_POINTER | The pUser parameter is NULL.
E_FAIL | Failure marking entry for deletion.
DQC_E_USER_HAS_FILES | The user owns files on the volume.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.

Remarks

This method does not actually remove the quota entry from the volume. It marks the entry for deletion. NTFS performs the actual deletion at a later time. Following a call to IDiskQuotaControl::DeleteUser, the IDiskQuotaUser interface is still active. This method does not delete the user object from memory. To release the user object, call IUnknown::Release.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::FindUserName

[This is preliminary documentation and subject to change.]

Locates a specific entry in the volume quota information. The user's domain and account name are used as the search key.

HRESULT FindUserName(
  LPCWSTR pszDomain,
  LPCWSTR pszName,
  PDISKQUOTA_USER *ppUser
);

Parameters

pszDomain
Pointer to the user's domain name string.
pszName
Pointer to the user's account name string.
ppUser
Pointer to receive the IDiskQuotaUser interface pointer to the quota user object.
fNameResolution
Indicates how the user account information is to be obtained. The volume's quota information identifies users by security identifier (SID). The user account information (such as domain name, account name, and full name) must be obtained from the network domain controller, or the local computer if it is not on a network. This parameter can be one of the following values.
Value | Meaning
DISKQUOTA_USERNAME_RESOLVE_NONE | Do not resolve user account information.
DISKQUOTA_USERNAME_RESOLVE_SYNC | Resolve user account information synchronously. FindUserName returns when the information has been resolved. If the information exists in the disk quota SID cache, it is returned immediately. Otherwise, the method must locate the information. This can take several seconds.
DISKQUOTA_USERNAME_RESOLVE_ASYNC | Resolve user account information asynchronously. FindUserName returns immediately. The caller must implement the IDiskQuotaEvents interface to receive notification when the information is available. If the information was cached during a previous request, notification occurs as soon as the object is serviced. Otherwise, the method obtains the information from the network domain controller, then notifies IDiskQuotaEvents.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_FILE_NOT_FOUND | The specified user account cannot be located.
E_POINTER | Either the pUserSid or ppUser parameter is NULL.
E_OUTOFMEMORY | Insufficient memory.
DQC_E_INVALID_SID | The SID for the user is invalid.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
DQC_E_NO_SID_MAPPING | There is no mapping available for the SID.

Remarks

This method will return a user object even if there is no quota record for the user in the quota file. This is consistent with the idea of automatic user addition and default quota settings. If there is currently no quota entry for the requested user, and the user would be added to the quota file if he were to request disk space, the returned user object will have warning threshold and hard quota limits equal to the volume default settings.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::FindUserSid

[This is preliminary documentation and subject to change.]

Locates a specific user entry in the volume quota information. The user's security identifier (SID) is used as the search key.

HRESULT FindUserSid(
  PSID pUserSid,
  DWORD fNameResolution,
  PDISKQUOTA_USER *ppUser
);

Parameters

pUserSid
Pointer to the user's SID.
fNameResolution
Indicates how the user account information is to be obtained. The volume's quota information identifies users by SID. The user account information (such as domain name, account name, and full name) must be obtained from the network domain controller, or the local computer if it is not on a network. This parameter can be one of the following values.
Value | Meaning
DISKQUOTA_USERNAME_RESOLVE_NONE | Do not resolve user account information.
DISKQUOTA_USERNAME_RESOLVE_SYNC | Resolve user account information synchronously. FindUserSid returns when the information has been resolved. If the information exists in the disk quota SID cache, it is returned immediately. Otherwise, the method must locate the information. This can take several seconds.
DISKQUOTA_USERNAME_RESOLVE_ASYNC | Resolve user account information asynchronously. FindUserSid returns immediately. The caller must implement the IDiskQuotaEvents interface to receive notification when the information is available. If the information was cached during a previous request, notification occurs as soon as the object is serviced. Otherwise, the method obtains the information from the network domain controller, then notifies IDiskQuotaEvents.

ppUser
Pointer to receive the IDiskQuotaUser interface pointer to the quota user object.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_FAIL | User not found in volume's quota information.
E_POINTER | Either the pUserSid or ppUser parameter is NULL.
E_OUTOFMEMORY | Insufficient memory.
DQC_E_INVALID_SID | The SID for the user is invalid.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.

Remarks

This method will return a user object even if there is no quota record for the user in the quota file. This is consistent with the idea of automatic user addition and default quota settings. If there is currently no quota entry for the requested user, and the user would be added to the quota file if he were to request disk space, the returned user object will have warning threshold and hard quota limits equal to the volume default settings.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::GetDefaultQuotaLimit

[This is preliminary documentation and subject to change.]

Retrieves the default quota limit for the volume. This limit is applied automatically to new users of the volume.

HRESULT GetDefaultQuotaLimit(
  PLONGLONG pllLimit
);

Parameters

pllLimit
Pointer to the variable to receive the quota limit.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_POINTER | The pllLimit parameter is NULL.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
E_FAIL | Failure reading quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::GetDefaultQuotaLimitText

[This is preliminary documentation and subject to change.]

Retrieves the default quota limit for the volume. This limit is applied automatically to new users of the volume. The limit is expressed as a text string, for example "10.5 MB". If the volume has no limit, the string returned is "No Limit" (localized).

HRESULT GetDefaultQuotaLimitText(
  LPWSTR pszText,
  DWORD cchText
);

Parameters

pszText
Pointer to the buffer to receive the text string.
cchText
Size of the buffer, in characters.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
E_FAIL | Failure reading quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::GetDefaultQuotaThreshold

[This is preliminary documentation and subject to change.]

Retrieves the default quota warning threshold for the volume. This threshold is applied automatically to new users of the volume.

HRESULT GetDefaultQuotaThreshold(
  PLONGLONG pllThreshold
);

Parameters

pllThreshold
Pointer to the variable to receive the default warning threshold value, in bytes.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_POINTER | The pllThreshold parameter is NULL.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
E_FAIL | Failed reading quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::GetDefaultQuotaThresholdText

[This is preliminary documentation and subject to change.]

Retrieves the default warning threshold for the volume. This threshold is expressed as a text string, for example "10.5 MB". If the volume does not have a threshold, the string returned is "No Limit" (localized).

HRESULT GetDefaultQuotaThresholdText(
  LPWSTR pszText,
  DWORD cchText
);

Parameters

pszText
Pointer to the buffer to receive the text string.
cchText
Size of the buffer, in characters.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
E_FAIL | Failure reading quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::GetQuotaLogFlags

[This is preliminary documentation and subject to change.]

Retrieves the flags that control the logging of user-related quota events on the volume. Logging makes an entry in the volume server's event log.

HRESULT GetQuotaLogFlags(
  LPDWORD pdwFlags
);

Parameters

pdwFlags
Pointer to a variable to receive the volume's quota logging flags. Use the following macros to retrieve the contents of the flag value.
Flag | Meaning
DISKQUOTA_IS_LOGGED_USER_THRESHOLD | If set, an event log entry will be created when the user exceeds his assigned warning threshold.
DISKQUOTA_IS_LOGGED_USER_LIMIT | If set, an event log entry will be created when the user exceeds his assigned hard quota limit.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_POINTER | The pdwFlags parameter is NULL.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
E_FAIL | Failure reading volume quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::GetQuotaState

[This is preliminary documentation and subject to change.]

Retrieves a set of flags describing the state of the quota system.

HRESULT GetQuotaState(
  LPDWORD pdwState
);

Parameters

pdwState
Pointer to a variable to receive the quota state flags. This parameter can be one or more of the following flags.
Flag | Meaning
DISKQUOTA_STATE_DISABLED | Quotas are not enabled on the volume.
DISKQUOTA_STATE_TRACK | Quotas are enabled but the limit value is not being enforced. Users may exceed their quota limit.
DISKQUOTA_STATE_ENFORCE | Quotas are enabled and the limit value is enforced. Users cannot exceed their quota limit.
DISKQUOTA_FILESTATE_INCOMPLETE | The volume's quota information is out of date. Quotas are probably disabled.
DISKQUOTA_FILESTATE_REBUILDING | The volume is rebuilding its quota information.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_POINTER | The pdwState parameter is NULL.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
E_FAIL | Failure reading volume quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::GiveUserNameResolutionPriority

[This is preliminary documentation and subject to change.]

Promotes the specified user object to the head of the queue so that it is next in line for resolution. By default, quota user objects are serviced in the order in which they were placed in the queue.

This method is applicable only when asynchronous name resolution is used.

HRESULT GiveUserNameResolutionPriority(
  PDISKQUOTA_USER pUser
);

Parameters

pUser
Pointer to the IDiskQuotaUser interface.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
S_FALSE | Quota user object not in the resolver queue.
E_UNEXPECTED | Unexpected error. Caught an exception or the SID-to-name resolver has not been created.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::Initialize

[This is preliminary documentation and subject to change.]

Initializes a new QuotaControl object by opening the NTFS volume with the requested access rights. The return value indicates whether the volume supports NTFS disk quotas and whether the caller has sufficient access rights.

HRESULT Initialize(
  LPCWSTR pszPath,
  BOOL bReadWrite
);

Parameters

pszPath
Specifies the name of the NTFS path to open. To obtain WRITE access, use a string of the form "\\.\X", where X is the drive letter for the volume. To obtain only READ access, use a string of the form "X:\".
bReadWrite
If this value is TRUE, the volume is opened in read/write mode. If this value is FALSE, the volume is opened in read-only mode.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_FAIL | Failure reading volume quota information.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
DQC_E_BAD_PATHNAME | The requested path name is invalid.
DQC_E_FILE_NOT_FOUND | The requested file or object was not found.
DQC_E_INITIALIZED | The controller object has already been initialized. Multiple initialization is not allowed.
DQC_E_INVALID_NAME | The requested file path is invalid.
DQC_E_NO_QUOTAS_FS | The file system does not support quotas. Currently, the file system must be NTFS.
DQC_E_NO_QUOTAS_FSVER | The file system version does not support quotas. Currently, the file system must be NTFS 5.0 or later.
DQC_E_PATH_NOT_FOUND | The requested file path was not found.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::InvalidateSidNameCache

[This is preliminary documentation and subject to change.]

Invalidates the contents of the system's SID-to-name cache so subsequent requests for new user objects (IEnumDiskQuotaUsers::Next, IDiskQuotaControl::FindUserSid and IDiskQuotaControl::FindUserName) must obtain user names from the network domain controller. As names are obtained, they are cached.

HRESULT InvalidateSidNameCache( void );

Parameters

This method has no parameters.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_FAIL | The SID-to-name cache is not available or could not be exclusively locked.

Remarks

In general, there is no reason to call this method. It is included to provide a method for programmatically refreshing the entire SID-to-name cache.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::SetDefaultQuotaLimit

[This is preliminary documentation and subject to change.]

Modifies the default quota limit. This limit is applied automatically to new users of the volume.

HRESULT SetDefaultQuotaLimit(
  LONGLONG llLimit
);

Parameters

llLimit
The value for the default quota limit, in bytes.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
E_FAIL | Failure writing quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::SetQuotaLogFlags

[This is preliminary documentation and subject to change.]

Controls the logging of user-related quota events on the volume. Logging makes an entry in the volume server system's event log.

HRESULT SetQuotaLogFlags(
  DWORD dwFlags
);

Parameters

dwFlags
Specifies the log flags to be applied to the volume. Use the following macros to set the proper bits in the dwFlags parameter.
Macro | Meaning
DISKQUOTA_SET_LOG_USER_THRESHOLD | Turn on/off logging of user warning threshold violations. If set, an event log entry will be created when the user exceeds his assigned warning threshold.
DISKQUOTA_SET_LOG_USER_LIMIT | Turn on/off logging of user quota limit violations. If set, an event log entry will be created when the user exceeds his assigned hard quota limit.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
E_FAIL | Failure writing quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::SetQuotaState

Sets the state of the quota system. Not all state attributes can be modified. The enable, track, and enforce attributes can be modified.

HRESULT SetQuotaState(
  DWORD dwState
);

Parameters

dwState
Specifies the state to be applied to the volume. Use the following macros to set the proper bits in the dwState parameter.
Macro | Enable | Track | Enforce
DISKQUOTA_SET_DISABLED | No | No | No
DISKQUOTA_SET_TRACKED | Yes | Yes | No
DISKQUOTA_SET_ENFORCED | Yes | Yes | Yes

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_INVALIDARG | The dwState parameter is incorrect.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
E_FAIL | Failure writing quota information.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::SetDefaultQuotaThreshold

[This is preliminary documentation and subject to change.]

Modifies the default warning threshold. This threshold is applied automatically to new users of the volume.

HRESULT SetDefaultQuotaThreshold(
  LONGLONG llThreshold
);

Parameters

llThreshold
Specifies the default warning threshold value, in bytes.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
E_FAIL | Failure writing quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaControl::ShutdownNameResolution

[This is preliminary documentation and subject to change.]

The SID-to-name resolver translates user security identifiers (SID) to user names. It runs as a background thread. When a quota control object is destroyed, this thread automatically terminates. The final call to the IUnknown::Release method terminates the thread. This is normally all that is required. If you finish with the quota control object, but it is not ready to be destroyed (there are other open reference counts), call this method to terminate the background thread before the object is destroyed.

HRESULT ShutdownNameResolution( void );

Parameters

This method has no parameters.

Return Values

This method returns S_OK.

Remarks

Asynchronous name resolution will also cease after the thread terminates. A subsequent call to the following methods may recreate the SID-to-name resolver thread:

IDiskQuotaControl::AddUserName
IDiskQuotaControl::AddUserSid
IDiskQuotaControl::CreateEnumUsers
IDiskQuotaControl::FindUserName
IDiskQuotaControl::FindUserSid

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaControl


IDiskQuotaEvents

A client must implement the IDiskQuotaEvents interface as an event sink to receive quota-related event notifications. The DiskQuotaControl object services this interface as a connection point. The connection point is used to notify client code when a significant event has occurred in the quota system. Currently, the only event supported is the asynchronous update of a quota user object's name information.

Virtual Function Table

IUnknown Methods

QueryInterface
AddRef
Release

IDiskQuotaEvents Methods

OnUserNameChanged

See Also

File Systems Overview, File System Interfaces


IDiskQuotaEvents::OnUserNameChanged

[This is preliminary documentation and subject to change.]

Notifies the client's connection sink whenever a user's SID has been asynchronously resolved. If IDiskQuotaUser::GetAccountStatus returns DISKQUOTA_USER_ACCOUNT_RESOLVED, the user's domain, account, and full name strings are available in the quota user object.

HRESULT OnUserNameChanged(
  PDISKQUOTA_USER pUser
);

Parameters

pUser
Pointer to the IDiskQuotaUser interface for the quota user object. It is not necessary to call Release on this pointer. The DiskQuotaControl object controls the lifetime of the user object.

Return Values

The return value is ignored.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaEvents


IDiskQuotaUser

The IDiskQuotaUser interface represents a single user quota entry in the volume quota information file. Through this interface, you can query and modify user-specific quota information on an NTFS volume. This interface is instantiated using IEnumDiskQuotaUsers, IDiskQuotaControl::FindUserSid, IDiskQuotaControl::FindUserName, IDiskQuotaControl::AddUserSid or IDiskQuotaControl::AddUserName.

Virtual Function Table

IUnknown Methods

QueryInterface
AddRef
Release

IDiskQuotaUser Methods

GetName
GetSidLength
GetSid
GetQuotaThreshold
GetQuotaThresholdText
GetQuotaLimit
GetQuotaLimitText
GetQuotaUsed
GetQuotaUsedText
GetQuotaInformation
SetQuotaThreshold
SetQuotaLimit
Invalidate
GetAccountStatus

See Also

File Systems Overview, File System Interfaces


IDiskQuotaUser::GetAccountStatus

[This is preliminary documentation and subject to change.]

Retrieves the status of the user object's account. User information is identified in the quota system by user security identifier (SID). This SID must resolve to a user account for the user's domain, account name, or full name to be retrieved. To determine why a user's name strings are not available, use the status information.

HRESULT GetAccountStatus(
  LPDWORD pdwStatus
);

Parameters

pdwStatus
Pointer to receive the user's account status. The status value can be one of the following.
Value | Meaning
DISKQUOTA_USER_ACCOUNT_RESOLVED | The SID was resolved to a user account. Names are available through IDiskQuotaUser::GetName.
DISKQUOTA_USER_ACCOUNT_UNAVAILABLE | The user account is unavailable at this time. The network domain controller may not be available. Name information is not available.
DISKQUOTA_USER_ACCOUNT_DELETED | The user account was deleted from the domain. Name information is not available.
DISKQUOTA_USER_ACCOUNT_INVALID | The user account is invalid. Name information is not available.
DISKQUOTA_USER_ACCOUNT_UNKNOWN | The user account is unknown. Name information is not available.
DISKQUOTA_USER_ACCOUNT_UNRESOLVED | The SID has not been resolved to a user account.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_POINTER | The pdwStatus parameter is NULL.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUser


IDiskQuotaUser::GetName

[This is preliminary documentation and subject to change.]

Retrieves the name strings associated with a disk quota user.

HRESULT GetName(
  LPWSTR pszDomain,
  DWORD cchDomain,
  LPWSTR pszName,
  DWORD cchName,
  LPWSTR pszFullName,
  DWORD cchFullName
);

Parameters

pszDomain
Pointer to the buffer to receive the name of the user's network domain. This value can be NULL.
cchDomain
Size of the domain buffer, in characters. Ignored if pszDomain is NULL.
pszName
Pointer to the buffer to receive the name of the user's account in the network domain. This value can be NULL.
cchName
Size of the name buffer, in characters. Ignored if pszName is NULL.
pszFullName
Pointer to the buffer to receive the full name for the quota user. This value can be NULL.
cchFullName
Size of the full-name buffer, in characters. Ignored if pszFullName is NULL.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_LOCK_FAILED | Failure to obtain an exclusive lock.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUser


IDiskQuotaUser::GetQuotaInformation

[This is preliminary documentation and subject to change.]

Retrieves the values for the user's warning threshold, hard quota limit, and quota used.

HRESULT GetQuotaInformation(
  LPVOID pbQuotaInfo,
  DWORD cbQuotaInfo
);

Parameters

pQuotaInfo
Pointer to the DISKQUOTA_USER_INFORMATION structure to receive the quota information.
cbQuotaInfo
Size of the quota information structure, in bytes.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
DQC_E_LOCK_FAILED | Failure to obtain an exclusive lock.
E_POINTER | The pQuotaInfo parameter is NULL.
E_OUTOFMEMORY | Insufficient memory.
E_FAIL | Failure reading quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUser


IDiskQuotaUser::GetQuotaLimit

[This is preliminary documentation and subject to change.]

Retrieves the user's quota limit value on the volume. The limit is set as the maximum amount of disk space available to the volume user.

HRESULT GetQuotaLimit(
  PLONGLONG pllLimit
);

Parameters

pllLimit
Pointer to the variable to receive the limit value. If this value is -1, the user has a unlimited quota.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
DQC_E_LOCK_FAILED | Failure to obtain an exclusive lock.
E_POINTER | The pllLimit parameter is NULL.
E_OUTOFMEMORY | Insufficient memory.
E_FAIL | Failure reading quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUser


IDiskQuotaUser::GetQuotaLimitText

[This is preliminary documentation and subject to change.]

Retrieves the user's quota limit for the volume. This limit is expressed as a text string, for example "10.5 MB". If the user has no quota limit, the string returned is "No Limit" (localized).

HRESULT GetQuotaLimitText(
  LPWSTR pszText,
  DWORD cchText
);

Parameters

pszText
Pointer to the buffer to receive the text string.
cchText
Size of the buffer, in characters.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
DQC_E_LOCK_FAILED | Failure to obtain an exclusive lock.
E_OUTOFMEMORY | Insufficient memory.
E_FAIL | Failure reading quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUser


IDiskQuotaUser::GetQuotaThreshold

[This is preliminary documentation and subject to change.]

Retrieves the user's warning threshold value on the volume. The threshold is an arbitrary value set by the volume's quota administrator. You can use it to identify users who are approaching their hard quota limit.

HRESULT GetQuotaThreshold(
  PLONGLONG pllThreshold
);

Parameters

pllThreshold
Pointer to a variable to receive the warning threshold value.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
DQC_E_LOCK_FAILED | Failure to obtain an exclusive lock.
E_POINTER | The pllThreshold parameter is NULL.
E_OUTOFMEMORY | Insufficient memory.
E_FAIL | Failure reading quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUser


IDiskQuotaUser::GetQuotaThresholdText

[This is preliminary documentation and subject to change.]

Retrieves the user's warning threshold for the volume. This threshold is expressed as a text string, for example "10.5 MB". If the user's threshold is unlimited, the string returned is "No Limit" (localized).

HRESULT GetQuotaThresholdText(
  LPWSTR pszText,
  DWORD cchText
);

Parameters

pszText
Pointer to the buffer to receive the text string.
cchText
Size of the destination buffer, in characters.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
DQC_E_LOCK_FAILED | Failure to obtain an exclusive lock.
E_OUTOFMEMORY | Insufficient memory.
E_FAIL | Failure reading quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUser


IDiskQuotaUser::GetQuotaUsed

[This is preliminary documentation and subject to change.]

Retrieves the user's quota used value on the volume. This is the amount of information stored on the volume by the user. Note that this is the amount of uncompressed information. Therefore, the use of NTFS compression does not affect this value.

HRESULT GetQuotaUsed(
  PLONGLONG pllUsed
);

Parameters

pllUsed
Pointer to the variable to receive the quota used value.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
DQC_E_LOCK_FAILED | Failure to obtain an exclusive lock.
E_POINTER | The pllUsed parameter is NULL.
E_OUTOFMEMORY | Insufficient memory.
E_FAIL | Failure reading quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUser


IDiskQuotaUser::GetQuotaUsedText

[This is preliminary documentation and subject to change.]

Retrieves the user's quota used value for the volume. This value is expressed as a text string, for example "10.5 MB".

HRESULT GetQuotaUsedText(
  LPWSTR pszText,
  DWORD cchText
);

Parameters

pszText
Pointer to the buffer to receive the text string.
cchText
Size of the buffer, in bytes.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
DQC_E_LOCK_FAILED | Failure to obtain an exclusive lock.
E_OUTOFMEMORY | Insufficient memory.
E_FAIL | Failure reading quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUser


IDiskQuotaUser::GetSid

[This is preliminary documentation and subject to change.]

Retrieves the user's security identifier (SID).

HRESULT GetSid(
  LPBYTE pbSidBuffer,
  DWORD cbSidBuffer
);

Parameters

pbSidBuffer
Pointer to the buffer to receive the SID.
cbSidBuffer
Size of the buffer, in bytes. Use the IDiskQuotaUser::GetSidLength method to obtain the required size for the buffer.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_POINTER | The pbSidBuffer parameter is NULL.
DQC_E_INVALID_SID | The SID for the user is invalid.
DQC_E_INSUFFICIENT_BUFFER | Insufficient destination buffer size.
DQC_E_LOCK_FAILED | Failure to obtain an exclusive lock.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUser


IDiskQuotaUser::GetSidLength

[This is preliminary documentation and subject to change.]

Retrieves the length of the user's security identifier (SID), in bytes. Use the return value to determine the size of the destination buffer you pass to IDiskQuotaUser::GetSid.

HRESULT GetSidLength(
  LPDWORD pdwLength
);

Parameters

pdwLength
Pointer to the variable to receive the SID length, in bytes.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_POINTER | The pdwLength parameter is NULL.
DQC_E_INVALID_SID | The SID for the user is invalid.
DQC_E_LOCK_FAILED | Failure to obtain an exclusive lock.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUser


IDiskQuotaUser::Invalidate

[This is preliminary documentation and subject to change.]

Invalidates the quota information stored in the quota user object. The next time information is requested, it is refreshed from disk.

HRESULT Invalidate( void );

Parameters

This method has no parameters.

Return Values

This method returns S_OK.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUser


IDiskQuotaUser::SetQuotaLimit

[This is preliminary documentation and subject to change.]

Sets the user's quota limit value on the volume. The limit is set as the maximum amount of disk space available to the volume user.

HRESULT SetQuotaLimit(
  LONGLONG llLimit,
  BOOL fWriteThrough
);

Parameters

llLimit
Specifies the limit value, in bytes. If this value is -1, the user has an unlimited quota.
fWriteThrough
If this value is TRUE, the value is written immediately to the volume's quota file. Otherwise, the value is written only to the quota user object's local memory. This value should typically be set to TRUE. Set it to FALSE when using the IDiskQuotaUserBatch interface to modify multiple user quota entries at once.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
DQC_E_LOCK_FAILED | Failure to obtain an exclusive lock.
E_FAIL | Failure writing quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUser


IDiskQuotaUser::SetQuotaThreshold

[This is preliminary documentation and subject to change.]

Sets the user's warning threshold value on the volume. The threshold is an arbitrary value set by the volume's quota administrator. You can use it to identify users who are approaching their hard quota limit.

HRESULT SetQuotaThreshold(
  LONGLONG llThreshold,
  BOOL fWriteThrough
);

Parameters

llThreshold
Specifies the warning threshold value.
fWriteThrough
If this value is TRUE, the value is written immediately to the volume's quota file. Otherwise, the value is written only to the quota user object's local memory. This value should typically be set to TRUE. Set it to FALSE when using the IDiskQuotaUserBatch interface to modify multiple user quota entries at the same time.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
DQC_E_LOCK_FAILED | Failure to obtain an exclusive lock.
E_FAIL | Failure writing quota information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUser


IDiskQuotaUserBatch

The IDiskQuotaUserBatch interface enables you to add multiple quota user objects to a container that is then submitted for update in a single call. This reduces the number of calls to the underlying file system, improving update efficiency when a large number of user objects must be updated. This interface is instantiated by using the IDiskQuotaControl::CreateUserBatch method.

Virtual Function Table

IUnknown Methods

QueryInterface
AddRef
Release

IDiskQuotaUserBatch Methods

Add
Remove
RemoveAll
FlushToDisk

See Also

File Systems Overview, File System Interfaces


IDiskQuotaUserBatch::Add

[This is preliminary documentation and subject to change.]

Adds an IDiskQuotaUser pointer to the batch list. This method calls AddRef on the pUser interface pointer. Release is automatically called on each contained IDiskQuotaUser interface pointer when the batch object is destroyed.

When setting values on a quota user object in preparation for batch processing, specify FALSE for the fWriteThrough parameter in the IDiskQuotaUser::SetQuotaLimit and IDiskQuotaUser::SetQuotaThreshold methods. This stores the values in memory without writing to disk. To write the changes to disk, call the IDiskQuotaUserBatch::FlushToDisk method.

HRESULT Add(
  PDISKQUOTA_USER pUser
);

Parameters

pUser
Pointer to the quota user object's IDiskQuotaUser interface.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_POINTER | The pUser parameter is NULL.
E_OUTOFMEMORY | Insufficient memory.
E_UNEXPECTED | An unexpected exception occurred.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUserBatch


IDiskQuotaUserBatch::Remove

[This is preliminary documentation and subject to change.]

Removes an IDiskQuotaUser pointer from the batch list.

HRESULT Remove(
  PDISKQUOTA_USER pUser
);

Parameters

pUser
Pointer to the quota user object's IDiskQuotaUser interface.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
S_FALSE | Quota user object not found in batch.
E_POINTER | The pUser parameter is NULL.
E_UNEXPECTED | An unexpected exception occurred.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUserBatch


IDiskQuotaUserBatch::RemoveAll

[This is preliminary documentation and subject to change.]

Removes all IDiskQuotaUser pointers from the batch list.

HRESULT RemoveAll( void );

Parameters

This method has no parameters.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_UNEXPECTED | An unexpected exception occurred.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUserBatch


IDiskQuotaUserBatch::FlushToDisk

[This is preliminary documentation and subject to change.]

Writes user object changes to disk in a single call to the underlying file system.

HRESULT FlushToDisk( void );

Parameters

This method has no parameters.

Return Values

This method returns one of the following values.

Value | Meaning
S_OK | Success.
E_FAIL | Error writing quota information.
E_OUTOFMEMORY | Insufficient memory.
E_UNEXPECTED | An unexpected exception occurred.
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.

Remarks

There are limitations on the amount of information that can be written to disk in a single call to the file system. The flush operation may generate multiple calls to the file system. Nonetheless, the batch operation will be more efficient than a single call for each user object.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IDiskQuotaUserBatch


IEnumDiskQuotaUsers

The IEnumDiskQuotaUsers interface enumerates user quota entries on the volume. This interface is instantiated by using the IDiskQuotaControl::CreateEnumUsers method.

Virtual Function Table

IUnknown Methods

QueryInterface
AddRef
Release

IEnumDiskQuotaUsers Methods

Next
Skip
Reset
Clone

Remarks

To use this interface, the client directs an object that maintains a collection of items to create an enumerator object. By repeatedly calling the Next method, the client gets successive pointers to each item in the collection.

See Also

File Systems Overview, File System Interfaces


IEnumDiskQuotaUsers::Clone

Creates another enumerator that contains the same enumeration state as the current one. Using this method, a client can record a particular point in the enumeration sequence, and then return to that point at a later time. The new enumerator supports the same interface as the original one.

HRESULT Clone(
  IEnumDiskQuotaUsers **ppEnum
);

Parameters

ppEnum
Pointer to the variable to receive the IEnumDiskQuotaUsers interface pointer. If the method is unsuccessful, the value of this variable is undefined.

Return Values

This method returns one of the following values.

Value | Meaning
E_INVALIDARG | The ppEnum parameter is incorrect.
E_OUTOFMEMORY | Insufficient memory.
E_UNEXPECTED | Unexpected error. Caught an exception or the SID-to-name resolver thread has not been created.

See Also

File Systems Overview, File System Interfaces, IEnumDiskQuotaUsers


IEnumDiskQuotaUsers::Next

[This is preliminary documentation and subject to change.]

Retrieves the next cUsers items in the enumeration sequence. If there are fewer than the requested number of elements left in the sequence, it retrieves the remaining elements. The number of elements actually retrieved is returned through pcUsersFetched (unless the caller passed in NULL for that parameter).

HRESULT Next(
  DWORD cUsers,
  PDISKQUOTA_USER *rgUsers,
  LPDWORD pcUsersFetched
);

Parameters

cUsers
Specifies the number of elements being requested.
rgUsers
Array of size cUsers or larger.
pcUsersFetched
Pointer to the number of elements actually supplied in rgUsers. The caller can pass in NULL if cUsers is one.

Return Values

The return value is S_OK if the number of elements supplied is cUsers; otherwise, the return value is S_FALSE.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IEnumDiskQuotaUsers


IEnumDiskQuotaUsers::Reset

[This is preliminary documentation and subject to change.]

Resets the enumeration sequence to the beginning.

HRESULT Reset( void );

Parameters

This method has no parameters.

Return Values

The return value is S_OK.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IEnumDiskQuotaUsers


IEnumDiskQuotaUsers::Skip

[This is preliminary documentation and subject to change.]

Skips over the next specified number of elements in the enumeration sequence.

HRESULT Skip(
  DWORD cUsers
);

Parameters

cUserst
Specifies the number of elements to be skipped.

Return Values

The return value is S_OK if the number of elements skipped is cUsers; otherwise, the return value is S_FALSE.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Interfaces, IEnumDiskQuotaUsers


File System Structures

The following structure is used with file systems.

DISKQUOTA_USER_INFORMATION


DISKQUOTA_USER_INFORMATION

[This is preliminary documentation and subject to change.]

The DISKQUOTA_USER_INFORMATION structure represents the per-user quota information.

typedef struct DiskQuotaUserInformation {
    LONGLONG QuotaUsed;
    LONGLONG QuotaThreshold;
    LONGLONG QuotaLimit;
} DISKQUOTA_USER_INFORMATION, *PDISKQUOTA_USER_INFORMATION;

Members

QuotaUsed
Disk space charged to the user, in bytes. This is the amount of information stored, not necessarily the number of bytes used on disk.
QuotaThreshold
Warning threshold for the user, in bytes. You can use the IDiskQuotaControl::SetQuotaLogFlags method to configure the system to generate a system logfile entry when the disk space charged to the user exceeds this value.
QuotaLimit
Quota limit for the user, in bytes. You can use the IDiskQuotaControl::SetQuotaLogFlags method to configure the system to generate a system logfile entry when the disk space charged to the user exceeds this value. You can also use the IDiskQuotaControl::SetQuotaState method to configure the system to deny additional disk space to the user when the disk space charged to the user exceeds this value.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dskquota.h.

See Also

File Systems Overview, File System Structures, IDiskQuotaControl::SetQuotaLogFlags, IDiskQuotaControl::SetQuotaState, IDiskQuotaUser::GetQuotaInformation


Disk Quota Interface Error Codes

The following error codes are custom HRESULT values defined in DSKQUOTA.H. They are returned by the disk quota interfaces, along with some of the standard HRESULT values.

Error | Meaning
DQC_E_ACCESS_DENIED | The caller has insufficient access rights.
DQC_E_BAD_PATHNAME | The requested path name is invalid.
DQC_E_FILE_NOT_FOUND | The specified user account cannot be located.
DQC_E_INITIALIZED | The object has already been initialized. Multiple initialization is not allowed.
DQC_E_INSUFFICIENT_BUFFER | There is insufficient memory to complete the operation.
DQC_E_INVALID_NAME | The requested file path is invalid.
DQC_E_INVALID_SID | The SID for the user is invalid.
DQC_E_LOCK_FAILED | Failure to obtain an exclusive lock.
DQC_E_NO_MORE_ITEMS | There are no more items in the enumeration.
DQC_E_NO_QUOTAS_FS | The file system does not support quotas. Currently, the file system must be NTFS.
DQC_E_NO_QUOTAS_FSVER | The file system version does not support quotas. Currently, the file system must be NTFS 5.0 or later.
DQC_E_NO_SID_MAPPING | There is no mapping available for the SID.
DQC_E_NOT_INITIALIZED | The object has not been initialized. Initialization must be completed before the operation can be performed.
DQC_E_NOT_SUPPORTED | The operation or capability is not supported.
DQC_E_PATH_NOT_FOUND | The requested file path was not found.
DQC_E_USER_HAS_FILES | The user owns files on the volume.
DQC_E_USER_UNKNOWN | The specified user is unknown.


File I/O

A file is the basic unit of storage that enables a computer to distinguish one set of information from another. This overview describes the Microsoft® Win32® file input and output (I/O) operations and the information provided by the Win32 file functions.


About Files

Files are stored on storage media, such as disks or tapes, and can be organized into groups called directories. The Microsoft® Win32® file I/O functions enable applications to create, open, modify, and delete files. They also enable applications to obtain system information, such as what disk drives are present.


File System Organization

A volume is a storage device, such as a fixed disk or floppy disk, formatted to store directories and files. Each volume has a root directory. Directories and files on the volume are organized in a tree structure that starts at the root directory. Each directory entry identifies the name, attributes, location, and size of a file or subdirectory.

A large volume can be divided into more than one logical volume, also called a partition. To the user and to the operating system, each partition appears to be a separate volume.

A file system is operating system software that manages the low-level organization of files on a volume. The operating system supports one or more of the following file systems:

  • File Allocation Table (FAT)
  • NTFS File System (NTFS)

The type of file system defines the filename conventions on a volume and may also provide specific file system features, such as security, recoverability, and high I/O performance. Each volume can use a different file system.

For more information on FAT and NTFS, see File Systems.


Accessing Files

The first time a file function accesses a volume and whenever a diskette is placed in a floppy-disk drive, the operating system examines the volume to determine its file system. Thereafter, the operating system manages all I/O to that volume through the device driver supporting the file system.

The Win32 file functions enable applications to access files regardless of the underlying file system. However, capabilities may vary depending on the file system and/or operating system in use. For example, the CreateFile function includes a security parameter that provides no security benefits for files not residing on an NTFS volume.

The Win32 file functions that create, open, and delete files and directories identify them by their names. These functions store or search for the file or directory in the current directory on the current disk drive, unless the name explicitly specifies a path to a different directory, disk drive, or both.


Filename Conventions

Although each file system can have specific rules about the formation of individual components in a directory or filename, all file systems follow the same general conventions: a base filename and an optional extension, separated by a period. For example, the MS-DOS FAT file system supports 8 characters for the base filename and 3 characters for the extension. This is known as an 8.3 filename. The FAT file system and NTFS support filenames that can be up to 255 characters long. This is known as a long filename. To get an MS-DOS filename given a long filename, use the GetShortPathName function. To get the full path of a file, use the GetFullPathName function.

Both file systems use the backslash (\) character to separate directory names and the filename when forming a path.

General rules for applications creating names for directories and files or processing names supplied by the user include the following:

  • Use any character in the current code page for a name, but do not use a path separator, a character in the range 0 through 31, or any character explicitly disallowed by the file system. A name can contain characters in the extended character set (128–255).
  • Use the backslash (\), the forward slash (/), or both to separate components in a path. No other character is acceptable as a path separator.
  • Use a period (.) as a directory component in a path to represent the current directory.
  • Use two consecutive periods (..) as a directory component in a path to represent the parent of the current directory.
  • Use a period (.) to separate the base filename from the extension in a directory name or filename.
  • Do not use the following characters in directory names or filenames, because they are reserved:

    < > : " / \ |

  • Do not use device names, such as aux, con, and prn, as filenames or directory names.
  • Process a path as a null-terminated string. The maximum length for a path, including a trailing backslash, is given by MAX_PATH.

    The wide (Unicode) versions of the CreateDirectory, FindFirstFile, GetFileAttributes, and SetFileAttributes functions permit paths that exceed the MAX_PATH length if the path has the "\\?\" or "\\?\UNC\" prefix. However, each component in the path cannot be more than MAX_PATH characters long. Use the "\\?\" prefix with paths for local storage devices and the "\\?\UNC\" prefix with paths having the Universal Naming Convention (UNC) format.

  • Do not assume case sensitivity. Consider names such as OSCAR, Oscar, and oscar to be the same.

By following the rules listed in this section, an application can create valid names for files and directories regardless of the file system in use.


Long Filenames on Windows NT

The operating system stores the long filenames on disk as special directory entries. When you create a long filename, the operating system creates a corresponding short 8.3 form of the name.

The operating system stores the long filenames on disk in Unicode. This means that the original long filename is always preserved, even if it contains extended characters, and regardless of the code page that is active during a disk read or write operation. The case of the filename is preserved, but the file system is not case-sensitive.

The valid character set for these long filenames is the NTFS character set, less one character: the colon (':') that NTFS uses for opening alternate file streams. This means that you can freely copy files between NTFS and FAT partitions without losing any file name information.


MS-DOS Device Names

MS-DOS device names are global. Once defined, an MS-DOS device name remains visible to all processes until either it is explicitly removed or the system reboots.

The DefineDosDevice function is used to create and modify the symbolic links used to implement the MS-DOS device namespace. To obtains a list of all MS-DOS devices known to the system, use the QueryDosDevice function.


File Operations

The Win32 API provides a variety of functions for performing file operations. These functions are discussed in the following topics:

  • Creating and Opening Files with the CreateFile Function
  • Creating Temporary Files
  • Copying and Moving Files
  • Reading From and Writing to a File
  • Locking and Unlocking Files
  • Searching for Files
  • Monitoring Directories
  • Closing and Deleting Files


Creating and Opening Files with the CreateFile Function

The CreateFile function can create a new file or open an existing file.

When an application uses CreateFile, it must specify whether it will read from the file, write to the file, or both. The application must also specify what action to take whether or not the file exists. For example, an application can specify that CreateFile always be used to create the file. As a result, the function creates the file if it does not exist and overwrites the file if it does exist.

CreateFile also enables an application to specify whether it wants to share the file for reading, writing, both, or neither. A file that is not shared cannot be opened more than once by the first application nor by another application until the first application has closed the file.

The operating system assigns a unique identifier, called a file handle, to each file that is opened or created. An application can use the file handle in functions that read from, write to, and describe the file. It is valid until the file is closed. When an application starts, it inherits all open file handles from the process that started it, if the handles are inheritable. For more information about processes, see Processes and Threads.

For information about the standard input, standard output, and standard error file handles, see Consoles and Character-Mode Support.

An application should check the return value of CreateFile before attempting to use the handle to access the file. If an error occurs, the application can use the GetLastError function to get extended error information.


Creating Temporary Files

Applications can obtain unique filenames for temporary files with the GetTempFileName function. The GetTempPath function retrieves the path to the directory where temporary files are to be created.


Copying and Moving Files

Before a file can be copied, it must be closed or opened only for reading. No thread can have the file opened for writing. To copy an existing file to a new one, use the CopyFile or CopyFileEx function. Applications can specify whether CopyFile and CopyFileEx fail if the destination file already exists.

The CopyFileEx function also allows an application to specify the address of a callback function (see CopyProgressRoutine) that is called each time another portion of the file has been copied. The application can use this information to display am indicator that shows the total number of bytes copied as a percent of the total file size.

A file must also be closed before an application can move it. The MoveFile and MoveFileEx functions copy an existing file to a new location and deletes the original.

The MoveFileEx function also allows an application to specify how to move the file. The function can replace an existing file, move a file across volumes, and delay moving the file until the operating system is restarted.


Reading from and Writing to a File

Every open file has a file pointer that specifies the next byte to be read or the location to receive the next byte written. When a file is opened for the first time, the system places the file pointer at the beginning of the file. As each byte is read or written, the system advances the file pointer. An application can also move the file pointer by using the SetFilePointer function.

An application reads from and writes to a file by using the ReadFile and WriteFile functions. These functions require a handle to a file to be opened for reading and writing, respectively. ReadFile and WriteFile read and write a specified number of bytes at the location indicated by the file pointer. The data is read and written exactly as specified; the functions do not format the data.

For Very Large Memory (VLM), ReadFileVlm and WriteFileVlm may be used similarly to ReadFile and WriteFile. For more information, see Very Large Memory (VLM).

An application can implement a scatter-gather scheme with ReadFileScatter and WriteFileGather. A scatter-gather scheme uses the operating system to deliver in one operation multiple discrete chunks of data (such as database records) from a file to separate, noncontiguous buffers in memory. A scatter-gather scheme also writes the data from noncontiguous buffers in one operation.

When the file pointer reaches the end of a file and the application attempts to read from the file, no error occurs, but no bytes are read. Therefore, reading zero bytes without an error means the application has reached the end of the file. Writing zero bytes does nothing.

An application can truncate or extend a file by using the SetEndOfFile function. This function sets the end of file to the current position of the file pointer.

When an application writes to a file, the system usually collects the data being written in an internal buffer and writes the data to the disk on a regular basis.

An application can force the operating system to write the contents of the buffer to the disk by using the FlushFileBuffers function. Alternatively, an application can specify that write operations are to bypass the internal buffer and write directly to the disk by setting a flag when the file is created or opened by using the CreateFile function.

If there is data in the internal buffer when the file is closed, the operating system does not automatically write the contents of the buffer to the disk before closing the file. If the application does not force the operating system to write the buffer to disk before closing the file, the caching algorithm determines when the buffer is written.

Note Accessing the data buffer while a read or write operation is using the buffer may lead to corruption of the data in that buffer. Applications must not read from, write to, reallocate, or free the data buffer that a read or write operation is using until the operation completes.


Locking and Unlocking Files

Although the system allows more than one application to open a file and write to it, applications must not write over each other's work. An application can prevent this problem by temporarily locking a region in a file. The LockFile and LockFileEx functions lock a specified range of bytes in a file. The range may extend beyond the current end of the file. Locking part of a file prevents all other processes from reading or writing anywhere in the specified area. Attempts to read from or write to a region locked by another process always fail.

The LockFileEx function allows an application to specify either a shared lock or an exclusive lock. An exclusive lock denies all other processes both read and write access to the specified region of the file. A shared lock denies all processes write access to the specified region of the file, including the process that first locks the region. This can be used to create a read-only region in a file.

The application unlocks the region by using the UnlockFile or UnlockFileEx function. An application should unlock all locked areas before closing a file.


Searching for Files

An application can search the current directory for all filenames that match a given pattern by using the FindFirstFile, FindFirstFileEx, FindNextFile, and FindClose functions. The pattern must be a valid filename and can include wildcard characters.

The FindFirstFile and FindFirstFileEx functions create handles that FindNextFile uses to search for other files with the same pattern. All functions return information about the file that was found. This information includes the filename, size, attributes, and time.

The FindFirstFileEx function also allows an application to search for files based on additional search criteria. The function can limit searches to device names or directory names.

The FindClose function destroys handles created by FindFirstFile and FindFirstFileEx.

An application can search for a single file on a specific path by using the SearchPath function.


Monitoring Directories

An application can monitor the contents of a directory and its subdirectories by using the FindFirstChangeNotification, FindNextChangeNotification, and FindCloseChangeNotification functions. Waiting for a change notification is similar to having a read operation pending against a directory and, if necessary, its subdirectories. When something changes within the directory being watched, the read operation is completed. For example, an application can use these functions to update a directory listing whenever a filename within the monitored directory changes.

An application can specify a set of conditions that trigger a change notification by using the FindFirstChangeNotification function. The conditions include changes to filenames, directory names, attributes, file size, time of last write, and security. This function also returns a handle that can be waited on by using the wait functions. If the wait condition is satisfied, FindNextChangeNotification can be used to provide a notification handle to wait on subsequent changes.

The FindCloseChangeNotification function closes the notification handle.

Another way to monitor directory changes is by using the ReadDirectoryChangesW function.


Closing and Deleting Files

To use operating system resources efficiently, an application should close files when they are no longer needed by using the CloseHandle function. If a file is open when an application terminates, the system closes it automatically.

The DeleteFile function can be used to delete a file. The file must, however, be closed before any attempt to delete it will succeed.


Directory Operations

When an application creates a new file, the operating system adds it to the specified directory. Each directory can have any number of files, up to the physical limit of the disk. An application can create new directories and delete existing directories by using the CreateDirectory, CreateDirectoryEx, and RemoveDirectory functions. An application cannot delete a directory unless it is empty.

The directory at the end of the active path is called the current directory; it is the directory in which the active application started, unless explicitly changed. An application can determine which directory is current by using the GetCurrentDirectory function. An application can change the current directory by using the SetCurrentDirectory function.

Windows NT: You can obtain a handle to a directory by calling the CreateFile function with the FILE_FLAG_BACKUP_SEMANTICS flag set, as follows:

hDir = CreateFile (
    DirName,
    GENERIC_READ,
    FILE_SHARE_READ|FILE_SHARE_DELETE,
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_BACKUP_SEMANTICS,
    NULL
);

You can pass a directory handle to the following functions:


Performing Asynchronous Input and Output

Asynchronous input and output (asynchronous I/O) allows some I/O functions to return immediately, even though an I/O request is still pending. Asynchronous I/O enables an application to continue with other processing and wait for the I/O to be completed at a later time.


Overlapped I/O

Asynchronous I/O is also called overlapped I/O. The ReadFile, WriteFile, ReadFileVlm, and WriteFileVlm functions enable an application to specify an OVERLAPPED structure that indicates where to position the file pointer before the read or write operation. The handle of the file being read from or written to must have been opened with the FILE_FLAG_OVERLAPPED flag. You can also create an event and put the handle in the OVERLAPPED structure; the wait functions can then be used to wait for the I/O operation to complete by waiting on the event handle.

An application can also wait on the file handle to synchronize the completion of an I/O operation, but doing so requires extreme caution. Each time an I/O operation is started, the operating system sets the file handle to the nonsignaled state. Each time an I/O operation is completed, the operating system sets the file handle to the signaled state. Therefore, if an application starts two I/O operations and waits on the file handle, there is no way to determine which operation is finished when the handle is set to the signaled state. If an application must perform multiple asynchronous I/O operations on a single file, it should wait on the event handle in the OVERLAPPED structure for each I/O operation, rather than on the file handle.

To cancel all pending asynchronous I/O operations, use the CancelIo function. This function only cancels operations issued by the calling thread for the specified file handle.

The ReadFileEx and WriteFileEx functions enable an application to specify a routine to execute (see FileIOCompletionRoutine) when the asynchronous I/O request is completed.

For more information, see Synchronization and Overlapped Input and Output.


Using I/O Completion Ports

I/O completion ports are used with asynchronous I/O. The CreateIoCompletionPort function associates an I/O completion port with one or more file handles. When an asynchronous I/O operation started on a file handle associated with an I/O completion port is completed, an I/O completion packet is queued to the port. This can be used to combine the synchronization point for multiple file handles into a single object.

A thread uses the GetQueuedCompletionStatus function to wait for an I/O completion packet to be queued to the I/O completion port, rather than waiting directly for the asynchronous I/O to complete. Threads that block their execution on an I/O completion port are released in last-in-first-out (LIFO) order. This means that when an I/O completion packet is queued to the I/O completion port, the system releases the last thread to block its execution on the port.

The most important property of an I/O completion port is the concurrency value. The concurrency value of an I/O completion port is specified when the I/O completion port is created. This value limits the number of runnable threads associated with the I/O completion port. When the total number of runnable threads associated with the I/O completion port reaches the concurrency value, the system blocks the execution of the threads until the number of runnable threads associated with the I/O completion port drops below the concurrency value. The most efficient scenario occurs when there are I/O completion packets waiting in the queue, but no waits can be satisfied because the port has reached its concurrency limit. In this case, when a running thread calls GetQueuedCompletionStatus, it will immediately pick up the queued I/O completion packet. No context switches will occur, because the running thread is continually picking up I/O completion packets and the other threads are unable to run.

The best value to pick for the concurrency value is the number of CPUs on the machine. If your transaction required a lengthy computation, a larger concurrency value will allow more threads to run. Each transaction will take longer to complete, but more transactions will be processed at the same time. It is easy to experiment with the concurrency value to achieve the best effect for your application.

The PostQueuedCompletionStatus function allows an application to queue its own special-purpose I/O completion packets to the I/O completion port without starting an asynchronous I/O operation. This is useful for notifying worker threads of external events.

The I/O completion port is freed when there are no more references to it. The port handle and every file handle associated with the I/O completion port reference the I/O completion port. All the handles must be closed to free the I/O completion port. To close the port handle, call the CloseHandle function.


Getting Information About Files

The Win32 API provides functions that you can use to obtain information about a file or the file system. These functions are discussed in the following topics:

  • File Attributes
  • File Type
  • File Date and Time
  • File Code Page
  • Volume Information


File Attributes

The GetFileInformationByHandle function retrieves information about a file and stores it in a structure of type BY_HANDLE_FILE_INFORMATION. This information includes creation time, file size, and attributes.

Eight characteristics called attributes may be associated with a file. The attributes can be one or more of the following values.

Attribute | Meaning
FILE_ATTRIBUTE_ARCHIVE | The file or directory is an archive file. Applications use this attribute to mark files for backup or removal.
FILE_ATTRIBUTE_COMPRESSED | The file or directory is compressed. For a file, this means that all of the data in the file is compressed. For a directory, this means that compression is the default for newly created files and subdirectories.
FILE_ATTRIBUTE_DIRECTORY | The handle identifies a directory.
FILE_ATTRIBUTE_ENCRYPTED | The file or directory is encrypted. For a file, this means that all of the data in the file is encrypted. For a directory, this means that encryption is the default for newly created files and subdirectories.
FILE_ATTRIBUTE_HIDDEN | The file or directory is hidden. It is not included in an ordinary directory listing.
FILE_ATTRIBUTE_NORMAL | The file or directory has no other attributes set. This attribute is valid only if used alone.
FILE_ATTRIBUTE_OFFLINE | The data of the file is not immediately available. Indicates that the file data has been physically moved to offline storage.
FILE_ATTRIBUTE_READONLY | The file or directory is read-only. Applications can read the file but cannot write to it or delete it. In the case of a directory, applications cannot delete it.
FILE_ATTRIBUTE_REPARSE_POINT | The file has an associated reparse point.
FILE_ATTRIBUTE_SPARSE_FILE | The file is a sparse file.
FILE_ATTRIBUTE_SYSTEM | The file or directory is part of the operating system or is used exclusively by the operating system.
FILE_ATTRIBUTE_TEMPORARY | The file is being used for temporary storage. File systems attempt to keep all of the data in memory for quicker access rather than flushing the data back to mass storage. A temporary file should be deleted by the application as soon as it is no longer needed..

An application can retrieve the file attributes by using the GetFileAttributes or GetFileAttributesEx function. The CreateFile and SetFileAttributes functions can set many of the attributes . However, applications cannot set all attributes. For more information on how to set these attributes, see SetFileAttributes.


File Type

The GetFileType function returns the type of a file: disk, character (such as a console), pipe, or unknown. The GetBinaryType function determines whether a file is executable, and if so, what type of executable file it is. The GetFileSize function returns the size of a file.


File Date and Time

Applications can retrieve and set the date and time a file was created, last modified, or last accessed by using the GetFileTime and SetFileTime functions. For more information about file times, see Time.


File Code Page

The AreFileApisANSI function determines whether the file functions are using the ANSI or OEM character set code page. The SetFileApisToANSI function causes the functions to use the ANSI code page. The SetFileApisToOEM function causes the functions to use the OEM code page.

By default, file functions use ANSI filenames. Functions exported by KERNEL32.DLL which accept or return file names are affected by the file code page setting.


Volume Information

The GetVolumeInformation function retrieves information about the file system on a given volume. This information includes the volume name, volume serial number, file system name, file system flags, maximum length of a filename, and so on. The SetVolumeLabel function sets the label of a file system volume.

The GetSystemDirectory and GetWindowsDirectory functions retrieve the paths to the system directory and the Windows directory, respectively.

The GetDiskFreeSpace function retrieves organizational information about a volume, including the number of bytes per sector, the number of sectors per cluster, the number of free clusters, and the total number of clusters.

The GetDriveType function indicates whether the volume referenced by the specified drive letter is a removable, fixed, CD-ROM, RAM, or network drive.

The GetLogicalDrives function identifies the volumes present. The GetLogicalDriveStrings function retrieves a null-terminated string for each volume present. Use these strings whenever a root directory is required.


Using Files

The Win32 file functions enable applications to access files regardless of the underlying file system. However, their functionality may vary depending on the operating system in use. If you have questions about a specific function, consult the reference information for that function.

For functions that manipulate files, the filenames may be relative to the current directory. A filename is relative to the current directory if it does not begin with a disk designator or directory name separator, such as a backslash (\). If the filename begins with a disk designator, it is a fully qualified path.

The examples in this section illustrate how to perform the following tasks:

  • Creating and opening files
  • Reading, writing, and locking files
  • Creating and using a temporary file
  • Searching for files and changing file attributes
  • Monitoring changes in a directory or directory tree
  • Testing for the end of the file
  • Retrieving a file pointer


Creating and Opening Files

You can use the CreateFile function to create a new file or open an existing file. You must specify the filename, preferred access, share mode, creation instructions, and attributes.

In the following example, CreateFile opens an existing file for reading.

HANDLE hFile;

hFile = CreateFile("MYFILE.TXT",           // open MYFILE.TXT
                GENERIC_READ,              // open for reading
                FILE_SHARE_READ,           // share for reading
                NULL,                      // no security
                OPEN_EXISTING,             // existing file only
                FILE_ATTRIBUTE_NORMAL,     // normal file
                NULL);                     // no attr. template

if (hFile == INVALID_HANDLE_VALUE)
{
        ErrorHandler("Could not open file.");   // process error
}

In this example, CreateFile succeeds only if a file named MYFILE.TXT already exists in the current directory. An application should check the return value of CreateFile before attempting to use the handle to access the file. If an error occurs, the application should use the GetLastError function to get extended error information and respond accordingly.

A file must be closed before it can be deleted. The following lines close and delete the MYFILE.TXT file.

CloseHandle(hFile);
DeleteFile("MYFILE.TXT");

In the following example, CreateFile creates a new file and opens it for writing.

HANDLE hFile;

hFile = CreateFile("MYFILE.TXT",           // create MYFILE.TXT
             GENERIC_WRITE,                // open for writing
             0,                            // do not share
             NULL,                         // no security
             CREATE_ALWAYS,                // overwrite existing
             FILE_ATTRIBUTE_NORMAL |       // normal file
             FILE_FLAG_OVERLAPPED,         // asynchronous I/O
             NULL);                        // no attr. template

if (hFile == INVALID_HANDLE_VALUE)
{
    ErrorHandler("Could not open file.");  // process error
}

In addition to the standard attributes (read only, hidden, system, and so on), you can also specify security attributes by including a pointer to a SECURITY_ATTRIBUTES structure as the fourth parameter. However, the underlying file system must support security for these attributes for them to have any effect. For more information about security attributes, see Access Control.


Reading, Writing, and Locking Files

The ReadFile function requires a file handle that is open for reading, or reading and writing. ReadFile copies a specified number of bytes, from the current position up to the end of the file, to a specified buffer. The current position is either the current file pointer setting or the Offset and OffsetHigh members of the specified OVERLAPPED structure. The function returns the actual number of bytes read in a variable specified by its fourth parameter.

The WriteFile function requires a file handle that is open for writing, or writing and reading. WriteFile copies a specified number of bytes, from the current position up to the end of the buffer, to a specified file. The function returns the actual number of bytes written in a variable specified by its fourth parameter.

The following example illustrates a possible flow for using callback completion asynchronous I/O.

Completion Routine:

VOID IoCompletionRoutine(DWORD dwErrorCode,
        DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
{
    // If an I/O error occurs, display the error and exit.

    if (dwErrorCode)
    {
        printf("FATAL I/O Error %ld I/O Context %lx.%lx\n",
            dwErrorCode, lpOverlapped, lpOverlapped->hEvent);
        ExitProcess(dwErrorCode);
    }
    LocalFree(lpOverlapped);
}

Main Thread:

VOID IoWorkerThread(VOID)
{
    HANDLE HandleVector[2];
    DWORD CompletionStatus;
    PIOREQUEST IoRequestPacket;
    LPOVERLAPPED Overlapped;
    BOOL IoOperationStatus;

    HandleVector[0] = IoWorkerListLock;
    HandleVector[1] = IoWorkerListSemaphore;

    for(;;)
    {

        // Do an alertable wait on the handle vector. Both objects
        // being signaled at the same time means that there is an
        // I/O request in the queue and the caller has exclusive
        // access to the queue.

        CompletionStatus = WaitForMultipleObjectsEx(2, HandleVector,
                TRUE, INFINITE, TRUE);

        // If the wait failed, error out.

        if (CompletionStatus == 0xFFFFFFFF)
        {
            printf("FATAL WAIT ERROR %ld\n", GetLastError());
            ExitProcess(1);
        }
        // If an I/O completion occurred, wait for another
        // I/O request or I/O completion.

        if (CompletionStatus != WAIT_IO_COMPLETION)
        {

            // The wait was satisfied. Ownership of the I/O
            // request queue is exclusive, and there is something in
            // the queue. To insert something in the queue, the
            // inserter gets the list lock (mutex), inserts an entry,
            // signals the list semaphore, and finally releases the
            // list lock.

            IoRequestPacket = RemoveHeadList(&IoRequestList);

            ReleaseMutex(IoWorkerListLock);

            // Allocate an overlapped structure.

            Overlapped = LocalAlloc(LMEM_ZEROINIT,
                    sizeof(OVERLAPPED));

            if (!Overlapped)
            {
                printf("FATAL allocation error\n");
                ExitProcess(1);
            }

            Overlapped->Offset = IoRequestPacket->Offset;
            Overlapped->OffsetHigh = IoRequestPacket->OffsetHigh;
            Overlapped->hEvent =
                    IoRequestPacket->dwAdditionalIoContext;

            if (IoRequestPacket->bRead)
            {
                IoOperationStatus =
                            ReadFileEx(IoRequestPacket->hFile,
                    IoRequestPacket->lpBuffer,
                    IoRequestPacket->dwTransferCount,
                    Overlapped, IoCompletionRoutine);
            }
            else
            {
                IoOperationStatus =
                    WriteFileEx(IoRequestPacket->hFile,
                        IoRequestPacket->lpBuffer,
                        IoRequestPacket->dwTransferCount,
                        Overlapped,
                        IoCompletionRoutine);
            }

            // Test to see if the I/O was queued successfully.

            if (!IoOperationStatus)
            {
                printf("FATAL I/O Error %ld I/O Context %lx.%lx\n",
                    GetLastError(), Overlapped, Overlapped->hEvent);
                ExitProcess(1);
            }

            // The I/O queued successfully. Go back into the
            // alertable wait for I/O completion or for
            // more I/O requests.

        }
    }
}

The SetFilePointer function moves the file pointer a specified number of bytes, relative to the beginning or end of the file, or the file pointer's current position. If a positive number of bytes is specified, SetFilePointer moves the file pointer toward the end of the file; a negative value moves the pointer toward the beginning of the file.

The following example appends one file to the end of another file. The application opens two files by using CreateFile: ONE.TXT is opened for reading, and TWO.TXT is opened for writing. Then the application appends the contents of ONE.TXT to the end of TWO.TXT by reading and writing 4K blocks by using ReadFile and WriteFile. Before writing to the second file, the application sets the second file's pointer to the end of the file by using SetFilePointer and locks the area to be written by using LockFile. This prevents another process from accessing the area while the write is in progress. After each write operation, UnlockFile unlocks the locked area.

HANDLE hFile;

HANDLE hAppend;

DWORD  dwBytesRead, dwBytesWritten, dwPos;

char   buff[4096];

// Open the existing file.

hFile = CreateFile("ONE.TXT",     // open ONE.TXT
    GENERIC_READ,                 // open for reading
    0,                            // do not share
    NULL,                         // no security
    OPEN_EXISTING,                // existing file only
    FILE_ATTRIBUTE_NORMAL,        // normal file
    NULL);                        // no attr. template

if (hFile == INVALID_HANDLE_VALUE)
{
    ErrorHandler("Could not open ONE.");  // process error
}

// Open the existing file, or if the file does not exist,
// create a new file.

hAppend = CreateFile("TWO.TXT",   // open TWO.TXT
    GENERIC_WRITE,                // open for writing
    0,                            // do not share
    NULL,                         // no security
    OPEN_ALWAYS,                  // open or create
    FILE_ATTRIBUTE_NORMAL,        // normal file
    NULL);                        // no attr. template

if (hAppend == INVALID_HANDLE_VALUE)
{
    ErrorHandler("Could not open TWO.");    // process error
}

// Append the first file to the end of the second file.
// Lock the second file to prevent another process from
// accessing it while writing to it. Unlock the
// file when writing is finished.

do
{
    if (ReadFile(hFile, buff, 4096, &dwBytesRead, NULL))
    {
        dwPos = SetFilePointer(hAppend, 0, NULL, FILE_END);
        LockFile(hAppend, dwPos, 0, dwPos + dwBytesRead, 0);
        WriteFile(hAppend, buff, dwBytesRead,
            &dwBytesWritten, NULL);
        UnlockFile(hAppend, dwPos, 0, dwPos + dwBytesRead, 0);
    }
} while (dwBytesRead == 4096);

// Close both files.

CloseHandle(hFile);
CloseHandle(hAppend);


Creating and Using a Temporary File

The following example copies one file to another. The second file is an uppercase version of the first file.

The application opens the ORIGINAL.TXT file by using CreateFile. The application then obtains a temporary filename with the GetTempFileName function and uses CreateFile to create the temporary file. The application reads 4K blocks into a buffer, converts the buffer contents to uppercase, and writes the converted buffer to the temporary file. When all of ORIGINAL.TXT has been written to the temporary file, the application closes both files and renames the temporary file to ALLCAPS.TXT by using the MoveFile function.

HANDLE hFile;

HANDLE hTempFile;

DWORD  dwBytesRead, dwBytesWritten, dwPos;

char szTempName[MAX_PATH];

char buffer[4096];

// Open the existing file.

hFile = CreateFile("ORIGINAL.TXT",  // filename
    GENERIC_READ,                   // open for reading
    0,                              // do not share
    NULL,                           // no security
    OPEN_EXISTING,                  // existing file only
    FILE_ATTRIBUTE_NORMAL,          // normal file
    NULL);                          // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
    ErrorHandler("Could not open file."); // process error
}

// Create a temporary file.

GetTempFileName("\\TEMP", // dir. for temp. files
    "NEW",                // temp. filename prefix
    0,                    // create unique name
    szTempName);          // buffer for name

hTempFile = CreateFile((LPTSTR) szTempName,  // filename
    GENERIC_READ | GENERIC_WRITE, // open for read-write
    0,                            // do not share
    NULL,                         // no security
    CREATE_ALWAYS,                // overwrite existing file
    FILE_ATTRIBUTE_NORMAL,        // normal file
    NULL);                        // no attr. template

if (hTempFile == INVALID_HANDLE_VALUE)
{
    ErrorHandler("Could not create temporary file.");
}

// Read 4K blocks to the buffer.
// Change all characters in the buffer to uppercase.
// Write the buffer to the temporary file.

do
{
    if (ReadFile(hFile, buffer, 4096,
        &dwBytesRead, NULL))
    {
        CharUpperBuff(buffer, dwBytesRead);

        WriteFile(hTempFile, buffer, dwBytesRead,
            &dwBytesWritten, NULL);
    }
} while (dwBytesRead == 4096);

// Close both files.

CloseHandle(hFile);
CloseHandle(hTempFile);

// Move the temporary file to the new text file.

if (!MoveFile(szTempName, "ALLCAPS.TXT"))
{
    ErrorHandler("Could not move temp. file.");
}


Searching for Files and Changing File Attributes

The following example copies all text files in the current directory to a new directory of read-only files named \TEXTRO. Files in the new directory are changed to read only, if necessary.

The application uses the GetCurrentDirectory function to retrieve the current directory path. This function is also used to return to the current directory after changing to the \TEXTRO directory.

The application then creates the \TEXTRO directory by using the CreateDirectory function.

The application searches the current directory for all .TXT files by using the FindFirstFile and FindNextFile functions. Each .TXT file is copied to the \TEXTRO directory. After a file is copied, the GetFileAttributes function determines whether the file is read only. If the file is not read only, the application changes directories to \TEXTRO and converts the copied file to read only by using the SetFileAttributes function.

After all .TXT files in the current directory have been copied, the application closes the search handle by using the FindClose function.

WIN32_FIND_DATA FileData;
HANDLE hSearch;
DWORD dwAttrs;
char szDirPath[] = "c:\\TEXTRO\\";
char szNewPath[MAX_PATH];
char szHome[MAX_PATH];

BOOL fFinished = FALSE;

// Create a new directory.

if (!CreateDirectory(szDirPath, NULL))
{
    ErrorHandler("Couldn't create new directory.");
}

// Start searching for .TXT files in the current directory.

hSearch = FindFirstFile("*.txt", &FileData);
if (hSearch == INVALID_HANDLE_VALUE)
{
    ErrorHandler("No .TXT files found.");
}

// Copy each .TXT file to the new directory
// and change it to read only, if not already.

while (!fFinished)
{
    lstrcpy(szNewPath, szDirPath);
    lstrcat(szNewPath, FileData.cFileName);
    if (CopyFile(FileData.cFileName, szNewPath, FALSE))
    {
        dwAttrs = GetFileAttributes(FileData.cFileName);
        if (!(dwAttrs & FILE_ATTRIBUTE_READONLY))
        {
            SetFileAttributes(szNewPath,
                dwAttrs | FILE_ATTRIBUTE_READONLY);
        }
    }
    else
    {
        ErrorHandler("Couldn't copy file.");
    }

    if (!FindNextFile(hSearch, &FileData))
    {
        if (GetLastError() == ERROR_NO_MORE_FILES)
        {
            MessageBox(hwnd, "No more .TXT files.",
                "Search completed.", MB_OK);
            fFinished = TRUE;
        }
        else
        {
            ErrorHandler("Couldn't find next file.");
        }
    }
}

// Close the search handle.

if (!FindClose(hSearch))
{
    ErrorHandler("Couldn't close search handle.");
}


Monitoring Changes in a Directory or Directory Tree

The following example monitors the directory tree starting at C:\ for directory name changes. It also monitors the C:\WINDOWS directory for filename changes.

The example uses the FindFirstChangeNotification function to create two notification handles and the WaitForMultipleObjects function to wait on the handles. Whenever a directory is created or deleted in the tree starting at C:\ , the example updates the entire directory tree. Whenever a file is created or deleted in the C:\WINDOWS directory, the example refreshes the WINDOWS directory. The FindNextChangeNotification function restarts the change notification each time the example processes a change.

DWORD dwWaitStatus;
HANDLE dwChangeHandles[2];

// Watch the C:\WINDOWS directory for file creation and
// deletion.

dwChangeHandles[0] = FindFirstChangeNotification(
    "C:\\WINDOWS",                 // directory to watch
    FALSE,                         // do not watch the subtree
    FILE_NOTIFY_CHANGE_FILE_NAME); // watch filename changes

if (dwChangeHandles[0] == INVALID_HANDLE_VALUE)
    ExitProcess(GetLastError());

// Watch the C:\ subtree for directory creation and
// deletion.

dwChangeHandles[1] = FindFirstChangeNotification(
    "C:\\",                        // directory to watch
    TRUE,                          // watch the subtree
    FILE_NOTIFY_CHANGE_DIR_NAME);  // watch dir. name changes

if (dwChangeHandles[1] == INVALID_HANDLE_VALUE)
    ExitProcess(GetLastError());

// Change notification is set. Now wait on both notification
// handles and refresh accordingly.

while (TRUE)
{

    // Wait for notification.

    dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles,
        FALSE, INFINITE);

    switch (dwWaitStatus)
    {
        case WAIT_OBJECT_0:

        // A file was created or deleted in C:\WINDOWS.
        // Refresh this directory and restart the
        // change notification. RefreshDirectory is an
        // application-defined function.

            RefreshDirectory("C:\\WINDOWS")
            if ( FindNextChangeNotification(
                    dwChangeHandles[0]) == FALSE )
                ExitProcess(GetLastError());
            break;

        case WAIT_OBJECT_0 + 1:

        // A directory was created or deleted in C:\.
        // Refresh the directory tree and restart the
        // change notification. RefreshTree is an
        // application-defined function.

            RefreshTree("C:\\");
            if (FindNextChangeNotification(
                    dwChangeHandles[1]) == FALSE)
                ExitProcess(GetLastError());
            break;

        default:
            ExitProcess(GetLastError());
    }
}


Testing for the End of the File

The ReadFile function checks for the end-of-file condition (eof) differently for synchronous and asynchronous read operations. When a synchronous read operation reaches the end of a file, ReadFile returns TRUE and sets the variable pointed to by lpNumberOfBytesRead to zero. An asynchronous read operation can encounter the end of a file during the initiating call to ReadFile or during subsequent asynchronous operation.

The test for end-of-file during a synchronous read operation is simple, as shown in the following example:

// Attempt a synchronous read operation
bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead, NULL);

// Check for eof
if (bResult &&  nBytesRead == 0, )
{
    // We're at the end of the file
}

The test for end-of-file during an asynchronous read operation is more difficult. There are three end-of-file indicators for asynchronous read operations:

  • ReadFile returns FALSE and GetLastError returns ERROR_HANDLE_EOF.
  • ReadFile returns FALSE and GetLastError returns ERROR_IO_PENDING.
  • GetOverlappedResult returns FALSE and GetLastError returns ERROR_HANDLE_EOF.

ReadFileVlm operates in a manner similar to ReadFile, and the same techniques detect the end of the file for both functions.

The following example shows how to test for an end-of-file during an asynchronous read operation:

// Attempt to initiate an asynchronous read operation.
bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead, NULL);

// Check if there was a problem.
if (!bResult)
{
    switch (dwError = GetLastError())
    {
        case ERROR_HANDLE_EOF:
        // At the end of the file.
            break;
        case ERROR_IO_PENDING:
        // I/O pending.
           break;
    }
}

// Check on an asynchronous read operation.
bResult = GetOverlappedResult(hFile, &gOverlapped, &nBytesRead, TRUE);

// Check if there was a problem.
if (!bResult)
{
    switch (dwError = GetLastError())
    {
        case ERROR_HANDLE_EOF:
        // At the end of the file
    }
}


Retrieving a File Pointer

The SetFilePointer function can be used to query the current file pointer position, by specifying a move method of FILE_CURRENT and a distance of zero.

HANDLE hFile;

DWORD dwCurrentFilePosition;

dwCurrentFilePosition = SetFilePointer(
    hFile, // must have GENERIC_READ and/or GENERIC_WRITE
    0,     // do not move pointer
    NULL,  // hFile is not large enough to need this pointer
    FILE_CURRENT);  // provides offset from current position

The following macro can be used to obtain the current file pointer position for files smaller than 2 gigabytes in size:

#define GetFilePointer(hFile) SetFilePointer(hFile, 0, NULL, FILE_CURRENT)

To get the current file positions on larger files, use the following:

#define GetVLFilePointer(hFile, lpPositionHigh) \
        (*lpPositionHigh = 0, \
        SetFilePointer(hFile, 0, lpPositionHigh, FILE_CURRENT))

where lpPositionHigh is a value of type PLONG. The high order long word of the current file position will be returned in lpPositionHigh.


File Reference

The following elements are used with files.

  • File Functions
  • File Structures
  • File Enumeration Types


File Functions

The following functions are used with files.

AreFileApisANSI
CancelIo
CopyFile
CopyFileEx
CopyProgressRoutine
CreateDirectory
CreateDirectoryEx
CreateFile
CreateIoCompletionPort
DefineDosDevice
DeleteFile
FileIOCompletionRoutine
FindClose
FindCloseChangeNotification
FindFirstChangeNotification
FindFirstFile
FindFirstFileEx
FindNextChangeNotification
FindNextFile
FlushFileBuffers
GetBinaryType
GetCurrentDirectory
GetDiskFreeSpace
GetDiskFreeSpaceEx
GetDriveType
GetFileAttributes
GetFileAttributesEx
GetFileInformationByHandle
GetFileSize
GetFileType
GetFullPathName
GetLogicalDrives
GetLogicalDriveStrings
GetLongPathName
GetQueuedCompletionStatus
GetShortPathName
GetTempFileName
GetTempPath
LockFile
LockFileEx
MoveFile
MoveFileEx
PostQueuedCompletionStatus
QueryDosDevice
ReadDirectoryChangesW
ReadFile
ReadFileEx
ReadFileScatter
ReadFileVlm
RemoveDirectory
SearchPath
SetCurrentDirectory
SetEndOfFile
SetFileApisToANSI
SetFileApisToOEM
SetFileAttributes
SetFilePointer
SetVolumeLabel
UnlockFile
UnlockFileEx
WriteFile
WriteFileEx
WriteFileGather
WriteFileVlm

Obsolete Functions

_hread
_hwrite
_lclose
_lcreat
_llseek
_lopen
_lread
_lwrite
OpenFile
SetHandleCount


_hread

The _hread function reads data from the specified file. This function is provided for compatibility with 16-bit versions of Windows. Win32-based applications should use the ReadFile function.

long _hread(
  HFILE hFile,      // handle to file
  LPVOID lpBuffer,  // pointer to buffer for read data
  long lBytes       // length, in bytes, of data buffer
);

Parameters

hFile
Handle to the specified file.
lpBuffer
Pointer to a buffer that contains the data read from the file.
lBytes
Specifies the number of bytes to be read from the file.

Return Values

The return value indicates the number of bytes actually read from the file. If the number of bytes read is less than lBytes, the function has reached the end of file (EOF) before reading the specified number of bytes.

If the function fails, the return value is HFILE_ERROR. To get extended error information, call GetLastError.

If you are attempting to read from a floppy drive that does not have a floppy disk, the system displays a message box prompting the user to retry the operation. To prevent the system from displaying this message box, call the SetErrorMode function with SEM_NOOPENFILEERRORBOX.

See Also

File I/O Overview, File Functions, _hwrite, ReadFile, SetErrorMode


_hwrite

The _hwrite function writes data to the specified file. This function is provided for compatibility with 16-bit versions of Windows. Win32-based applications should use the WriteFile function.

long _hwrite(
  HFILE hFile,      // handle to file
  LPCSTR lpBuffer,  // pointer to buffer for data to be written
  long lBytes       // number of bytes to write
);

Parameters

hFile
Handle to the specified file.
lpBuffer
Pointer to a buffer that contains the data to be written to the file.
lBytes
Specifies the number of bytes to be written to the file.

Return Values

If the function succeeds, the return value indicates the number of bytes actually written to the file.

If the function fails, the return value is HFILE_ERROR. To get extended error information, call GetLastError.

If you are attempting to write to a floppy drive that does not have a floppy disk, the system displays a message box prompting the user to retry the operation. To prevent the system from displaying this message box, call the SetErrorMode function with SEM_NOOPENFILEERRORBOX.

See Also

File I/O Overview, File Functions, _hread, SetErrorMode, WriteFile


_lclose

The _lclose function closes the specified file so that it is no longer available for reading or writing. This function is provided for compatibility with 16-bit versions of Windows. Win32-based applications should use the CloseHandle function.

HFILE _lclose(
  HFILE hFile   // handle to file to close
);

Parameters

hFile
Handle to the file to be closed. This handle is returned by the function that created or last opened the file.

Return Values

If the function succeeds, the return value is zero.

If the function fails, the return value is HFILE_ERROR. To get extended error information, call GetLastError.

See Also

File I/O Overview, File Functions, CloseHandle, CreateFile, _lopen


_lcreat

The _lcreat function creates or opens a specified file. This function is provided for compatibility with 16-bit versions of Windows. Win32-based applications should use the CreateFile function.

HFILE _lcreat(
  LPCSTR lpPathName,  // pointer to name of file to open
  int iAttribute      // file attribute
);

Parameters

lpPathName
Pointer to a null-terminated string that names the file to be opened. The string must consist of characters from the ANSI character set.
iAttribute
Specifies the file attributes. This parameter must be one of the following values:
Value | Meaning
0 | Normal (can be read from or written to without restriction).
1 | Read only (cannot be opened for write)
2 | Hidden (not found by directory search)
4 | System (not found by directory search)

Return Values

If the function succeeds, the return value is a file handle.

If the function fails, the return value is HFILE_ERROR. To get extended error information, call GetLastError.

Remarks

If the file does not exist, the _lcreat function creates a new file and opens it for writing. If the file exists, _lcreat truncates the file size to zero and opens it for reading and writing. When the function opens the file, the pointer is set to the beginning of the file.

The _lcreat function should be used carefully. It can open any file, even one already opened by another function.

See Also

File I/O Overview, File Functions, CreateFile, _lopen


_llseek

The _llseek function repositions the file pointer in a previously opened file. This function is provided for compatibility with 16-bit versions of Windows. Win32-based applications should use the SetFilePointer function.

LONG _llseek(
  HFILE hFile,  // handle to file
  LONG lOffset, // number of bytes to move
  int iOrigin   // position to move from
);

Parameters

hFile
Handle to the file.
lOffset
Specifies the number of bytes the file pointer is to be moved.
iOrigin
Specifies the starting position and direction of the file pointer. This parameter must be one of the following values:
Value | Meaning
FILE_BEGIN | Moves the file pointer lOffset bytes from the beginning of the file.
FILE_CURRENT | Moves the file pointer lOffset bytes from its current position.
FILE_END | Moves the file pointer lOffset bytes from the end of the file.

Return Values

If the function succeeds, the return value specifies the new offset of the pointer, in bytes, from the beginning of the file.

If the function fails, the return value is HFILE_ERROR. To get extended error information, call GetLastError.

Remarks

When a file is initially opened, the file pointer is set to the beginning of the file. The _llseek function moves the pointer an arbitrary amount without reading data, which facilitates random access to the file's contents.

See Also

File I/O Overview, File Functions, _lopen, SetFilePointer


_lopen

The _lopen function opens an existing file and sets the file pointer to the beginning of the file. This function is provided for compatibility with 16-bit versions of Windows. Win32-based applications should use the CreateFile function.

HFILE _lopen(
  LPCSTR lpPathName,  // pointer to name of file to open
  int iReadWrite      // file access mode
);

Parameters

lpPathName
Pointer to a null-terminated string that names the file to open. The string must consist of characters from the ANSI character set.
iReadWrite
Specifies the modes in which to open the file. This parameter consists of one access mode and an optional share mode. The access mode must be one of the following values:
Value | Meaning
OF_READ | Opens the file for reading only.
OF_READWRITE | Opens the file for reading and writing.
OF_WRITE | Opens the file for writing only.

The share mode can be one of the following values:
Value | Meaning
OF_SHARE_COMPAT | Opens the file in compatibility mode, enabling any process on a given computer to open the file any number of times. If the file has been opened by using any of the other share modes, _lopen fails.
OF_SHARE_DENY_NONE | Opens the file without denying other processes read or write access to the file. If the file has been opened in compatibility mode by any other process, _lopen fails.
OF_SHARE_DENY_READ | Opens the file and denies other processes read access to the file. If the file has been opened in compatibility mode or for read access by any other process, _lopen fails.
OF_SHARE_DENY_WRITE | Opens the file and denies other processes write access to the file. If the file has been opened in compatibility mode or for write access by any other process, _lopen fails.
OF_SHARE_EXCLUSIVE | Opens the file in exclusive mode, denying other processes both read and write access to the file. If the file has been opened in any other mode for read or write access, even by the current process, _lopen fails.

Return Values

If the function succeeds, the return value is a file handle.

If the function fails, the return value is HFILE_ERROR. To get extended error information, call GetLastError.

See Also

File I/O Overview, File Functions, CreateFile


_lread

The _lread function reads data from the specified file. This function is provided for compatibility with 16-bit versions of Windows. Win32-based applications should use the ReadFile function.

UINT _lread(
  HFILE hFile,      // handle to file
  LPVOID lpBuffer,  // pointer to buffer for read data
  UINT uBytes       // length, in bytes, of data buffer
);

Parameters

hFile
Handle to the specified file.
lpBuffer
Pointer to a buffer that contains the data read from the file.
uBytes
Specifies the number of bytes to be read from the file.

Return Values

The return value indicates the number of bytes actually read from the file. If the number of bytes read is less than uBytes, the function has reached the end of file (EOF) before reading the specified number of bytes.

If the function fails, the return value is HFILE_ERROR. To get extended error information, call GetLastError.

If you are attempting to read from a floppy drive that does not have a floppy disk, the system displays a message box prompting the user to retry the operation. To prevent the system from displaying this message box, call the SetErrorMode function with SEM_NOOPENFILEERRORBOX.

See Also

File I/O Overview, File Functions, _lwrite, ReadFile, SetErrorMode


_lwrite

The _lwrite function writes data to the specified file. This function is provided for compatibility with 16-bit versions of Windows. Win32-based applications should use the WriteFile function.

UINT _lwrite(
  HFILE hFile,      // handle to file
  LPCSTR lpBuffer,  // pointer to buffer for data to be written
  UINT uBytes       // number of bytes to write
);

Parameters

hFile
Handle to the specified file.
lpBuffer
Pointer to a buffer that contains the data to write to the file.
uBytes
Specifies the number of bytes to be written to the file.

Return Values

If the function succeeds, the return value indicates the number of bytes actually written to the file.

If the function fails, the return value is HFILE_ERROR. To get extended error information, call GetLastError.

If you are attempting to write to a floppy drive that does not have a floppy disk, the system displays a message box prompting the user to retry the operation. To prevent the system from displaying this message box, call the SetErrorMode function with SEM_NOOPENFILEERRORBOX.

See Also

File I/O Overview, File Functions, _lread, SetErrorMode, WriteFile


AreFileApisANSI

The AreFileApisANSI function determines whether a set of Win32 file functions is using the ANSI or OEM character set code page. This function is useful for 8-bit console input and output operations.

BOOL AreFileApisANSI(VOID)

Parameters

This function has no parameters.

Return Values

If the set of Win32 file functions is using the ANSI code page, the return value is nonzero.

If the set of Win32 file functions is using the OEM code page, the return value is zero.

Remarks

The SetFileApisToOEM function causes a set of Win32 file functions to use the OEM code page. The SetFileApisToANSI function causes the same set of Win32 file functions to use the ANSI code page. Use the AreFileApisANSI function to determine which code page the set of file functions is currently using. For a discussion of these functions' usage, please refer to the Remarks sections of SetFileApisToOEM and SetFileApisToANSI.

The Win32 file functions whose code page is ascertained by AreFileApisANSI are those functions exported by KERNEL32.DLL which accept or return a file name.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, SetFileApisToANSI, SetFileApisToOEM


CancelIo

The CancelIo function cancels all pending input and output (I/O) operations that were issued by the calling thread for the specified file handle. The function does not cancel I/O operations issued for the file handle by other threads.

BOOL CancelIo(
  HANDLE hFile  // file handle for which to cancel I/O
);

Parameters

hFile
Handle to a file. The function cancels all pending I/O operations for this file handle.

Return Values

If the function succeeds, the return value is nonzero All pending I/O operations issued by the calling thread for the file handle were successfully canceled.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If there are any I/O operations in progress for the specified file handle, and they were issued by the calling thread, the CancelIo function cancels them.

Note that the I/O operations must have been issued as overlapped I/O. If they were not, the I/O operations would not have returned to allow the thread to call the CancelIo function. Calling the CancelIo function with a file handle that was not opened with FILE_FLAG_OVERLAPPED does nothing.

All I/O operations that are canceled will complete with the error ERROR_OPERATION_ABORTED. All completion notifications for the I/O operations will occur normally.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, CreateFile, DeviceIoControl, LockFileEx, ReadDirectoryChangesW, ReadFile, ReadFileEx, WriteFile, WriteFileEx


CopyFile

The CopyFile function copies an existing file to a new file.

BOOL CopyFile(
  LPCTSTR lpExistingFileName,
                          // pointer to name of an existing file
  LPCTSTR lpNewFileName,  // pointer to filename to copy to
  BOOL bFailIfExists      // flag for operation if file exists
);

Parameters

lpExistingFileName
Pointer to a null-terminated string that specifies the name of an existing file.
lpNewFileName
Pointer to a null-terminated string that specifies the name of the new file.
bFailIfExists
Specifies how this operation is to proceed if a file of the same name as that specified by lpNewFileName already exists. If this parameter is TRUE and the new file already exists, the function fails. If this parameter is FALSE and the new file already exists, the function overwrites the existing file and succeeds.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Security attributes for the existing file are not copied to the new file.

File attributes for the existing file are copied to the new file. For example, if an existing file has the FILE_ATTRIBUTE_READONLY file attribute, a copy created through a call to CopyFile will also have the FILE_ATTRIBUTE_READONLY file attribute.

Windows CE: If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, CreateFile, MoveFile


CopyFileEx

The CopyFileEx function copies an existing file to a new file. This function preserves extended attributes, OLE structured storage, NTFS alternate data streams, and file attributes. Security attributes for the existing file are not copied to the new file.

BOOL CopyFileEx(
  LPCWSTR lpExistingFileName,
                    // pointer to name of an existing file
  LPCWSTR lpNewFileName,
                    // pointer to filename to copy to
  LPPROGRESS_ROUTINE lpProgressRoutine,
                    // pointer to the callback function
  LPVOID lpData,    // to be passed to the callback function
  LPBOOL pbCancel,  // flag that can be used to cancel the operation
  DWORD dwCopyFlags // flags that specify how the file is copied
);

Parameters

lpExistingFileName
Pointer to a null-terminated string that specifies the name of an existing file.
lpNewFileName
Pointer to a null-terminated string that specifies the name of the new file.
lpProgressRoutine
Specifies the address of a callback function of type LPPROGRESS_ROUTINE that is called each time another portion of the file has been copied. This parameter can be NULL. For more information on the progress callback function, see CopyProgressRoutine.
lpData
Specifies an argument to be passed to the callback function. This parameter can be NULL.
pbCancel
Pointer to a Boolean variable that can be used to cancel the operation. If this flag is set to TRUE during the copy operation, the operation is canceled.
dwCopyFlags
Specifies how the file is to be copied. This parameter can be a combination of the following values:
Value | Meaning
COPY_FILE_FAIL_IF_EXISTS | The copy operation fails immediately if the target file already exists.
COPY_FILE_RESTARTABLE | Progress of the copy is tracked in the target file in case the copy fails. The failed copy can be restarted at a later time by specifying the same values for lpExistingFileName and lpNewFileName as those used in the call that failed.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information call GetLastError.

Remarks

For information, see CopyFile.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, CreateFile, CopyFile, CopyProgressRoutine, MoveFile


CopyProgressRoutine

The CopyProgressRoutine function is an application-defined callback function used with the CopyFileEx function. It is called when a portion of a copy operation is completed. The LPPROGRESS_ROUTINE type defines a pointer to this callback function. CopyProgresRoutine is a placeholder for the application-defined function name.

DWORD CALLBACK CopyProgressRoutine(
  LARGE_INTEGER TotalFileSize,  // total file size, in bytes
  LARGE_INTEGER TotalBytesTransferred,
                            // total number of bytes transferred
  LARGE_INTEGER StreamSize,  // total number of bytes for this stream
  LARGE_INTEGER StreamBytesTransferred,
                            // total number of bytes transferred for
                            // this stream
  DWORD dwStreamNumber,     // the current stream
  DWORD dwCallbackReason,   // reason for callback
  HANDLE hSourceFile,       // handle to the source file
  HANDLE hDestinationFile,  // handle to the destination file
  LPVOID lpData             // passed by CopyFileEx
);

Parameters

TotalFileSize
The total size of the file, in bytes.
TotalBytesTransferred
The total number of bytes transferred from the source file to the destination file since the copy operation began.
StreamSize
The total size of the current file stream, in bytes.
StreamBytesTransferred
The total number of bytes in the current stream that have been transferred from the source file to the destination file since the copy operation began.
dwStreamNumber
Handle to the current stream. The stream number is 1 the first time CopyProgressRoutine is called.
dwCallbackReason
Specifies the reason that CopyProgressRoutine was called. This parameter can be one of the following values:
Value | Meaning
CALLBACK_CHUNK_FINISHED | Another part of the data file was copied.
CALLBACK_STREAM_SWITCH | Another stream was created and is about to be copied. This is the callback reason given when the callback routine is first invoked.

hSourceFile
Handle to the source file.
hDestinationFile
Handle to the destination file
lpData
The argument passed to CopyProgressRoutine by the CopyFileEx function.

Return Values

The CopyProgressRoutine function should return one of the following values:

Value | Meaning
PROGRESS_CONTINUE | Continue the copy operation.
PROGRESS_CANCEL | Cancel the copy operation and delete the destination file.
PROGRESS_STOP | Stop the copy operation. It can be restarted at a later time.
PROGRESS_QUIET | Continue the copy operation, but stop invoking CopyProgressRoutine to report progress.

Remarks

An application can use this information to display a progress bar that shows the total number of bytes copied as a percent of the total file size.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: User-defined.

See Also

File I/O Overview, File Functions, CopyFileEx


CreateDirectory

The CreateDirectory function creates a new directory. If the underlying file system supports security on files and directories, the function applies a specified security descriptor to the new directory. Note that CreateDirectory does not have a template parameter, while CreateDirectoryEx does.

BOOL CreateDirectory(
  LPCTSTR lpPathName,                         // pointer to directory path string
  LPSECURITY_ATTRIBUTES lpSecurityAttributes  // pointer to security descriptor
);

Parameters

lpPathName
Pointer to a null-terminated string that specifies the path of the directory to be created.

There is a default string size limit for paths of MAX_PATH characters. This limit is related to how the CreateDirectory function parses paths.

Windows NT: An application can transcend this limit and send in paths longer than MAX_PATH characters by calling the wide (W) version of CreateDirectory and prepending "\\?\" to the path. The "\\?\" tells the function to turn off path parsing; it lets paths longer than MAX_PATH be used with CreateDirectoryW. However, each component in the path cannot be more than MAX_PATH characters long. This also works with UNC names. The "\\?\" is ignored as part of the path. For example, "\\?\C:\myworld\private" is seen as "C:\myworld\private", and "\\?\UNC\bill_g_1\hotstuff\coolapps" is seen as "\\bill_g_1\hotstuff\coolapps".

lpSecurityAttributes
Windows NT: Pointer to a SECURITY_ATTRIBUTES structure. The lpSecurityDescriptor member of the structure specifies a security descriptor for the new directory. If lpSecurityAttributes is NULL, the directory gets a default security descriptor. The target file system must support security on files and directories for this parameter to have an effect.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Some file systems, such as NTFS, support compression or encryption for individual files and directories. On volumes formatted for such a file system, a new directory inherits the compression and encryption attributes of its parent directory.

Windows NT: An application can obtain a handle to a directory by calling CreateFile with the FILE_FLAG_BACKUP_SEMANTICS flag set. For a code example, see CreateFile.

Windows CE: The lpSecurityAttributes parameter is ignored and should be set to NULL. Windows CE does not support security attributes.

For more information, see Accessing Persistent Storage.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, CreateDirectoryEx, CreateFile, RemoveDirectory, SECURITY_ATTRIBUTES


CreateDirectoryEx

The CreateDirectoryEx function creates a new directory with a specified path that retains the attributes of a specified template directory. If the underlying file system supports security on files and directories, the function applies a specified security descriptor to the new directory. The new directory retains the other attributes of the specified template directory. Note that CreateDirectoryEx has a template parameter, while CreateDirectory does not.

BOOL CreateDirectoryEx(
  LPCTSTR lpTemplateDirectory,  // pointer to template directory path
  LPCTSTR lpNewDirectory,       // pointer to path of directory to create
  LPSECURITY_ATTRIBUTES lpSecurityAttributes  // pointer to security descriptor
);

Parameters

lpTemplateDirectory
Pointer to a null-terminated string that specifies the path of the directory to use as a template when creating the new directory.
lpNewDirectory
Pointer to a null-terminated string that specifies the path of the directory to be created.
lpSecurityAttributes
Windows NT: Pointer to a SECURITY_ATTRIBUTES structure. The lpSecurityDescriptor member of the structure specifies a security descriptor for the new directory. If lpSecurityAttributes is NULL, the directory gets a default security descriptor. The target file system must support security on files and directories for this parameter to have an effect.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The CreateDirectoryEx function allows you to create directories that inherit stream information from other directories. This function is useful, for example, when dealing with Macintosh directories, which have a resource stream that is needed to properly identify directory contents as an attribute.

Some file systems, such as NTFS, support compression or encryption for individual files and directories. On volumes formatted for such a file system, a new directory inherits the compression and encryption attributes of its parent directory.

Windows NT: You can obtain a handle to a directory by calling the CreateFile function with the FILE_FLAG_BACKUP_SEMANTICS flag set. See CreateFile for a code example.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, CreateDirectory, CreateFile, RemoveDirectory, SECURITY_ATTRIBUTES


CreateFile

The CreateFile function creates or opens the following objects and returns a handle that can be used to access the object:

  • files
  • pipes
  • mailslots
  • communications resources
  • disk devices (Windows NT only)
  • consoles
  • directories (open only)
HANDLE CreateFile(
  LPCTSTR lpFileName,          // pointer to name of the file
  DWORD dwDesiredAccess,       // access (read-write) mode
  DWORD dwShareMode,           // share mode
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
                               // pointer to security attributes
  DWORD dwCreationDisposition,  // how to create
  DWORD dwFlagsAndAttributes,  // file attributes
  HANDLE hTemplateFile         // handle to file with attributes to
                               // copy
);

Parameters

lpFileName
Pointer to a null-terminated string that specifies the name of the object (file, pipe, mailslot, communications resource, disk device, console, or directory) to create or open.

If *lpFileName is a path, there is a default string size limit of MAX_PATH characters. This limit is related to how the CreateFile function parses paths.

Windows NT: You can use paths longer than MAX_PATH characters by calling the wide (W) version of CreateFile and prepending "\\?\" to the path. The "\\?\" tells the function to turn off path parsing. This lets you use paths that are nearly 32,000 Unicode characters long. However, each component in the path cannot be more than MAX_PATH characters long. You must use fully-qualified paths with this technique. This also works with UNC names. The "\\?\" is ignored as part of the path. For example, "\\?\C:\myworld\private" is seen as "C:\myworld\private", and "\\?\UNC\tom_1\hotstuff\coolapps" is seen as "\\tom_1\hotstuff\coolapps".

dwDesiredAccess
Specifies the type of access to the object. An application can obtain read access, write access, read-write access, or device query access. This parameter can be any combination of the following values.
Value | Meaning
0 | Specifies device query access to the object. An application can query device attributes without accessing the device.
GENERIC_READ | Specifies read access to the object. Data can be read from the file and the file pointer can be moved. Combine with GENERIC_WRITE for read-write access.
GENERIC_WRITE | Specifies write access to the object. Data can be written to the file and the file pointer can be moved. Combine with GENERIC_READ for read-write access.

dwShareMode
Set of bit flags that specifies how the object can be shared. If dwShareMode is 0, the object cannot be shared. Subsequent open operations on the object will fail, until the handle is closed.

To share the object, use a combination of one or more of the following values:
Value | Meaning
FILE_SHARE_DELETE | Windows NT: Subsequent open operations on the object will succeed only if delete access is requested.
FILE_SHARE_READ | Subsequent open operations on the object will succeed only if read access is requested.
FILE_SHARE_WRITE | Subsequent open operations on the object will succeed only if write access is requested.

lpSecurityAttributes
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpSecurityAttributes is NULL, the handle cannot be inherited.

Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the object. If lpSecurityAttributes is NULL, the object gets a default security descriptor. The target file system must support security on files and directories for this parameter to have an effect on files.

dwCreationDisposition
Specifies which action to take on files that exist, and which action to take when files do not exist. For more information about this parameter, see the Remarks section. This parameter must be one of the following values:
Value | Meaning
CREATE_NEW | Creates a new file. The function fails if the specified file already exists.
CREATE_ALWAYS | Creates a new file. If the file exists, the function overwrites the file and clears the existing attributes.
OPEN_EXISTING | Opens the file. The function fails if the file does not exist.
See the Remarks section for a discussion of why you should use the OPEN_EXISTING flag if you are using the CreateFile function for devices, including the console.
OPEN_ALWAYS | Opens the file, if it exists. If the file does not exist, the function creates the file as if dwCreationDisposition were CREATE_NEW.
TRUNCATE_EXISTING | Opens the file. Once opened, the file is truncated so that its size is zero bytes. The calling process must open the file with at least GENERIC_WRITE access. The function fails if the file does not exist.

dwFlagsAndAttributes
Specifies the file attributes and flags for the file.

Any combination of the following attributes is acceptable for the dwFlagsAndAttributes parameter, except all other file attributes override FILE_ATTRIBUTE_NORMAL.
Attribute | Meaning
FILE_ATTRIBUTE_ARCHIVE | The file should be archived. Applications use this attribute to mark files for backup or removal.
FILE_ATTRIBUTE_HIDDEN | The file is hidden. It is not to be included in an ordinary directory listing.
FILE_ATTRIBUTE_NORMAL | The file has no other attributes set. This attribute is valid only if used alone.
FILE_ATTRIBUTE_OFFLINE | The data of the file is not immediately available. Indicates that the file data has been physically moved to offline storage.
FILE_ATTRIBUTE_READONLY | The file is read only. Applications can read the file but cannot write to it or delete it.
FILE_ATTRIBUTE_SYSTEM | The file is part of or is used exclusively by the operating system.
FILE_ATTRIBUTE_TEMPORARY | The file is being used for temporary storage. File systems attempt to keep all of the data in memory for quicker access rather than flushing the data back to mass storage. A temporary file should be deleted by the application as soon as it is no longer needed.

Any combination of the following flags is acceptable for the dwFlagsAndAttributes parameter.
Flag Meaning
FILE_FLAG_WRITE_THROUGH
Instructs the system to write through any intermediate cache and go directly to disk. The system can still cache write operations, but cannot lazily flush them.
FILE_FLAG_OVERLAPPED
Instructs the system to initialize the object, so that operations that take a significant amount of time to process return ERROR_IO_PENDING. When the operation is finished, the specified event is set to the signaled state.
When you specify FILE_FLAG_OVERLAPPED, the file read and write functions must specify an OVERLAPPED structure. That is, when FILE_FLAG_OVERLAPPED is specified, an application must perform overlapped reading and writing.
When FILE_FLAG_OVERLAPPED is specified, the system does not maintain the file pointer. The file position must be passed as part of the lpOverlapped parameter (pointing to an OVERLAPPED structure) to the file read and write functions.
This flag also enables more than one operation to be performed simultaneously with the handle (a simultaneous read and write operation, for example).
FILE_FLAG_NO_BUFFERING
Instructs the system to open the file with no intermediate buffering or caching. When combined with FILE_FLAG_OVERLAPPED, the flag gives maximum asynchronous performance, because the I/O does not rely on the synchronous operations of the memory manager. However, some I/O operations will take longer, because data is not being held in the cache.

An application must meet certain requirements when working with files opened with FILE_FLAG_NO_BUFFERING:

  • File access must begin at byte offsets within the file that are integer multiples of the volume's sector size.
  • File access must be for numbers of bytes that are integer multiples of the volume's sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes.
  • Buffer addresses for read and write operations must be sector aligned (aligned on addresses in memory that are integer multiples of the volume's sector size).

One way to align buffers on integer multiples of the volume sector size is to use VirtualAlloc to allocate the buffers. It allocates memory that is aligned on addresses that are integer multiples of the operating system's memory page size. Because both memory page and volume sector sizes are powers of 2, this memory is also aligned on addresses that are integer multiples of a volume's sector size.

An application can determine a volume's sector size by calling the GetDiskFreeSpace function.

FILE_FLAG_RANDOM_ACCESS
Indicates that the file is accessed randomly. The system can use this as a hint to optimize file caching.
FILE_FLAG_SEQUENTIAL_SCAN
Indicates that the file is to be accessed sequentially from beginning to end. The system can use this as a hint to optimize file caching. If an application moves the file pointer for random access, optimum caching may not occur; however, correct operation is still guaranteed.
Specifying this flag can increase performance for applications that read large files using sequential access. Performance gains can be even more noticeable for applications that read large files mostly sequentially, but occasionally skip over small ranges of bytes.
FILE_FLAG_DELETE_ON_CLOSE
Indicates that the operating system is to delete the file immediately after all of its handles have been closed, not just the handle for which you specified FILE_FLAG_DELETE_ON_CLOSE.

Subsequent open requests for the file will fail, unless FILE_SHARE_DELETE is used.

FILE_FLAG_BACKUP_SEMANTICS
Windows NT: Indicates that the file is being opened or created for a backup or restore operation. The system ensures that the calling process overrides file security checks, provided it has the necessary privileges. The relevant privileges are SE_BACKUP_NAME and SE_RESTORE_NAME.

You can also set this flag to obtain a handle to a directory. A directory handle can be passed to some Win32 functions in place of a file handle.
FILE_FLAG_POSIX_SEMANTICS
Indicates that the file is to be accessed according to POSIX rules. This includes allowing multiple files with names, differing only in case, for file systems that support such naming. Use care when using this option because files created with this flag may not be accessible by applications written for MS-DOS or 16-bit Windows.
FILE_FLAG_OPEN_REPARSE_POINT
Specifying this flag inhibits the reparse behavior of NTFS reparse points. When the file is opened, a file handle is returned, whether the filter that controls the reparse point is operational or not. This flag cannot be used with the CREATE_ALWAYS flag.
FILE_FLAG_OPEN_NO_RECALL
Indicates that the file data is requested, but it should continue to reside in remote storage. It should not be transported back to local storage. This flag is intended for use by remote storage systems or the Hierarchical Storage Management system.

If the CreateFile function opens the client side of a named pipe, the dwFlagsAndAttributes parameter can also contain Security Quality of Service information. For more information, see Impersonation Levels. When the calling application specifies the SECURITY_SQOS_PRESENT flag, the dwFlagsAndAttributes parameter can contain one or more of the following values:
Value | Meaning
SECURITY_ANONYMOUS | Specifies to impersonate the client at the Anonymous impersonation level.
SECURITY_IDENTIFICATION | Specifies to impersonate the client at the Identification impersonation level.
SECURITY_IMPERSONATION | Specifies to impersonate the client at the Impersonation impersonation level.
SECURITY_DELEGATION | Specifies to impersonate the client at the Delegation impersonation level.
SECURITY_CONTEXT_TRACKING | Specifies that the security tracking mode is dynamic. If this flag is not specified, Security Tracking Mode is static.
SECURITY_EFFECTIVE_ONLY Specifies that only the enabled aspects of the client's security context are available to the server. If you do not specify this flag, all aspects of the client's security context are available.

This flag allows the client to limit the groups and privileges that a server can use while impersonating the client.

hTemplateFile
Specifies a handle with GENERIC_READ access to a template file. The template file supplies file attributes and extended attributes for the file being created.

Windows 95: The hTemplateFile parameter must be NULL. If you supply a handle, the call fails and GetLastError returns ERROR_NOT_SUPPORTED.

Return Values

If the function succeeds, the return value is an open handle to the specified file. If the specified file exists before the function call and dwCreationDisposition is CREATE_ALWAYS or OPEN_ALWAYS, a call to GetLastError returns ERROR_ALREADY_EXISTS (even though the function has succeeded). If the file does not exist before the call, GetLastError returns zero.

If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.

Remarks

Use the CloseHandle function to close an object handle returned by CreateFile.

As noted above, specifying zero for dwDesiredAccess allows an application to query device attributes without actually accessing the device. This type of querying is useful, for example, if an application wants to determine the size of a floppy disk drive and the formats it supports without having a floppy in the drive.

Files

When creating a new file, the CreateFile function performs the following actions:

  • Combines the file attributes and flags specified by dwFlagsAndAttributes with FILE_ATTRIBUTE_ARCHIVE.
  • Sets the file length to zero.
  • Copies the extended attributes supplied by the template file to the new file if the hTemplateFile parameter is specified.

When opening an existing file, CreateFile performs the following actions:

  • Combines the file flags specified by dwFlagsAndAttributes with existing file attributes. CreateFile ignores the file attributes specified by dwFlagsAndAttributes.
  • Sets the file length according to the value of dwCreationDisposition.
  • Ignores the hTemplateFile parameter.
  • Ignores the lpSecurityDescriptor member of the SECURITY_ATTRIBUTES structure if the lpSecurityAttributes parameter is not NULL. The other structure members are used. The bInheritHandle member is the only way to indicate whether the file handle can be inherited.

If you are attempting to create a file on a floppy drive that does not have a floppy disk or a CD-ROM drive that does not have a CD, the system displays a message box asking the user to insert a disk or a CD, respectively. To prevent the system from displaying this message box, call the SetErrorMode function with SEM_FAILCRITICALERRORS.

Windows NT: Some file systems, such as NTFS, support compression or encryption for individual files and directories. On volumes formatted for such a file system, a new file inherits the compression and encryption attributes of its directory.

You cannot use the CreateFile function to set a file's compression or encryption state. Use the DeviceIoControl function to set a file's compression state. Use the EncryptFile function to set a file's encryption state.

Pipes

If CreateFile opens the client end of a named pipe, the function uses any instance of the named pipe that is in the listening state. The opening process can duplicate the handle as many times as required but, once opened, the named pipe instance cannot be opened by another client. The access specified when a pipe is opened must be compatible with the access specified in the dwOpenMode parameter of the CreateNamedPipe function. For more information about pipes, see Pipes.

Mailslots

If CreateFile opens the client end of a mailslot, the function returns INVALID_HANDLE_VALUE if the mailslot client attempts to open a local mailslot before the mailslot server has created it with the CreateMailSlot function. For more information about mailslots, see Mailslots.

Communications Resources

The CreateFile function can create a handle to a communications resource, such as the serial port COM1. For communications resources, the dwCreationDisposition parameter must be OPEN_EXISTING, and the hTemplate parameter must be NULL. Read, write, or read-write access can be specified, and the handle can be opened for overlapped I/O. For more information about communications, see Communications.

Disk Devices

Windows NT: You can use the CreateFile function to open a disk drive or a partition on a disk drive. The function returns a handle to the disk device; that handle can be used with the DeviceIOControl function. The following requirements must be met in order for such a call to succeed:

  • The caller must have administrative privileges for the operation to succeed on a hard disk drive.
  • The lpFileName string should be of the form \\.\PHYSICALDRIVEx to open the hard disk x. Hard disk numbers start at zero. For example:
String | Meaning
\\.\PHYSICALDRIVE2 | Obtains a handle to the third physical drive on the user's computer.

  • The lpFileName string should be \\.\x: to open a floppy drive x or a partition x on a hard disk. For example:
String | Meaning
\\.\A: | Obtains a handle to drive A on the user's computer.
\\.\C: | Obtains a handle to drive C on the user's computer.

Note that all I/O buffers must be sector aligned (aligned on addresses in memory that are integer multiples of the volume's sector size), even if the disk device is opened without the FILE_FLAG_NO_BUFFERING flag.

Windows 95: This technique does not work for opening a logical drive. In Windows 95, specifying a string in this form causes CreateFile to return an error.

  • The dwCreationDisposition parameter must have the OPEN_EXISTING value.
  • When opening a floppy disk or a partition on a hard disk, you must set the FILE_SHARE_WRITE flag in the dwShareMode parameter.

Consoles

The CreateFile function can create a handle to console input (CONIN$). If the process has an open handle to it as a result of inheritance or duplication, it can also create a handle to the active screen buffer (CONOUT$). The calling process must be attached to an inherited console or one allocated by the AllocConsole function. For console handles, set the CreateFile parameters as follows:

Parameters | Value
lpFileName | Use the CONIN$ value to specify console input and the CONOUT$ value to specify console output.
 | CONIN$ gets a handle to the console's input buffer, even if the SetStdHandle function redirected the standard input handle. To get the standard input handle, use the GetStdHandle function.
 | CONOUT$ gets a handle to the active screen buffer, even if SetStdHandle redirected the standard output handle. To get the standard output handle, use GetStdHandle.
dwDesiredAccess | GENERIC_READ | GENERIC_WRITE is preferred, but either one can limit access.
dwShareMode | If the calling process inherited the console or if a child process should be able to access the console, this parameter must be FILE_SHARE_READ | FILE_SHARE_WRITE.
lpSecurityAttributes | If you want the console to be inherited, the bInheritHandle member of the SECURITY_ATTRIBUTES structure must be TRUE.
dwCreationDisposition | You should specify OPEN_EXISTING when using CreateFile to open the console.
dwFlagsAndAttributes | Ignored.
hTemplateFile | Ignored.

The following list shows the effects of various settings of fwdAccess and lpFileName.

lpFileName | fwdAccess | Result
CON | GENERIC_READ | Opens console for input.
CON | GENERIC_WRITE | Opens console for output.
CON | GENERIC_READ\ GENERIC_WRITE | Windows 95: Causes CreateFile to fail; GetLastError returns ERROR_PATH_NOT_FOUND. Windows NT: Causes CreateFile to fail; GetLastError returns ERROR_FILE_NOT_FOUND.

Directories

An application cannot create a directory with CreateFile; it must call CreateDirectory or CreateDirectoryEx to create a directory.

Windows NT: You can obtain a handle to a directory by setting the FILE_FLAG_BACKUP_SEMANTICS flag. A directory handle can be passed to some Win32 functions in place of a file handle.

Some file systems, such as NTFS, support compression or encryption for individual files and directories. On volumes formatted for such a file system, a new directory inherits the compression and encryption attributes of its parent directory.

You cannot use the CreateFile function to set a directory's compression or encryption state. Use the DeviceIoControl function to set a directory's compression state. Use the EncryptFile function to set a directory's encryption state.

Windows CE: Windows CE uses special device file names to access peripheral devices. For information on the format of these names, see the Windows CE Device Driver Kit documentation.

The lpSecurityAttributes parameter is ignored and should be set to NULL.

The following attribute flags are not supported for the dwFlagsAndAttributes parameter:

FILE_ATTRIBUTE_OFFLINE

FILE_ATTRIBUTE_TEMPORARY

The following file flags are not supported for the dwFlagsAndAttributes parameter:

FILE_FLAG_OVERLAPPED However, multiple reads/writes pending on a device at a time are allowed.

FILE_FLAG_SEQUENTIAL_SCAN

FILE_FLAG_NO_BUFFERING

FILE_FLAG_DELETE_ON_CLOSE

FILE_FLAG_BACKUP_SEMANTICS

FILE_FLAG_POSIX_SEMANTICS

The dwFlagsAndAttributes parameter does not support the SECURITY_SQOS_PRESENT flag or its corresponding values.

The hTemplateFile parameter is ignored and as a result CreateFile does not copy the extended attributes to the new file.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, AllocConsole, CloseHandle, ConnectNamedPipe, CreateDirectory, CreateDirectoryEx, CreateNamedPipe, DeviceIOControl, GetDiskFreeSpace, GetOverlappedResult, GetStdHandle, OpenFile, OVERLAPPED, ReadFile, SECURITY_ATTRIBUTES, SetErrorMode, SetStdHandle TransactNamedPipe, VirtualAlloc, WriteFile


CreateIoCompletionPort

The CreateIoCompletionPort function can associate an instance of an opened file with a newly created or an existing input/output (I/O) completion port; or it can create an I/O completion port without associating it with a file.

Associating an instance of an opened file with an I/O completion port lets an application receive notification of the completion of asynchronous I/O operations involving that file.

HANDLE CreateIoCompletionPort (
  HANDLE FileHandle,              // file handle to associate with
                                  // the I/O completion port
  HANDLE ExistingCompletionPort,  // handle to the I/O completion port
  DWORD CompletionKey,            // per-file completion key for I/O
                                  // completion packets
  DWORD NumberOfConcurrentThreads // number of threads allowed to
                                  // execute concurrently
);

Parameters

FileHandle
Handle to a file opened for overlapped I/O completion. You must specify the FILE_FLAG_OVERLAPPED flag when using the CreateFile function to obtain the handle.

If FileHandle specifies INVALID_HANDLE_VALUE, CreateIoCompletionPort creates an I/O completion port without associating it with a file. In this case, the ExistingCompletionPort parameter must be NULL, and the CompletionKey parameter is ignored.

ExistingCompletionPort
Handle to the I/O completion port.

If this parameter specifies an existing completion port, the function associates it with the file specified by the FileHandle parameter. The function returns the handle of the existing completion port; it does not create a new I/O completion port.

If this parameter is NULL, the function creates a new I/O completion port and associates it with the file specified by the FileHandle parameter. The function returns the handle to the new I/O completion port.

CompletionKey
Specifies a per-file completion key that will be included in every I/O completion packet for the specified file.
NumberOfConcurrentThreads
Specifies the number of threads that are allowed to execute concurrently.

If one thread enters a wait state, then another thread is allowed to proceed. There may be brief periods when the number of active threads exceeds the specified value, but the operating system quickly brings the number down.

A value of 0 for this parameter indicates that the system can allow as many threads as there are processors in the system.

Return Values

If the function succeeds, the return value is the handle to the I/O completion port that is associated with the specified file.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The I/O system can be instructed to send I/O completion notification packets to I/O completion ports, where they are queued. The CreateIoCompletionPort function provides this functionality.

After an instance of an open file is associated with an I/O completion port, it cannot be used in the ReadFileEx or WriteFileEx function. It is best not to share such an associated file through either handle inheritance or a call to the DuplicateHandle function. Operations performed with such duplicate handles will generate completion notifications.

When you perform an I/O operation with a file handle that has an associated I/O completion port, the I/O system sends a completion notification packet to the completion port when the I/O operation completes. The I/O completion port places the completion packet in a first-in-first-out queue. Use the GetQueuedCompletionStatus function to retrieve these queued I/O completion packets.

Threads in the same process can use the PostQueuedCompletionStatus function to place I/O completion notification packets in a completion port's queue. This allows you to use the port to receive communications from other threads of the process, in addition to receiving I/O completion notification packets from the I/O system.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, GetQueuedCompletionStatus, PostQueuedCompletionStatus


DefineDosDevice

The DefineDosDevice function lets an application define, redefine, or delete MS-DOS device names.

MS-DOS device names are stored as symbolic links in the object name space in Windows NT. The code that converts an MS-DOS path into a corresponding Windows NT path uses these symbolic links to map MS-DOS devices and drive letters. The DefineDosDevice function provides a mechanism whereby an application can modify the symbolic links used to implement the MS-DOS device name space.

BOOL DefineDosDevice(
  DWORD dwFlags,        // controllable aspect flag
  LPCTSTR lpDeviceName, // pointer to an MS-DOS device name string
  LPCTSTR lpTargetPath  // pointer to an MS-DOS or Windows NT path string
);

Parameters

dwFlags
Specifies several controllable aspects of the DefineDosDevice function. One or more of the following values can be used:
Value | Meaning
DDD_RAW_TARGET_PATH | If this value is specified, the function does not convert the lpTargetPath string from an MS-DOS path to a Windows NT path, but takes it as is.
DDD_REMOVE_DEFINITION If this value is specified, the function removes the specified definition for the specified device. To determine which definition to remove, the function walks the list of mappings for the device, looking for a match of lpTargetPath against a prefix of each mapping associated with this device. The first mapping that matches is the one removed, and then the function returns.

If lpTargetPath is NULL or a pointer to a NULL string, the function will remove the first mapping associated with the device and pop the most recent one pushed. If there is nothing left to pop, the device name will be removed.

If this value is NOT specified, the string pointed to by the lpTargetPath parameter will become the new mapping for this device.
DDD_EXACT_MATCH_ON_REMOVE | If this value is specified along with DDD_REMOVE_DEFINITION, the function will use an exact match to determine which mapping to remove. Use this value to insure that you do not delete something that you did not define.

lpDeviceName
Pointer to an MS-DOS device name string specifying the device the function is defining, redefining, or deleting. The device name string must not have a trailing colon, unless a drive letter (C or D, for example) is being defined, redefined, or deleted.
lpTargetPath
Pointer to a path string that will implement this device. The string is an MS-DOS path string unless the DDD_RAW_TARGET_PATH flag is specified, in which case this string is a Windows NT path string.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

As stated in this function's introductory summary, the DefineDosDevice function provides a means whereby an application can create and modify the symbolic links used to implement the MS-DOS device namespace. To retrieve the current mapping for a particular MS-DOS device name or to obtain a list of all MS-DOS devices known to the system, use the QueryDosDevice function.

MS-DOS Device names are global. Once defined, an MS-DOS device name remains visible to all processes until either it is explicitly removed or the system reboots.

Note Drive letters and device names defined at system boot time are protected from redefinition and deletion unless the user is an administrator.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, QueryDosDevice


DeleteFile

The DeleteFile function deletes an existing file.

BOOL DeleteFile(
  LPCTSTR lpFileName   // pointer to name of file to delete
);

Parameters

lpFileName
Pointer to a null-terminated string that specifies the file to be deleted.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If an application attempts to delete a file that does not exist, the DeleteFile function fails.

Windows 95: The DeleteFile function deletes a file even if it is open for normal I/O or as a memory-mapped file. To prevent loss of data, close files before attempting to delete them.

Windows NT: The DeleteFile function fails if an application attempts to delete a file that is open for normal I/O or as a memory-mapped file.

To close an open file, use the CloseHandle function.

Windows CE: If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, CloseHandle, CreateFile


FileIOCompletionRoutine

The FileIOCompletionRoutine function is an application-defined callback function used with the ReadFileEx or WriteFileEx function. It is called when the asynchronous input and output (I/O) operation is completed or canceled and the calling thread is in an alertable state (using the SleepEx, MsgWaitForMultipleObjectsEx, WaitForSingleObjectEx, or WaitForMultipleObjectsEx function with the fAlertable flag set to TRUE).

The LPOVERLAPPED_COMPLETION_ROUTINE type defines a pointer to this callback function. FileIOCompletionRoutine is a placeholder for the application-defined function name.

VOID CALLBACK FileIOCompletionRoutine(
  DWORD dwErrorCode,                // completion code
  DWORD dwNumberOfBytesTransfered,  // number of bytes transferred
  LPOVERLAPPED lpOverlapped         // pointer to structure with I/O
                                    // information
);

Parameters

dwErrorCode
Specifies the I/O completion status. This parameter may be one of the following values:
Value | Meaning
0 | The I/O was successful.
ERROR_HANDLE_EOF | The ReadFileEx function tried to read past the end of the file.

dwNumberOfBytesTransfered
Specifies the number of bytes transferred. If an error occurs, this parameter is zero.
lpOverlapped
Pointer to the OVERLAPPED structure specified by the asynchronous I/O function.

The system does not use the hEvent member of the OVERLAPPED structure; the calling application may use this member to pass information to the completion routine. The system does not use the OVERLAPPED structure after the completion routine is called, so the completion routine can deallocate the memory used by the overlapped structure.

Return Values

This function does not return a value.

Remarks

The FileIOCompletionRoutine function is a placeholder for an application-defined or library-defined function name.

Returning from this function allows another pending I/O completion routine to be called. All waiting completion routines are called before the alertable thread's wait is completed with a return code of WAIT_IO_COMPLETION. The system may call the waiting completion routines in any order. They may or may not be called in the order the I/O functions are completed.

Each time the system calls a completion routine, it uses some of the application's stack. If the completion routine does additional asynchronous I/O and alertable waits, the stack may grow.

For more information, see Asynchronous Procedure Calls.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: User-defined.

See Also

File I/O Overview, File Functions, OVERLAPPED, ReadFileEx, SleepEx, WaitForMultipleObjectsEx, WaitForSingleObjectEx, WriteFileEx


FindClose

The FindClose function closes the specified search handle. The FindFirstFile and FindNextFile functions use the search handle to locate files with names that match a given name.

BOOL FindClose(
  HANDLE hFindFile   // file search handle
);

Parameters

hFindFile
Handle to the search handle. This handle must have been previously opened by the FindFirstFile function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

After the FindClose function is called, the handle specified by the hFindFile parameter cannot be used in subsequent calls to either the FindNextFile or FindClose function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, FindFirstFile, FindNextFile


FindCloseChangeNotification

The FindCloseChangeNotification function stops change notification handle monitoring.

BOOL FindCloseChangeNotification(
  HANDLE hChangeHandle   // handle to change notification to close
);

Parameters

hChangeHandle
Handle to a change notification handle created by the FindFirstChangeNotification function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

After the FindCloseChangeNotification function is called, the handle specified by the hChangeHandle parameter cannot be used in subsequent calls to either the FindNextChangeNotification or FindCloseChangeNotification function.

Change notifications can also be used in the wait functions.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, FindFirstChangeNotification, FindNextChangeNotification


FindFirstChangeNotification

The FindFirstChangeNotification function creates a change notification handle and sets up initial change notification filter conditions. A wait on a notification handle succeeds when a change matching the filter conditions occurs in the specified directory or subtree.

HANDLE FindFirstChangeNotification(
  LPCTSTR lpPathName,    // pointer to name of directory to watch
  BOOL bWatchSubtree,    // flag for monitoring directory or
                         // directory tree
  DWORD dwNotifyFilter   // filter conditions to watch for
);

Parameters

lpPathName
Pointer to a null-terminated string that specifies the path of the directory to watch.
bWatchSubtree
Specifies whether the function will monitor the directory or the directory tree. If this parameter is TRUE, the function monitors the directory tree rooted at the specified directory; if it is FALSE, it monitors only the specified directory.
dwNotifyFilter
Specifies the filter conditions that satisfy a change notification wait. This parameter can be one or more of the following values:
Value Meaning
FILE_NOTIFY_CHANGE_FILE_NAME
Any filename change in the watched directory or subtree causes a change notification wait operation to return. Changes include renaming, creating, or deleting a filename.
FILE_NOTIFY_CHANGE_DIR_NAME
Any directory-name change in the watched directory or subtree causes a change notification wait operation to return. Changes include creating or deleting a directory.
FILE_NOTIFY_CHANGE_ATTRIBUTES
Any attribute change in the watched directory or subtree causes a change notification wait operation to return.
FILE_NOTIFY_CHANGE_SIZE
Any file-size change in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change in file size only when the file is written to the disk. For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.
FILE_NOTIFY_CHANGE_LAST_WRITE
Any change to the last write-time of files in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change to the last write-time only when the file is written to the disk. For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.
FILE_NOTIFY_CHANGE_SECURITY
Any security-descriptor change in the watched directory or subtree causes a change notification wait operation to return.

Return Values

If the function succeeds, the return value is a handle to a find change notification object.

If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.

Remarks

The wait functions can monitor the specified directory or subtree by using the handle returned by the FindFirstChangeNotification function. A wait is satisfied when one of the filter conditions occurs in the monitored directory or subtree.

After the wait has been satisfied, the application can respond to this condition and continue monitoring the directory by calling the FindNextChangeNotification function and the appropriate wait function. When the handle is no longer needed, it can be closed by using the FindCloseChangeNotification function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, FindCloseChangeNotification, FindNextChangeNotification


FindFirstFile

The FindFirstFile function searches a directory for a file whose name matches the specified filename. FindFirstFile examines subdirectory names as well as filenames.

HANDLE FindFirstFile(
  LPCTSTR lpFileName,  // pointer to name of file to search for
  LPWIN32_FIND_DATA lpFindFileData
                       // pointer to returned information
);

Parameters

lpFileName
Windows 95: Pointer to a null-terminated string that specifies a valid directory or path and filename, which can contain wildcard characters (* and ?). This string must not exceed MAX_PATH characters.

Windows NT: Pointer to a null-terminated string that specifies a valid directory or path and filename, which can contain wildcard characters (* and ?).

There is a default string size limit for paths of MAX_PATH characters. This limit is related to how the FindFirstFile function parses paths. An application can transcend this limit and send in paths longer than MAX_PATH characters by calling the wide (W) version of FindFirstFile and prepending "\\?\" to the path. The "\\?\" tells the function to turn off path parsing; it lets paths longer than MAX_PATH be used with FindFirstFileW. However, each component in the path cannot be more than MAX_PATH characters long. This also works with UNC names. The "\\?\" is ignored as part of the path. For example, "\\?\C:\myworld\private" is seen as "C:\myworld\private", and "\\?\UNC\bill_g_1\hotstuff\coolapps" is seen as "\\bill_g_1\hotstuff\coolapps".

lpFindFileData
Pointer to the WIN32_FIND_DATA structure that receives information about the found file or subdirectory. The structure can be used in subsequent calls to the FindNextFile or FindClose function to refer to the file or subdirectory.

Return Values

If the function succeeds, the return value is a search handle used in a subsequent call to FindNextFile or FindClose.

If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.

Remarks

The FindFirstFile function opens a search handle and returns information about the first file whose name matches the specified pattern. Once the search handle is established, you can use the FindNextFile function to search for other files that match the same pattern. When the search handle is no longer needed, close it by using the FindClose function.

This function searches for files by name only; it cannot be used for attribute-based searches.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, FindClose, FindNextFile, GetFileAttributes, SetFileAttributes, WIN32_FIND_DATA


FindFirstFileEx

The FindFirstFileEx function searches a directory for a file whose name and attributes match those specified in the function call.

HANDLE FindFirstFileEx(
  LPCTSTR lpFileName,     // pointer to the name of the file to
                          // search for
  FINDEX_INFO_LEVELS fInfoLevelId,
                          // information level of the returned data
  LPVOID lpFindFileData,  // pointer to the returned information
  FINDEX_SEARCH_OPS fSearchOp,
                          // type of filtering to perform
  LPVOID lpSearchFilter,  // pointer to search criteria
  DWORD dwAdditionalFlags  // additional search control flags
);

Parameters

lpFileName
Pointer to a null-terminated string that specifies a valid directory or path and filename, which can contain wildcard characters (* and ?).
fInfoLevelId
Specifies a FINDEX_INFO_LEVELS enumeration type that gives the information level of the returned data.
lpFindFileData
Pointer to the file data. The pointer type is determined by the level of information specified in the fInfoLevelId parameter.
fSearchOp
Specifies a FINDEX_SEARCH_OPS enumeration type that gives the type of filtering to perform beyond wildcard matching.
lpSearchFilter
If the specified fSearchOp needs structured search information, lpSearchFilter points to the search criteria. At this time, none of the supported fSearchOp values require extended search information. Therefore, this pointer must be NULL.
dwAdditionalFlags
Specifies additional flags for controlling the search. You can use the FIND_FIRST_EX_CASE_SENSITIVE flag for case-sensitive searches. The default search is case insensitive. At this time, no other flags are defined.

Return Values

If the function succeeds, the return value is a search handle that can be used in a subsequent call to the FindNextFile or FindClose functions.

If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.

Remarks

The FindFirstFileEx function is provided to open a search handle and return information about the first file whose name matches the specified pattern and attributes.

If the underlying file system does not support the specified type of filtering, other than directory filtering, FindFirstFileEx fails with the error ERROR_NOT_SUPPORTED. The application has to use FINDEX_SEARCH_OPS type FileExSearchNameMatch and perform its own filtering.

Once established, the search handle can be used in the FindNextFile function to search for other files that match the same pattern with the same filtering being performed. When the search handle is no longer needed, it should be closed using the FindClose function.

The call

FindFirstFileEx( lpFileName,
                 FindExInfoStandard,
                 lpFindData,
                 FindExSearchNameMatch,
                 NULL,
                 0 );

is equivalent to the call

FindFirstFile( lpFileName, lpFindData);

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, FINDEX_INFO_LEVELS, FINDEX_SEARCH_OPS, FindFirstFile, FindNextFile, FindClose


FindNextChangeNotification

The FindNextChangeNotification function requests that the operating system signal a change notification handle the next time it detects an appropriate change.

BOOL FindNextChangeNotification(
  HANDLE hChangeHandle   // handle to change notification to signal
);

Parameters

hChangeHandle
Handle to a change notification handle created by the FindFirstChangeNotification function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

After the FindNextChangeNotification function returns successfully, the application can wait for notification that a change has occurred by using the wait functions.

If a change occurs after a call to FindFirstChangeNotification but before a call to FindNextChangeNotification, the operating system records the change. When FindNextChangeNotification is executed, the recorded change immediately satisfies a wait for the change notification.

FindNextChangeNotification should not be used more than once on the same handle without using one of the wait functions. An application may miss a change notification if it uses FindNextChangeNotification when there is a change request outstanding.

When hChangeHandle is no longer needed, close it by using the FindCloseChangeNotification function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, FindCloseChangeNotification, FindFirstChangeNotification


FindNextFile

The FindNextFile function continues a file search from a previous call to the FindFirstFile function.

BOOL FindNextFile(
  HANDLE hFindFile,  // handle to search
  LPWIN32_FIND_DATA lpFindFileData
                     // pointer to structure for data on found file
);

Parameters

hFindFile
A search handle returned by a previous call to the FindFirstFile function.
lpFindFileData
Pointer to the WIN32_FIND_DATA structure that receives information about the found file or subdirectory. The structure can be used in subsequent calls to FindNextFile to refer to the found file or directory.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. If no matching files can be found, the GetLastError function returns ERROR_NO_MORE_FILES.

Remarks

The FindNextFile function searches for files by name only; it cannot be used for attribute-based searches.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, FindClose, FindFirstFile, GetFileAttributes, SetFileAttributes, WIN32_FIND_DATA


FlushFileBuffers

The FlushFileBuffers function clears the buffers for the specified file and causes all buffered data to be written to the file.

BOOL FlushFileBuffers(
  HANDLE hFile   // open handle to file whose buffers are to be
                 // flushed
);

Parameters

hFile
An open file handle. The function flushes this file's buffers. The file handle must have GENERIC_WRITE access to the file.

If hFile is a handle to a communications device, the function only flushes the transmit buffer.

If hFile is a handle to the server end of a named pipe, the function does not return until the client has read all buffered data from the pipe.

Windows NT: The function fails if hFile is a handle to console output. That is because console output is not buffered. The function returns FALSE, and GetLastError returns ERROR_INVALID_HANDLE.

Windows 95: The function does nothing if hFile is a handle to console output. That is because console output is not buffered. The function returns TRUE, but it does nothing.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The WriteFile and WriteFileEx functions typically write data to an internal buffer that the operating system writes to disk on a regular basis. The FlushFileBuffers function writes all of the buffered information for the specified file to disk.

You can pass the same file handle used with the _lread, _lwrite, _lcreat, and related functions to FlushFileBuffers.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, _lread, _lwrite, _lcreat, WriteFile, WriteFileEx


GetBinaryType

The GetBinaryType function determines whether a file is executable, and if so, what type of executable file it is. That last property determines which subsystem an executable file runs under.

BOOL GetBinaryType (
  LPCTSTR lpApplicationName,  // pointer to fully qualified path of
                              // file to test
  LPDWORD lpBinaryType        // pointer to variable to receive
                              // binary type information
);

Parameters

lpApplicationName
Pointer to a null-terminated string that contains the fully qualified path of the file whose binary type the function shall determine.
lpBinaryType
Pointer to a variable to receive information about the executable type of the file specified by lpApplicationName. The function adjusts a set of bit flags in this variable. The following bit flag constants are defined:
Value | Description
SCS_32BIT_BINARY | A Win32-based application
SCS_DOS_BINARY | An MS-DOS – based application
SCS_OS216_BINARY | A 16-bit OS/2-based application
SCS_PIF_BINARY | A PIF file that executes an MS-DOS – based application
SCS_POSIX_BINARY | A POSIX – based application
SCS_WOW_BINARY | A 16-bit Windows-based application

Return Values

If the file is executable, the return value is nonzero. The function sets the variable pointed to by lpBinaryType to indicate the file's executable type.

If the function is not executable, or if the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

As an alternative, you can obtain the same information by calling the SHGetFileInfo function, passing the SHGFI_EXETYPE flag in the uFlags parameter.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions


GetCurrentDirectory

The GetCurrentDirectory function retrieves the current directory for the current process.

DWORD GetCurrentDirectory(
  DWORD nBufferLength,  // size, in characters, of directory buffer
  LPTSTR lpBuffer       // pointer to buffer for current directory
);

Parameters

nBufferLength
Specifies the length, in characters, of the buffer for the current directory string. The buffer length must include room for a terminating null character.
lpBuffer
Pointer to the buffer for the current directory string. This null-terminated string specifies the absolute path to the current directory.

Return Values

If the function succeeds, the return value specifies the number of characters written to the buffer, not including the terminating null character.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

If the buffer pointed to by lpBuffer is not large enough, the return value specifies the required size of the buffer, including the number of bytes necessary for a terminating null character.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, CreateDirectory, GetSystemDirectory, GetWindowsDirectory, RemoveDirectory, SetCurrentDirectory


GetDiskFreeSpace

The GetDiskFreeSpace function retrieves information about the specified disk, including the amount of free space on the disk.

This function has been superseded by the GetDiskFreeSpaceEx function. New Win32-based applications should use GetDiskFreeSpaceEx.

BOOL GetDiskFreeSpace(
  LPCTSTR lpRootPathName,    // pointer to root path
  LPDWORD lpSectorsPerCluster,  // pointer to sectors per cluster
  LPDWORD lpBytesPerSector,  // pointer to bytes per sector
  LPDWORD lpNumberOfFreeClusters,
                             // pointer to number of free clusters
  LPDWORD lpTotalNumberOfClusters
                             // pointer to total number of clusters
);

Parameters

lpRootPathName
Pointer to a null-terminated string that specifies the root directory of the disk to return information about. If lpRootPathName is NULL, the function uses the root of the current directory. If this parameter is a UNC name, you must follow it with an additional backslash. For example, you would specify \\MyServer\MyShare as \\MyServer\MyShare\.

Windows 95: The initial release of Windows 95 does not support UNC paths for the lpszRootPathName parameter. To query the free disk space using a UNC path, temporarily map the UNC path to a drive letter, query the free disk space on the drive, then remove the temporary mapping. Windows 95 OSR2 and later: UNC paths are supported.

lpSectorsPerCluster
Pointer to a variable for the number of sectors per cluster.
lpBytesPerSector
Pointer to a variable for the number of bytes per sector.
lpNumberOfFreeClusters
Pointer to a variable for the total number of free clusters on the disk that are available to the user associated with the calling thread.

Windows NT 5.0 and later: If per-user disk quotas are in use, this value may be less than the total number of free clusters on the disk.

lpTotalNumberOfClusters
Pointer to a variable for the total number of clusters on the disk that are available to the user associated with the calling thread.

Windows NT 5.0 and later: If per-user disk quotas are in use, this value may be less than the total number of clusters on the disk.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The GetDiskFreeSpaceEx function lets you avoid the arithmetic required by the GetDiskFreeSpace function.

Windows 95:
The GetDiskFreeSpace function returns incorrect values for volumes that are larger than 2 gigabytes. The function caps the values stored into *lpNumberOfFreeClusters and *lpTotalNumberOfClusters so as to never report volume sizes that are greater than 2 gigabytes.

Even on volumes that are smaller than 2 gigabytes, the values stored into *lpSectorsPerCluster, *lpNumberOfFreeClusters, and *lpTotalNumberOfClusters values may be incorrect. That is because the operating system manipulates the values so that computations with them yield the correct volume size.

Windows 95 OSR2 and later:
The GetDiskFreeSpaceEx function is available on Windows 95 systems beginning with OEM Service Release 2 (OSR2). The GetDiskFreeSpaceEx function returns correct values for all volumes, including those that are greater than 2 gigabytes.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, GetDiskFreeSpaceEx, GetDriveType


GetDiskFreeSpaceEx

The GetDiskFreeSpaceEx function obtains information about the amount of space available on a disk volume: the total amount of space, the total amount of free space, and the total amount of free space available to the user associated with the calling thread.

BOOL GetDiskFreeSpaceEx(
  LPCTSTR lpDirectoryName,                 // pointer to the directory name
  PULARGE_INTEGER lpFreeBytesAvailableToCaller, // receives the number of bytes on
                                                // disk available to the caller
  PULARGE_INTEGER lpTotalNumberOfBytes,    // receives the number of bytes on disk
  PULARGE_INTEGER lpTotalNumberOfFreeBytes // receives the free bytes on disk
);

Parameters

lpDirectoryName
Pointer to a null-terminated string that specifies a directory on the disk of interest. This string can be a UNC name. If this parameter is a UNC name, you must follow it with an additional backslash. For example, you would specify \\MyServer\MyShare as \\MyServer\MyShare\.

If lpDirectoryName is NULL, the GetDiskFreeSpaceEx function obtains information about the disk that contains the current directory.

Note that lpDirectoryName does not have to specify the root directory on a disk. The function accepts any directory on the disk.

lpFreeBytesAvailableToCaller
Pointer to a variable to receive the total number of free bytes on the disk that are available to the user associated with the calling thread.

Windows NT 5.0 and later: If per-user quotas are in use, this value may be less than the total number of free bytes on the disk.

lpTotalNumberOfBytes
Pointer to a variable to receive the total number of bytes on the disk that are available to the user associated with the calling thread.

Windows NT 5.0 and later: If per-user quotas are in use, this value may be less than the total number of bytes on the disk.

lpTotalNumberOfFreeBytes
Pointer to a variable to receive the total number of free bytes on the disk.

This parameter can be NULL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Note that the values obtained by this function are of type ULARGE_INTEGER. Be careful not to truncate these values to 32 bits.

Windows 95 OSR2: The GetDiskFreeSpaceEx function is available on Windows 95 systems beginning with OEM Service Release 2 (OSR2).

To determine whether GetDiskFreeSpaceEx is available, call the LoadLibrary or LoadLibraryEx function to load the KERNEL32.DLL file, then call the GetProcAddress function to obtain an address for GetDiskFreeSpaceEx. If GetProcAddress fails, or if GetDiskFreeSpaceEx fails with the ERROR_CALL_NOT_IMPLEMENTED code, use the GetDiskFreeSpace function instead of GetDiskFreeSpaceEx.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 OSR2 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, GetDiskFreeSpace


GetDriveType

The GetDriveType function determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive.

UINT GetDriveType(
  LPCTSTR lpRootPathName   // pointer to root path
);

Parameters

lpRootPathName
Pointer to a null-terminated string that specifies the root directory of the disk to return information about. If lpRootPathName is NULL, the function uses the root of the current directory.

Return Values

The return value specifies the type of drive. It can be one of the following values:

Value | Meaning
DRIVE_UNKNOWN | The drive type cannot be determined.
DRIVE_NO_ROOT_DIR | The root directory does not exist.
DRIVE_REMOVABLE | The disk can be removed from the drive.
DRIVE_FIXED | The disk cannot be removed from the drive.
DRIVE_REMOTE | The drive is a remote (network) drive.
DRIVE_CDROM | The drive is a CD-ROM drive.
DRIVE_RAMDISK | The drive is a RAM disk.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, GetDiskFreeSpace


GetFileAttributes

The GetFileAttributes function returns attributes for a specified file or directory.

DWORD GetFileAttributes(
  LPCTSTR lpFileName   // pointer to the name of a file or directory
);

Parameters

lpFileName
Pointer to a null-terminated string that specifies the name of a file or directory.
Windows NT:
There is a default string size limit for paths of MAX_PATH characters. This limit is related to how the GetFileAttributes function parses paths. An application can transcend this limit and send in paths longer than MAX_PATH characters by calling the wide (W) version of GetFileAttributes and prepending "\\?\" to the path. The "\\?\" tells the function to turn off path parsing; it lets paths longer than MAX_PATH be used with GetFileAttributesW. However, each component in the path cannot be more than MAX_PATH characters long. This also works with UNC names. The "\\?\" is ignored as part of the path. For example, "\\?\C:\myworld\private" is seen as "C:\myworld\private", and "\\?\UNC\bill_g_1\hotstuff\coolapps" is seen as "\\bill_g_1\hotstuff\coolapps".
Windows 95:
The lpFileName string must not exceed MAX_PATH characters. Windows 95 does not support the "\\?\" prefix.

Return Values

If the function succeeds, the return value contains the attributes of the specified file or directory.

If the function fails, the return value is 0xFFFFFFFF. To get extended error information, call GetLastError.

The attributes can be one or more of the following values:

Attribute | Meaning
FILE_ATTRIBUTE_ARCHIVE | The file or directory is an archive file or directory. Applications use this attribute to mark files for backup or removal.
FILE_ATTRIBUTE_COMPRESSED | The file or directory is compressed. For a file, this means that all of the data in the file is compressed. For a directory, this means that compression is the default for newly created files and subdirectories.
FILE_ATTRIBUTE_DIRECTORY | The handle identifies a directory.
FILE_ATTRIBUTE_ENCRYPTED | The file or directory is encrypted. For a file, this means that all data streams are encrypted. For a directory, this means that encryption is the default for newly created files and subdirectories.
FILE_ATTRIBUTE_HIDDEN | The file or directory is hidden. It is not included in an ordinary directory listing.
FILE_ATTRIBUTE_NORMAL | The file or directory has no other attributes set. This attribute is valid only if used alone.
FILE_ATTRIBUTE_OFFLINE | The data of the file is not immediately available. Indicates that the file data has been physically moved to offline storage.
FILE_ATTRIBUTE_READONLY | The file or directory is read-only. Applications can read the file but cannot write to it or delete it. In the case of a directory, applications cannot delete it.
FILE_ATTRIBUTE_REPARSE_POINT | The file has an associated reparse point.
FILE_ATTRIBUTE_SPARSE_FILE | The file is a sparse file.
FILE_ATTRIBUTE_SYSTEM | The file or directory is part of, or is used exclusively by, the operating system.
FILE_ATTRIBUTE_TEMPORARY | The file is being used for temporary storage. File systems attempt to keep all of the data in memory for quicker access rather than flushing the data back to mass storage. A temporary file should be deleted by the application as soon as it is no longer needed.

Remarks

Windows CE: Windows CE supports the following additional return values:

FILE_ATTRIBUTE_INROM
This file is an operating system file stored in ROM. These files are read-only; they cannot be modified.
FILE_ATTRIBUTE_ROMMODULE
This file is an operating system file stored in ROM, designed to execute in place. In other words, code from this file is executed directly from ROM, rather than being first copied to RAM. The CreateFile function cannot be used to access this file, instead the LoadLibrary and CreateProcess functions must be used.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, DeviceIoControl, FindFirstFile, FindNextFile, SetFileAttributes


GetFileAttributesEx

The GetFileAttributesEx function obtains attribute information about a specified file or directory.

This function is similar to the GetFileAttributes function. GetFileAttributes returns a set of FAT-style attribute information. GetFileAttributesEx is designed to obtain other sets of file or directory attribute information. Currently, GetFileAttributeEx obtains a set of standard attributes that is a superset of the FAT-style attribute information.

BOOL GetFileAttributesEx(
  LPCTSTR lpFileName,        // pointer to string that specifies a
                             // file or directory
  GET_FILEEX_INFO_LEVELS fInfoLevelId,
                             // value that specifies the type of
                             // attribute information to obtain
  LPVOID lpFileInformation   // pointer to buffer to receive
                             // attribute information
);

Parameters

lpFileName
Pointer to a null-terminated string that specifies a file or directory.

By default, this string is limited to MAX_PATH characters. The limit is related to how the GetFileAttributesEx function parses paths. An application can transcend this limit and send in paths longer than MAX_PATH characters by calling the wide (W) version of GetFileAttributesEx and prepending "\\?\" to the path. However, each component in the path cannot be more than MAX_PATH characters long. The "\\?\" tells the function to turn off path parsing. This technique also works with UNC names. The "\\?\" is ignored as part of the path. For example, "\\?\C:\myworld\private" is seen as "C:\myworld\private", and "\\?\UNC\peanuts\hotstuff\coolapps" is seen as "\\peanuts\hotstuff\coolapps".

fInfoLevelId
Specifies a GET_FILEEX_INFO_LEVELS enumeration type that gives the set of attribute information to obtain.
lpFileInformation
Pointer to a buffer that receives the attribute information. The type of attribute information stored into this buffer is determined by the value of fInfoLevelId.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, GetFileAttributes, GET_FILEEX_INFO_LEVELS, SetFileAttributes


GetFileInformationByHandle

The GetFileInformationByHandle function retrieves information about a specified file.

BOOL GetFileInformationByHandle(
  HANDLE hFile,                                  // handle of file
  LPBY_HANDLE_FILE_INFORMATION lpFileInformation // pointer to structure
);

Parameters

hFile
Handle to the file that you want to obtain information about.

This handle should not be a pipe handle. The GetFileInformationByHandle function does not work with pipe handles.

lpFileInformation
Pointer to a BY_HANDLE_FILE_INFORMATION structure that receives the file information. The structure can be used in subsequent calls to GetFileInformationByHandle to refer to the information about the file.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Depending on the underlying network components of the operating system and the type of server connected to, the GetFileInformationByHandle function may fail, return partial information, or full information for the given file. In general, you should not use GetFileInformationByHandle unless your application is intended to be run on a limited set of operating system configurations.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, BY_HANDLE_FILE_INFORMATION


GetFileSize

The GetFileSize function retrieves the size, in bytes, of the specified file.

DWORD GetFileSize(
  HANDLE hFile,  // handle of file to get size of
  LPDWORD lpFileSizeHigh
                 // pointer to high-order word for file size
);

Parameters

hFile
Specifies an open handle of the file whose size is being returned. The handle must have been created with either GENERIC_READ or GENERIC_WRITE access to the file.
lpFileSizeHigh
Pointer to the variable where the high-order word of the file size is returned. This parameter can be NULL if the application does not require the high-order word.

Return Values

If the function succeeds, the return value is the low-order doubleword of the file size, and, if lpFileSizeHigh is non-NULL, the function puts the high-order doubleword of the file size into the variable pointed to by that parameter.

If the function fails and lpFileSizeHigh is NULL, the return value is 0xFFFFFFFF. To get extended error information, call GetLastError.

If the function fails and lpFileSizeHigh is non-NULL, the return value is 0xFFFFFFFF and GetLastError will return a value other than NO_ERROR.

Remarks

You cannot use the GetFileSize function with a handle of a nonseeking device such as a pipe or a communications device. To determine the file type for hFile, use the GetFileType function.

The GetFileSize function obtains the uncompressed size of a file. Use the GetCompressedFileSize function to obtain the compressed size of a file.

Note that if the return value is 0xFFFFFFFF and lpFileSizeHigh is non-NULL, an application must call GetLastError to determine whether the function has succeeded or failed. The following sample code illustrates this point:

//
// Case One: calling the function with
//           lpFileSizeHigh == NULL

// Try to obtain hFile's size
dwSize = GetFileSize (hFile, NULL) ;

// If we failed ...
if (dwSize == 0xFFFFFFFF) {

    // Obtain the error code.
    dwError = GetLastError() ;

    // Deal with that failure.
    .
    .
    .

    } // End of error handler

//
// Case Two: calling the function with
//           lpFileSizeHigh != NULL

// Try to obtain hFile's huge size.
dwSizeLow = GetFileSize (hFile, & dwSizeHigh) ;

// If we failed ...
if (dwSizeLow == 0xFFFFFFFF
    &&
    (dwError = GetLastError()) != NO_ERROR ){

    // Deal with that failure.
    .
    .
    .

    } // End of error handler.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, GetCompressedFileSize, GetFileType


GetFileType

The GetFileType function returns the type of the specified file.

DWORD GetFileType(
  HANDLE hFile   // file handle
);

Parameters

hFile
Handle to an open file handle.

Return Values

The return value is one of the following values:

Value | Meaning
FILE_TYPE_UNKNOWN | The type of the specified file is unknown.
FILE_TYPE_DISK | The specified file is a disk file.
FILE_TYPE_CHAR | The specified file is a character file, typically an LPT device or a console.
FILE_TYPE_PIPE | The specified file is either a named or anonymous pipe.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, GetFileSize, GetFileTime


GetFullPathName

The GetFullPathName function retrieves the full path and filename of a specified file.

DWORD GetFullPathName(
  LPCTSTR lpFileName,  // pointer to name of file to find path for
  DWORD nBufferLength, // size, in characters, of path buffer
  LPTSTR lpBuffer,     // pointer to path buffer
  LPTSTR *lpFilePart   // pointer to filename in path
);

Parameters

lpFileName
Pointer to a null-terminated string that specifies a valid filename. This string can use either short (the 8.3 form) or long filenames.
nBufferLength
Specifies the size, in characters, of the buffer for the drive and path.
lpBuffer
Pointer to a buffer that contains the null-terminated string for the name of the drive and path.
lpFilePart
Pointer to a variable that receives the address (in lpBuffer) of the final filename component in the path.

Return Values

If the GetFullPathName function succeeds, the return value is the length, in characters, of the string copied to lpBuffer, not including the terminating null character.

If the lpBuffer buffer is too small, the return value is the size of the buffer, in characters, required to hold the path.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The GetFullPathName function merges the name of the current drive and directory with the specified filename to determine the full path and filename of the specified file. It also calculates the address of the filename portion of the full path and filename. This function does not verify that the resulting path and filename are valid or that they refer to an existing file on the associated volume.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, GetShortPathName, GetTempPath, SearchPath


GetLogicalDrives

The GetLogicalDrives function returns a bitmask representing the currently available disk drives.

DWORD GetLogicalDrives(VOID)

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is a bitmask representing the currently available disk drives. Bit position 0 (the least-significant bit) is drive A, bit position 1 is drive B, bit position 2 is drive C, and so on.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, GetLogicalDriveStrings


GetLogicalDriveStrings

The GetLogicalDriveStrings function fills a buffer with strings that specify valid drives in the system.

DWORD GetLogicalDriveStrings(
  DWORD nBufferLength,  // size of buffer
  LPTSTR lpBuffer       // pointer to buffer for drive strings
);

Parameters

nBufferLength
Specifies the maximum size, in characters, of the buffer pointed to by lpBuffer. This size does not include the terminating null character.
lpBuffer
Pointer to a buffer that receives a series of null-terminated strings, one for each valid drive in the system, that end with a second null character. The following example shows the buffer contents with <null> representing the terminating null character.
c:\<null>d:\<null><null>

Return Values

If the function succeeds, the return value is the length, in characters, of the strings copied to the buffer, not including the terminating null character. Note that an ANSI-ASCII null character uses one byte, but a Unicode null character uses two bytes.

If the buffer is not large enough, the return value is greater than nBufferLength. It is the size of the buffer required to hold the drive strings.

If the function fails, the return value is zero. To get extended error information, use the GetLastError function.

Remarks

Each string in the buffer may be used wherever a root directory is required, such as for the GetDriveType and GetDiskFreeSpace functions.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, GetDriveType, GetDiskFreeSpace, GetLogicalDrives


GetLongPathName

[This is preliminary documentation and subject to change.]

The GetLongPathName function converts the specified path to its long form. If no long path is found, this function simply returns the specified name.

DWORD GetLongPathName(
  LPCTSTR lpszShortPath,
  LPTSTR lpszLongPath,
  DWORD cchBuffer
);

Parameters

lpszShortPath
Pointer to a null-terminated path to be converted.
lpszLongPath
Pointer to the buffer to receive the long path. You can use the same buffer you used for the lpszShortPath parameter.
cchBuffer
Specifies the size of the buffer, in characters.

Return Values

If the function succeeds, the return value is the length of the string copied to the lpszLongPath parameter, in characters. This length does not include the terminating null character.

If lpszLongPath is too small, the function returns the size of the buffer required to hold the long path, in characters.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, GetShortPathName


GetQueuedCompletionStatus

The GetQueuedCompletionStatus function attempts to dequeue an I/O completion packet from a specified input/output completion port. If there is no completion packet queued, the function waits for a pending input/output operation associated with the completion port to complete. The function returns when it can dequeue a completion packet, or optionally when the function times out. If the function returns because of an I/O operation completion, it sets several variables that provide information about the operation.

BOOL GetQueuedCompletionStatus(
  HANDLE CompletionPort,       // the I/O completion port of interest
  LPDWORD lpNumberOfBytesTransferred,
                               // to receive number of bytes
                               // transferred during I/O
  LPDWORD lpCompletionKey,     // to receive file's completion key
  LPOVERLAPPED *lpOverlapped,  // to receive pointer to OVERLAPPED
                               // structure
  DWORD dwMilliseconds         // optional timeout value
);

Parameters

CompletionPort
Handle to the input/output completion port of interest. I/O completion ports are created by the CreateIoCompletionPort function.
lpNumberOfBytesTransferred
Pointer to a variable that the function sets to the number of bytes transferred during an I/O operation that has completed.
lpCompletionKey
Pointer to a variable that the function sets to the completion key value associated with the file handle whose I/O operation has completed. A completion key is a per-file key that is specified in a call to CreateIoCompletionPort.
lpOverlapped
Pointer to a variable that the function sets to the address of the OVERLAPPED structure that was specified when the completed input/output operation was started.

The following functions can be used to start input/output operations that complete using I/O completion ports. You must pass the function an OVERLAPPED structure and a file handle associated (by a call to CreateIoCompletionPort) with an I/O completion port to invoke the I/O completion port mechanism:

  • ConnectNamedPipe
  • DeviceIoControl
  • LockFileEx
  • ReadDirectoryChangesW
  • ReadFile
  • ReadFileVlm
  • TransactNamedPipe
  • WaitCommEvent
  • WriteFile
  • WriteFileVlm

Even if you have passed the function a file handle associated with a completion port and a valid OVERLAPPED structure, an application can prevent completion port notification. This is done by specifying a valid event handle for the hEvent member of the OVERLAPPED structure, and setting its low-order bit. A valid event handle whose low-order bit is set keeps I/O completion from being queued to the completion port.

dwMilliseconds
Specifies the number of milliseconds that the caller is willing to wait for an completion packet to appear at the I/O completion port. If a completion packet doesn't appear within the specified time, the function times out, returns FALSE, and sets *lpOverlapped to NULL.

If dwMilliseconds is INFINITE, the function will never time out. If dwMilliseconds is zero and there is no I/O operation to dequeue, the function will time out immediately.

Return Values

If the function dequeues a completion packet for a successful I/O operation from the completion port, the return value is nonzero. The function stores information in the variables pointed to by the lpNumberOfBytesTransferred, lpCompletionKey, and lpOverlapped parameters.

If *lpOverlapped is NULL and the function does not dequeue a completion packet from the completion port, the return value is zero. The function does not store information in the variables pointed to by the lpNumberOfBytesTransferred and lpCompletionKey parameters. To get extended error information, call GetLastError. If the function did not dequeue a completion packet because the wait timed out, GetLastError returns WAIT_TIMEOUT.

If *lpOverlapped is not NULL and the function dequeues a completion packet for a failed I/O operation from the completion port, the return value is zero. The function stores information in the variables pointed to by lpNumberOfBytesTransferred, lpCompletionKey, and lpOverlapped. To get extended error information, call GetLastError.

Remarks

The I/O system can be instructed to send I/O completion notification packets to input/output completion ports, where they are queued up. The CreateIoCompletionPort function provides a mechanism for this.

When you perform an input/output operation with a file handle that has an associated input/output completion port, the I/O system sends a completion notification packet to the completion port when the I/O operation completes. The I/O completion port places the completion packet in a first-in-first-out queue. The GetQueuedCompletionStatus function retrieves these queued I/O completion packets.

A server application may have several threads calling GetQueuedCompletionStatus for the same completion port. As input operations complete, the operating system queues completion packets to the completion port. If threads are actively waiting in a call to this function, queued requests complete their call.

You can call the PostQueuedCompletionStatus function to post an I/O completion packet to an I/O completion port. The I/O completion packet will satisfy an outstanding call to the GetQueuedCompletionStatus function.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, ConnectNamedPipe, CreateIoCompletionPort, DeviceIoControl, LockFileEx, OVERLAPPED, ReadFile, PostQueuedCompletionStatus, TransactNamedPipe, WaitCommEvent, WriteFile


GetShortPathName

The GetShortPathName function obtains the short path form of a specified input path.

DWORD GetShortPathName(
  LPCTSTR lpszLongPath,  // pointer to a null-terminated path string
  LPTSTR lpszShortPath,  // pointer to a buffer to receive the
                         // null-terminated short form of the path
  DWORD cchBuffer        // specifies the size of the buffer pointed
                         // to by lpszShortPath
);

Parameters

lpszLongPath
Pointer to a null-terminated path string. The function obtains the short form of this path.
lpszShortPath
Pointer to a buffer to receive the null-terminated short form of the path specified by lpszLongPath.
cchBuffer
Specifies the size, in characters, of the buffer pointed to by lpszShortPath.

Return Values

If the function succeeds, the return value is the length, in characters, of the string copied to lpszShortPath, not including the terminating null character.

If the function fails due to the lpszShortPath buffer being too small to contain the short path string, the return value is the size, in characters, of the short path string. You need to call the function with a short path buffer that is at least as large as the short path string.

If the function fails for any other reason, the return value is zero. To get extended error information, call GetLastError.

Remarks

When an application calls this function and specifies a path on a volume that does not support 8.3 aliases, the function fails with ERROR_INVALID_PARAMETER if the path is longer than 67 bytes.

The path specified by lpszLongPath does not have to be a fully qualified path or a long path. The short form may be longer than the specifed path.

If the specified path is already in its short form, there is no need for any conversion, and the function simply copies the specified path to the buffer for the short path.

You can set lpszShortPath to the same value as lpszLongPath; in other words, you can set the buffer for the short path to the address of the input path string.

You can obtain the long name of a file from the short name by calling the FindFirstFile function.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, GetFullPathName, FindFirstFile


GetTempFileName

The GetTempFileName function creates a name for a temporary file. The filename is the concatenation of specified path and prefix strings, a hexadecimal string formed from a specified integer, and the .TMP extension.

The specified integer can be nonzero, in which case, the function creates the filename but does not create the file. If you specify zero for the integer, the function creates a unique filename and creates the file in the specified directory.

UINT GetTempFileName(
  LPCTSTR lpPathName,  // pointer to directory name for temporary
                       // file
  LPCTSTR lpPrefixString,  // pointer to filename prefix
  UINT uUnique,        // number used to create temporary filename
  LPTSTR lpTempFileName
                       // pointer to buffer that receives the new
                       // filename
);

Parameters

lpPathName
Pointer to a null-terminated string that specifies the directory path for the filename. This string must consist of characters in the ANSI character set. Applications typically specify a period (.) or the result of the GetTempPath function for this parameter. If this parameter is NULL, the function fails.
lpPrefixString
Pointer to a null-terminated prefix string. The function uses the first three characters of this string as the prefix of the filename. This string must consist of characters in the ANSI character set.
uUnique
Specifies an unsigned integer that the function converts to a hexadecimal string for use in creating the temporary filename.

If uUnique is nonzero, the function appends the hexadecimal string to lpPrefixString to form the temporary filename. In this case, the function does not create the specified file, and does not test whether the filename is unique.

If uUnique is zero, the function uses a hexadecimal string derived from the current system time. In this case, the function uses different values until it finds a unique filename, and then it creates the file in the lpPathName directory.

lpTempFileName
Pointer to the buffer that receives the temporary filename. This null-terminated string consists of characters in the ANSI character set. This buffer should be at least the length, in bytes, specified by MAX_PATH to accommodate the path.

Return Values

If the function succeeds, the return value specifies the unique numeric value used in the temporary filename. If the uUnique parameter is nonzero, the return value specifies that same number.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The GetTempFileName function creates a temporary filename of the following form:

path\preuuuu.TMP

The following table describes the filename syntax:

Component | Meaning
path | Path specified by the lpPathName parameter
pre | First three letters of the lpPrefixString string
uuuu | Hexadecimal value of uUnique

When the system shuts down, temporary files whose names have been created by this function are not automatically deleted.

To avoid problems resulting when converting an ANSI string, an application should call the CreateFile function to create a temporary file.

If the uUnique parameter is zero, GetTempFileName attempts to form a unique number based on the current system time. If a file with the resulting filename exists, the number is increased by one and the test for existence is repeated. Testing continues until a unique filename is found. GetTempFileName then creates a file by that name and closes it. When uUnique is nonzero, no attempt is made to create and open the file.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, CreateFile, GetTempPath


GetTempPath

The GetTempPath function retrieves the path of the directory designated for temporary files.

DWORD GetTempPath(
  DWORD nBufferLength,  // size, in characters, of the buffer
  LPTSTR lpBuffer       // pointer to buffer for temp. path
);

Parameters

nBufferLength
Specifies the size, in characters, of the string buffer identified by lpBuffer.
lpBuffer
Pointer to a string buffer that receives the null-terminated string specifying the temporary file path. The returned string ends with a backslash, for example, C:\TEMP\.

Return Values

If the function succeeds, the return value is the length, in characters, of the string copied to lpBuffer, not including the terminating null character. If the return value is greater than nBufferLength, the return value is the size of the buffer required to hold the path.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows 95 and Windows 98: The GetTempPath function gets the temporary file path as follows:

  1. The path specified by the TMP environment variable.
  2. The path specified by the TEMP environment variable, if TMP is not defined or if TMP specifies a directory that does not exist.
  3. The current directory, if both TMP and TEMP are not defined or specify nonexistent directories.

Windows NT: The GetTempPath function does not verify that the directory specified by the TMP or TEMP environment variables exists. The function gets the temporary file path as follows:

  1. The path specified by the TMP environment variable.
  2. The path specified by the TEMP environment variable, if TMP is not defined.
  3. The Windows directory, if both TMP and TEMP are not defined.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, GetTempFileName


LockFile

The LockFile function locks a region in an open file. Locking a region prevents other processes from accessing the region.

BOOL LockFile(
  HANDLE hFile,           // handle of file to lock
  DWORD dwFileOffsetLow,  // low-order word of lock region offset
  DWORD dwFileOffsetHigh,  // high-order word of lock region offset
  DWORD nNumberOfBytesToLockLow,
                          // low-order word of length to lock
  DWORD nNumberOfBytesToLockHigh
                          // high-order word of length to lock
);

Parameters

hFile
Handle to the file with a region to be locked. The file handle must have been created with GENERIC_READ or GENERIC_WRITE access to the file (or both).
dwFileOffsetLow
Specifies the low-order word of the starting byte offset in the file where the lock should begin.
dwFileOffsetHigh
Specifies the high-order word of the starting byte offset in the file where the lock should begin.
nNumberOfBytesToLockLow
Specifies the low-order word of the length of the byte range to be locked.
nNumberOfBytesToLockHigh
Specifies the high-order word of the length of the byte range to be locked.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Locking a region of a file gives the locking process exclusive access to the specified region. File locks are not inherited by processes created by the locking process.

Locking a region of a file denies all other processes both read and write access to the specified region. Locking a region that goes beyond the current end-of-file position is not an error.

Locks may not overlap an existing locked region of the file.

The UnlockFile function unlocks a file region locked by LockFile.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, CreateFile, UnlockFile


LockFileEx

The LockFileEx function locks a byte range within an open file for shared or exclusive access.

BOOL LockFileEx(
  HANDLE hFile,      // handle of file to lock
  DWORD dwFlags,     // functional behavior modification flags
  DWORD dwReserved,  // reserved, must be set to zero
  DWORD nNumberOfBytesToLockLow,
                     // low-order 32 bits of length to lock
  DWORD nNumberOfBytesToLockHigh,
                     // high-order 32 bits of length to lock
  LPOVERLAPPED lpOverlapped
                     // addr. of structure with lock region start
                     // offset
);

Parameters

hFile
Handle to an open handle to a file that is to have a range of bytes locked for shared or exclusive access. The handle must have been created with either GENERIC_READ or GENERIC_WRITE access to the file.
dwFlags
Specifies flags that modify the behavior of this function. This parameter may be one or more of the following values:
Value | Meaning
LOCKFILE_FAIL_IMMEDIATELY | If this value is specified, the function returns immediately if it is unable to acquire the requested lock. Otherwise, it waits.
LOCKFILE_EXCLUSIVE_LOCK | If this value is specified, the function requests an exclusive lock. Otherwise, it requests a shared lock.

dwReserved
Reserved parameter; must be set to zero.
nNumberOfBytesToLockLow
Specifies the low-order 32 bits of the length of the byte range to lock.
nNumberOfBytesToLockHigh
Specifies the high-order 32 bits of the length of the byte range to lock.
lpOverlapped
Pointer to an OVERLAPPED structure that the function uses with the locking request. This structure, which is required, contains the file offset of the beginning of the lock range. Be sure to initialize the hEvent member to a valid handle or zero.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero or NULL. To get extended error information, call GetLastError.

Remarks

Locking a region of a file is used to acquire shared or exclusive access to the specified region of the file. File locks are not inherited by a new process during process creation.

Locking a portion of a file for exclusive access denies all other processes both read and write access to the specified region of the file. Locking a region that goes beyond the current end-of-file position is not an error.

Locking a portion of a file for shared access denies all processes write access to the specified region of the file, including the process that first locks the region. All processes can read the locked region.

If an exclusive lock is requested for a range of a file that already has a shared or exclusive lock, this call waits until the lock is granted, unless the LOCKFILE_FAIL_IMMEDIATELY flag is specified.

Locks may not overlap an existing locked region of the file.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, CreateFile, LockFile, OVERLAPPED, UnlockFile, UnlockFileEx


MoveFile

The MoveFile function renames an existing file or a directory (including all its children).

BOOL MoveFile(
  LPCTSTR lpExistingFileName, // pointer to the name of the existing file
  LPCTSTR lpNewFileName       // pointer to the new name for the file
);

Parameters

lpExistingFileName
Pointer to a null-terminated string that names an existing file or directory.
lpNewFileName
Pointer to a null-terminated string that specifies the new name of a file or directory. The new name must not already exist. A new file may be on a different file system or drive. A new directory must be on the same drive.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The MoveFile function will move (rename) either a file or a directory (including all its children) either in the same directory or across directories. The one caveat is that the MoveFile function will fail on directory moves when the destination is on a different volume.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, CopyFile, MoveFileEx


MoveFileEx

The MoveFileEx function renames an existing file or directory.

BOOL MoveFileEx(
  LPCTSTR lpExistingFileName,  // pointer to the name of the existing file
  LPCTSTR lpNewFileName,       // pointer to the new name for the file
  DWORD dwFlags                // flag that specifies how to move file
);

Parameters

lpExistingFileName
Pointer to a null-terminated string that names an existing file or directory on the local machine.
lpNewFileName
Pointer to a null-terminated string that specifies the new name of lpExistingFileName on the local machine.

When moving a file, the destination can be on a different file system or drive. If the destination is on another drive, you must set the MOVEFILE_COPY_ALLOWED flag in dwFlags.

When moving a directory, the destination must be on the same drive.

If dwFlags specifies MOVEFILE_DELAY_UNTIL_REBOOT, lpNewFileName can be NULL. In this case, MoveFileEx registers the lpExistingFileName file to be deleted when the system reboots. If lpExistingFileName refers to a directory, the system removes the directory at reboot only if the directory is empty.

dwFlags
Set of bit flags that specify how to move the file. You can specify any combination of the following values:
Value Meaning
MOVEFILE_COPY_ALLOWED
If the file is to be moved to a different volume, the function simulates the move by using the CopyFile and DeleteFile functions.

This flag cannot be used with the MOVEFILE_DELAY_UNTIL_REBOOT flag.
MOVEFILE_DELAY_UNTIL_REBOOT
The function does not move the file until the operating system is restarted. The system moves the file immediately after AUTOCHK is executed, but before creating any paging files. Consequently, this parameter enables the function to delete paging files from previous startups.

This flag can only be used if the process is in the context of a user who belongs to the administrator group or the LocalSystem account.

This flag cannot be used with the MOVEFILE_COPY_ALLOWED flag.
MOVEFILE_REPLACE_EXISTING
If a file of the name specified by lpNewFileName already exists, the function replaces its contents with those specified by lpExistingFileName.
MOVEFILE_WRITE_THROUGH
The function does not return until the file has actually been moved on the disk.

Setting this flag guarantees that a move performed as a copy and delete operation is flushed to disk before the function returns. The flush occurs at the end of the copy operation.

This flag has no effect if the MOVEFILE_DELAY_UNTIL_REBOOT flag is set.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the dwFlags parameter specifies MOVEFILE_DELAY_UNTIL_REBOOT, MoveFileEx stores the locations of the files to be renamed at reboot in the following registry value:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations

The function fails if it cannot access the registry.

The PendingFileRenameOperations value is of type REG_MULTI_SZ. Each rename operation stores a pair of NULL-terminated strings. The system uses these registry entries to complete the operations at reboot in the same order that they were issued. For example, the following code fragment creates registry entries that delete szDstFile and rename szSrcFile to be szDstFile at reboot:

MoveFileEx(szDstFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
MoveFileEx(szSrcFile, szDstFile, MOVEFILE_DELAY_UNTIL_REBOOT);

The system stores the following entries in PendingFileRenameOperations:

szDstFile\0\0
szSrcFile\0szDstFile\0\0

Because the actual move and deletion operations specified with the MOVEFILE_DELAY_UNTIL_REBOOT flag take place after the calling application has ceased running, the return value cannot reflect success or failure in moving or deleting the file. Rather, it reflects success or failure in placing the appropriate entries into the registry.

The system deletes a directory tagged for deletion with the MOVEFILE_DELAY_UNTIL_REBOOT flag only if it is empty. To ensure deletion of directories, move or delete all files from the directory before attempting to delete it. Files may be in the directory at boot time, but they must be deleted or moved before the system can delete the directory.

Windows 95 and Windows 98: The MoveFileEx function is not supported. To rename or delete a file at reboot, use the following procedure.

To rename or delete a file on Windows 95 and Windows 98
  1. Check for the existence of the WININIT.INI file in the Windows directory.
  2. If WININIT.INI exists, open it and add new entries to the existing [rename] section. If the file does not exist, create the file and create a [rename] section.
  3. Add lines of the following format to the [rename] section:
    DestinationFileName=SourceFileName

    Both DestinationFileName and SourceFileName must be short filenames. To delete a file, use NUL as the value for DestinationFileName.

The system processes WININIT.INI during system boot. After WININIT.INI has been processed, the system names it WININIT.BAK.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, CopyFile, DeleteFile, GetWindowsDirectory, WritePrivateProfileString


OpenFile

The OpenFile function creates, opens, reopens, or deletes a file.

This function is provided for compatibility with 16-bit versions of Windows. In particular, the OpenFile function cannot open a named pipe. Win32-based applications should use the CreateFile function.

HFILE OpenFile(
  LPCSTR lpFileName,        // pointer to the filename
  LPOFSTRUCT lpReOpenBuff,  // pointer to the file information struct
  UINT uStyle               // specifies the action and attributes
);

Parameters

lpFileName
Pointer to a null-terminated string that names the file to be opened. The string must consist of characters from the Windows 3.x character set. The OpenFile function does not support Unicode filenames.
lpReOpenBuff
Pointer to the OFSTRUCT structure that receives information about the file when it is first opened. The structure can be used in subsequent calls to the OpenFile function to refer to the open file.

The OFSTRUCT structure contains a pathname string member whose length is limited to OFS_MAXPATHNAME characters. OFS_MAXPATHNAME is currently defined to be 128. Because of this, you cannot use the OpenFile function to open a file whose path length exceeds 128 characters. The CreateFile function does not have such a path length limitation.

uStyle
Specifies the action to take. The following values can be combined by using the bitwise OR operator:
Value | Meaning
OF_CANCEL | Ignored. In the Win32 application programming interface (API), the OF_PROMPT style produces a dialog box containing a Cancel button.
OF_CREATE | Creates a new file. If the file already exists, it is truncated to zero length.
OF_DELETE | Deletes the file.
OF_EXIST | Opens the file and then closes it. Used to test for a file's existence.
OF_PARSE | Fills the OFSTRUCT structure but carries out no other action.
OF_PROMPT | Displays a dialog box if the requested file does not exist. The dialog box informs the user that the system cannot find the file, and it contains Retry and Cancel buttons. Choosing the Cancel button directs OpenFile to return a file-not-found error message.
OF_READ | Opens the file for reading only.
OF_READWRITE | Opens the file for reading and writing.
OF_REOPEN | Opens the file using information in the reopen buffer.
OF_SHARE_COMPAT For MS-DOS–based file systems using the Win32 API, opens the file with compatibility mode, allowing any process on a specified computer to open the file any number of times. Other efforts to open with any other sharing mode fail.

Windows NT: This flag is mapped to the CreateFile function's FILE_SHARE_READ | FILE_SHARE_WRITE flags.
OF_SHARE_DENY_NONE Opens the file without denying read or write access to other processes. On MS-DOS-based file systems using the Win32 API, if the file has been opened in compatibility mode by any other process, the function fails.

Windows NT: This flag is mapped to the CreateFile function's FILE_SHARE_READ | FILE_SHARE_WRITE flags.
OF_SHARE_DENY_READ | Opens the file and denies read access to other processes. On MS-DOS-based file systems using the Win32 API, if the file has been opened in compatibility mode or for read access by any other process, the function fails. Windows NT: This flag is mapped to the CreateFile function's FILE_SHARE_WRITE flag.
OF_SHARE_DENY_WRITE Opens the file and denies write access to other processes. On MS-DOS-based file systems using the Win32 API, if the file has been opened in compatibility mode or for write access by any other process, the function fails.

Windows NT: This flag is mapped to the CreateFile function's FILE_SHARE_READ flag.
OF_SHARE_EXCLUSIVE | Opens the file with exclusive mode, denying both read and write access to other processes. If the file has been opened in any other mode for read or write access, even by the current process, the function fails.
OF_VERIFY | Verifies that the date and time of the file are the same as when it was previously opened. This is useful as an extra check for read-only files.
OF_WRITE | Opens the file for writing only.

Return Values

If the function succeeds, the return value specifies a file handle.

If the function fails, the return value is HFILE_ERROR. To get extended error information, call GetLastError.

Remarks

If the lpFileName parameter specifies a filename and extension only, this function searches for a matching file in the following directories, in the order shown:

  1. The directory from which the application loaded.
  2. The current directory.
  3. Windows 95: The Windows system directory. Use the GetSystemDirectory function to get the path of this directory.

    Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is SYSTEM32.

  4. Windows NT: The 16-bit Windows system directory. There is no Win32 function that obtains the path of this directory, but it is searched. The name of this directory is SYSTEM.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable.

The lpFileName parameter cannot contain wildcard characters.

The 32-bit OpenFile function does not support the OF_SEARCH flag supported by the 16-bit Windows OpenFile function. The OF_SEARCH flag directs the system to search for a matching file even when the filename includes a full path. To search for a file in a Win32-based application, use the SearchPath function.

To close the file after use, call the _lclose function.

See Also

File I/O Overview, File Functions, CreateFile, GetSystemDirectory, GetWindowsDirectory, _lclose, OFSTRUCT, SearchPath


PostQueuedCompletionStatus

The PostQueuedCompletionStatus function lets you post an I/O completion packet to an I/O completion port. The I/O completion packet will satisfy an outstanding call to the GetQueuedCompletionStatus function. The GetQueuedCompletionStatus function returns with the three values passed as the second, third, and fourth parameters of the call to PostQueuedCompletionStatus.

BOOL PostQueuedCompletionStatus(
  HANDLE CompletionPort,  // handle to an I/O completion port
  DWORD dwNumberOfBytesTransferred,  // value to return via
                          // GetQueuedCompletionStatus'
                          // lpNumberOfBytesTranferred
  DWORD dwCompletionKey,  // value to return via
                          // GetQueuedCompletionStatus'
                          // lpCompletionKey
  LPOVERLAPPED lpOverlapped  // value to return via
                             // GetQueuedCompletionStatus' lpOverlapped
);

Parameters

CompletionPort
Handle to an I/O completion port that you want to post an I/O completion packet to.
dwNumberOfBytesTransferred
Specifies a value to be returned through the lpNumberOfBytesTransferred parameter of the GetQueuedCompletionStatus function.
dwCompletionKey
Specifies a value to be returned through the lpCompletionKey parameter of the GetQueuedCompletionStatus function.
lpOverlapped
Specifies a value to be returned through the lpOverlapped parameter of the GetQueuedCompletionStatus function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError .

Remarks

For more information concerning dwNumberOfBytesTransferred, dwCompletionKey, and lpOverlapped, see GetQueuedCompletionStatus and the descriptions of the parameters those values are returned through.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, CreateIoCompletionPort, GetQueuedCompletionStatus, OVERLAPPED


QueryDosDevice

The QueryDosDevice function lets an application obtain information about MS-DOS device names. The function can obtain the current mapping for a particular MS-DOS device name. The function can also obtain a list of all existing MS-DOS device names.

MS-DOS device names are stored as symbolic links in the Windows NT object name space. The code that converts an MS-DOS path into a corresponding Windows NT path uses these symbolic links to map MS-DOS devices and drive letters. The QueryDosDevice function provides a mechanism whereby a Win32-based application can query the names of the symbolic links used to implement the MS-DOS device namespace as well as the value of each specific symbolic link.

DWORD QueryDosDevice(
  LPCTSTR lpDeviceName, // pointer to MS-DOS device name string
  LPTSTR lpTargetPath,  // pointer to buffer for storing query results
  DWORD ucchMax         // maximum storage capacity of buffer
);

Parameters

lpDeviceName
Pointer to an MS-DOS device name string specifying the target of the query.

This parameter can be NULL. In that case, the QueryDosDevice function will store a list of all existing MS-DOS device names into the buffer pointed to by lpTargetPath.

lpTargetPath
Pointer to a buffer that will receive the result of the query. The function fills this buffer with one or more null-terminated strings. The final null-terminated string is followed by an additional NULL.

If lpDeviceName is non-NULL, the function obtains information about the particular MS-DOS device specified by lpDeviceName. The first null-terminated string stored into the buffer is the current mapping for the device. The other null-terminated strings represent undeleted prior mappings for the device.

If lpDeviceName is NULL, the function obtains a list of all existing MS-DOS device names. Each null-terminated string stored into the buffer is the name of an existing MS-DOS device.

ucchMax
Specifies the maximum number of characters that can be stored into the buffer pointed to by lpTargetPath.

Return Values

If the function succeeds, the return value is the number of characters stored into the buffer pointed to by lpTargetPath.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The DefineDosDevice function provides a means whereby a Win32-based application can create and modify the symbolic links used to implement the MS-DOS device namespace.

MS-DOS device names are global. Once defined, an MS-DOS device name remains visible to all processes until either it is explicity removed or the system reboots.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, DefineDosDevice


ReadDirectoryChangesW

The ReadDirectoryChangesW function returns information describing the changes occurring within a directory.

BOOL ReadDirectoryChangesW(
  HANDLE hDirectory,    // handle to the directory to be watched
  LPVOID lpBuffer,      // pointer to the buffer to receive the read
                        // results
  DWORD nBufferLength,  // length of lpBuffer
  BOOL bWatchSubtree,   // flag for monitoring directory or
                        // directory tree
  DWORD dwNotifyFilter, // filter conditions to watch for
  LPDWORD lpBytesReturned,  // number of bytes returned
  LPOVERLAPPED lpOverlapped,
                        // pointer to structure needed for
                        // overlapped I/O
  LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
                        // pointer to completion routine
);

Parameters

hDirectory
Handle to the directory to be watched. This directory must be opened with the FILE_LIST_DIRECTORY access right.
lpBuffer
Specifies the address of the formatted buffer in which the read results are to be returned. The structure of this buffer is defined by the FILE_NOTIFY_INFORMATION structure. This buffer is filled either synchronously or asynchronously, depending on how the directory is opened and what value is given to the lpOverlapped parameter. For more information, see the Remarks section.
nBufferLength
Specifies the length of the buffer pointed to by the lpBuffer parameter.
bWatchSubtree
Specifies whether the ReadDirectoryChangesW function will monitor the directory or the directory tree. If TRUE is specified, the function monitors the directory tree rooted at the specified directory. If FALSE is specified, the function monitors only the directory specified by the hDirectory parameter.
dwNotifyFilter
Specifies filter criteria the function checks to determine if the wait operation has completed. This parameter can be one or more of the following values:
Value | Meaning
FILE_NOTIFY_CHANGE_FILE_NAME | Any filename change in the watched directory or subtree causes a change notification wait operation to return. Changes include renaming, creating, or deleting a file.
FILE_NOTIFY_CHANGE_DIR_NAME | Any directory-name change in the watched directory or subtree causes a change notification wait operation to return. Changes include creating or deleting a directory.
FILE_NOTIFY_CHANGE_ATTRIBUTES | Any attribute change in the watched directory or subtree causes a change notification wait operation to return.
FILE_NOTIFY_CHANGE_SIZE | Any file-size change in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change in file size only when the file is written to the disk. For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.
FILE_NOTIFY_CHANGE_LAST_WRITE | Any change to the last write-time of files in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change to the last write-time only when the file is written to the disk. For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.
FILE_NOTIFY_CHANGE_LAST_ACCESS | Any change to the last access time of files in the watched directory or subtree causes a change notification wait operation to return.
FILE_NOTIFY_CHANGE_CREATION | Any change to the creation time of files in the watched directory or subtree causes a change notification wait operation to return.
FILE_NOTIFY_CHANGE_SECURITY | Any security-descriptor change in the watched directory or subtree causes a change notification wait operation to return.

lpBytesReturned
For synchronous calls, this parameter specifies the number of bytes transferred into the lpBuffer parameter. For asynchronous calls, this parameter is undefined. You must use an asynchronous notification technique to retrieve the number of bytes transferred.
lpOverlapped
Pointer to an OVERLAPPED structure that supplies data to be used during asynchronous operation. Otherwise, this value is NULL. The Offset and OffsetHigh members of this structure are not used.
lpCompletionRoutine
Pointer to a completion routine to be called when the operation has been completed or canceled and the calling thread is in an alertable wait state. For more information about this completion routine, see FileIOCompletionRoutine.

Return Values

If the function succeeds, the return value is nonzero. For synchronous calls, this means that the operation succeeded. For asynchronous calls, this indicates that the operation was successfully queued.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

To obtain a handle to a directory, use the CreateFile function with FILE_FLAG_BACKUP_SEMANTICS as follows:

hDir = CreateFile(
  DirName,                            // pointer to the file name
  FILE_LIST_DIRECTORY,                // access (read-write) mode
  FILE_SHARE_READ|FILE_SHARE_DELETE,  // share mode
  NULL,                               // security descriptor
  OPEN_EXISTING,                      // how to create
  FILE_FLAG_BACKUP_SEMANTICS,         // file attributes
  NULL                                // file with attributes to copy
);

A call to ReadDirectoryChangesW can be completed synchronously or asynchronously. To specify asynchronous completion, open the directory with CreateFile as shown above, but additionally specify the FILE_FLAG_OVERLAPPED attribute in the dwFlagsAndAttributes parameter. Then specify an OVERLAPPED structure when you call ReadDirectoryChangesW.

Upon successful synchronous completion, the lpBuffer parameter is a formatted buffer and the number of bytes written to the buffer is available in lpBytesReturned. If the number of bytes transferred is zero, the buffer was too small to provide detailed information on all the changes that occurred in the directory or subtree. In this case, you should compute the changes by enumerating the directory or subtree.

For asynchronous completion, you can receive notification in one of three ways:

  • Using the GetOverlappedResult function. To receive notification through GetOverlappedResult, do not specify a completion routine in the lpCompletionRoutine parameter. Be sure to set the hEvent member of the OVERLAPPED structure to a unique event.
  • Using the GetQueuedCompletionStatus function. To receive notification through GetQueuedCompletionStatus, do not specify a completion routine in lpCompletionRoutine. Associate the directory handle hDirectory with a completion port by calling the CreateIoCompletionPort function.
  • Using a completion routine. To receive notification through a completion routine, do not associate the directory with a completion port. Specify a completion routine in lpCompletionRoutine. This routine is called whenever the operation has been completed or canceled while the thread is in an alertable wait state. The hEvent member of the OVERLAPPED structure is not used by the system, so you can use it yourself.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, CreateFile, CreateIoCompletionPort, FILE_NOTIFY_INFORMATION, FileIOCompletionRoutine, GetOverlappedResult, GetQueuedCompletionStatus, OVERLAPPED


ReadFile

The ReadFile function reads data from a file, starting at the position indicated by the file pointer. After the read operation has been completed, the file pointer is adjusted by the number of bytes actually read, unless the file handle is created with the overlapped attribute. If the file handle is created for overlapped input and output (I/O), the application must adjust the position of the file pointer after the read operation.

BOOL ReadFile(
  HANDLE hFile,                // handle of file to read
  LPVOID lpBuffer,             // pointer to buffer that receives data
  DWORD nNumberOfBytesToRead,  // number of bytes to read
  LPDWORD lpNumberOfBytesRead, // pointer to number of bytes read
  LPOVERLAPPED lpOverlapped    // pointer to structure for data
);

Parameters

hFile
Handle to the file to be read. The file handle must have been created with GENERIC_READ access to the file.
Windows NT:
For asynchronous read operations, hFile can be any handle opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile function, or a socket handle returned by the socket or accept functions.
Windows 95:
For asynchronous read operations, hFile can be a communications resource, mailslot, or named pipe handle opened with the FILE_FLAG_OVERLAPPED flag by CreateFile, or a socket handle returned by the socket or accept functions. Windows 95 does not support asynchronous read operations on disk files.
lpBuffer
Pointer to the buffer that receives the data read from the file.
nNumberOfBytesToRead
Number of bytes to be read from the file.
lpNumberOfBytesRead
Pointer to the number of bytes read. ReadFile sets this value to zero before doing any work or error checking. If this parameter is zero when ReadFile returns TRUE on a named pipe, the other end of the message-mode pipe called the WriteFile function with nNumberOfBytesToWrite set to zero.

Windows NT: If lpOverlapped is NULL, lpNumberOfBytesRead cannot be NULL.

Windows NT: If lpOverlapped is not NULL, lpNumberOfBytesRead can be NULL. If this is an overlapped read operation, you can get the number of bytes read by calling GetOverlappedResult. If hFile is associated with an I/O completion port, you can get the number of bytes read by calling GetQueuedCompletionStatus.

Windows 95 and Windows 98: This parameter cannot be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure. This structure is required if hFile was created with FILE_FLAG_OVERLAPPED.

If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hFile was created with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the read operation is complete.

If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the read operation starts at the offset specified in the OVERLAPPED structure and ReadFile may return before the read operation has been completed. In this case, ReadFile returns FALSE and the GetLastError function returns ERROR_IO_PENDING. This allows the calling process to continue while the read operation finishes. The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the read operation.

If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the read operation starts at the current file position and ReadFile does not return until the operation has been completed.

If hFile is not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the read operation starts at the offset specified in the OVERLAPPED structure. ReadFile does not return until the read operation has been completed.

Return Values

The ReadFile function returns when one of the following is true: a write operation completes on the write end of the pipe, the number of bytes requested has been read, or an error occurs.

If the function succeeds, the return value is nonzero.

If the return value is nonzero and the number of bytes read is zero, the file pointer was beyond the current end of the file at the time of the read operation. However, if the file was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the return value is FALSE and GetLastError returns ERROR_HANDLE_EOF when the file pointer goes beyond the current end of file.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If part of the file is locked by another process and the read operation overlaps the locked portion, this function fails.

An application must meet certain requirements when working with files opened with FILE_FLAG_NO_BUFFERING:

  • File access must begin at byte offsets within the file that are integer multiples of the volume's sector size. To determine a volume's sector size, call the GetDiskFreeSpace function.
  • File access must be for numbers of bytes that are integer multiples of the volume's sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes.
  • Buffer addresses for read and write operations must be sector aligned (aligned on addresses in memory that are integer multiples of the volume's sector size). One way to sector align buffers is to use the VirtualAlloc function to allocate the buffers. This function allocates memory that is aligned on addresses that are integer multiples of the system's page size. Because both page and volume sector sizes are powers of 2, memory aligned by multiples of the system's page size is also aligned by multiples of the volume's sector size.

Accessing the input buffer while a read operation is using the buffer may lead to corruption of the data read into that buffer. Applications must not read from, write to, reallocate, or free the input buffer that a read operation is using until the read operation completes.

Characters can be read from the console input buffer by using ReadFile with a handle to console input. The console mode determines the exact behavior of the ReadFile function.

If a named pipe is being read in message mode and the next message is longer than the nNumberOfBytesToRead parameter specifies, ReadFile returns FALSE and GetLastError returns ERROR_MORE_DATA. The remainder of the message may be read by a subsequent call to the ReadFile or PeekNamedPipe function.

When reading from a communications device, the behavior of ReadFile is governed by the current communication time-outs as set and retrieved using the SetCommTimeouts and GetCommTimeouts functions. Unpredictable results can occur if you fail to set the time-out values. For more information about communication time-outs, see COMMTIMEOUTS.

If ReadFile attempts to read from a mailslot whose buffer is too small, the function returns FALSE and GetLastError returns ERROR_INSUFFICIENT_BUFFER.

If the anonymous write pipe handle has been closed and ReadFile attempts to read using the corresponding anonymous read pipe handle, the function returns FALSE and GetLastError returns ERROR_BROKEN_PIPE.

The ReadFile function may fail and return ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding asynchronous I/O requests.

The ReadFile code to check for the end-of-file condition (eof) differs for synchronous and asynchronous read operations.

When a synchronous read operation reaches the end of a file, ReadFile returns TRUE and sets *lpNumberOfBytesRead to zero. The following sample code tests for end-of-file for a synchronous read operation:

// Attempt a synchronous read operation.
bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead, NULL) ;
// Check for end of file.
if (bResult &&  nBytesRead == 0, )
{
    // we're at the end of the file
}

An asynchronous read operation can encounter the end of a file during the initiating call to ReadFile, or during subsequent asynchronous operation.

If EOF is detected at ReadFile time for an asynchronous read operation, ReadFile returns FALSE and GetLastError returns ERROR_HANDLE_EOF.

If EOF is detected during subsequent asynchronous operation, the call to GetOverlappedResult to obtain the results of that operation returns FALSE and GetLastError returns ERROR_HANDLE_EOF.

To cancel all pending asynchronous I/O operations, use the CancelIo function. This function only cancels operations issued by the calling thread for the specified file handle. I/O operations that are canceled complete with the error ERROR_OPERATION_ABORTED.

If you are attempting to read from a floppy drive that does not have a floppy disk, the system displays a message box prompting the user to retry the operation. To prevent the system from displaying this message box, call the SetErrorMode function with SEM_NOOPENFILEERRORBOX.

The following sample code illustrates testing for end-of-file for an asynchronous read operation:

// set up overlapped structure fields
// to simplify this sample, we'll eschew an event handle
gOverLapped.Offset     = 0;
gOverLapped.OffsetHigh = 0;
gOverLapped.hEvent     = NULL;

// attempt an asynchronous read operation
bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead,
    &gOverlapped) ;

// if there was a problem, or the async. operation's still pending ...
if (!bResult)
{
    // deal with the error code
    switch (dwError = GetLastError())
    {
        case ERROR_HANDLE_EOF:
        {
            // we're reached the end of the file
            // during the call to ReadFile

            // code to handle that
        }

        case ERROR_IO_PENDING:
        {
            // asynchronous i/o is still in progress

            // do something else for a while
            GoDoSomethingElse() ;

            // check on the results of the asynchronous read
            bResult = GetOverlappedResult(hFile, &gOverlapped,
                &nBytesRead, FALSE) ;

            // if there was a problem ...
            if (!bResult)
            {
                // deal with the error code
                switch (dwError = GetLastError())
                {
                    case ERROR_HANDLE_EOF:
                    {
                        // we're reached the end of the file
                        //during asynchronous operation
                    }

                    // deal with other error cases
                }
            }
        } // end case

        // deal with other error cases

    } // end switch
} // end if

Windows CE: The lpOverlapped parameter must be set to NULL. Windows CE does not allow files to be created with the overlapped attribute.

Windows CE does not support asynchronous read operations on files.

The hFile.parameter cannot be a socket handle.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, CancelIo, CreateFile, GetCommTimeouts, GetOverlappedResult, GetQueuedCompletionStatus, OVERLAPPED, PeekNamedPipe, ReadFileEx, SetCommTimeouts, SetErrorMode, WriteFile


ReadFileEx

The ReadFileEx function reads data from a file asynchronously. It is designed solely for asynchronous operation, unlike the ReadFile function, which is designed for both synchronous and asynchronous operation. ReadFileEx lets an application perform other processing during a file read operation.

The ReadFileEx function reports its completion status asynchronously, calling a specified completion routine when reading is completed or canceled and the calling thread is in an alertable wait state.

BOOL ReadFileEx(
  HANDLE hFile,                // handle of file to read
  LPVOID lpBuffer,             // pointer to buffer
  DWORD nNumberOfBytesToRead,  // number of bytes to read
  LPOVERLAPPED lpOverlapped,   // pointer to offset
  LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
                               // pointer to completion routine
);

Parameters

hFile
Open handle that specifies the file entity to be read from. This file handle must have been created with the FILE_FLAG_OVERLAPPED flag and must have GENERIC_READ access to the file.
Windows NT:
hFile can be any handle opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile function, or a socket handle returned by the socket or accept functions.
Windows 95:
hFile can be a communications resource, mailslot, or named pipe handle opened with the FILE_FLAG_OVERLAPPED flag by CreateFile, or a socket handle returned by the socket or accept functions. Windows 95 does not support asynchronous operations on disk files.
lpBuffer
Pointer to a buffer that receives the data read from the file.

This buffer must remain valid for the duration of the read operation. The application should not use this buffer until the read operation is completed.

nNumberOfBytesToRead
Number of bytes to be read from the file.
lpOverlapped
Pointer to an OVERLAPPED data structure that supplies data to be used during the asynchronous (overlapped) file read operation.

If the file specified by hFile supports the concept of byte offsets, the caller of ReadFileEx must specify a byte offset within the file at which reading should begin. The caller specifies the byte offset by setting the OVERLAPPED structure's Offset and OffsetHigh members.

The ReadFileEx function ignores the OVERLAPPED structure's hEvent member. An application is free to use that member for its own purposes in the context of a ReadFileEx call. ReadFileEx signals completion of its read operation by calling, or queuing a call to, the completion routine pointed to by lpCompletionRoutine, so it does not need an event handle.

The ReadFileEx function does use the OVERLAPPED structure's Internal and InternalHigh members. An application should not set these members.

The OVERLAPPED data structure pointed to by lpOverlapped must remain valid for the duration of the read operation. It should not be a variable that can go out of scope while the file read operation is in progress.

lpCompletionRoutine
Pointer to the completion routine to be called when the read operation is complete and the calling thread is in an alertable wait state. For more information about the completion routine, see FileIOCompletionRoutine.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

If the function succeeds, the calling thread has an asynchronous input/output (I/O) operation pending: the overlapped read operation from the file. When this I/O operation completes, and the calling thread is blocked in an alertable wait state, the system calls the function pointed to by lpCompletionRoutine, and the wait state completes with a return code of WAIT_IO_COMPLETION.

If the function succeeds, and the file reading operation completes, but the calling thread is not in an alertable wait state, the system queues the completion routine call, holding the call until the calling thread enters an alertable wait state. For information about alertable waits and overlapped input/output operations, see Synchronization and Overlapped Input and Output.

If ReadFileEx attempts to read past the end of the file, the function returns zero, and GetLastError returns ERROR_HANDLE_EOF.

Remarks

An application must meet certain requirements when working with files opened with FILE_FLAG_NO_BUFFERING:

  • File access must begin at byte offsets within the file that are integer multiples of the volume's sector size. To determine a volume's sector size, call the GetDiskFreeSpace function.
  • File access must be for numbers of bytes that are integer multiples of the volume's sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes.
  • Buffer addresses for read and write operations must be sector aligned (aligned on addresses in memory that are integer multiples of the volume's sector size). One way to sector align buffers is to use the VirtualAlloc function to allocate the buffers. This function allocates memory that is aligned on addresses that are integer multiples of the system's page size. Because both page and volume sector sizes are powers of 2, memory aligned by multiples of the system's page size is also aligned by multiples of the volume's sector size.

If a portion of the file specified by hFile is locked by another process, and the read operation specified in a call to ReadFileEx overlaps the locked portion, the call to ReadFileEx fails.

If ReadFileEx attempts to read data from a mailslot whose buffer is too small, the function returns FALSE, and GetLastError returns ERROR_INSUFFICIENT_BUFFER.

Accessing the input buffer while a read operation is using the buffer may lead to corruption of the data read into that buffer. Applications must not read from, write to, reallocate, or free the input buffer that a read operation is using until the read operation completes.

The ReadFileEx function may fail if there are too many outstanding asynchronous I/O requests. In the event of such a failure, GetLastError can return ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY.

To cancel all pending asynchronous I/O operations, use the CancelIo function. This function only cancels operations issued by the calling thread for the specified file handle. I/O operations that are canceled complete with the error ERROR_OPERATION_ABORTED.

If you are attempting to read from a floppy drive that does not have a floppy disk, the system displays a message box prompting the user to retry the operation. To prevent the system from displaying this message box, call the SetErrorMode function with SEM_NOOPENFILEERRORBOX.

An application uses the MsgWaitForMultipleObjectsEx, WaitForSingleObjectEx, WaitForMultipleObjectsEx, and SleepEx functions to enter an alertable wait state. For more information about alertable waits and overlapped input/output, refer to those functions' reference and Synchronization.

Windows 95: On this platform, neither ReadFileEx nor WriteFileEx can be used by the comm ports to communicate. However, you can use ReadFile and WriteFile to perform asynchronous communication.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, CancelIo, CreateFile, FileIOCompletionRoutine, MsgWaitForMultipleObjectsEx, OVERLAPPED, ReadFile, SetErrorMode, SleepEx, WaitForMultipleObjectsEx, WaitForSingleObjectEx, WriteFileEx


ReadFileScatter

The ReadFileScatter function reads data from a file and stores the data into a set of buffers.

The ReadFileScatter function starts reading data from the file at a position specified by an OVERLAPPED structure.

The ReadFileScatter function operates asynchronously.

BOOL ReadFileScatter(
  HANDLE hFile,              // handle to a file to read data from
  FILE_SEGMENT_ELEMENT aSegmentArray [],
                             // pointer to an array of buffer
                             // pointers
  DWORD nNumberOfBytesToRead,  // number of bytes to read
  LPDWORD lpReserved,        // reserved; must be NULL
  LPOVERLAPPED lpOverlapped  // pointer to an asynchronous I/O data
                             // structure
);

Parameters

hFile
An open handle to the file to read from.

This file handle must have been created using GENERIC_READ to specify read access to the file, FILE_FLAG_OVERLAPPED to specify asynchronous I/O, and FILE_FLAG_NO_BUFFERING to specify non-cached I/O.

aSegmentArray
Pointer to an array of FILE_SEGMENT_ELEMENT pointers to buffers. The function stores the data it reads from the file into this set of buffers.

Each buffer should be the size of a system memory page. Each buffer should be aligned on a system memory page size boundary.

A FILE_SEGMENT_ELEMENT pointer is a 64-bit value. The ReadFileScatter function uses all 64 bits. Since the operating systems do not currently support 64-bit memory addressing, you must explicitly zero the upper 32 bits of each FILE_SEGMENT_ELEMENT pointer.

The function stores the data into the buffers in a sequential manner: it stores data into the first buffer, then into the second buffer, then into the next, filling each buffer, until there is no more data or there are no more buffers.

The final element of the array should be a NULL pointer.

nNumberOfBytesToRead
Specifies the number of bytes to read from the file.
lpReserved
This parameter is reserved for future use. You must set it to NULL.
lpOverlapped
Pointer to an OVERLAPPED data structure.

The ReadFileScatter function requires a valid OVERLAPPED structure. The lpOverlapped parameter cannot be NULL.

The ReadFileScatter function starts reading data from the file at a position specified by the Offset and OffsetHigh members of the OVERLAPPED structure.

The ReadFileScatter function may return before the read operation has completed. In that case, the ReadFileScatter function returns the value zero, and the GetLastError function returns the value ERROR_IO_PENDING. This asynchronous operation of ReadFileScatter lets the calling process continue while the read operation completes. You can call the GetOverlappedResult, HasOverlappedIoCompleted, or GetQueuedCompletionStatus function to obtain information about the completion of the read operation.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call the GetLastError function.

If the function attempts to read past the end of the file, the function returns zero, and GetLastError returns ERROR_HANDLE_EOF.

If the function returns before the read operation has completed, the function returns zero, and GetLastError returns ERROR_IO_PENDING.

QuickInfo

Windows NT: Requires version 4.0 SP2 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, CreateFile, GetOverlappedResult, GetQueuedCompletionStatus, HasOverlappedIoCompleted, OVERLAPPED, ReadFile, ReadFileEx, ReadFileVlm, WriteFileGather


RemoveDirectory

The RemoveDirectory function deletes an existing empty directory.

BOOL RemoveDirectory(
  LPCTSTR lpPathName   // pointer to directory to remove
);

Parameters

lpPathName
Pointer to a null-terminated string that specifies the path of the directory to be removed. The path must specify an empty directory, and the calling process must have delete access to the directory.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows CE: If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, CreateDirectory


SearchPath

The SearchPath function searches for the specified file.

DWORD SearchPath(
  LPCTSTR lpPath,      // pointer to search path
  LPCTSTR lpFileName,  // pointer to filename
  LPCTSTR lpExtension, // pointer to extension
  DWORD nBufferLength, // size, in characters, of buffer
  LPTSTR lpBuffer,     // pointer to buffer for found filename
  LPTSTR *lpFilePart   // pointer to pointer to file component
);

Parameters

lpPath
Pointer to a null-terminated string that specifies the path to be searched for the file. If this parameter is NULL, the function searches for a matching file in the following directories in the following sequence:
  1. The directory from which the application loaded.
  2. The current directory.
  3. Windows 95: The Windows system directory. Use the GetSystemDirectory function to get the path of this directory.

    Windows NT: The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is SYSTEM32.

  4. Windows NT: The 16-bit Windows system directory. There is no Win32 function that obtains the path of this directory, but it is searched. The name of this directory is SYSTEM.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable.
lpFileName
Pointer to a null-terminated string that specifies the name of the file to search for.
lpExtension
Pointer to a null-terminated string that specifies an extension to be added to the filename when searching for the file. The first character of the filename extension must be a period (.). The extension is added only if the specified filename does not end with an extension.

If a filename extension is not required or if the filename contains an extension, this parameter can be NULL.

nBufferLength
Specifies the length, in characters, of the buffer that receives the valid path and filename.
lpBuffer
Pointer to the buffer for the valid path and filename of the file found.
lpFilePart
Pointer to the address (within lpBuffer) of the last component of the valid path and filename, which is the address of the character immediately following the final backslash (\) in the path.

Return Values

If the function succeeds, the value returned is the length, in characters, of the string copied to the buffer, not including the terminating null character. If the return value is greater than nBufferLength, the value returned is the size of the buffer required to hold the path.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, FindFirstFile, FindNextFile, GetSystemDirectory, GetWindowsDirectory


SetCurrentDirectory

The SetCurrentDirectory function changes the current directory for the current process.

BOOL SetCurrentDirectory(
  LPCTSTR lpPathName   // pointer to name of new current directory
);

Parameters

lpPathName
Pointer to a null-terminated string that specifies the path to the new current directory. This parameter may be a relative path or a fully qualified path. In either case, the fully qualified path of the specified directory is calculated and stored as the current directory.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Each process has a single current directory made up of two parts:

  • A disk designator that is either a drive letter followed by a colon, or a server name and share name (\\servername\sharename)
  • A directory on the disk designator

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, GetCurrentDirectory


SetEndOfFile

The SetEndOfFile function moves the end-of-file (EOF) position for the specified file to the current position of the file pointer.

BOOL SetEndOfFile(
  HANDLE hFile   // handle of file whose EOF is to be set
);

Parameters

hFile
Handle to the file to have its EOF position moved. The file handle must have been created with GENERIC_WRITE access to the file.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

This function can be used to truncate or extend a file. If the file is extended, the contents of the file between the old EOF position and the new position are not defined.

If you called CreateFileMapping to create a file-mapping object for hFile, you must first call UnmapViewOfFile to unmap all views and call CloseHandle to close the file-mapping object before you can call SetEndOfFile.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, CloseHandle, CreateFile, CreateFileMapping, UnmapViewOfFile


SetFileApisToANSI

The SetFileApisToANSI function causes a set of Win32 file functions to use the ANSI character set code page. This function is useful for 8-bit console input and output operations.

VOID SetFileApisToANSI(VOID)

Parameters

This function has no parameters.

Return Values

This function has no return value.

Remarks

The Win32 file functions whose code page is set by SetFileApisToANSI are those functions exported by KERNEL32.DLL which accept or return a file name.

The SetFileApisToANSI function complements the SetFileApisToOEM function, which causes the same set of Win32 file functions to use the OEM character set code page.

The 8-bit console functions use the OEM code page by default. All other functions use the ANSI code page by default. This means that strings returned by the console functions may not be processed correctly by other functions, and vice versa. For example, if the FindFirstFileA function returns a string that contains certain extended ANSI characters, and the 8-bit console functions are set to use the OEM code page, then the WriteConsoleA function will not display the string properly.

Use the AreFileApisANSI function to determine which code page the set of file functions is currently using. Use the SetConsoleCP and SetConsoleOutputCP functions to set the code page for the 8-bit console functions.

To solve the problem of code page incompatibility, it is best to use Unicode for console applications. Console applications that use Unicode are much more versatile than those that use 8-bit console functions. Barring that solution, a console application can call the SetFileApisToOEM function to cause the set of Win32 file functions to use OEM character set strings rather than ANSI character set strings. Use the SetFileApisToANSI function to set those functions back to the ANSI code page.

When dealing with command lines, a console application should obtain the command line in Unicode form, and then convert it to OEM form using the relevant character-to-OEM functions. Note also that the argv function uses the ANSI character set.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, AreFileApisANSI, FindFirstFileA, SetFileApisToOEM, SetConsoleCP, SetConsoleOutputCP, WriteConsoleA


SetFileApisToOEM

The SetFileApisToOEM function causes a set of Win32 file functions to use the OEM character set code page. This function is useful for 8-bit console input and output operations.

VOID SetFileApisToOEM(VOID)

Parameters

This function has no parameters.

Return Values

This function has no return value.

Remarks

The Win32 file functions whose code page is set by SetFileApisToOEM are those functions exported by KERNEL32.DLL which accept or return a file name.

The SetFileApisToOEM function is complemented by the SetFileApisToANSI function, which causes the same set of Win32 file functions to use the ANSI character set code page.

The 8-bit console functions use the OEM code page by default. All other functions use the ANSI code page by default. This means that strings returned by the console functions may not be processed correctly by other functions, and vice versa. For example, if the FindFirstFileA function returns a string that contains certain extended ANSI characters, and the 8-bit console functions are set to use the OEM code page, then the WriteConsoleA function will not display the string properly.

Use the AreFileApisANSI function to determine which code page the set of file functions is currently using. Use the SetConsoleCP and SetConsoleOutputCP functions to set the code page for the 8-bit console functions.

To solve the problem of code page incompatibility, it is best to use Unicode for console applications. Console applications that use Unicode are much more versatile than those that use 8-bit console functions. Barring that solution, a console application can call the SetFileApisToOEM function to cause the set of Win32 file functions to use OEM character set strings rather than ANSI character set strings. Use the SetFileApisToANSI function to set those functions back to the ANSI code page.

When dealing with command lines, a console application should obtain the command line in Unicode form, and then convert it to OEM form using the relevant character-to-OEM functions. Note also that the argv function uses the ANSI character set.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, AreFileApisANSI, FindFirstFileA, SetConsoleCP, SetConsoleCP, SetConsoleOutputCP, SetFileApisToANSI, WriteConsoleA


SetFileAttributes

The SetFileAttributes function sets a file's attributes.

BOOL SetFileAttributes(
  LPCTSTR lpFileName,  // pointer to filename
  DWORD dwFileAttributes   // attributes to set
);

Parameters

lpFileName
Pointer to a string that specifies the name of the file whose attributes are to be set.

Windows 95: This string must not exceed MAX_PATH characters.

Windows NT: There is a default string size limit for paths of MAX_PATH characters. This limit is related to how the SetFileAttributes function parses paths. An application can transcend this limit and send in paths longer than MAX_PATH characters by calling the wide (W) version of SetFileAttributes and prepending "\\?\" to the path. However, each component in the path cannot be more than MAX_PATH characters long. The "\\?\" tells the function to turn off path parsing; it lets paths longer than MAX_PATH be used with SetFileAttributesW. However, each component in the path cannot be more than MAX_PATH characters long. This also works with UNC names. The "\\?\" is ignored as part of the path. For example, "\\?\C:\myworld\private" is seen as "C:\myworld\private", and "\\?\UNC\wow\hotstuff\coolapps" is seen as "\\wow\hotstuff\coolapps".

dwFileAttributes
Specifies the file attributes to set for the file. This parameter can be a combination of the following values. However, all other values override FILE_ATTRIBUTE_NORMAL.
Attribute | Meaning
FILE_ATTRIBUTE_ARCHIVE | The file is an archive file. Applications use this attribute to mark files for backup or removal.
FILE_ATTRIBUTE_HIDDEN | The file is hidden. It is not included in an ordinary directory listing.
FILE_ATTRIBUTE_NORMAL | The file has no other attributes set. This attribute is valid only if used alone.
FILE_ATTRIBUTE_OFFLINE | The data of the file is not immediately available. Indicates that the file data has been physically moved to offline storage.
FILE_ATTRIBUTE_READONLY | The file is read-only. Applications can read the file but cannot write to it or delete it.
FILE_ATTRIBUTE_SYSTEM | The file is part of the operating system or is used exclusively by it.
FILE_ATTRIBUTE_TEMPORARY | The file is being used for temporary storage. File systems attempt to keep all of the data in memory for quicker access rather than flushing the data back to mass storage. A temporary file should be deleted by the application as soon as it is no longer needed.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The following table describes how to set the attributes that cannot be set using SetFileAttributes..

Attribute | How to Set
FILE_ATTRIBUTE_COMPRESSED | To set a file's compression state, use the DeviceIoControl function with the FSCTL_SET_COMPRESSION operation.
FILE_ATTRIBUTE_DIRECTORY | Files cannot be converted into directories. To create a directory, use the CreateDirectory or CreateDirectoryEx function.
FILE_ATTRIBUTE_ENCRYPTED | To encrypt a file, use the EncryptFile function.
FILE_ATTRIBUTE_REPARSE_POINT | To associate a reparse point with a file, use the DeviceIoControl function with the FSCTL_SET_REPARSE_POINT operation.
FILE_ATTRIBUTE_SPARSE_FILE | To set a file's sparse attribute, use the DeviceIoControl function with the FSCTL_SET_SPARSE operation.
FILE_ATTRIBUTE_SYSTEM | This attribute cannot be set.

Windows CE: If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, GetFileAttributes


SetFilePointer

The SetFilePointer function moves the file pointer of an open file.

DWORD SetFilePointer(
  HANDLE hFile,          // handle of file
  LONG lDistanceToMove,  // number of bytes to move file pointer
  PLONG lpDistanceToMoveHigh,
                         // pointer to high-order DWORD of
                         // distance to move
  DWORD dwMoveMethod     // how to move
);

Parameters

hFile
Handle to the file whose file pointer is to be moved. The file handle must have been created with GENERIC_READ or GENERIC_WRITE access to the file.
lDistanceToMove
Low-order 32 bits of a signed value that specifies the number of bytes to move the file pointer. If lpDistanceToMoveHigh is not NULL, lpDistanceToMoveHigh and lDistanceToMove form a single 64-bit signed value that specifies the distance to move. If lpDistanceToMoveHigh is NULL, lDistanceToMove is a 32-bit signed value. A positive value for lDistanceToMove moves the file pointer forward in the file, and a negative value moves the file pointer backward.
lpDistanceToMoveHigh
Pointer to the high-order 32 bits of the signed 64-bit distance to move. If you do not need the high-order 32 bits, this pointer may be NULL. When non-NULL, this parameter also receives the high-order DWORD of the new value of the file pointer. For more information, see the Remarks section later in this topic.
dwMoveMethod
Starting point for the file pointer move. This parameter can be one of the following values.
Value | Meaning
FILE_BEGIN | The starting point is zero or the beginning of the file.
FILE_CURRENT | The starting point is the current value of the file pointer.
FILE_END | The starting point is the current end-of-file position.

Return Values

If the SetFilePointer function succeeds and lpDistanceToMoveHigh is NULL, the return value is the low-order DWORD of the new file pointer. If lpDistanceToMoveHigh is not NULL, the function returns the low order DWORD of the new file pointer, and puts the high-order DWORD of the new file pointer into the LONG pointed to by that parameter.

If the function fails and lpDistanceToMoveHigh is NULL, the return value is 0xFFFFFFFF. To get extended error information, call GetLastError.

If the function fails, and lpDistanceToMoveHigh is non-NULL, the return value is 0xFFFFFFFF. However, because 0xFFFFFFFF is a valid value for the low-order DWORD of the new file pointer, you must check GetLastError to determine whether an error occurred. If an error occurred, GetLastError returns a value other than NO_ERROR. For a code example that illustrates this point, see the Remarks section later in this topic.

If the new file pointer would have been a negative value, the function fails, the file pointer is not moved, and the code returned by GetLastError is ERROR_NEGATIVE_SEEK.

Remarks

You cannot use the SetFilePointer function with a handle to a nonseeking device, such as a pipe or a communications device. To determine the file type for hFile, use the GetFileType function.

To determine the present position of a file pointer, see Retrieving a File Pointer.

You should be careful when setting the file pointer in a multithreaded application. For example, an application whose threads share a file handle, update the file pointer, and read from the file must protect this sequence by using a critical section object or mutex object. For more information about these objects, see Critical Section Objects and Mutex Objects.

If the hFile file handle was opened with the FILE_FLAG_NO_BUFFERING flag set, an application can move the file pointer only to sector-aligned positions. A sector-aligned position is a position that is a whole number multiple of the volume's sector size. An application can obtain a volume's sector size by calling the GetDiskFreeSpace function. If an application calls SetFilePointer with distance-to-move values that result in a position that is not sector-aligned and a handle that was opened with FILE_FLAG_NO_BUFFERING, the function fails, and GetLastError returns ERROR_INVALID_PARAMETER.

Note that it is not an error to set the file pointer to a position beyond the end of the file. The size of the file does not increase until you call the SetEndOfFile, WriteFile, or WriteFileEx function. A write operation increases the size of the file to the file pointer position plus the size of the buffer written, leaving the intervening bytes uninitialized.

If the return value is 0xFFFFFFFF and if lpDistanceToMoveHigh is non-NULL, an application must call GetLastError to determine whether the function has succeeded or failed. The following sample code illustrates this point:

//
// Case One: calling the function with lpDistanceToMoveHigh == NULL

// Try to move hFile's file pointer some distance
dwPtr = SetFilePointer (hFile, lDistance, NULL, FILE_BEGIN) ;

if (dwPtr == 0xFFFFFFFF) // Test for failure
{
    // Obtain the error code
    dwError = GetLastError() ;

    // Deal with failure
    // . . .

} // End of error handler

//
// Case Two: calling the function with lpDistanceToMoveHigh != NULL

// Try to move hFile's file pointer some huge distance
dwPtrLow = SetFilePointer (hFile, lDistLow, & lDistHigh, FILE_BEGIN) ;

// Test for failure
if (dwPtrLow == 0xFFFFFFFF && (dwError = GetLastError()) != NO_ERROR )
{
    // Deal with failure
    // . . .

} // End of error handler

The parameter lpDistanceToMoveHigh is used to manipulate huge files. If it is set to NULL, then lDistanceToMove has a maximum value of 2^31–2, or 2 gigabytes less two. This is because all file pointer values are signed values. Therefore if there is even a small change that the file will grow to that size, you should treat the file as a huge file and work with 64-bit file pointers. With file compression on NTFS, and sparse files, it is possible to have files that large even if the underlying volume is not that large.

If lpDistanceToMoveHigh is not NULL, then lpDistanceToMoveHigh and lDistanceToMove form a single 64-bit signed value. The lDistanceToMove parameter is treated as the low-order 32 bits of the value, and lpDistanceToMoveHigh as the upper 32 bits. Thus, lpDistanceToMoveHigh is a sign extension of lDistanceToMove.

To move the file pointer from zero to 2 gigabytes, lpDistanceToMoveHigh can be either NULL or a sign extension of lDistanceToMove. To move the pointer more than 2 gigabytes, use lpDistanceToMoveHigh and lDistanceToMove as a single 64-bit quantity. For example, to move in the range from 2 gigabytes to 4 gigabytes set the contents of lpDistanceToMoveHigh to zero, or to –1 for a negative sign extension of lDistanceToMove.

To work with 64-bit file pointers, you can declare a LONG, treat it as the upper half of the 64-bit file pointer, and pass its address in lpDistanceToMoveHigh. This means you have to treat two different variables as a logical unit, which is error-prone. The problems can be ameliorated by using the LARGE_INTEGER structure to create a 64-bit value and passing the two 32-bit values by means of the appropriate elements of the union.

It is conceptually simpler and better design to use a function to hide the interface to SetFilePointer. To do so, use something like this:

__int64 myFileSeek (HANDLE hf, __int64 distance, DWORD MoveMethod)
{
   LARGE_INTEGER li;

   li.QuadPart = distance;

   li.LowPart = SetFilePointer (hf, li.LowPart, &li.HighPart, MoveMethod);

   if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR)
   {
      li.QuadPart = -1;
   }

   return li.QuadPart;
}

Note You can use SetFilePointer to determine the length of a file. To do this, use FILE_END for dwMoveMethod and seek to location zero. The file offset returned is the length of the file. However, this practice can have unintended side effects, such as failure to save the current file pointer so that the program can return to that location. It is simpler and safer to use GetFileSize instead.

You can also use the SetFilePointer function to query the current file pointer position. To do this, specify a move method of FILE_CURRENT and a distance of zero.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, GetDiskFreeSpace, GetFileSize, GetFileType, ReadFile, ReadFileEx, ReadFileVlm, WriteFile, WriteFileEx, WriteFileVlm


SetHandleCount

The SetHandleCount function sets the number of file handles available to a process.

Windows NT, Windows 95, Windows 98: This function has no effect, because there is no explicit file handle limit for applications on these platforms.

Win32s: There are only 20 file handles available to a process by default; however you could use SetHandleCount to allow a process to use up to 255 file handles.

UINT SetHandleCount(
  UINT uNumber   // number of file handles needed
);

Parameters

uNumber
Specifies the number of file handles needed by the application.

Return Values

Windows NT, Windows 95, Windows 98: This function simply returns the value specified in the uNumber parameter.

Win32s: The return value specifies the number of file handles actually available to the application. It may be fewer than the number specified by the uNumber parameter.

Remarks

Windows NT, Windows 95, Windows 98: The maximum number of files that an application can open is determined by the amount of available non-paged memory pool, because each open file handle requires non-paged memory.

See Also

File I/O Overview, File Functions


SetVolumeLabel

The SetVolumeLabel function sets the label of a file system volume.

BOOL SetVolumeLabel(
  LPCTSTR lpRootPathName,  // pointer to name of root directory for
                           // volume
  LPCTSTR lpVolumeName   // name for the volume
);

Parameters

lpRootPathName
Pointer to a null-terminated string specifying the root directory of a file system volume. This is the volume the function will label. If this parameter is NULL, the root of the current directory is used.
lpVolumeName
Pointer to a string specifying a name for the volume. If this parameter is NULL, the function deletes the name of the specified volume.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File I/O Overview, File Functions, GetVolumeInformation


UnlockFile

The UnlockFile function unlocks a region in an open file. Unlocking a region enables other processes to access the region.

BOOL UnlockFile(
  HANDLE hFile,           // handle of file to unlock
  DWORD dwFileOffsetLow,  // low-order word of lock region offset
  DWORD dwFileOffsetHigh,  // high-order word of lock region offset
  DWORD nNumberOfBytesToUnlockLow,
                          // low-order word of length to unlock
  DWORD nNumberOfBytesToUnlockHigh
                          // high-order word of length to unlock
);

Parameters

hFile
Handle to a file that contains a region locked with LockFile. The file handle must have been created with either GENERIC_READ or GENERIC_WRITE access to the file.
dwFileOffsetLow
Specifies the low-order word of the starting byte offset in the file where the locked region begins.
dwFileOffsetHigh
Specifies the high-order word of the starting byte offset in the file where the locked region begins.
nNumberOfBytesToUnlockLow
Specifies the low-order word of the length of the byte range to be unlocked.
nNumberOfBytesToUnlockHigh
Specifies the high-order word of the length of the byte range to be unlocked.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Unlocking a region of a file releases a lock on the file. The region to unlock must correspond exactly to an existing locked region. For example, two adjacent regions of a file cannot be locked separately and then unlocked as a single region that spans both locked regions.

A process should not be terminated with a portion of a file locked and a file that has locked regions should not be closed.

This function works on a file allocation table (FAT) – based file system only if the operating system is running SHARE.EXE.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, CreateFile, LockFile


UnlockFileEx

The UnlockFileEx function unlocks a previously locked byte range in an open file.

BOOL UnlockFileEx(
  HANDLE hFile,      // handle of file to unlock
  DWORD dwReserved,  // reserved, must be set to zero
  DWORD nNumberOfBytesToUnlockLow,
                     // low order 32-bits of length to unlock
  DWORD nNumberOfBytesToUnlockHigh,
                     // high order 32-bits of length to unlock
  LPOVERLAPPED lpOverlapped
                     // addr. of struct. with unlock region start
                     // offset
);

Parameters

hFile
Handle to a file that is to have an existing locked region unlocked. The handle must have been created with either GENERIC_READ or GENERIC_WRITE access to the file.
dwReserved
Reserved parameter; must be zero.
nNumberOfBytesToUnlockLow
Specifies the low-order 32-bits of the length of the byte range to unlock.
nNumberOfBytesToUnlockHigh
Specifies the high-order 32-bits of the length of the byte range to unlock.
lpOverlapped
Pointer to an OVERLAPPED structure that the function uses with the unlocking request. This structure contains the file offset of the beginning of the unlock range.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero or NULL. To get extended error information, call GetLastError.

Remarks

Unlocking a region of a file releases a previously acquired lock on a file. The region to unlock must correspond exactly to an existing locked region. Two adjacent regions of a file can not be locked separately and then unlocked using a single region that spans both locked regions.

If a process terminates with a portion of a file locked or closes a file that has outstanding locks, the behavior is not specified.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, CreateFile, LockFile, LockFileEx, OVERLAPPED, UnlockFile


WriteFile

The WriteFile function writes data to a file and is designed for both synchronous and asynchronous operation. The function starts writing data to the file at the position indicated by the file pointer. After the write operation has been completed, the file pointer is adjusted by the number of bytes actually written, except when the file is opened with FILE_FLAG_OVERLAPPED. If the file handle was created for overlapped input and output (I/O), the application must adjust the position of the file pointer after the write operation is finished.

BOOL WriteFile(
  HANDLE hFile,                    // handle to file to write to
  LPCVOID lpBuffer,                // pointer to data to write to file
  DWORD nNumberOfBytesToWrite,     // number of bytes to write
  LPDWORD lpNumberOfBytesWritten,  // pointer to number of bytes written
  LPOVERLAPPED lpOverlapped        // pointer to structure for overlapped I/O
);

Parameters

hFile
Handle to the file to be written to. The file handle must have been created with GENERIC_WRITE access to the file.
Windows NT:
For asynchronous write operations, hFile can be any handle opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile function, or a socket handle returned by the socket or accept functions.
Windows 95:
For asynchronous write operations, hFile can be a communications resource, mailslot, or named pipe handle opened with the FILE_FLAG_OVERLAPPED flag by CreateFile, or a socket handle returned by the socket or accept functions. Windows 95 does not support asynchronous write operations on disk files.
lpBuffer
Pointer to the buffer containing the data to be written to the file.
nNumberOfBytesToWrite
Number of bytes to write to the file.

A value of zero specifies a null write operation. A null write operation does not write any bytes but does cause the time stamp to change.

Named pipe write operations across a network are limited to 65,535 bytes.

lpNumberOfBytesWritten
Pointer to the number of bytes written by this function call. WriteFile sets this value to zero before doing any work or error checking.

Windows NT: If lpOverlapped is NULL, lpNumberOfBytesWritten cannot be NULL.

Windows NT: If lpOverlapped is not NULL, lpNumberOfBytesWritten can be NULL. If this is an overlapped write operation, you can get the number of bytes written by calling GetOverlappedResult. If hFile is associated with an I/O completion port, you can get the number of bytes written by calling GetQueuedCompletionStatus.

Windows 95 and Windows 98: This parameter cannot be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure. This structure is required if hFile was opened with FILE_FLAG_OVERLAPPED.

If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the write operation is complete.

If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the write operation starts at the offset specified in the OVERLAPPED structure and WriteFile may return before the write operation has been completed. In this case, WriteFile returns FALSE and the GetLastError function returns ERROR_IO_PENDING. This allows the calling process to continue processing while the write operation is being completed. The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the write operation.

If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the write operation starts at the current file position and WriteFile does not return until the operation has been completed.

If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the write operation starts at the offset specified in the OVERLAPPED structure and WriteFile does not return until the write operation has been completed.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

An application must meet certain requirements when working with files opened with FILE_FLAG_NO_BUFFERING:

  • File access must begin at byte offsets within the file that are integer multiples of the volume's sector size. To determine a volume's sector size, call the GetDiskFreeSpace function.
  • File access must be for numbers of bytes that are integer multiples of the volume's sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes.
  • Buffer addresses for read and write operations must be sector aligned (aligned on addresses in memory that are integer multiples of the volume's sector size). One way to sector align buffers is to use the VirtualAlloc function to allocate the buffers. This function allocates memory that is aligned on addresses that are integer multiples of the system's page size. Because both page and volume sector sizes are powers of 2, memory aligned by multiples of the system's page size is also aligned by multiples of the volume's sector size.

If part of the file is locked by another process and the write operation overlaps the locked portion, this function fails.

Accessing the output buffer while a write operation is using the buffer may lead to corruption of the data written from that buffer. Applications must not read from, write to, reallocate, or free the output buffer that a write operation is using until the write operation completes.

Characters can be written to the screen buffer using WriteFile with a handle to console output. The exact behavior of the function is determined by the console mode. The data is written to the current cursor position. The cursor position is updated after the write operation.

The system interprets zero bytes to write as specifying a null write operation and WriteFile does not truncate or extend the file. To truncate or extend a file, use the SetEndOfFile function.

When writing to a nonblocking, byte-mode pipe handle with insufficient buffer space, WriteFile returns TRUE with *lpNumberOfBytesWritten < nNumberOfBytesToWrite.

When an application uses the WriteFile function to write to a pipe, the write operation may not finish if the pipe buffer is full. The write operation is completed when a read operation (using the ReadFile function) makes more buffer space available.

If the anonymous read pipe handle has been closed and WriteFile attempts to write using the corresponding anonymous write pipe handle, the function returns FALSE and GetLastError returns ERROR_BROKEN_PIPE.

The WriteFile function may fail with ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding asynchronous I/O requests.

To cancel all pending asynchronous I/O operations, use the CancelIo function. This function only cancels operations issued by the calling thread for the specified file handle. I/O operations that are canceled complete with the error ERROR_OPERATION_ABORTED.

If you are attempting to write to a floppy drive that does not have a floppy disk, the system displays a message box prompting the user to retry the operation. To prevent the system from displaying this message box, call the SetErrorMode function with SEM_NOOPENFILEERRORBOX.

Windows CE: Windows CE does not support asynchronous write operations. The lpOverlapped parameter is ignored and should be set to NULL before calling WriteFile.

Unlike the MS-DOS operating system, Windows CE interprets zero bytes to write as specifying a null write operation and WriteFile does not truncate or extend the file. To truncate or extend a file, use the SetEndOfFile function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, CancelIo, CreateFile, GetLastError, GetOverlappedResult, GetQueuedCompletionStatus, OVERLAPPED, ReadFile, SetEndOfFile, SetErrorMode, WriteFileEx


WriteFileEx

The WriteFileEx function writes data to a file. It is designed solely for asynchronous operation, unlike WriteFile, which is designed for both synchronous and asynchronous operation.

WriteFileEx reports its completion status asynchronously, calling a specified completion routine when writing is completed or canceled and the calling thread is in an alertable wait state.

BOOL WriteFileEx(
  HANDLE hFile,                 // handle to output file
  LPCVOID lpBuffer,             // pointer to input buffer
  DWORD nNumberOfBytesToWrite,  // number of bytes to write
  LPOVERLAPPED lpOverlapped,    // pointer to async. i/o data
  LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
                                // pointer to completion routine
);

Parameters

hFile
Open handle that specifies the file entity to be written to. This file handle must have been created with the FILE_FLAG_OVERLAPPED flag and with GENERIC_WRITE access to the file.

Windows NT: hFile can be any handle opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile function, or a socket handle returned by the socket or accept functions.

Windows 95: hFile can be a communications resource, mailslot, or named pipe handle opened with the FILE_FLAG_OVERLAPPED flag by CreateFile, or a socket handle returned by the socket or accept functions. Windows 95 does not support asynchronous operations on disk files.

lpBuffer
Pointer to the buffer containing the data to be written to the file.

This buffer must remain valid for the duration of the write operation. The caller must not use this buffer until the write operation is completed.

nNumberOfBytesToWrite
Number of bytes to write to the file.

If nNumberOfBtyesToWrite is zero, this function does nothing; in particular, it does not truncate the file. For additional discussion, see the following Remarks section.

lpOverlapped
Pointer to an OVERLAPPED data structure that supplies data to be used during the overlapped (asynchronous) write operation.

For files that support byte offsets, you must specify a byte offset at which to start writing to the file. You specify this offset by setting the Offset and OffsetHigh members of the OVERLAPPED structure. For files that do not support byte offsets, Offset and OffsetHigh are ignored.

The WriteFileEx function ignores the OVERLAPPED structure's hEvent member. An application is free to use that member for its own purposes in the context of a WriteFileEx call. WriteFileEx signals completion of its writing operation by calling, or queuing a call to, the completion routine pointed to by lpCompletionRoutine, so it does not need an event handle.

The WriteFileEx function does use the Internal and InternalHigh members of the OVERLAPPED structure. You should not change the value of these members.

The OVERLAPPED data structure must remain valid for the duration of the write operation. It should not be a variable that can go out of scope while the write operation is pending completion.

lpCompletionRoutine
Pointer to a completion routine to be called when the write operation has been completed and the calling thread is in an alertable wait state. For more information about this completion routine, see FileIOCompletionRoutine.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

If the WriteFileEx function succeeds, the calling thread has an asynchronous I/O (input/output) operation pending: the overlapped write operation to the file. When this I/O operation finishes, and the calling thread is blocked in an alertable wait state, the operating system calls the function pointed to by lpCompletionRoutine, and the wait completes with a return code of WAIT_IO_COMPLETION.

If the function succeeds and the file-writing operation finishes, but the calling thread is not in an alertable wait state, the system queues the call to *lpCompletionRoutine, holding the call until the calling thread enters an alertable wait state. See Synchronization for more information about alertable wait states and overlapped input/output operations.

Remarks

An application must meet certain requirements when working with files opened with FILE_FLAG_NO_BUFFERING:

  • File access must begin at byte offsets within the file that are integer multiples of the volume's sector size. To determine a volume's sector size, call the GetDiskFreeSpace function.
  • File access must be for numbers of bytes that are integer multiples of the volume's sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes.
  • Buffer addresses for read and write operations must be sector aligned (aligned on addresses in memory that are integer multiples of the volume's sector size). One way to sector align buffers is to use the VirtualAlloc function to allocate the buffers. This function allocates memory that is aligned on addresses that are integer multiples of the system's page size. Because both page and volume sector sizes are powers of 2, memory aligned by multiples of the system's page size is also aligned by multiples of the volume's sector size.

If part of the output file is locked by another process, and the specified write operation overlaps the locked portion, the WriteFileEx function fails.

Accessing the output buffer while a write operation is using the buffer may lead to corruption of the data written from that buffer. Applications must not read from, write to, reallocate, or free the output buffer that a write operation is using until the write operation completes.

The WriteFileEx function may fail, returning the messages ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY if there are too many outstanding asynchronous I/O requests.

To cancel all pending asynchronous I/O operations, use the CancelIo function. This function only cancels operations issued by the calling thread for the specified file handle. I/O operations that are canceled complete with the error ERROR_OPERATION_ABORTED.

If you are attempting to write to a floppy drive that does not have a floppy disk, the system displays a message box prompting the user to retry the operation. To prevent the system from displaying this message box, call the SetErrorMode function with SEM_NOOPENFILEERRORBOX.

An application uses the WaitForSingleObjectEx, WaitForMultipleObjectsEx, MsgWaitForMultipleObjectsEx, SignalObjectAndWait, and SleepEx functions to enter an alertable wait state. Refer to Synchronization for more information about alertable wait states and overlapped input/output operations.

Windows 95: On this platform, neither WriteFileEx nor ReadFileEx can be used by the comm ports to communicate. However, you can use WriteFile and ReadFile to perform asynchronous communication.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, CancelIo, CreateFile, FileIOCompletionRoutine, MsgWaitForMultipleObjectsEx, OVERLAPPED, ReadFileEx, SetEndOfFile, SetErrorMode, SleepEx, SignalObjectAndWait, WaitForMultipleObjectsEx, WaitForSingleObjectEx, WriteFile, WriteFileVlm


WriteFileGather

The WriteFileGather function gathers data from a set of buffers and writes the data to a file.

The WriteFileGather function starts writing data to the file at a position specified by an OVERLAPPED structure.

The WriteFileGather function operates asynchronously.

BOOL WriteFileGather(
  HANDLE hFile,              // handle to a file to write data to
  FILE_SEGMENT_ELEMENT aSegmentArray [],
                             // pointer to an array of buffer
                             // pointers
  DWORD nNumberOfBytesToWrite,  // number of bytes to write
  LPDWORD lpReserved,        // reserved; must be NULL
  LPOVERLAPPED lpOverlapped  // pointer to an asynchronous I/O data
                             // structure
);

Parameters

hFile
An open handle to the file to write to.

This file handle must have been created using GENERIC_WRITE to specify write access to the file, FILE_FLAG_OVERLAPPED to specify asynchronous I/O, and FILE_FLAG_NO_BUFFERING to specify non-cached I/O.

aSegmentArray
Pointer to an array of FILE_SEGMENT_ELEMENT pointers to buffers. The function gathers the data it writes to the file from this set of buffers.

Each buffer should be the size of a system memory page. Each buffer should be aligned on a system memory page size boundary.

A FILE_SEGMENT_ELEMENT pointer is a 64-bit value. The WriteFileGather function uses all 64 bits. Since the operating systems do not currently support 64-bit memory addressing, you must explicitly zero the upper 32 bits of each FILE_SEGMENT_ELEMENT pointer.

The function gathers the data from the buffers in a sequential manner: it writes data to the file from the first buffer, then from the second buffer, then from the next, until there is no more data to write.

The final element of the array should be a NULL pointer.

nNumberOfBytesToWrite
Specifies the number of bytes to write to the file.

If nNumberOfBytesToWrite is zero, the function performs a null write operation. A null write operation does not write any bytes to the file, but it does cause the file's time stamp to change.

Note that this behavior differs from file writing functions on the MS-DOS platform, where a write count of zero bytes truncates a file. WriteFileGather does not truncate or extend the file. To truncate or extend a file on Windows NT, use the SetEndOfFile function..

lpReserved
This parameter is reserved for future use. You must set it to NULL.
lpOverlapped
Pointer to an OVERLAPPED data structure.

The WriteFileGather function requires a valid OVERLAPPED structure. The lpOverlapped parameter cannot be NULL.

The WriteFileGather function starts writing data to the file at a position specified by the Offset and OffsetHigh members of the OVERLAPPED structure.

The WriteFileGather function may return before the write operation has completed. In that case, the WriteFileGather function returns the value zero, and the GetLastError function returns the value ERROR_IO_PENDING. This asynchronous operation of WriteFileGather lets the calling process continue while the write operation completes. You can call the GetOverlappedResult, HasOverlappedIoCompleted, or GetQueuedCompletionStatus function to obtain information about the completion of the write operation.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call the GetLastError function.

If the function returns before the write operation has completed, the function returns zero, and GetLastError returns ERROR_IO_PENDING.

Remarks

If part of the file specified by hFile is locked by another process, and the write operation overlaps the locked portion, the WriteFileGather function fails.

QuickInfo

Windows NT: Requires version 4.0 SP2 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File I/O Overview, File Functions, CreateFile, GetOverlappedResult, GetQueuedCompletionStatus, HasOverlappedIoCompleted, OVERLAPPED, ReadFile, ReadFileEx, ReadFileScatter, ReadFileVlm


File Structures

The following structures are used with files.

BY_HANDLE_FILE_INFORMATION
FILE_NOTIFY_INFORMATION
OFSTRUCT
WIN32_FILE_ATTRIBUTE_DATA
WIN32_FIND_DATA


BY_HANDLE_FILE_INFORMATION

The BY_HANDLE_FILE_INFORMATION structure contains information retrieved by the GetFileInformationByHandle function.

typedef struct _BY_HANDLE_FILE_INFORMATION { // bhfi
    DWORD    dwFileAttributes;
    FILETIME ftCreationTime;
    FILETIME ftLastAccessTime;
    FILETIME ftLastWriteTime;
    DWORD    dwVolumeSerialNumber;
    DWORD    nFileSizeHigh;
    DWORD    nFileSizeLow;
    DWORD    nNumberOfLinks;
    DWORD    nFileIndexHigh;
    DWORD    nFileIndexLow;
} BY_HANDLE_FILE_INFORMATION;

Members

dwFileAttributes
Specifies file attributes. This member can be one or more of the following values:
Attribute Meaning
FILE_ATTRIBUTE_ARCHIVE
The file or directory is an archive file. Applications use this attribute to mark files for backup or removal.
FILE_ATTRIBUTE_COMPRESSED
The file or directory is compressed. For a file, this means that all of the data in the file is compressed. For a directory, this means that compression is the default for newly created files and subdirectories.
FILE_ATTRIBUTE_ENCRYPTED
The file or directory is encrypted. For a file, this means that all of the data streams are encrypted. For a directory, this means that encryption is the default for newly created files and directories.
FILE_ATTRIBUTE_DIRECTORY
The handle identifies a directory.
FILE_ATTRIBUTE_HIDDEN
The file or directory is hidden. It is not included in an ordinary directory listing.
FILE_ATTRIBUTE_NORMAL
The file has no other attributes. This attribute is valid only if used alone.
FILE_ATTRIBUTE_OFFLINE
The file data is not immediately available. Indicates that the file data has been physically moved to offline storage.
FILE_ATTRIBUTE_READONLY
The file or directory is read-only. Applications can read the file but cannot write to it or delete it. In the case of a directory, applications cannot delete it.
FILE_ATTRIBUTE_REPARSE_POINT
The file has an associated reparse point.
FILE_ATTRIBUTE_SPARSE_FILE
The file is a sparse file.
FILE_ATTRIBUTE_SYSTEM
The file or directory is part of the operating system or is used exclusively by the operating system.
FILE_ATTRIBUTE_TEMPORARY
The file is being used for temporary storage. File systems attempt to keep all the data in memory for quicker access, rather than flushing the data back to mass storage. A temporary file should be deleted by the application as soon as it is no longer needed.

ftCreationTime
Specifies the time the file was created. If the underlying file system does not support this time member, ftCreationTime is zero.
ftLastAccessTime
Specifies the time the file was last accessed. If the underlying file system does not support this time member, ftLastAccessTime is zero.
ftLastWriteTime
Specifies the last time the file was written to.
dwVolumeSerialNumber
Specifies the serial number of the volume that contains the file.
nFileSizeHigh
Specifies the high-order word of the file size.
nFileSizeLow
Specifies the low-order word of the file size.
nNumberOfLinks
Specifies the number of links to this file. For the FAT file system this member is always 1. For NTFS, it may be more than 1.
nFileIndexHigh
Specifies the high-order word of a unique identifier associated with the file.
nFileIndexLow
Specifies the low-order word of a unique identifier associated with the file. This identifier and the volume serial number uniquely identify a file. This number may change when the system is restarted or when the file is opened. After a process opens a file, the identifier is constant until the file is closed. An application can use this identifier and the volume serial number to determine whether two handles refer to the same file.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.

See Also

File I/O Overview, File Structures, GetFileInformationByHandle


FILE_NOTIFY_INFORMATION

The FIND_NOTIFY_INFORMATION structure describes the changes found by the ReadDirectoryChangesW function.

typedef struct _FILE_NOTIFY_INFORMATION {
   DWORD NextEntryOffset;
   DWORD Action;
   DWORD FileNameLength;
   WCHAR FileName[1];
} FILE_NOTIFY_INFORMATION;

Members

NextEntryOffset
Specifies the number of bytes that must be skipped to get to the next record. A value of zero indicates that this is the last record.
Action
Specifies the type of change that occurred.
Value | Meaning
FILE_ACTION_ADDED | The file was added to the directory.
FILE_ACTION_REMOVED | The file was removed from the directory.
FILE_ACTION_MODIFIED | The file was modified. This can be a change in the time stamp or attributes.
FILE_ACTION_RENAMED_OLD_NAME | The file was renamed and this is the old name.
FILE_ACTION_RENAMED_NEW_NAME | The file was renamed and this is the new name.

FileNameLength
Specifies the length, in bytes, of the filename portion of the record. Note that this length does not include the terminating null character.
FileName
This is a variable-length field that contains the filename relative to the directory handle. The filename is in the Unicode character format and is not null-terminated.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

File I/O Overview, File Structures, ReadDirectoryChangesW


OFSTRUCT

The OFSTRUCT structure contains information about a file that the OpenFile function opened or attempted to open.

typedef struct _OFSTRUCT { // of
    BYTE cBytes;
    BYTE fFixedDisk;
    WORD nErrCode;
    WORD Reserved1;
    WORD Reserved2;
    CHAR szPathName[OFS_MAXPATHNAME];
} OFSTRUCT;

Members

cBytes
Specifies the length, in bytes, of the structure.
fFixedDisk
Specifies whether the file is on a hard (fixed) disk. This member is nonzero if the file is on a hard disk.
nErrCode
Specifies the MS-DOS error code if the OpenFile function failed.
Reserved1
Reserved; do not use.
Reserved2
Reserved; do not use.
szPathName
Specifies the path and filename of the file.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

File I/O Overview, File Structures, OpenFile


WIN32_FILE_ATTRIBUTE_DATA

The WIN32_FILE_ATTRIBUTE_DATA structure contains attribute information for a file or directory. The GetFileAttributesEx function uses this structure.

typedef struct _WIN32_FILE_ATTRIBUTE_DATA{
    DWORD      dwFileAttributes;
    FILETIME   ftCreationTime;
    FILETIME   ftLastAccessTime;
    FILETIME   ftLastWriteTime;
    DWORD      nFileSizeHigh;
    DWORD      nFileSizeLow;
} WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA;

Members

dwFileAttributes
A set of bit flags that specifies FAT-style attribute information for the file or directory.

The following attribute flags are defined:
Attribute | Meaning
FILE_ATTRIBUTE_ARCHIVE | The file or directory is an archive file. Applications use this attribute to mark files for backup or removal.
FILE_ATTRIBUTE_COMPRESSED | The file or directory is compressed. For a file, this means that all of the data in the file is compressed. For a directory, this means that compression is the default for newly created files and subdirectories.
FILE_ATTRIBUTE_DIRECTORY | The handle identifies a directory.
FILE_ATTRIBUTE_ENCRYPTED | The file or directory is encrypted. For a file, this means that all of the data in the file is encrypted. For a directory, this means that encryption is the default for newly created files and subdirectories.
FILE_ATTRIBUTE_HIDDEN | The file or directory is hidden. It is not included in an ordinary directory listing.
FILE_ATTRIBUTE_NORMAL | The file or directory has no other attributes set. This attribute is valid only if used alone.
FILE_ATTRIBUTE_OFFLINE | The data of the file is not immediately available. Indicates that the file data has been physically moved to offline storage.
FILE_ATTRIBUTE_READONLY | The file or directory is read-only. Applications can read the file but cannot write to it or delete it. In the case of a directory, applications cannot delete it.
FILE_ATTRIBUTE_REPARSE_POINT | The file has an associated reparse point.
FILE_ATTRIBUTE_SPARSE_FILE | The file is a sparse file.
FILE_ATTRIBUTE_SYSTEM | The file or directory is part of the operating system or is used exclusively by the operating system.
FILE_ATTRIBUTE_TEMPORARY | The file is being used for temporary storage. File systems attempt to keep all of the data in memory for quicker access rather than flushing the data back to mass storage. A temporary file should be deleted by the application as soon as it is no longer needed..

ftCreationTime
A FILETIME structure that specifies when the file or directory was created.
ftLastAccessTime
A FILETIME structure. For a file, the structure specifies when the file was last read from or written to. For a directory, the structure specifies when the directory was created. For both files and directories, the specified date will be correct, but the time of day will always be set to midnight.
ftLastWriteTime
A FILETIME structure. For a file, the structure specifies when the file was last written to. For a directory, the structure specifies when the directory was created.
nFileSizeHigh
Specifies the high-order DWORD of the file size. This member has no meaning for directories.
nFileSizeLow
Specifies the low-order DWORD of the file size. This member has no meaning for directories.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

File I/O Overview, File Structures, GetFileAttributesEx, GET_FILEEX_INFO_LEVELS


WIN32_FIND_DATA

The WIN32_FIND_DATA structure describes a file found by the FindFirstFile, FindFirstFileEx, or FindNextFile function.

typedef struct _WIN32_FIND_DATA { // wfd
    DWORD dwFileAttributes;
    FILETIME ftCreationTime;
    FILETIME ftLastAccessTime;
    FILETIME ftLastWriteTime;
    DWORD    nFileSizeHigh;
    DWORD    nFileSizeLow;
    DWORD    dwReserved0;
    DWORD    dwReserved1;
    TCHAR    cFileName[ MAX_PATH ];
    TCHAR    cAlternateFileName[ 14 ];
} WIN32_FIND_DATA;

Members

dwFileAttributes
Specifies the file attributes of the file found. This member can be one or more of the following values:
Attribute | Meaning
FILE_ATTRIBUTE_ARCHIVE | The file or directory is an archive file or directory. Applications use this attribute to mark files for backup or removal.
FILE_ATTRIBUTE_COMPRESSED | The file or directory is compressed. For a file, this means that all of the data in the file is compressed. For a directory, this means that compression is the default for newly created files and subdirectories.
FILE_ATTRIBUTE_DIRECTORY | The handle identifies a directory.
FILE_ATTRIBUTE_ENCRYPTED | The file or directory is encrypted. For a file, this means that all data streams are encrypted. For a directory, this means that encryption is the default for newly created files and subdirectories.
FILE_ATTRIBUTE_HIDDEN | The file or directory is hidden. It is not included in an ordinary directory listing.
FILE_ATTRIBUTE_NORMAL | The file or directory has no other attributes set. This attribute is valid only if used alone.
FILE_ATTRIBUTE_OFFLINE | The file data is not immediately available. Indicates that the file data has been physically moved to offline storage.
FILE_ATTRIBUTE_READONLY | The file or directory is read-only. Applications can read the file but cannot write to it or delete it. In the case of a directory, applications cannot delete it.
FILE_ATTRIBUTE_REPARSE_POINT | The file has an associated reparse point.
FILE_ATTRIBUTE_SPARSE_FILE | The file is a sparse file.
FILE_ATTRIBUTE_SYSTEM | The file or directory is part of the operating system or is used exclusively by the operating system.
FILE_ATTRIBUTE_TEMPORARY | The file is being used for temporary storage. File systems attempt to keep all of the data in memory for quicker access, rather than flushing it back to mass storage. A temporary file should be deleted by the application as soon as it is no longer needed.

ftCreationTime
Specifies a FILETIME structure containing the time the file was created. FindFirstFile and FindNextFile report file times in Coordinated Universal Time (UTC) format. These functions set the FILETIME members to zero if the file system containing the file does not support this time member. You can use the FileTimeToLocalFileTime function to convert from UTC to local time, and then use the FileTimeToSystemTime function to convert the local time to a SYSTEMTIME structure containing individual members for the month, day, year, weekday, hour, minute, second, and millisecond.
ftLastAccessTime
Specifies a FILETIME structure containing the time that the file was last accessed. The time is in UTC format; the FILETIME members are zero if the file system does not support this time member.
ftLastWriteTime
Specifies a FILETIME structure containing the time that the file was last written to. The time is in UTC format; the FILETIME members are zero if the file system does not support this time member.
nFileSizeHigh
Specifies the high-order DWORD value of the file size, in bytes. This value is zero unless the file size is greater than MAXDWORD. The size of the file is equal to (nFileSizeHigh * MAXDWORD) + nFileSizeLow.
nFileSizeLow
Specifies the low-order DWORD value of the file size, in bytes.
dwReserved0
If the dwFileAttributes member includes the FILE_ATTRIBUTE_REPARSE_POINT attribute, this member specifies the reparse tag. Otherwise, this value is undefined and should not be used.
dwReserved1
Reserved for future use.
cFileName
A null-terminated string that is the name of the file.
cAlternateFileName
A null-terminated string that is an alternative name for the file. This name is in the classic 8.3 (filename.ext) filename format.

Remarks

If a file has a long filename, the complete name appears in the cFileName field, and the 8.3 format truncated version of the name appears in the cAlternateFileName field. Otherwise, cAlternateFileName is empty. As an alternative, you can use the GetShortPathName function to find the 8.3 format version of a filename.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

File I/O Overview, File Structures, FINDEX_INFO_LEVELS FindFirstFile, FindFirstFileEx, FindNextFile, FILETIME, FileTimeToLocalFileTime, FileTimeToSystemTime, GetShortPathName


File Enumeration Types

The following enumeration types are used with files.

FINDEX_INFO_LEVELS
FINDEX_SEARCH_OPS
GET_FILEEX_INFO_LEVELS


FINDEX_INFO_LEVELS

The FINDEX_INFO_LEVELS enumeration type defines values that are used with the FindFirstFileEx function to specify the information level of the returned data.

typedef enum _FINDEX_INFO_LEVELS {
    FindExInfoStandard
} FINDEX_INFO_LEVELS ;

Enumerator Value | Meaning
FindExInfoStandard | The FindFirstFileEx function obtains a standard set of attribute information. The data is returned in a WIN32_FIND_DATA structure.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

File I/O Overview, File Enumeration Types, FindFirstFileEx, WIN32_FIND_DATA


FINDEX_SEARCH_OPS

The FINDEX_SEARCH_OPS enumeration type defines values that are used with the FindFirstFileEx function to specify the type of filtering to perform.

typedef enum _FINDEX_INFO_LEVELS {
    FindExSearchNameMatch,
    FindExSearchLimitToDirectories,
    FindExSearchLimitToDevices,
} FINDEX_INFO_LEVELS ;
Enumerator Value | Meaning
FindExSearchNameMatch | Search for a file that matches the specified filename. Note that lpSearchFilter parameter of FindFirstFileEx must be NULL when this search operation is used.
FindExSearchLimitToDevices | Only device names are returned. Device names are generally accessible through the \\.\<name> convention. The dwAdditionalFlags parameter of FindFirstFileEx cannot be FIND_FIRST_EX_CASE_SENSITIVE when this search operation is used.
FindExSearchLimitToDirectories This is an advisory flag.

If the file system supports directory filtering, the function searches for a "file" that matches the specified filename and that is a directory.

If the file system does not support directory filtering, this flag is silently ignored.

The lpSearchFilter parameter of FindFirstFileEx must be NULL when this search operation is used.

If you want directory filtering, use this flag on all file systems, but be sure to examine the file attribute data stored into the *lpFindFileData parameter of FindFirstFileEx to determine whether the function has indeed returned a handle to a directory.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

File I/O Overview, File Enumeration Types, FindFirstFileEx


GET_FILEEX_INFO_LEVELS

The GET_FILEEX_INFO_LEVELS enumeration type defines values that are used with the GetFileAttributesEx function to specify the type of attribute information to obtain.

typedef enum _GET_FILEEX_INFO_LEVELS {
    GetFileExInfoStandard
} GET_FILEEX_INFO_LEVELS ;

Enumerator Value | Meaning
GetFileExInfoStandard | The GetFileAttributesEx function obtains a standard set of attribute information. The data is returned in a WIN32_FILE_ATTRIBUTE_DATA structure.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

File I/O Overview, File Enumeration Types, GetFileAttributesEx, WIN32_FILE_ATTRIBUTE_DATA


Tape Backup

The tape functions provided by the Microsoft® Win32® API enable backup applications to read from and write to a tape, initialize a tape, and retrieve tape or tape drive information.


About Tape Backup

A tape volume consists of a recording medium and its physical carrier. The entire length of tape in a volume is not available for recording data. Short sections at the beginning and the end of the tape are reserved for attaching the tape to the hubs in the carrier. The first position on the tape where data can be recorded is the called the beginning-of-medium marker, and the last position is called the end-of-medium marker.

Every tape volume has one or more partitions. A partition is a portion of the volume, containing its own beginning and ending points, that does not overlap with any other portion of the volume. Each partition has three predefined positions. The first position in a partition where you can record data is called the beginning-of-partition marker, and the last is called end-of-partition marker. The early-warning position is located immediately before the end-of-partition marker. The early-warning position notifies tape applications to transfer buffered data to the tape before reaching the end-of-partition marker.

The area between a partition's beginning and ending points is typically divided into sections by filemarks or setmarks. Filemarks and setmarks are special recorded elements that do not contain user data; they simply divide the partition into smaller areas to provide an address scheme. Filemarks and setmarks serve similar purposes, but setmarks provide faster positioning on high-capacity tape drives.

Typically, tape devices support filemarks and setmarks. Support of both enables tape data to be formatted such that setmarks separate data from different disk volumes and filemarks separate data from individual files on a disk volume.

Another recorded element that denotes locations on the tape is an erase gap, an area of erased tape or a pattern that the device does not recognize as a mark or as user data.

There are three types of filemarks. A short filemark contains a short erase gap that cannot be overwritten unless the write operation is performed from the beginning of the partition or from an earlier long filemark. A long filemark contains a long erase gap that enables an application to position the tape at the beginning of the filemark and to overwrite the filemark and the erase gap. A normal filemark does not contain an erase gap. Tape devices that use filemarks support either short and long filemarks or normal filemarks, but not all three.

The area on a partition between setmarks or filemarks is available for recording data. A unit of data written to or read from a tape is referred to as a block.


Tape Initialization

An application must use the CreateFile function to create a handle of a tape device. This handle is used in subsequent operations on the tape in the device.

Before an application writes to a tape, the tape must be formatted according to the needs of the application and the capabilities of the tape drive being used. The CreateTapePartition function reformats a tape, creating on it a given number of partitions of a specified size.

The PrepareTape function prepares a tape to be accessed or removed. This function can load, unload, lock, or unlock a tape. This function can also tension the tape by moving the tape to the end of the tape and back to the beginning.

To retrieve and set information about a tape and tape drive, an application uses the GetTapeParameters, SetTapeParameters, and GetTapeStatus functions.

GetTapeParameters retrieves information that describes a tape or a tape drive. The tape information includes the tape's type, density, and block size; the number of partitions on the tape; the amount of tape remaining; and so on. The tape drive information includes the drive's default block size, the maximum partition count, and the features that are supported.

SetTapeParameters either sets the tape block size or sets the tape drive flags that indicate whether the drive supports hardware error correction, data compression, data padding, or any combination of the three.

GetTapeStatus indicates whether the tape drive is ready to process tape commands.


Tape Input and Output

The Win32 API provides several functions that applications can use to perform input and output (I/O) on a tape drive. Tape I/O is similar to I/O performed on a communications device.

When performing tape I/O, some tape drives store tape firmware information in the first few blocks on a tape, typically using some portion of the first 100 blocks. Applications should not use those blocks. More specific information on this subject is available from individual tape system manufacturers. In general, an application that skips the first 100 blocks on a tape will avoid tape drive idiosyncrasies.

The GetTapePosition and SetTapePosition functions retrieve and move the current tape position. The WriteTapemark function writes a specified number of setmarks, filemarks, short filemarks, and long filemarks. The EraseTape function erases all or part of a tape.

The ReadFile and WriteFile functions read and write file data from and to the tape. The data is read and written in complete blocks. If the tape's block size is 512 bytes, all read and write operations must use buffers that are simple integer multiples of that block size: 512, 1024, 1536, 2048, and so on. Most, if not all, drives only allow a write operation after the tape is rewound or after a read operation produces an end-of-data error message.

If ReadFile encounters a filemark, the data up to the filemark is read and the function fails. (The GetLastError function returns an error code indicating the type of filemark that was encountered.) The operating system moves the tape past the filemark, and an application can call ReadFile again to continue reading.

ReadFile and WriteFile read and write only the data stream. The BackupRead and BackupWrite functions read and write all the streams associated with a file. These include data, extended attributes, security, and alternative data streams. The security and alternate data streams are relevant only on the NTFS partition.

The BackupSeek function seeks forward in a file initially accessed by BackupRead or BackupWrite. This function enables an application to skip information that causes access errors.

If an application needs to access only the file data, it should use ReadFile and WriteFile. These functions can also read alternative data streams if the streams were created by using the CreateFile function.

A tape-backup application must use BackupRead and BackupWrite to copy all information pertaining to a file. However, these functions do not read or write file characteristics such as attributes, file creation time, and so on. Applications must use the file input and output functions, such as GetFileAttributes and SetFileAttributes, to retrieve and set those values.


Using Tape Backup

  • Creating a backup application
  • Backing up and restoring POSIX file links


Creating a Backup Application

To perform any input or output on a tape, a backup application must first obtain a handle of the tape device. The following code sample shows how to use the CreateFile function to open a tape device.

HANDLE hTape;   // handle to tape device

hTape = CreateFile(
    "\\\\.\\TAPE0",               // name of tape device to open
    GENERIC_READ | GENERIC_WRITE, // read-write access
    0,                            // not used
    0,                            // not used
    OPEN_EXISTING,                // required for tape devices
    0,                            // not used
    NULL);                        // not used

To back up a directory tree to a tape, an application must use the FindFirstFile and FindNextFile functions to traverse the directory tree. Each time a file is found, the application should get the file's attributes by using the GetFileAttributes function. If there are hard links, the application should determine the number of links and save the file's unique identifier in a table for future comparisons. The first time a file is found, the application should use CreateFile to open the file and the BackupRead function to begin the backup. Then it can use the WriteFile function repeatedly to transfer all the information in the buffer filled by BackupRead to the tape. The second time a file is found (checked against the table of file identifiers when there are hard links), the application can simply write the general file information to the tape, followed by a stream whose identifier is BACKUP_LINK.

When restoring files from tape to disk, an application must use the CreateFile, BackupWrite, and ReadFile functions. For each file on the tape, the application should use CreateFile to create a new file on disk and BackupWrite to begin restoring the file. Then it should use ReadFile repeatedly until all the information for the file has been read from the tape into the buffer filled by BackupWrite. If one of the streams in the BackupWrite buffer has a BACKUP_LINK stream identifier, the application must establish a hard link. If the data needed to establish the link does not exist, BackupWrite fails. The application can use a preexisting catalog to locate and restore the original data, or it can notify the user that the file data to be restored is in a different location.


Backing Up and Restoring POSIX File Links

A backup application can use the BackupWrite function to recreate POSIX file links.

The BackupRead function does not return POSIX file link data. A backup application must maintain the link information itself. The following pseudocode presents algorithms for backing up and restoring POSIX file link data along with other file information.

PseudoCode Algorithm for Backing Up POSIX File Links

1.  Initialize and empty a list of known links.
2.  While there are more files to back up
3.     Read the disk and get the next file.
4.     Open the file for read.
5.     Call GetFileInformationByHandle() to get the
          NumberOfLinks and the FileIndex.
6.     If the NumberOfLinks is greater than 1
7.        Search the list of know links looking for
             the same FileIndex.
8.           If a match is NOT found
9.              add the full path of the file and the
                   FileIndex to the list.
10.             Call BackupRead() to copy all data to
                   your backup media.
10.          Else
11.             Mark the data as a LINK on your backup media
11.             store the full path from the list
                   to your backup media.
12.          Endif
13.    Else
14.       Call BackupRead() to copy all data to your
             backup media.
15.    Endif
16. EndWhile

PseudoCode Algorithm for Restoring POSIX File Links

1.  While there are more files to restore
2.     If the file is a LINK
3.        use the full path which was saved as data
             to open the file.
4.        Initialize a WIN32_STREAM_ID structure with
             dwStreamId equal to BACKUP_LINK.
5.        Initialize the dwStreamAttributes to 0.
6.        Initialize the dwStreamNameSize to 0.
7.        Initialize a buffer containing the full path
             of the file you are restoring in UNICODE.
8.        Initialize the dwStreamSizeHigh to 0.
9.        Initialize the dwStreamSizeLow to the size
             in bytes of the buffer     containing the full path.
10.       Call BackupWrite() with the WIN32_STREAM_ID
11.       Call BackupWrite() with the buffer containing
             the full path.
13.          Else
14.       Call BackupWrite() with the data stored on
             your backup media.
15.    Endif
16. EndWhile


Tape Backup Reference

The following elements are used with tape backup.

  • Tape Backup Functions
  • Tape Backup Structures


Tape Backup Functions

The following functions are used with tape backup.

BackupRead
BackupSeek
BackupWrite
CreateTapePartition
EraseTape
GetTapeParameters
GetTapePosition
GetTapeStatus
PrepareTape
SetTapeParameters
SetTapePosition
WriteTapemark


BackupRead

The BackupRead function reads data associated with a specified file or directory into a buffer. You use this function to back up a file or directory.

BOOL BackupRead(
  HANDLE hFile,                // handle to file or directory
  LPBYTE lpBuffer,             // pointer to buffer to read to
  DWORD nNumberOfBytesToRead,  // number of bytes to read
  LPDWORD lpNumberOfBytesRead, // pointer to variable to receive
                               // number of bytes read
  BOOL bAbort,                 // termination type
  BOOL bProcessSecurity,       // process security flag
  LPVOID *lpContext            // pointer to pointer to internal
                               // context information
);

Parameters

hFile
Handle to the file or directory being backed up. The function reads data associated with this file. You obtain this handle by calling the CreateFile function.

The BackupRead function fails if CreateFile was called with the flag FILE_FLAG_NO_BUFFERING. In this case, the GetLastError function returns the value ERROR_INVALID_PARAMETER.

lpBuffer
Pointer to a buffer that the function writes data to.
nNumberOfBytesToRead
Specifies the length of the buffer. The buffer size must be greater than the size of a WIN32_STREAM_ID structure.
lpNumberOfBytesRead
Pointer to a variable that, when the function returns, contains the number of bytes read.

If the function returns a nonzero value, and the variable pointed to by lpNumberOfBytesRead is zero, then all the data associated with the file handle has been read.

bAbort
Indicates whether BackupRead terminated abnormally. If this value is TRUE, the operation terminates abnormally and all buffers are deallocated.
bProcessSecurity
Indicates whether the function will restore the access-control list (ACL) data for the file or directory.

If bProcessSecurity is TRUE, the ACL data will be backed up.

lpContext
Pointer to a variable that receives and holds a pointer to an internal data structure used by BackupRead to maintain context information during a backup operation.

You must set the variable pointed to by lpContext to NULL before the first call to BackupRead for the specified file or directory. The function allocates memory for the data structure, and then sets the variable to point to that structure. You must not change lpContext or the variable that it points to between calls to BackupRead.

To release the memory used by the data structure, call BackupRead with the bAbort parameter set to TRUE when the backup operation is complete.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero, indicating that an I/O error occurred. To get extended error information, call GetLastError.

Remarks

BackupRead processes all of the data pertaining to an opened object as a series of discrete byte streams. Each stream is preceded by a 32-bit aligned WIN32_STREAM_ID structure.

Streams must be processed in the same order in which they were written to the tape. This ordering enables applications to compare the data backed up against the data on the source device. The data returned by BackupRead is to be used only as input to the BackupWrite function. This data is returned as one large data stream divided into substreams. The substreams are separated by WIN32_STREAM_ID headers.

If an error occurs while BackupRead is reading, the calling process can skip the bad data by calling the BackupSeek function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Tape Backup Overview, Tape Backup Functions, BackupWrite, BackupSeek, WIN32_STREAM_ID


BackupSeek

The BackupSeek function seeks forward in a data stream initially accessed by using the BackupRead or BackupWrite function.

BOOL BackupSeek(
  HANDLE hFile,       // handle to open file
  DWORD dwLowBytesToSeek,
                      // low-order 32 bits of number of bytes
  DWORD dwHighBytesToSeek,
                      // high-order 32 bits of number of bytes
  LPDWORD lpdwLowByteSeeked,
                      // pointer to number of bytes function seeks
  LPDWORD lpdwHighByteSeeked,
                      // pointer to number of bytes function seeks
  LPVOID *lpContext   //pointer to internal context information
);

Parameters

hFile
Identifies the file or directory being backed up. This handle is created by using the CreateFile function.
dwLowBytesToSeek
Specifies the low-order 32 bits of the number of bytes to seek.
dwHighBytesToSeek
Specifies the high-order 32 bits of the number of bytes to seek.
lpdwLowByteSeeked
Pointer to a doubleword that, when the function returns, contains the low-order 32 bits of the number of bytes the function actually seeks.
lpdwHighByteSeeked
Pointer to a doubleword that, when the function returns, contains the high-order 32 bits of the number of bytes the function actually seeks.
lpContext
Pointer to an internal data structure used by the function. This structure must be the same structure that was initialized by the BackupRead function. An application must not touch the contents of this structure.

Return Values

If the function could seek the requested amount, the function returns nonzero.

If the function could not seek the requested amount, the function returns zero. To get extended error information, call GetLastError.

Remarks

Applications use the BackUpSeek function to skip portions of a data stream that cause errors. This function does not seek across stream headers. If an application attempts to seek past the end of a substream, the function fails, the lpdwLowByteSeeked and lpdwHighByteSeeked parameters indicate the actual number of bytes the function seeks, and the file position is placed at the start of the next stream header.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Tape Backup Overview, Tape Backup Functions, BackupRead, BackupWrite, CreateFile


BackupWrite

The BackupWrite function writes a stream of data from a buffer to a specified file or directory. The data must be divided into substreams separated by WIN32_STREAM_ID structures. You use this function to restore a file or directory that has been backed up.

BOOL BackupWrite(
  HANDLE hFile,                 // handle to file or directory
  LPBYTE lpBuffer,              // pointer to buffer containing data
                                // to write
  DWORD nNumberOfBytesToWrite,  // number of bytes to write
  LPDWORD lpNumberOfBytesWritten,  // pointer to variable to receive
                                   // number of bytes written
  BOOL bAbort,                  // termination type
  BOOL bProcessSecurity,        // process security
  LPVOID *lpContext             // pointer to pointer to internal
                                // context information
);

Parameters

hFile
Handle to the file or directory being restored. The function writes data to this file. You obtain this handle by calling the CreateFile function.

The BackupWrite function fails if CreateFile was called with the flag FILE_FLAG_NO_BUFFERING. In this case, the GetLastError function returns the value ERROR_INVALID_PARAMETER.

lpBuffer
Pointer to a buffer that the function writes data from.
nNumberOfBytesToWrite
Specifies the length of the buffer. The buffer size must be greater than the size of a WIN32_STREAM_ID structure.
lpNumberOfBytesWritten
Pointer to a variable that, when the function returns, contains the number of bytes written.
bAbort
Specifies whether BackupWrite terminated abnormally. If this value is TRUE, the operation terminated abnormally and all buffers were deallocated.
bProcessSecurity
Specifies whether the function will restore the access-control list (ACL) data for the file or directory.

If bProcessSecurity is TRUE, you need to have specified WRITE_OWNER and WRITE_DAC access when opening the file or directory handle. If the handle does not have those access rights, the operating system denies access to the ACL data, and ACL data restoration will not occur.

lpContext
Pointer to a variable that receives and holds a pointer to an internal data structure used by BackupWrite to maintain context information during a restore operation.

You must set the variable pointed to by lpContext to NULL before the first call to BackupWrite for the specified file or directory. The function allocates memory for the data structure, and then sets the variable to point to that structure. You must not change lpContext or the variable that it points to between calls to BackupWrite.

To release the memory used by the data structure, call BackupWrite with the bAbort parameter set to TRUE when the restore operation is complete.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero, indicating that an I/O error occurred. To get extended error information, call GetLastError.

Remarks

The BACKUP_LINK stream type lets you restore files with hard links.

Data obtained by the BackupRead function should only be used as input to the BackupWrite function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Tape Backup Overview, Tape Backup Functions, BackupRead, BackupSeek, CreateFile, WIN32_STREAM_ID


CreateTapePartition

The CreateTapePartition function reformats a tape.

DWORD CreateTapePartition(
  HANDLE hDevice,           // handle to open device
  DWORD dwPartitionMethod,  // type of new partition
  DWORD dwCount,            // number of new partitions to create
  DWORD dwSize              // size of new partition, in megabytes
);

Parameters

hDevice
Identifies the device where the new partition is to be created. This handle is created by using the CreateFile function.
dwPartitionMethod
Specifies the type of partition to create. To determine what type of partitions your device supports, see the documentation for your hardware. This parameter can have one of the following values:
Value | Description
TAPE_FIXED_PARTITIONS | Partitions the tape based on the device's default definition of partitions. The dwCount and dwSize parameters are ignored.
TAPE_INITIATOR_PARTITIONS | Partitions the tape into the number and size of partitions specified by dwCount and dwSize, respectively, except for the last partition. The size of the last partition is the remainder of the tape.
TAPE_SELECT_PARTITIONS | Partitions the tape into the number of partitions specified by dwCount. The dwSize parameter is ignored. The size of the partitions is determined by the device's default partition size. For more specific information, refer to the documentation for your tape device.

dwCount
Specifies the number of partitions to create. The GetTapeParameters function provides the maximum number of partitions a tape can support.
dwSize
Specifies the size, in megabytes, of each partition. This value is ignored if the dwPartitionMethod parameter is TAPE_SELECT_PARTITIONS.

Return Values

If the function succeeds, the return value is NO_ERROR.

If the function fails, it may return one of the following error codes:

Error | Description
ERROR_BEGINNING_OF_MEDIA | An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET | A reset condition was detected on the bus.
ERROR_END_OF_MEDIA | The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED | A filemark was reached during an operation.
ERROR_SETMARK_DETECTED | A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED | The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE | The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH | The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED | The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED | The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE | There is no media in the drive.
ERROR_NOT_SUPPORTED | The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA | An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA | An attempt to unload the tape failed.
ERROR_WRITE_PROTECT | The media is write protected.

Remarks

Creating partitions reformats the tape. All previous information recorded on the tape is destroyed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Tape Backup Overview, Tape Backup Functions, CreateFile, GetTapeParameters


EraseTape

The EraseTape function erases all or part of a tape.

DWORD EraseTape(
  HANDLE hDevice,     // handle to open device
  DWORD dwEraseType,  // type of erasure to perform
  BOOL bImmediate     // return after erase operation begins
);

Parameters

hDevice
Identifies the device where the tape is to be erased. This handle is created by using the CreateFile function.
dwEraseType
Specifies the erasing technique. This parameter can be one of the following values:
Value | Description
TAPE_ERASE_LONG | Erases the tape from the current position to the end of the current partition.
TAPE_ERASE_SHORT | Writes an erase gap or end-of-data marker at the current position.

bImmediate
Specifies whether to return as soon as the erase operation begins. If this parameter is TRUE, the function returns immediately; if it is FALSE, the function does not return until the erase operation has been completed.

Return Values

If the function succeeds, the return value is NO_ERROR.

If the function fails, the return value is one of the following error codes:

Error code | Description
ERROR_BEGINNING_OF_MEDIA | An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET | A reset condition was detected on the bus.
ERROR_END_OF_MEDIA | The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED | A filemark was reached during an operation.
ERROR_SETMARK_DETECTED | A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED | The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE | The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH | The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED | The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED | The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE | There is no media in the drive.
ERROR_NOT_SUPPORTED | The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA | An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA | An attempt to unload the tape failed.
ERROR_WRITE_PROTECT | The media is write protected.

Remarks

Some tape devices do not support certain tape operations. To determine your tape device's capabilities, see your tape device documentation and use the GetTapeParameters function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Tape Backup Overview, Tape Backup Functions, CreateFile, GetTapeParameters


GetTapeParameters

The GetTapeParameters function retrieves information that describes the tape or the tape drive.

DWORD GetTapeParameters(
  HANDLE hDevice,            // handle of open device
  DWORD dwOperation,         // type of information requested
  LPDWORD lpdwSize,          // address of returned information
  LPVOID lpTapeInformation   // tape media or drive information
);

Parameters

hDevice
Identifies the device about which information is sought. This handle is created by using the CreateFile function.
dwOperation
Specifies the type of information requested. This parameter must be one of the following values:
Value | Description
GET_TAPE_MEDIA_INFORMATION | Retrieves information about the tape in the tape device.
GET_TAPE_DRIVE_INFORMATION | Retrieves information about the tape device.

lpdwSize
Points to a variable that receives the size, in bytes, of the buffer specified by the lpTapeInformation parameter. If the buffer is too small, this parameter receives the required size.
lpTapeInformation
Points to a structure that contains the requested information. If the dwOperation parameter is GET_TAPE_MEDIA_INFORMATION, lpTapeInformation points to a TAPE_GET_MEDIA_PARAMETERS structure.

If dwOperation is GET_TAPE_DRIVE_INFORMATION, lpTapeInformation points to a TAPE_GET_DRIVE_PARAMETERS structure.

Return Values

If the function succeeds, the return value is NO_ERROR.

If the function fails, the return value is one of the following error codes:

Error code | Description
ERROR_BEGINNING_OF_MEDIA | An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET | A reset condition was detected on the bus.
ERROR_END_OF_MEDIA | The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED | A filemark was reached during an operation.
ERROR_SETMARK_DETECTED | A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED | The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE | The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH | The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED | The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED | The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE | There is no media in the drive.
ERROR_NOT_SUPPORTED | The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA | An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA | An attempt to unload the tape failed.
ERROR_WRITE_PROTECT | The media is write protected.

Remarks

The block size range values (maximum and minimum) returned by the GetTapeParameters function called with the dwOperation parameter set to the GET_TAPE_DRIVE_INFORMATION value will indicate system limits, not drive limits. However, it is the tape drive device and the media present in the drive that determine the true block size limits. Thus, an application may not be able to set all the block sizes mentioned in the range obtained by specifying GET_TAPE_DRIVE_INFORMATION in dwOperation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Tape Backup Overview, Tape Backup Functions, CreateFile, SetTapeParameters, TAPE_GET_DRIVE_PARAMETERS, TAPE_GET_MEDIA_PARAMETERS


GetTapePosition

The GetTapePosition function retrieves the current address of the tape, in logical or absolute blocks.

DWORD GetTapePosition(
  HANDLE hDevice,          // handle of open device
  DWORD dwPositionType,    // type of address to obtain
  LPDWORD lpdwPartition,   // address of current tape partition
  LPDWORD lpdwOffsetLow,   // address of low-order 32 bits of tape
                           // position
  LPDWORD lpdwOffsetHigh   // address of high-order 32 bits of tape
                           // position
);

Parameters

hDevice
Identifies the device on which to get the tape position. This handle is created by using CreateFile.
dwPositionType
Specifies the type of address to obtain. This parameter can be one of the following values:
Value | Description
TAPE_ABSOLUTE_POSITION | The lpdwOffsetLow and lpdwOffsetHigh parameters receive the device-specific block address. The dwPartition parameter receives zero.
TAPE_LOGICAL_POSITION | The lpdwOffsetLow and lpdwOffsetHigh parameters receive the logical block address. The dwPartition parameter receives the logical tape partition.

lpdwPartition
Points to a variable that receives the number of the current tape partition. Partitions are numbered logically from 1 through n, where 1 is the first partition on the tape and n is the last. When a device-specific block address is retrieved, or if the device supports only one partition, this parameter receives zero.
lpdwOffsetLow
Points to a variable that receives the low-order 32 bits of the current tape position.
lpdwOffsetHigh
Points to a variable that receives the high-order 32 bits of the current tape position. This parameter can be NULL if the high-order 32 bits are not required.

Return Values

If the function succeeds, the return value is NO_ERROR.

If the function fails, the return value is one of the following error codes:

Error code | Description
ERROR_BEGINNING_OF_MEDIA | An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET | A reset condition was detected on the bus.
ERROR_END_OF_MEDIA | The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED | A filemark was reached during an operation.
ERROR_SETMARK_DETECTED | A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED | The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE | The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH | The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED | The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED | The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE | There is no media in the drive.
ERROR_NOT_SUPPORTED | The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA | An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA | An attempt to unload the tape failed.
ERROR_WRITE_PROTECT | The media is write protected.

Remarks

A logical block address is relative to a partition. The first logical block address on each partition is zero.

Call the GetTapeParameters function to obtain information about the status, capabilities, and capacities of tape drives and media.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Tape Backup Overview, Tape Backup Functions, CreateFile, GetTapeParameters, SetTapePosition


GetTapeStatus

The GetTapeStatus function indicates whether the tape device is ready to process tape commands.

DWORD GetTapeStatus(
  HANDLE hDevice   // handle of open device
);

Parameters

hDevice
Identifies the device for which to get the device status. This handle is created by using the CreateFile function.

Return Values

If the tape device is ready to accept appropriate tape-access commands without returning errors, the return value is NO_ERROR.

If the function fails, the return value is one of the following error codes:

Error code | Description
ERROR_BEGINNING_OF_MEDIA | An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET | A reset condition was detected on the bus.
ERROR_END_OF_MEDIA | The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED | A filemark was reached during an operation.
ERROR_SETMARK_DETECTED | A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED | The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE | The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH | The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED | The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED | The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE | There is no media in the drive.
ERROR_NOT_SUPPORTED | The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA | An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA | An attempt to unload the tape failed.
ERROR_WRITE_PROTECT | The media is write protected.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Tape Backup Overview, Tape Backup Functions, CreateFile


PrepareTape

The PrepareTape function prepares the tape to be accessed or removed.

DWORD PrepareTape(
  HANDLE hDevice,     // handle of open device
  DWORD dwOperation,  // preparation method
  BOOL bImmediate     // return after operation begins
);

Parameters

hDevice
Identifies the device preparing the tape. This handle is created by using the CreateFile function.
dwOperation
Specifies how the tape device is to be prepared. This parameter can be one of the following values:
Value | Meaning
TAPE_FORMAT | Performs a low-level format of the tape. Currently, only the QIC117 device supports this feature.
TAPE_LOAD | Loads the tape and moves the tape to the beginning.
TAPE_LOCK | Locks the tape ejection mechanism so that the tape is not ejected accidentally.
TAPE_TENSION | Adjusts the tension by moving the tape to the end of the tape and back to the beginning. This option is not supported by all devices. This value is ignored if it is not supported.
TAPE_UNLOAD | Moves the tape to the beginning for removal from the device. After a successful unload operation, the device returns errors to applications that attempt to access the tape, until the tape is loaded again.
TAPE_UNLOCK | Unlocks the tape ejection mechanism.

bImmediate
Specifies whether to return as soon as the preparation begins. If this parameter is TRUE, the function returns immediately. If it is FALSE, the function does not return until the operation has been completed.

Return Values

If the function succeeds, the return value is NO_ERROR.

If the function fails, the return value is one of the following error codes:

Error | Description
ERROR_BEGINNING_OF_MEDIA | An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET | A reset condition was detected on the bus.
ERROR_END_OF_MEDIA | The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED | A filemark was reached during an operation.
ERROR_SETMARK_DETECTED | A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED | The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE | The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH | The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED | The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED | The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE | There is no media in the drive.
ERROR_NOT_SUPPORTED | The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA | An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA | An attempt to unload the tape failed.
ERROR_WRITE_PROTECT | The media is write protected.

Remarks

Some tape devices do not support certain tape operations. See your tape device documentation and use the GetTapeParameters function to determine your tape device's capabilities.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Tape Backup Overview, Tape Backup Functions, CreateFile, GetTapeParameters


SetTapeParameters

The SetTapeParameters function either specifies the block size of a tape or configures the tape device.

DWORD SetTapeParameters(
  HANDLE hDevice,     // handle of open device
  DWORD dwOperation,  // type of information to set
  LPVOID lpTapeInformation
                      // address of buffer with information to set
);

Parameters

hDevice
Identifies the device for which to set configuration information. This handle is created by using the CreateFile function.
dwOperation
Specifies the type of information to set. This parameter must be one of the following values:
Value | Description
SET_TAPE_MEDIA_INFORMATION | Sets the tape-specific information specified by the lpTapeInformation parameter.
SET_TAPE_DRIVE_INFORMATION | Sets the device-specific information specified by lpTapeInformation.

lpTapeInformation
Points to a structure that contains the information to set. If the dwOperation parameter is SET_TAPE_MEDIA_INFORMATION, lpTapeInformation points to a TAPE_SET_MEDIA_PARAMETERS structure.

If dwOperation is SET_TAPE_DRIVE_INFORMATION, lpTapeInformation points to a TAPE_SET_DRIVE_PARAMETERS structure.

Return Values

If the function succeeds, the return value is NO_ERROR.

If the function fails, the return value is one of the following error codes:

Error | Description
ERROR_BEGINNING_OF_MEDIA | An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET | A reset condition was detected on the bus.
ERROR_END_OF_MEDIA | The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED | A filemark was reached during an operation.
ERROR_SETMARK_DETECTED | A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED | The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE | The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH | The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED | The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED | The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE | There is no media in the drive.
ERROR_NOT_SUPPORTED | The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA | An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA | An attempt to unload the tape failed.
ERROR_WRITE_PROTECT | The media is write protected.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Tape Backup Overview, Tape Backup Functions, GetTapeParameters, TAPE_SET_DRIVE_PARAMETERS, TAPE_SET_MEDIA_PARAMETERS


SetTapePosition

The SetTapePosition sets the tape position on the specified device.

DWORD SetTapePosition(
  HANDLE hDevice,          // handle of open device
  DWORD dwPositionMethod,  // type of positioning to perform
  DWORD dwPartition,       // new tape partition
  DWORD dwOffsetLow,       // low-order 32 bits of tape position
  DWORD dwOffsetHigh,      // high-order 32 bits of tape position
  BOOL bImmediate          // return after operation begins
);

Parameters

hDevice
Identifies the device on which to set the tape position. This handle is created by using the CreateFile function.
dwPositionMethod
Specifies the type of positioning to perform. This parameter must be one of the following values:
Value | Meaning
TAPE_ABSOLUTE_BLOCK | Moves the tape to the device-specific block address specified by the dwOffsetLow and dwOffsetHigh parameters. The dwPartition parameter is ignored.
TAPE_LOGICAL_BLOCK | Moves the tape to the block address specified by dwOffsetLow and dwOffsetHigh in the partition specified by dwPartition.
TAPE_REWIND | Moves the tape to the beginning of the current partition. The dwPartition, dwOffsetLow, and dwOffsetHigh parameters are ignored.
TAPE_SPACE_END_OF_DATA | Moves the tape to the end of the data on the partition specified by dwPartition.
TAPE_SPACE_FILEMARKS | Moves the tape forward (or backward) the number of filemarks specified by dwOffsetLow and dwOffsetHigh in the current partition. The dwPartition parameter is ignored.
TAPE_SPACE_RELATIVE_BLOCKS | Moves the tape forward (or backward) the number of blocks specified by dwOffsetLow and dwOffsetHigh in the current partition. The dwPartition parameter is ignored.
TAPE_SPACE_SEQUENTIAL_FMKS | Moves the tape forward (or backward) to the first occurrence of n filemarks in the current partition, where n is the number specified by dwOffsetLow and dwOffsetHigh. The dwPartition parameter is ignored.
TAPE_SPACE_SEQUENTIAL_SMKS | Moves the tape forward (or backward) to the first occurrence of n setmarks in the current partition, where n is the number specified by dwOffsetLow and dwOffsetHigh. The dwPartition parameter is ignored.
TAPE_SPACE_SETMARKS | Moves the tape forward (or backward) the number of setmarks specified by dwOffsetLow and dwOffsetHigh in the current partition. The dwPartition parameter is ignored.

dwPartition
Specifies the partition to position within. If dwPartition is zero, the current partition is used. Partitions are numbered logically from 1 through n, where 1 is the first partition on the tape and n is the last.
dwOffsetLow
Specifies the low-order 32 bits of the block address or count for the position operation specified by the dwPositionMethod parameter.
dwOffsetHigh
Specifies the high-order 32 bits of the block address or count for the position operation specified by the dwPositionMethod parameter. If the high-order 32 bits are not required, this parameter should be zero.
bImmediate
Indicates whether to return as soon as the move operation begins. If this parameter is TRUE, the function returns immediately; if FALSE, the function does not return until the move operation has been completed.

Return Values

If the function succeeds, the return value is NO_ERROR.

If the function fails, the return value is one of the following error codes:

Error | Description
ERROR_BEGINNING_OF_MEDIA | An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET | A reset condition was detected on the bus.
ERROR_END_OF_MEDIA | The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED | A filemark was reached during an operation.
ERROR_SETMARK_DETECTED | A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED | The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE | The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH | The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED | The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED | The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE | There is no media in the drive.
ERROR_NOT_SUPPORTED | The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA | An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA | An attempt to unload the tape failed.
ERROR_WRITE_PROTECT | The media is write protected.

Remarks

If the offset specified by dwOffsetLow and dwOffsetHigh specifies the number of blocks, filemarks, or setmarks to move, a positive offset moves the tape forward to the end of the last block, filemark, or setmark. A negative offset moves the tape backward to the beginning of the last block, filemark, or setmark. If the offset is zero, the tape does not move.

To obtain information about the status, capabilities, and capacities of tape drives and media, call the GetTapeParameters function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Tape Backup Overview, Tape Backup Functions, CreateFile, GetTapeParameters, GetTapePosition


WriteTapemark

The WriteTapemark function writes a specified number of filemarks, setmarks, short filemarks, or long filemarks to a tape device. These tapemarks divide a tape partition into smaller areas.

DWORD WriteTapemark(
  HANDLE hDevice,        // handle to open device
  DWORD dwTapemarkType,  // type of tapemarks to write
  DWORD dwTapemarkCount, // number of tapemarks to write
  BOOL bImmediate        // return after write begins
);

Parameters

hDevice
Identifies the device on which to write tapemarks. This handle is created by using the CreateFile function.
dwTapemarkType
Specifies the type of tapemarks to write. This parameter can be one of the following values:
Value | Description
TAPE_FILEMARKS | Writes the number of filemarks specified by the dwTapemarkCount parameter.
TAPE_LONG_FILEMARKS | Writes the number of long filemarks specified by dwTapemarkCount.
TAPE_SETMARKS | Writes the number of setmarks specified by dwTapemarkCount.
TAPE_SHORT_FILEMARKS | Writes the number of short filemarks specified by dwTapemarkCount.

dwTapemarkCount
Specifies the number of tapemarks to write.
bImmediate
Specifies whether to return as soon as the operation begins. If this parameter is TRUE, the function returns immediately; if it is FALSE, the function does not return until the operation has been completed.

Return Values

If the function succeeds, the return value is NO_ERROR.

If the function fails, the return value is one of the following error codes:

Error | Description
ERROR_BEGINNING_OF_MEDIA | An attempt to access data before the beginning-of-medium marker failed.
ERROR_BUS_RESET | A reset condition was detected on the bus.
ERROR_END_OF_MEDIA | The end-of-tape marker was reached during an operation.
ERROR_FILEMARK_DETECTED | A filemark was reached during an operation.
ERROR_SETMARK_DETECTED | A setmark was reached during an operation.
ERROR_NO_DATA_DETECTED | The end-of-data marker was reached during an operation.
ERROR_PARTITION_FAILURE | The tape could not be partitioned.
ERROR_INVALID_BLOCK_LENGTH | The block size is incorrect on a new tape in a multivolume partition.
ERROR_DEVICE_NOT_PARTITIONED | The partition information could not be found when a tape was being loaded.
ERROR_MEDIA_CHANGED | The tape that was in the drive has been replaced or removed.
ERROR_NO_MEDIA_IN_DRIVE | There is no media in the drive.
ERROR_NOT_SUPPORTED | The tape driver does not support a requested function.
ERROR_UNABLE_TO_LOCK_MEDIA | An attempt to lock the ejection mechanism failed.
ERROR_UNABLE_TO_UNLOAD_MEDIA | An attempt to unload the tape failed.
ERROR_WRITE_PROTECT | The media is write protected.

Remarks

Filemarks, setmarks, short filemarks, and long filemarks are special recorded elements that denote the linear organization of the tape. None of these marks contain user data. Filemarks are the most general marks; setmarks provide a hierarchy not available with filemarks.

A short filemark contains a short erase gap that cannot be overwritten unless the write operation is performed from the beginning of the partition or from an earlier long filemark.

A long filemark contains a long erase gap that allows an application to position the tape at the beginning of the filemark and to overwrite the filemark and the erase gap.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Tape Backup Overview, Tape Backup Functions, CreateFile


Tape Backup Structures

The following structures are used with tape backup.

TAPE_ERASE
TAPE_GET_DRIVE_PARAMETERS
TAPE_GET_MEDIA_PARAMETERS
TAPE_GET_POSITION
TAPE_PREPARE
TAPE_SET_DRIVE_PARAMETERS
TAPE_SET_MEDIA_PARAMETERS
TAPE_SET_POSITION
TAPE_WRITE_MARKS
WIN32_STREAM_ID


TAPE_ERASE

The TAPE_ERASE structure describes the partition to be erased.

typedef struct _TAPE_ERASE { // ter
    ULONG Type;
} TAPE_ERASE;

Members

Type
Specifies how to erase the tape. This member must have one of the following values:
Value | Description
TAPE_ERASE_LONG | Erases the entire partition.
TAPE_ERASE_SHORT | Erases only the partition's header block.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Tape Backup Overview, Tape Backup Structures


TAPE_GET_DRIVE_PARAMETERS

The TAPE_GET_DRIVE_PARAMETERS structure describes the tape drive.

typedef struct _TAPE_GET_DRIVE_PARAMETERS { // tgdp
    BOOLEAN ECC;
    BOOLEAN Compression;
    BOOLEAN DataPadding;
    BOOLEAN ReportSetmarks;
    ULONG   DefaultBlockSize;
    ULONG   MaximumBlockSize;
    ULONG   MinimumBlockSize;
    ULONG   MaximumPartitionCount;
    ULONG   FeaturesLow;
    ULONG   FeaturesHigh;
    ULONG   EOTWarningZoneSize;
} TAPE_GET_DRIVE_PARAMETERS;

Members

ECC
Specifies whether the device supports hardware error correction. This member is TRUE if hardware error correction is supported.
Compression
Specifies whether hardware data compression is enabled or disabled. This member is TRUE if hardware data compression is enabled.
DataPadding
Specifies whether data padding is enabled or disabled. Data padding keeps the tape streaming at a constant speed. This member is TRUE if data padding is enabled.
ReportSetmarks
Specifies whether setmark reporting is enabled or disabled. This member is TRUE if setmark reporting is enabled.
DefaultBlockSize
Specifies the device's default fixed block size.
MaximumBlockSize
Specifies the device's maximum block size.
MinimumBlockSize
Specifies the device's minimum block size.
MaximumPartitionCount
Specifies the maximum number of partitions that can be created on the device.
FeaturesLow
Specifies the low-order 32 bits of the device features flag. This member can be one or more of following values:
Value | Meaning
TAPE_DRIVE_COMPRESSION | The device supports hardware data compression.
TAPE_DRIVE_ECC | The device supports hardware error correction.
TAPE_DRIVE_EJECT_MEDIA | The device physically ejects the tape on a software eject.
TAPE_DRIVE_ERASE_BOP_ONLY | The device performs the erase operation from the beginning-of-partition marker only.
TAPE_DRIVE_ERASE_LONG | The device performs a long erase operation.
TAPE_DRIVE_ERASE_IMMEDIATE | The device performs an immediate erase operation — that is, it returns when the erase operation begins.
TAPE_DRIVE_ERASE_SHORT | The device performs a short erase operation.
TAPE_DRIVE_FIXED | The device creates fixed data partitions.
TAPE_DRIVE_FIXED_BLOCK | The device supports fixed-length block mode.
TAPE_DRIVE_INITIATOR | The device creates initiator-defined partitions.
TAPE_DRIVE_PADDING | The device supports data padding.
TAPE_DRIVE_GET_ABSOLUTE_BLK | The device provides the current device-specific block address.
TAPE_DRIVE_GET_LOGICAL_BLK | The device provides the current logical block address (and logical tape partition).
TAPE_DRIVE_REPORT_SMKS | The device supports setmark reporting.
TAPE_DRIVE_SELECT | The device creates select data partitions.
TAPE_DRIVE_SET_EOT_WZ_SIZE | The device supports setting the end-of-medium warning size.
TAPE_DRIVE_TAPE_CAPACITY | The device returns the maximum capacity of the tape.
TAPE_DRIVE_TAPE_REMAINING | The device returns the remaining capacity of the tape.
TAPE_DRIVE_VARIABLE_BLOCK | The device supports variable-length block mode.
TAPE_DRIVE_WRITE_PROTECT | The device returns an error if the tape is write-enabled or write-protected.

FeaturesHigh
Contains the high-order 32 bits of the device features flag. This member can be one or more of the following values:
Value | Meaning
TAPE_DRIVE_ABS_BLK_IMMED | The device moves the tape to a device-specific block address and returns as soon as the move begins.
TAPE_DRIVE_ABSOLUTE_BLK | The device moves the tape to a device specific block address.
TAPE_DRIVE_END_OF_DATA | The device moves the tape to the end-of-data marker in a partition.
TAPE_DRIVE_FILEMARKS | The device moves the tape forward (or backward) a specified number of filemarks.
TAPE_DRIVE_LOAD_UNLOAD | The device enables and disables the device for further operations.
TAPE_DRIVE_LOAD_UNLD_IMMED | The device supports immediate load and unload operations.
TAPE_DRIVE_LOCK_UNLOCK | The device enables and disables the tape ejection mechanism.
TAPE_DRIVE_LOCK_UNLK_IMMED | The device supports immediate lock and unlock operations.
TAPE_DRIVE_LOG_BLK_IMMED | The device moves the tape to a logical block address in a partition and returns as soon as the move begins.
TAPE_DRIVE_LOGICAL_BLK | The device moves the tape to a logical block address in a partition.
TAPE_DRIVE_RELATIVE_BLKS | The device moves the tape forward (or backward) a specified number of blocks.
TAPE_DRIVE_REVERSE_POSITION | The device moves the tape backward over blocks, filemarks, or setmarks.
TAPE_DRIVE_REWIND_IMMEDIATE | The device supports immediate rewind operation.
TAPE_DRIVE_SEQUENTIAL_FMKS | The device moves the tape forward (or backward) to the first occurrence of a specified number of consecutive filemarks.
TAPE_DRIVE_SEQUENTIAL_SMKS | The device moves the tape forward (or backward) to the first occurrence of a specified number of consecutive setmarks.
TAPE_DRIVE_SET_BLOCK_SIZE | The device supports setting the size of a fixed-length logical block or setting the variable-length block mode.
TAPE_DRIVE_SET_COMPRESSION | The device enables and disables hardware data compression.
TAPE_DRIVE_SET_ECC | The device enables and disables hardware error correction.
TAPE_DRIVE_SET_PADDING | The device enables and disables data padding.
TAPE_DRIVE_SET_REPORT_SMKS | The device enables and disables the reporting of setmarks.
TAPE_DRIVE_SETMARKS | The device moves the tape forward (or reverse) a specified number of setmarks.
TAPE_DRIVE_SPACE_IMMEDIATE | The device supports immediate spacing.
TAPE_DRIVE_TENSION | The device supports tape tensioning.
TAPE_DRIVE_TENSION_IMMED | The device supports immediate tape tensioning.
TAPE_DRIVE_WRITE_FILEMARKS | The device writes filemarks.
TAPE_DRIVE_WRITE_LONG_FMKS | The device writes long filemarks.
TAPE_DRIVE_WRITE_MARK_IMMED | The device supports immediate writing of short and long filemarks.
TAPE_DRIVE_WRITE_SETMARKS | The device writes setmarks.
TAPE_DRIVE_WRITE_SHORT_FMKS | The device writes short filemarks.

EOTWarningZoneSize
Indicates the number of bytes between the end-of-tape warning and the physical end of the tape.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Tape Backup Overview, Tape Backup Structures


TAPE_GET_MEDIA_PARAMETERS

The TAPE_GET_MEDIA_PARAMETERS structure describes the tape in the tape drive.

typedef struct _TAPE_GET_MEDIA_PARAMETERS {  // tgmp
    LARGE_INTEGER   Capacity;
    LARGE_INTEGER   Remaining;
    DWORD   BlockSize;
    DWORD   PartitionCount;
    BOOLEAN WriteProtected;
} TAPE_GET_MEDIA_PARAMETERS;

Members

Capacity
Specifies the total number of bytes on the current tape partition.
Remaining
Specifies the number of bytes between the current position and the end of the current tape partition.
BlockSize
Specifies the number of bytes per block.
PartitionCount
Specifies the number of partitions on the tape.
WriteProtected
Specifies whether the tape is write-protected. If this member is TRUE, the tape is write-protected.

Remarks

The GetTapeParameters function fills the Remaining and Capacity members with estimates of the tape remaining in the current tape partition and the total capacity of the current tape partition.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Tape Backup Overview, Tape Backup Structures, GetTapeParameters


TAPE_GET_POSITION

The TAPE_GET_POSITION structure describes the position of the tape.

typedef struct _TAPE_GET_POSITION { // tgpos
    ULONG Type;
    ULONG Partition;
    ULONG OffsetLow;
    ULONG OffsetHigh;
} TAPE_GET_POSITION;

Members

Type
Specifies the type of position. This member must be one of the following values:
Value | Description
TAPE_ABSOLUTE_POSITION | The position specified by the OffsetLow and OffsetHigh members is an absolute number of blocks from the beginning of the partition specified by the Partition member.
TAPE_LOGICAL_POSITION | The position specified by OffsetLow and OffsetHigh is relative to the current position in the partition specified by Partition.

Partition
Specifies the partition to position within. If this member is zero, the current partition is assumed.
OffsetLow
Specifies the low-order 32 bits of the block address.
OffsetHigh
Specifies the high-order 32 bits of the block address. If the high-order 32 bits are not required, this member should be zero.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Tape Backup Overview, Tape Backup Structures


TAPE_PREPARE

The TAPE_PREPARE structure describes how to prepare the tape.

typedef struct _TAPE_PREPARE { // tp
    ULONG Operation;
} TAPE_PREPARE;

Members

Operation
Specifies how to prepare the tape. This member must be one of the following values:
Value | Description
TAPE_LOCK | Locks the tape ejection mechanism so that the tape is not ejected accidentally during a tape operation.
TAPE_TENSION | Moves to the end of the tape and rewinds to the beginning of the tape. This value is ignored if the tape device does not support tensioning.
TAPE_UNLOAD | Rewinds and unloads the tape.
TAPE_UNLOCK | Unlocks the tape ejection mechanism.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Tape Backup Overview, Tape Backup Structures


TAPE_SET_DRIVE_PARAMETERS

The TAPE_SET_DRIVE_PARAMETERS structure describes the tape drive.

typedef struct _TAPE_SET_DRIVE_PARAMETERS {  // tsdp
    BOOLEAN ECC;
    BOOLEAN Compression;
    BOOLEAN DataPadding;
    BOOLEAN ReportSetmarks;
    ULONG   EOTWarningZoneSize;
} TAPE_SET_DRIVE_PARAMETERS;

Members

ECC
Specifies whether the device supports hardware error correction. This member is TRUE if hardware error correction is supported.
Compression
Specifies whether hardware data compression is enabled or disabled. This member is TRUE if hardware data compression is enabled.
DataPadding
Specifies whether data padding is enabled or disabled. Data padding keeps the tape streaming at a constant speed. This member is TRUE if data padding is enabled.
ReportSetmarks
Specifies whether setmark reporting is enabled or disabled. This member is TRUE if setmarks are enabled.
EOTWarningZoneSize
Specifies the number of bytes between the end-of-tape warning and the physical end of the tape.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Tape Backup Overview, Tape Backup Structures


TAPE_SET_MEDIA_PARAMETERS

The TAPE_SET_MEDIA_PARAMETERS structure describes the tape in the tape drive.

typedef struct _TAPE_SET_MEDIA_PARAMETERS { // tsmp
    ULONG BlockSize;
} TAPE_SET_MEDIA_PARAMETERS;

Members

BlockSize
Specifies the number of bytes per block. Maximum and minimum block sizes can be obtained by calling the GetTapeParameters function.

Remarks

There is no longer a requirement that block sizes be powers of 2.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Tape Backup Overview, Tape Backup Structures, GetTapeParameters, SetTapeParameters


TAPE_SET_POSITION

The TAPE_SET_POSITION structure describes how and where to position the tape.

typedef struct _TAPE_SET_POSITION { // tspos
    ULONG Method;
    ULONG Partition;
    ULONG OffsetLow;
    ULONG OffsetHigh;
} TAPE_SET_POSITION;

Members

Method
Specifies the type of positioning. This member must be one of the following values:
Value | Description
TAPE_ABSOLUTE_BLOCK | Moves the tape to the device-specific block address specified by the OffsetLow and OffsetHigh members. The Partition member is ignored.
TAPE_LOGICAL_BLOCK | Moves the tape to the block address specified by OffsetLow and OffsetHigh in the partition specified by Partition.
TAPE_REWIND | Moves the tape to the beginning of the current partition. The Partition, OffsetLow, and OffsetHigh members are ignored.
TAPE_SPACE_END_OF_DATA | Moves the tape to the end of the data on the partition specified by Partition.
TAPE_SPACE_FILEMARKS | Moves the tape forward (or backward) the number of filemarks specified by OffsetLow and OffsetHigh in the current partition. The Partition member is ignored.
TAPE_SPACE_RELATIVE_BLOCKS | Moves the tape forward (or backward) the number of blocks specified by OffsetLow and OffsetHigh in the current partition. The Partition member is ignored.
TAPE_SPACE_SEQUENTIAL_FMKS | Moves the tape forward (or backward) to the first occurrence of n filemarks in the current partition, where n is the number specified by OffsetLow and OffsetHigh. The Partition parameter is ignored.
TAPE_SPACE_SEQUENTIAL_SMKS | Moves the tape forward (or backward) to the first occurrence of n setmarks in the current partition, where n is the number specified by OffsetLow and OffsetHigh. The Partition member is ignored.
TAPE_SPACE_SETMARKS | Moves the tape forward (or backward) the number of setmarks specified by OffsetLow and OffsetHigh in the current partition. The Partition member is ignored.

Partition
Specifies the partition to position within. If this member is zero, the current partition is assumed.
OffsetLow
Specifies the low-order 32 bits of the block address or count for the position operation specified by the Method member.
OffsetHigh
Specifies the high-order 32 bits of the block address or count for the position operation specified by the Method member. If the high-order 32 bits are not required, this member should be zero.

Remarks

If the positioning is relative, a positive offset moves the tape forward (toward the end of the tape) and a negative offset moves the tape backward (toward the beginning of the tape).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Tape Backup Overview, Tape Backup Structures


TAPE_WRITE_MARKS

The TAPE_WRITE_MARKS structure describes the type and number of tapemarks to write.

typedef struct _TAPE_WRITE_MARKS { // twm
    ULONG Type;
    ULONG Count;
} TAPE_WRITE_MARKS;

Members

Type
Specifies the type of tapemark to write. This member can be one of the following values:
Value | Description
TAPE_LONG_FILEMARKS | Writes long filemarks.
TAPE_SEQUENTIAL_FILEMARKS | Writes sequential filemarks.
TAPE_SETMARKS | Writes setmarks.
TAPE_SHORT_FILEMARKS | Writes short filemarks.

Count
Specifies the number of tapemarks to write.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Tape Backup Overview, Tape Backup Structures


WIN32_STREAM_ID

struct WIN32_STREAM_ID {
    DWORD dwStreamId;
    DWORD dwStreamAttributes;
    LARGE_INTEGER Size;
    DWORD dwStreamNameSize;
    WCHAR  cStreamName[ ] ;
}

Members

dwStreamId
Specifies the type of data. This member can be one of the following values:
Value | Meaning
BACKUP_DATA | Standard data
BACKUP_EA_DATA | Extended attribute data
BACKUP_SECURITY_DATA | Security descriptor data
BACKUP_ALTERNATE_DATA | Alternative data streams
BACKUP_LINK | Hard link information
BACKUP_PROPERTY_DATA | Property data
BACKUP_OBJECT_ID | Objects identifiers
BACKUP_REPARSE_DATA | Reparse points
BACKUP_SPARSE_BLOCK | Sparse file.

dwStreamAttributes
Specifies the attributes of data to facilitate cross-operating system transfer. This member must be one or more of the following values:
Value | Description
STREAM_MODIFIED_WHEN_READ | Attribute set if the stream contains data that is modified when read. Allows the backup application to know that verification of data will fail.
STREAM_CONTAINS_SECURITY | Stream contains security data (general attributes). Allows the stream to be ignored on cross-operations restore.

Size
Specifies the size, in bytes, of data. Note that this is a 64-bit value.
dwStreamNameSize
Specifies the length of the name of the alternative data stream.
cStreamName
Specifies the name of the alternative data stream, in Unicode™.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Tape Backup Overview, Tape Backup Structures, BackupRead, BackupSeek, BackupWrite


Generic Thunks

Microsoft® Windows NT® supports 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 of 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

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 and Windows 98: 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 is not guaranteed to work under Windows 95 and Windows 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, 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 and Windows 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.CallProc32W
    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 or CallProc32W function. You cannot create a prototype for CallProc32W unless you do one of the following:

  • Restrict each file so that it only uses calls to functions that contain the same number of parameters.
  • Create a prototype CallProc32W_1 for functions that use one parameter, CallProc32W_2 for functions that use two parameters, and so forth. When linking your application or DLL, use forwarders to map calls to these functions to CallProc32W.

This is a limitation of the Pascal calling convention. For this reason, you may choose to use the CallProcEx32W function, which uses the C calling convention to support a variable number of arguments.

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);

This first example uses CallProcEx32W.

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

This next example uses CallProc32W:

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

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 CallProc32W or 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 and Windows 98:

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:

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.

If you are targeting only Windows NT 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 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, 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 16-bit and 32-bit functions are associated with generic thunking.


16-bit Generic Thunk Functions

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


CallProc32W

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

You cannot create a prototype for CallProc32W unless you do one of the following:

  • Restrict each file so that it only uses calls to functions that contain the same number of parameters.
  • Create a prototype CallProc32W_1 for functions that use one parameter, CallProc32W_2 for functions that use two parameters, and so forth. When linking your application or DLL, use forwarders to map calls to these functions to CallProc32W.

This is a limitation of the Pascal calling convention. For this reason, you should use the CallProcEx32W function, which uses the C calling convention to support a variable number of arguments.

DWORD FAR PASCAL CallProc32W(
  DWORD param1,            // parameter for DLL function
  DWORD param2,            // parameter for DLL function
  ... ,                    // up to 32 parameters for DLL function
  LPVOID lpProcAddress32,  // the DLL function to be called
  DWORD fAddressConvert,   // bit mask
  DWORD nParams            // number of parameters passed
);

Parameters

param1 through param32
Parameters for the 32-bit procedure represented by lpProcAddress32.
lpProcAddress32
A value corresponding to the procedure to be called, which is returned by the GetProcAddress32W function.
fAddressConvert
Bit mask representing which parameters will be treated as 16:16 pointers and translated into flat linear pointers before being passed to the 32-bit procedure. The lowest bit in the mask represents the last parameter specified (paramN), the second lowest bit represents the second to the last parameter specified (paramN-1), and so on, so that the highest bit in the mask represents param1.
nParams
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 constants:
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.

Return Values

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

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

Remarks

CallProc32W takes at least three parameters: lpProcAddress32, fAddressConvert, and nParams. In addition, it can take a maximum of 32 optional parameters. These parameters must be DWORD types and must match the type that the 32-bit thunk DLL is expecting. If the appropriate bit is set in the fAddressConvert mask, the parameter will be translated from a 16:16 pointer to a 32-bit flat linear pointer.

CallProc32W and CallProcEx32W do 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 and Windows 98: 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, but may cause race conditions in Windows 95 or Windows 98.

Note You should be careful when using this function, because there is no compiler check made on the number and type of parameters, no conversion of types (all parameters are passed as type DWORD and are passed directly to the function without conversion). No checks of the 16:16 address are made (limit checks, NULL checks, correct ring level, and so on).

See Also

CallProcEx32W, GetProcAddress32W


CallProcEx32W

Use the CallProcEx32W function in 16-bit code to call an entry-point function in a 32-bit DLL. CallProcEx32W is similar to CallProc32W, but it uses the C calling convention to allow a variable number of arguments.

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 parameters for DLL function
);

Parameters

nParams
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 constants:
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
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
A value corresponding to the procedure to be called, which is returned by the GetProcAddress32W function.
param1 through param32
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

CallProc32W and CallProcEx32W do 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 and Windows 98: 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, but may cause race conditions in Windows 95 or Windows 98.

See Also

CallProc32W, GetProcAddress32W


FreeLibrary32W

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

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

Parameters

hInst
Identifies 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 and Windows 98: 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.

See Also

LoadLibraryEx32W


GetProcAddress32W

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

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

Parameters

hModule
Identifies the loaded library module that contains the function. The LoadLibraryEx32W function returns this handle.
lpszProc
Points 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 CallProc32W or CallProcEx32W function rather than being used directly.

Remarks

Windows 95 and Windows 98: 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.

See Also

CallProc32W, 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
Valid protected or real mode 16:16 address.
fMode
One of the following flags:
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 and Windows 98: 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.


LoadLibraryEx32W

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

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

Parameters

lpszLibFile
Points to a null-terminated string that names a Win32-based DLL module.
hFile
This parameter is reserved for future use. It must be NULL.
dwFlags
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 CallProc32W or CallProcEx32W function.

Windows 95 and Windows 98: 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.

See Also

CallProc32W, CallProcEx32W, GetProcAddress32W


32-bit Generic Thunk Functions

The following generic thunk functions can be called by Win32-based applications.

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
A 16:16 pointer to 16-bit callback routine, passed from the 16-bit side.
dwParam
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.

See Also

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 pArgs arguments
  PVOID pArgs,       // arguments for callback function
  PDWORD pdwRetCode  // callback function return code
);

Parameters

vpfn16
A 16:16 pointer to 16-bit callback routine, passed from the 16-bit side.
dwFlags
One of the following flags:
WCB16_CDECL | Calls a _cdecl callback routine.
WCB16_PASCAL | Calls a _pascal callback routine (default).

cbArgs
Count of bytes in arguments (used to properly clean the 16-bit stack).
pArgs
Arguments for the callback routine.
pdwRetCode
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.

See Also

LOWORD


WOWGetVDMPointer

The WOWGetVDMPointer function converts a 16:16 address to the equivalent linear address.

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

Parameters

vp
Valid 16:16 address.
dwBytes
Size of the block pointed to by vp.
fProtectedMode
One of the following flags:
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: 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 and Windows 98: 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.


WOWGetVDMPointerFix

The WOWGetVDMPointerFix function converts a 16:16 address to the equivalent linear address.

Windows 95 and Windows 98: 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: 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
Valid 16:16 address.
dwBytes
Size of the block pointed to by vp.
fProtectedMode
One of the following flags:
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.

See Also

WOWGetVDMPointer


WOWGetVDMPointerUnfix

Windows 95 and Windows 98: The WOWGetVDMPointerUnfix function uses the GlobalUnfix function to unfix a pointer retrieved by the WOWGetVDMPointerFix function.

Windows NT: This function has no effect.

VOID WINAPI WOWGetVDMPointerUnfix(
  LPCSTR vp  // 32-bit linear address
);

Parameters

vp
Address retrieved by the WOWGetVDMPointerFix function.

Return Values

This function does not return a value.

See Also

WOWGetVDMPointerFix


WOWGlobalAlloc16

The WOWGlobalAlloc16 function allocates the specified number of bytes from the 16-bit global heap.

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

Parameters

wFlags
Specifies how to allocate memory. This parameter can be a combination of the following values: GHND, GMEM_DDESHARE, GMEM_DISCARDABLE, GMEM_FIXED, GMEM_LOWER, GMEM_MOVEABLE, GMEM_NOCOMPACT, GMEM_NODISCARD, GMEM_NOT_BANKED, GMEM_NOTIFY, GMEM_SHARE, GMEM_ZEROINIT, and GPTR.
cb
Specifies the number of bytes to allocate.

Return Values

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

See Also

WOWGlobalLock16


WOWGlobalAllocLock16

The WOWGlobalAllocLock16 function combines the functionality of the WOWGlobalAlloc16 and WOWGlobalLock16 functions.

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

Parameters

wFlags
Specifies how to allocate memory. This parameter can be a combination of the following values: GHND, GMEM_DDESHARE, GMEM_DISCARDABLE, GMEM_FIXED, GMEM_LOWER, GMEM_MOVEABLE, GMEM_NOCOMPACT, GMEM_NODISCARD, GMEM_NOT_BANKED, GMEM_NOTIFY, GMEM_SHARE, GMEM_ZEROINIT, and GPTR.
cb
Specifies the number of bytes to allocate.
phMem
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.

See Also

WOWGetVDMPointerFix, WOWGlobalAlloc16, WOWGlobalLock16


WOWGlobalFree16

The WOWGlobalFree16 function frees the specified global memory object.

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

Parameters

hMem
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.

See Also

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.

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

Parameters

hMem
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.

See Also

WOWGetVDMPointerFix, WOWGlobalAlloc16, WOWGlobalAllocLock16


WOWGlobalLockSize16

The WOWGlobalLockSize16 function combines the functionality of the WOWGlobalLock16 and 16-bit GlobalSize functions.

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

Parameters

hMem
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.

See Also

WOWGlobalAlloc16, WOWGlobalAllocLock16, WOWGlobalLock16


WOWGlobalUnlock16

The WOWGlobalUnlock16 function unlocks a global memory object.

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

Parameters

hMem
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.


WOWGlobalUnlockFree16

The WOWGlobalUnlockFree16 function combines the functionality of the WOWGlobalUnlock16 and WOWGlobalFree16 functions.

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

Parameters

vpMem
Address of memory block returned by the WOWGlobalLock16 or WOWGlobalAllocLock16 function.

Return Values

Returns NULL if successful.

See Also

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.

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

Parameters

Handle
The 32-bit handle to be mapped.
Type
Indicates the type of handle being translated. The accepted values are of the form WOW_TYPE_handle where handle can be HWND, HMENU, HDWP, HDROP, HDC, HFONT, HMETAFILE, HRGN, HBITMAP, HBRUSH, HPALETTE, HPEN, HACCEL, and 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.


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.

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

Parameters

Handle
The 16-bit handle to be mapped.
Type
Indicates the type of handle being translated. The accepted values are of the form WOW_TYPE_handle where handle can be HWND, HMENU, HDWP, HDROP, HDC, HFONT, HMETAFILE, HRGN, HBITMAP, HBRUSH, HPALETTE, HPEN, HACCEL, HTASK, and FULLHWND. 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.


Handles and Objects

An object is a data structure that represents a system resource, such as a file, thread, or graphic image. An application cannot directly access object data or the system resource that an object represents. Instead, an application must obtain an object handle, which it can use to examine or modify the system resource. Each handle has an entry in an internally maintained table. These entries contain the addresses of the resources and the means to identify the resource type.


About Handles and Objects

The system uses objects and handles to regulate access to system resources for two main reasons. First, the use of objects ensures that Microsoft can update system functionality, as long as the original object interface is maintained. When subsequent versions of the system are released, you can use the updated object with little or no additional work.

Secondly, the use of objects enables you to take advantage of Microsoft® Windows NT® security. Each object has its own access-control list (ACL) that specifies the actions a process can perform on the object. Windows NT examines an object's ACL each time an application creates a handle to the object. For more information, see Access Control.


Object Manager

An object consists of a standard header and object-specific attributes. Because all objects have the same structure, there is a single object manager that maintains all objects.

The object header includes items such as the object name, so that other processes can reference the object by name, and a security descriptor, so that the object manager can control which processes access the system resource.

The tasks that the object manager performs include the following:

  • Creating objects
  • Verifying that that a process has the right to use the object
  • Creating object handles and returning them to the caller
  • Maintaining resource quotas
  • Creating duplicate handles
  • Closing handles to objects


Object Interface

The Microsoft® Win32® application programming interface (API) provides functions that perform the following tasks:

  • Create an object
  • Get an object handle
  • Get information about the object
  • Set information about the object
  • Close the object handle
  • Destroy the object

Some of these tasks are not necessary for each object. Some of these tasks are combined for certain objects. For example, an application can create an event object. Other applications can open the event to obtain a unique handle to this event object. As each application finishes using the event, it closes its handle to the object. When there are no remaining open handles to the event object, the system destroys the event object. In contrast, an application can obtain a handle to an existing window object. When the window object is no longer needed, the application must destroy the object, which invalidates the window handle.

Occasionally, an object remains in memory after all object handles have been closed. For example, a thread could create an event object and wait on the event handle. While the thread is waiting, another thread could close the same event object handle. The event object remains in memory, without any event object handles, until the event object is set to the signaled state and the wait operation is completed. At this time, the system removes the object from memory.

Handles and objects consume memory. Therefore, to preserve system performance, you should close handles and delete objects as soon as they are no longer needed. If you do not do this, your application can hurt system performance, due to excessive use of the paging file.

Note When a process terminates, the system automatically closes handles and deletes objects created by the process. However, when a thread terminates, the system usually does not close handles or delete objects. The only exceptions are window, hook, window position, and dynamic data exchange (DDE) conversation objects; these objects are destroyed when the creating thread terminates.


Handle Limitations

Some objects support only one handle at a time. The system provides the handle when an application creates the object and invalidates the handle when the application destroys the object. Other objects support multiple handles to a single object. The operating system automatically removes the object from memory after the last handle to the object is closed.

The total number of open handles in the system is limited only by the amount of memory available. However, a single process can have no more than 65,536 handles. Some object types support a limited number of handles per process, while other object types support a limited number of handles in the system.


Handle Inheritance

A child process can inherit handles from its parent process. An inherited handle is valid only in the context of the child process. To enable a child process to inherit open handles from its parent process, use the following steps.

  1. Create the handle with the bInheritHandle member of the SECURITY_ATTRIBUTES structure set to TRUE.
  2. Create the child process using the CreateProcess function, with the bInheritHandles parameter set to TRUE.

The DuplicateHandle function duplicates a handle to be used in the current process or in another process. If an application duplicates one of its handles for another process, the duplicated handle is valid only in the context of the other process.

A duplicated or inherited handle is a unique value, but it refers to the same object as the original handle. Processes can inherit or duplicate handles to the following types of objects:

  • Communications device
  • Console input
  • Console screen buffer
  • Desktop
  • Directory
  • Event
  • File
  • File mapping
  • Job
  • Mailslot
  • Mutex
  • Pipe
  • Process
  • Registry key
  • Semaphore
  • Socket
  • Thread
  • Timer
  • Window station

All other objects are private to the process that created them; their object handles cannot be duplicated or inherited.

For more information, see Inheritance.


Object Categories

The system provides three categories of objects: user, graphics device interface (GDI), and kernel. The system uses user objects to support window management, GDI objects to support graphics, and kernel objects to support memory management, process execution, and interprocess communications (IPC). For information about creating and using a specific object, refer to the associated overview.

User Objects

User object | Overview
Accelerator table | Keyboard Accelerators
Caret | Carets
Cursor | Cursors
DDE conversation | Dynamic Data Exchange Management Library
Desktop | Window Stations and Desktops
Hook | Hooks
Icon | Icons
Menu | Menus
Window | Windows
Window position | Windows
Window station | Window Stations and Desktops

GDI Objects

GDI object | Overview
Bitmap | Bitmaps
Brush | Brushes
DC | Device Contexts
Enhanced metafile | Metafiles
Enhanced-metafile DC | Metafiles
Font | Fonts and Text
Memory DC | Device Contexts
Metafile | Metafiles
Metafile DC | Metafiles
Palette | Colors
Pen and extended pen | Pens
Region | Regions

Kernel Objects

Kernel object | Overview
Change notification | File I/O
Communications device | Communications
Console input | Consoles and Character-Mode Support
Console screen buffer | Consoles and Character-Mode Support
Event | Synchronization
Event log | Event Logging
File | File I/O
File mapping | File Mapping
Find file | File I/O
Heap | Memory Management
Job | Job Objects
Mailslot | Mailslots
Module | Dynamic-Link Libraries
Mutex | Synchronization
Pipe | Pipes
Process | Processes and Threads
Semaphore | Synchronization
Socket | Windows Sockets 2
Thread | Processes and Threads
Timer | Synchronization
Update resource | Resources


User Objects

User objects support only one handle per object. Processes cannot inherit or duplicate handles to user objects. There is no per-process limit on user handles, but there is a system-wide limit of 65,536 user handles.

Handles to user objects are public to all processes. That is, any process can use the user object handle, provided that the process has security access to the object.

In the following illustration, an application creates a window object. The CreateWindow function creates the window object and returns an object handle.

After the window object has been created, the application can use the window handle to display or change the window. The handle remains valid until the window object is destroyed.

In the next illustration, the application destroys the window object. The DestroyWindow function removes the window object from memory, which invalidates the window handle.

The following table lists the user objects, along with each object's creator and destroyer functions. The creator functions either create the object and an object handle or simply return the existing object handle. The destroyer functions remove the object from memory, which invalidates the object handle.

User Objects

Object | Creator function | Destroyer function
Accelerator table | CreateAcceleratorTable | DestroyAcceleratorTable
Caret | CreateCaret | DestroyCaret
Cursor | CreateCursor, LoadCursor, LoadImage | DestroyCursor
DDE conversation | DdeConnect, DdeConnectList | DdeDisconnect, DdeDisconnectList
Desktop | GetThreadDesktop | Applications cannot delete this object.
Hook | SetWindowsHookEx | UnhookWindowsHookEx
Icon | CreateIconIndirect, LoadIcon, LoadImage | DestroyIcon
Menu | CreateMenu, CreatePopupMenu, LoadMenu, LoadMenuIndirect | DestroyMenu
Window | CreateWindow, CreateWindowEx, CreateDialogParam, CreateDialogIndirectParam, CreateMDIWindow | DestroyWindow
Window position | BeginDeferWindowPos | EndDeferWindowPos
Window station | GetProcessWindowStation | Applications cannot delete this object.


GDI Objects

GDI objects support only one handle per object. Handles to GDI objects are private to a process. That is, only the process that created the GDI object can use the object handle. A single process may have no more than 16,384 open GDI object handles.

The following table lists the GDI objects, along with each object's creator and destroyer functions. The creator functions either create the object and an object handle or simply return the existing object handle. The destroyer functions remove the object from memory, which invalidates the object handle.

GDI Objects

Object | Creator function | Destroyer function
Bitmap | CreateBitmap, CreateBitmapIndirect, CreateCompatibleBitmap, CreateDIBitmap, CreateDIBSection, CreateDiscardableBitmap | DeleteObject
Brush | CreateBrushIndirect, CreateDIBPatternBrush, CreateDIBPatternBrushPt, CreateHatchBrush, CreatePatternBrush, CreateSolidBrush | DeleteObject
DC | CreateDC | DeleteDC, ReleaseDC
Enhanced metafile | CreateEnhMetaFile | DeleteEnhMetaFile
Enhanced-metafile DC | CreateEnhMetaFile | CloseEnhMetaFile
Font | CreateFont, CreateFontIndirect | DeleteObject
Memory DC | CreateCompatibleDC | DeleteDC
Metafile | CreateMetaFile | DeleteMetaFile
Metafile DC | CreateMetaFile | CloseMetaFile
Palette | CreatePalette | DeleteObject
Pen and extended pen | CreatePen, CreatePenIndirect, ExtCreatePen | DeleteObject
Region | CombineRgn, CreateEllipticRgn, CreateEllipticRgnIndirect, CreatePolygonRgn, CreatePolyPolygonRgn, CreateRectRgn, CreateRectRgnIndirect, CreateRoundRectRgn, ExtCreateRegion, PathToRegion | DeleteObject


Kernel Objects

Kernel object handles are process specific. That is, a process must either create the object or open an existing object to obtain a kernel object handle. The per-process limit on kernel handles is 2^30.

Any process can create a new handle to an existing kernel object (even one created by another process), provided that the process knows the name of the object and has security access to the object. Kernel object handles include access rights that indicate the actions that can be granted or denied to a process. An application specifies access rights when it creates an object or obtains an existing object handle. Each type of kernel object supports its own set of access rights. For example, event handles can have "set" or "wait" access (or both), file handles can have "read" or "write" access (or both), and so on. For more information, see Securable Objects.

In the following illustration, an application creates an event object. The CreateEvent function creates the event object and returns an object handle.

After the event object has been created, the application can use the event handle to set or wait on the event. The handle remains valid until the application closes the handle or terminates.

Most kernel objects support multiple handles to a single object. For example, the application in the preceding illustration could obtain additional event object handles by using the OpenEvent function, as shown in the following illustration.

This method enables an application to have handles with different access rights. For example, Handle 1 might have "set" and "wait" access to the event, and Handle 2 might have only "wait" access.

If another process knows the event name and has security access to the object, it can create its own event object handle by using OpenEvent. The creating application could also duplicate one of its handles into the same process or into another process by using the DuplicateHandle function.

An object remains in memory as long as at least one object handle exists. In the following illustration, the applications use the CloseHandle function to close their event object handles. When there are no event handles, the system removes the object from memory, as shown in the following illustration.

The system manages file objects somewhat differently from other kernel objects. File objects contain the file pointer — the pointer to the next byte to be read or written in a file. Whenever an application creates a new file handle, the system creates a new file object. Therefore, more than one file object can refer to a single file on disk, as shown in the next illustration.

Only through duplication or inheritance can more than one file handle refer to the same file object, as shown in the following illustration.

The following table lists each of the kernel objects, along with each object's creator and destroyer functions. The creator functions either create the object and an object handle or create a new existing object handle. The destroyer functions close the object handle. When an application closes the last handle to a kernel object, the system removes the object from memory.

Kernel Objects

Object | Creator function | Destroyer function
Change notification | FindFirstChangeNotification | FindCloseChangeNotification
Communications
device 		CreateFile CloseHandle
Console input | CreateFile, with CONIN$ | CloseHandle
Console screen buffer | CreateFile, with CONOUT$ | CloseHandle
Event | CreateEvent, OpenEvent | CloseHandle
Event log | OpenEventLog, RegisterEventSource, OpenBackupEventLog | CloseEventLog
File | CreateFile | CloseHandle , DeleteFile
File mapping | CreateFileMapping, OpenFileMapping | CloseHandle
Find file | FindFirstFile | FindClose
Heap | HeapCreate | HeapDestroy
Job | CreateJobObject | CloseHandle
Mailslot | CreateMailslot | CloseHandle
Module | LoadLibrary, GetModuleHandle | FreeLibrary
Mutex | CreateMutex, OpenMutex | CloseHandle
Pipe | CreateNamedPipe, CreatePipe | CloseHandle, DisconnectNamedPipe
Process | CreateProcess, OpenProcess, GetCurrentProcess | CloseHandle, TerminateProcess
Semaphore | CreateSemaphore , OpenSemaphore | CloseHandle
Socket | socket, accept | CloseHandle
Thread | CreateThread, CreateRemoteThread, GetCurrentThread | CloseHandle, TerminateThread
Timer | CreateWaitableTimer , OpenWaitableTimer | CloseHandle
Update resource | BeginUpdateResource | EndUpdateResource


Handle and Object Reference

The following elements are used with handles and objects.

  • Handle and Object Functions


Handle and Object Functions

The following functions are used with handles and objects.

CloseHandle
DuplicateHandle
GetHandleInformation
SetHandleInformation


CloseHandle

The CloseHandle function closes an open object handle.

BOOL CloseHandle(
  HANDLE hObject   // handle to object to close
);

Parameters

hObject
Handle to an open object.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The CloseHandle function closes handles to the following objects:

  • Communications device
  • Console input
  • Console screen buffer
  • Event
  • File
  • File mapping
  • Job
  • Mailslot
  • Mutex
  • Named pipe
  • Process
  • Semaphore
  • Socket
  • Thread
  • Token

CloseHandle invalidates the specified object handle, decrements the object's handle count, and performs object retention checks. After the last handle to an object is closed, the object is removed from the system.

Closing a thread handle does not terminate the associated thread. To remove a thread object, you must terminate the thread, then close all handles to the thread.

Use CloseHandle to close handles returned by calls to the CreateFile function. Use FindClose to close handles returned by calls to the FindFirstFile function.

Closing an invalid handle raises an exception. This includes closing a handle twice, not checking the return value and closing an invalid handle, and using CloseHandle on a handle returned by FindFirstFile.

Windows CE: Windows CE does not support closing handles to the following objects:

  • Console input or output
  • File mapping
  • Named pipe
  • Semaphore
  • Token

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Handles and Objects Overview, Handle and Object Functions, CreateFile, DeleteFile, FindClose, FindFirstFile


DuplicateHandle

The DuplicateHandle function duplicates an object handle.

BOOL DuplicateHandle(
  HANDLE hSourceProcessHandle,  // handle to the source process
  HANDLE hSourceHandle,         // handle to duplicate
  HANDLE hTargetProcessHandle,  // handle to process to duplicate to
  LPHANDLE lpTargetHandle,  // pointer to duplicate handle
  DWORD dwDesiredAccess,    // access for duplicate handle
  BOOL bInheritHandle,      // handle inheritance flag
  DWORD dwOptions           // optional actions
);

Parameters

hSourceProcessHandle
Handle to the process with the handle to duplicate.

Windows NT: The handle must have PROCESS_DUP_HANDLE access.

hSourceHandle
Handle to duplicate. This is an open object handle that is valid in the context of the source process. For a list of objects whose handles can be duplicated, see the following Remarks section.
hTargetProcessHandle
Handle to the process that is to receive the duplicated handle. The handle must have PROCESS_DUP_HANDLE access.
lpTargetHandle
Pointer to a variable receiving the value of the duplicate handle. This handle value is valid in the context of the target process.

If lpTargetHandle is NULL, the function duplicates the handle, but does not return the duplicate handle value to the caller. This behavior exists only for backward compatibility with previous versions of this function. You should not use this feature, as you will lose system resources until the target process terminates.

dwDesiredAccess
Specifies the access requested for the new handle. This parameter is ignored if the dwOptions parameter specifies the DUPLICATE_SAME_ACCESS flag. Otherwise, the flags that can be specified depend on the type of object whose handle is being duplicated. For the flags that can be specified for each object type, see the following Remarks section. Note that the new handle can have more access than the original handle.
bInheritHandle
Indicates whether the handle is inheritable. If TRUE, the duplicate handle can be inherited by new processes created by the target process. If FALSE, the new handle cannot be inherited.
dwOptions
Specifies optional actions. This parameter can be zero, or any combination of the following flags:
Value | Meaning
DUPLICATE_CLOSE_SOURCE | Closes the source handle. This occurs regardless of any error status returned.
DUPLICATE_SAME_ACCESS | Ignores the dwDesiredAccess parameter. The duplicate handle has the same access as the source handle.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

DuplicateHandle can be called by either the source process or the target process. It can also be invoked where the source and target process are the same. For example, a process can use DuplicateHandle to create a noninheritable duplicate of an inheritable handle, or a handle with different access than the original handle.

The duplicating process uses the GetCurrentProcess function to get a handle of itself. To get the other process handle, it may be necessary to use some form of interprocess communication (for example, named pipe or shared memory) to communicate the process identifier to the duplicating process. This identifier is then used in the OpenProcess function to open a handle.

If the process that calls DuplicateHandle is not the target process, the duplicating process must use interprocess communication to pass the value of the duplicate handle to the target process.

The duplicate handle is the same object handle as the source handle. This means that the state of the object is the same for both handles. For example, the current file mark for a file handle is always the same for both handles.

DuplicateHandle can duplicate handles to the following types of objects:

Object | Description
Communications device | The handle is returned by the CreateFile function.
Console input | The handle is returned by the CreateFile function when CONIN$ is specified, or by the GetStdHandle function when STD_INPUT_HANDLE is specified. Console handles can be duplicated for use only in the same process.
Console screen buffer | The handle is returned by the CreateFile function when CONOUT$ is specified, or by the GetStdHandle function when STD_OUTPUT_HANDLE is specified. Console handles can be duplicated for use only in the same process.
Desktop | The handle is returned by the GetThreadDesktop function.
Directory | The handle is returned by the CreateDirectory function.
Event | The handle is returned by the CreateEvent or OpenEvent function.
File | The handle is returned by the CreateFile function.
File mapping | The handle is returned by the CreateFileMapping function.
Job | The handle is returned by the CreateJobObject function.
Mailslot | The handle is returned by the CreateMailslot function.
Mutex | The handle is returned by the CreateMutex or OpenMutex function.
Pipe | A named pipe handle is returned by the CreateNamedPipe or CreateFile function. An anonymous pipe handle is returned by the CreatePipe function.
Process | The handle is returned by the CreateProcess, GetCurrentProcess, or OpenProcess function.
Registry key Windows NT: The handle is returned by the RegCreateKey, RegCreateKeyEx, RegOpenKey, or RegOpenKeyEx function. Note that registry key handles returned by the RegConnectRegistry function cannot be used in a call to DuplicateHandle.

Windows 95: You cannot use DuplicateHandle to duplicate registry key handles.

Semaphore | The handle is returned by the CreateSemaphore or OpenSemaphore function.
Socket | The handle is returned by the socket or accept function.
Thread | The handle is returned by the CreateProcess, CreateThread, CreateRemoteThread, or GetCurrentThread function
Timer | The handle is returned by the CreateWaitableTimer or OpenWaitableTimer function.
Window station | The handle is returned by the GetProcessWindowStation function.

In addition to STANDARD_RIGHTS_REQUIRED, the following access flags can be specified in the dwDesiredAccess parameter for the different object types. Note that the new handle can have more access than the original handle. However, in some cases DuplicateHandle cannot create a duplicate handle with more access permission than the original handle. For example, a file handle created with GENERIC_READ access cannot be duplicated so that it has both GENERIC_READ and GENERIC_WRITE access.

Any combination of the following access flags is valid for handles to communications devices, console input, console screen buffers, files, and pipes:

Access | Description
GENERIC_READ | Enables read access.
GENERIC_WRITE | Enables write access.

Any combination of the following access flags is valid for file-mapping objects:

Access | Description
FILE_MAP_ALL_ACCESS | Specifies all possible access flags for the file-mapping object.
FILE_MAP_READ | Enables mapping the object into memory that permits read access.
FILE_MAP_WRITE | Enables mapping the object into memory that permits write access. For write access, PAGE_READWRITE protection must have been specified when the file-mapping object was created by the CreateFileMapping function.

Any combination of the following access flags is valid for mutex objects:

Access | Description
MUTEX_ALL_ACCESS | Specifies all possible access flags for the mutex object.
SYNCHRONIZE | Windows NT: Enables use of the mutex handle in any of the wait functions to acquire ownership of the mutex, or in the ReleaseMutex function to release ownership.

Any combination of the following access flags is valid for semaphore objects:

Access | Description
SEMAPHORE_ALL_ACCESS | Specifies all possible access flags for the semaphore object.
SEMAPHORE_MODIFY_STATE | Enables use of the semaphore handle in the ReleaseSemaphore function to modify the semaphore's count.
SYNCHRONIZE | Windows NT: Enables use of the semaphore handle in any of the wait functions to wait for the semaphore's state to be signaled.

Any combination of the following access flags is valid for event objects:

Access | Description
EVENT_ALL_ACCESS | Specifies all possible access flags for the event object.
EVENT_MODIFY_STATE | Enables use of the event handle in the SetEvent and ResetEvent functions to modify the event's state.
SYNCHRONIZE | Windows NT: Enables use of the event handle in any of the wait functions to wait for the event's state to be signaled.

Any combination of the following access flags is valid for handles to registry keys:

Value | Meaning
KEY_ALL_ACCESS | Specifies all possible flags for the registry key.
KEY_CREATE_LINK | Enables using the handle to create a link to a registry-key object.
KEY_CREATE_SUB_KEY | Enables using the handle to create a subkey of a registry-key object.
KEY_ENUMERATE_SUB_KEYS | Enables using the handle to enumerate the subkeys of a registry-key object.
KEY_EXECUTE | Equivalent to KEY_READ.
KEY_NOTIFY | Enables using the handle to request change notifications for a registry key or for subkeys of a registry key.
KEY_QUERY_VALUE | Enables using the handle to query a value of a registry-key object.
KEY_READ | Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY values.
KEY_SET_VALUE | Enables using the handle to create or set a value of a registry-key object.
KEY_WRITE | Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUB_KEY values.

Any combination of the following access flags is valid for process objects:

Access | Description
PROCESS_ALL_ACCESS | Specifies all possible access flags for the process object.
PROCESS_CREATE_PROCESS | Used internally.
PROCESS_CREATE_THREAD | Enables using the process handle in the CreateRemoteThread function to create a thread in the process.
PROCESS_DUP_HANDLE | Enables using the process handle as either the source or target process in the DuplicateHandle function to duplicate a handle.
PROCESS_QUERY_INFORMATION | Enables using the process handle in the GetExitCodeProcess and GetPriorityClass functions to read information from the process object.
PROCESS_SET_INFORMATION | Enables using the process handle in the SetPriorityClass function to set the process's priority class.
PROCESS_TERMINATE | Enables using the process handle in the TerminateProcess function to terminate the process.
PROCESS_VM_OPERATION | Enables using the process handle in the VirtualProtectEx and WriteProcessMemory functions to modify the virtual memory of the process.
PROCESS_VM_READ | Enables using the process handle in the ReadProcessMemory function to read from the virtual memory of the process.
PROCESS_VM_WRITE | Enables using the process handle in the WriteProcessMemory function to write to the virtual memory of the process.
SYNCHRONIZE | Windows NT: Enables using the process handle in any of the wait functions to wait for the process to terminate.

Any combination of the following access flags is valid for thread objects:

Access | Description
SYNCHRONIZE | Windows NT: Enables using the thread handle in any of the wait functions to wait for the thread to terminate.
THREAD_ALL_ACCESS | Specifies all possible access flags for the thread object.
THREAD_DIRECT_IMPERSONATION | Used internally.
THREAD_GET_CONTEXT | Enables using the thread handle in the GetThreadContext function to read the thread's context.
THREAD_IMPERSONATE | Used internally.
THREAD_QUERY_INFORMATION | Enables using the thread handle in the GetExitCodeThread, GetThreadPriority, and GetThreadSelectorEntry functions to read information from the thread object.
THREAD_SET_CONTEXT | Enables using the thread handle in the SetThreadContext function to set the thread's context.
THREAD_SET_INFORMATION | Enables using the thread handle in the SetThreadPriority function to set the thread's priority.
THREAD_SET_THREAD_TOKEN | Used internally.
THREAD_SUSPEND_RESUME | Enables using the thread handle in the SuspendThread or ResumeThread functions to suspend or resume a thread.
THREAD_TERMINATE | Enables using the thread handle in the TerminateThread function to terminate the thread.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Handles and Objects Overview, Handle and Object Functions, CloseHandle, CreateEvent, CreateFile, CreateFileMapping, CreateMutex, CreateNamedPipe, CreatePipe, CreateProcess, CreateRemoteThread, CreateSemaphore, CreateThread, CreateWaitableTimer, GetCurrentProcess, GetExitCodeProcess, GetExitCodeThread, GetPriorityClass, GetStdHandle, GetThreadContext, GetThreadPriority, GetThreadSelectorEntry, OpenEvent, OpenMutex, OpenProcess, OpenSemaphore, OpenWaitableTimer, ReadProcessMemory, RegConnectRegistry, RegCreateKey, RegCreateKeyEx, RegOpenKey, RegOpenKeyEx, ReleaseMutex, ReleaseSemaphore, ResetEvent, ResumeThread, SetEvent, SetPriorityClass, SetThreadContext, SetThreadPriority, SuspendThread, TerminateProcess, TerminateThread, VirtualProtectEx, WriteProcessMemory


GetHandleInformation

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

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

Parameters

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

You can specify a handle to one of the following types of objects: access token, event, file, file mapping, job, mailslot, mutex, pipe, printer, process, registry key, semaphore, serial communication device, socket, thread, or waitable timer.

Windows NT 5.0 and later: This parameter can also be a handle to a console input buffer or a console screen buffer.

lpdwFlags
Pointer to a variable that receives a set of bit flags that specify properties of the object handle. The following flags are defined:
Value | Meaning
HANDLE_FLAG_INHERIT | If this flag is set, a child process created with the bInheritHandles parameter of CreateProcess set to TRUE will inherit the object handle.
HANDLE_FLAG_PROTECT_FROM_CLOSE | If this flag is set, calling the CloseHandle function will not close the object handle.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Handles and Objects Overview, Handle and Object Functions, CloseHandle, CreateProcess, SetHandleInformation


SetHandleInformation

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

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

Parameters

hObject
Handle to an object. The SetHandleInformation function sets information associated with this object handle.

You can specify a handle to one of the following types of objects: access token, event, file, file mapping, job, mailslot, mutex, pipe, printer, process, registry key, semaphore, serial communication device, socket, thread, or waitable timer.

Windows NT 5.0 and later: This parameter can also be a handle to a console input buffer or a console screen buffer.

dwMask
A mask that specifies the bit flags to be changed. Use the same flag constants shown in the description of dwFlags.
dwFlags
A set of bit flags that specify properties of the object handle. The following flags are defined:
Value | Meaning
HANDLE_FLAG_INHERIT | If this flag is set, a child process created with the bInheritHandles parameter of CreateProcess set to TRUE will inherit the object handle.
HANDLE_FLAG_PROTECT_FROM_CLOSE | If this flag is set, calling the CloseHandle function will not close the object handle.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

To set or clear the associated bit flag in dwFlags, you must set a change mask bit flag in dwMask.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Handles and Objects Overview, Handle and Object Functions, CreateProcess, CloseHandle, GetHandleInformation


Large Integer Operations

This overview describes the support for operations on large (64-bit) integers provided by the Microsoft® Win32® API.

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 Operations Reference

The following elements are used with large integer operations.

  • Large Integer Operations Functions
  • Large Integer Operations Structures


Large Integer Operations Functions

The following functions are used with large integer operations.

Int32x32To64
Int64ShllMod32
Int64ShraMod32
Int64ShrlMod32
MulDiv
UInt32x32To64


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,    // the first signed 32-bit integer
  LONG Multiplicand   // the second signed 32-bit integer
);

Parameters

Multiplier
Specifies the first signed 32-bit integer for the multiplication.
Multiplicand
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.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Large Integer Operations Overview, Large Integer Operations Functions, 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,  // the unsigned 64-bit integer to shift left logically
  DWORD ShiftCount  // a shift count in the range 0 - 31
);

Parameters

Value
Specifies the unsigned 64-bit integer to be shifted.
ShiftCount
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.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Large Integer Operations Overview, Large Integer Operations Functions, 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 to shift right arithmetically
  DWORD ShiftCount   // a shift count in the range 0 – 31
);

Parameters

Value
Specifies the signed 64-bit integer to be shifted.
ShiftCount
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.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Large Integer Operations Overview, Large Integer Operations Functions, 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 to shift right logically
  DWORD ShiftCount  // a shift count in the range 0 – 31
);

Parameters

Value
Specifies the unsigned 64-bit integer to be shifted.
ShiftCount
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.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Large Integer Operations Overview, Large Integer Operations Functions, 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
Specifies the multiplicand.
nNumerator
Specifies the multiplier.
nDenominator
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.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Large Integer Operations Overview, Large Integer Operations Functions, 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,    // the first unsigned 32-bit integer
  DWORD Multiplicand   // the second unsigned 32-bit integer
);

Parameters

Multiplier
Specifies the first unsigned 32-bit integer for the multiplication.
Multiplicand
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.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Large Integer Operations Overview, Large Integer Operations Functions, Int32x32To64


Large Integer Operations Structures

The following structures are used with large integer operations.

LARGE_INTEGER
ULARGE_INTEGER


LARGE_INTEGER

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

typedef union _LARGE_INTEGER {
    struct {
        DWORD LowPart;
        LONG  HighPart;
    };
    LONGLONG QuadPart;
} LARGE_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.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Large Integer Operations Overview, Large Integer Operations Structures, LUID, ULARGE_INTEGER


ULARGE_INTEGER

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

typedef union _ULARGE_INTEGER {
    struct {
        DWORD LowPart;
        DWORD HighPart;
    };
    ULONGLONG QuadPart;
} ULARGE_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.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnt.h.

See Also

Large Integer Operations Overview, Large Integer Operations Structures, LARGE_INTEGER


Memory Management

This overview describes the memory management provided by the Microsoft® Win32® API. It also explains how to allocate and use memory.


About Memory Management

Each process has its own 32-bit virtual address space that enables addressing up to 4 gigabytes (GB) of memory. For information on the virtual address space and the functions provided by Win32® memory management, see the following topics.

  • Virtual Address Space
  • Virtual Memory Functions
  • Heap Functions
  • Access Validation Functions
  • Global and Local Functions
  • Standard C Library Functions


Virtual Address Space

The virtual addresses used by a process do not represent the actual physical location of an object in memory. Instead, the system maintains a page map for each process, which is an internal data structure used to translate virtual addresses into corresponding physical addresses.

The virtual address space is divided into partitions.

Windows NT Server, Enterprise Edition: The 3 GB partition in low memory (0x00000000 to 0xBFFFFFFF) is available to the process, and the 1 GB partition in high memory (0xC0000000 to 0xFFFFFFFF) is reserved for the system.

Windows NT: The 2 GB partition in low memory (0x00000000 to 0x7FFFFFFF) is available to the process, and the 2 GB partition in high memory (0x80000000 to 0xFFFFFFFF) is reserved for the system.

Windows 95 and Windows 98: The 4 MB partition in low memory (0x00000000 to 0x00000FFF) is used for compatibility with MS-DOS and 16-bit Windows, the next approximately 2G partition (0x00400000 to 0x7FFFFFFF) is available to the process for private use, the next 1 GB partition (0x80000000 to 0xBFFFFFFF) is shared by all Win32 processes, and the 1 GB partition in high memory (0xC0000000 to 0xFFFFFFF) is used by the system.

For more information on virtual memory, see the following topics.

  • Virtual Address Space and Physical Storage
  • Page State
  • Scope of Allocated Memory


Virtual Address Space and Physical Storage

The virtual address space of each process is much larger than the total physical memory available to all processes. To increase the size of physical storage, the system uses the disk for additional storage. The total amount of storage available to all executing processes is the sum of the physical memory and the free space on disk available to the paging file, a disk file used to increase the amount of physical storage. Physical storage and the virtual address space of each process are organized into pages, units of memory, whose size depends on the host computer. For example, on x86 computers the host page size is 4 kilobytes.

To maximize its flexibility in managing memory, the system can move pages of physical memory to and from a paging file on disk. When a page is moved in physical memory, the system updates the page maps of the affected processes. When the system needs space in physical memory, it moves the least recently used pages of physical memory to the paging file. Manipulation of physical memory by the system is completely transparent to applications, which operate only in their virtual address spaces.


Page State

The pages of a process's virtual address space can be in one of the following states.

State | Description
Free | A free page is not currently accessible, but it is available to be committed or reserved.
Reserved | A reserved page is a block of the process's virtual address space that has been set aside for future use. The process cannot access a reserved page, and there is no physical storage associated with it. A reserved page reserves a range of virtual addresses that cannot be used subsequently by other allocation functions. A process can use the VirtualAlloc function to reserve pages of its address space and later to commit the reserved pages. It can use the VirtualFree function to release them.
Committed | A committed page is one for which physical storage (in memory or on disk) has been allocated. It can be protected to allow either no access or read-only access, or it can have read and write access. A process can use the VirtualAlloc function to allocate committed pages. The GlobalAlloc and LocalAlloc functions allocate committed pages with read-write access. A committed page allocated by VirtualAlloc can be decommitted by the VirtualFree function, which releases the page's storage and changes the state of the page to reserved.


Scope of Allocated Memory

All memory a process allocates by using the Win32 memory allocation functions (HeapAlloc, VirtualAlloc, GlobalAlloc, LocalAlloc, or their VLM equivalents) is accessible only to the process. However, memory allocated by a DLL is allocated in the address space of the process that called the DLL and is not accessible to other processes using the same DLL. To create shared memory, you must use file mapping.

Named file mapping provides an easy way to create a block of shared memory. A process can specify a name when it uses the CreateFileMapping function to create a file-mapping object. Other processes can specify the same name to either the CreateFileMapping or OpenFileMapping function to obtain a handle to the mapping object.

Each process specifies its handle to the file-mapping object in the MapViewOfFile function to map a view of the file into its own address space. The views of all processes for a single file-mapping object are mapped into the same sharable pages of physical storage. However, the virtual addresses of the mapped views can vary from one process to another, unless the MapViewOfFileEx function is used to map the view at a specified address. Although sharable, the pages of physical storage used for a mapped file view are not global; they are not accessible to processes that have not mapped a view of the file.

Any pages committed by mapping a view of a file are released when the last process with a view of the mapping object either terminates or unmaps its view by calling the UnmapViewOfFile function. At this time, the specified file (if any) associated with the mapping object is updated. A specified file can also be forced to update by calling the FlushViewOfFile function.

For more information, see File Mapping. For an example of shared memory in a DLL, see Using Shared Memory in a Dynamic-Link Library.

If multiple processes have write access to shared memory, you must synchronize access to the memory. For more information, see Synchronization.


Virtual Memory Functions

The Microsoft® Win32® API provides a set of virtual memory functions that enable a process to manipulate or determine the status of pages in its virtual address space. They can perform the following operations:

  • Reserve a range of a process's virtual address space. Reserving address space does not allocate any physical storage, but it prevents other allocation operations from using the specified range. It does not affect the virtual address spaces of other processes. Reserving pages prevents needless consumption of physical storage, while enabling a process to reserve a range of its address space into which a dynamic data structure can grow. The process can allocate physical storage for this space, as needed.
  • Commit a range of reserved pages in a process's virtual address space so that physical storage (either in RAM or on disk) is accessible only to the allocating process.
  • Specify read-write, read-only, or no access for a range of committed pages. This differs from the standard allocation functions that always allocate pages with read-write access.
  • Free a range of reserved pages, making the range of virtual addresses available for subsequent allocation operations by the calling process.
  • Decommit a range of committed pages, releasing their physical storage and making it available for subsequent allocation by any process.
  • Lock one or more pages of committed memory into physical memory (RAM) so that the system cannot swap the pages out to the paging file.
  • Obtain information about a range of pages in the virtual address space of the calling process or a specified process.
  • Change the access protection for a specified range of committed pages in the virtual address space of the calling process or a specified process.

For more information, see the following topics.

  • Allocating Virtual Memory
  • Freeing Virtual Memory
  • Working With Pages


Allocating Virtual Memory

The virtual memory functions manipulate pages of memory. The functions use the size of a page on the current computer to round off specified sizes and addresses.

The VirtualAlloc function performs one of the following operations:

  • Reserves one or more free pages.
  • Commits one or more reserved pages.
  • Reserves and commits one or more free pages.

You can specify the starting address of the pages to be reserved or committed, or you can allow the system to determine the address. The function rounds the specified address to the appropriate page boundary. Reserved pages are not accessible, but committed pages can be allocated with the PAGE_READWRITE, PAGE_READONLY, or PAGE_NOACCESS flag. When pages are committed, storage is allocated in the paging file, but each page is initialized and loaded into physical memory only at the first attempt to read from or write to that page. You can use normal pointer references to access memory committed by the VirtualAlloc function.


Freeing Virtual Memory

The VirtualFree function performs one of the following operations:

  • Decommits one or more committed pages, changing the state of the pages to reserved. Decommitting pages releases the physical storage associated with the pages, making it available to be allocated by any process. Any block of committed pages can be decommitted.
  • Releases a block of one or more reserved pages, changing the state of the pages to free. Releasing a block of pages makes the range of reserved addresses available to be allocated by the process. Reserved pages can be released only by freeing the entire block that was initially reserved by VirtualAlloc.
  • Decommits and releases a block of one or more committed pages simultaneously, changing the state of the pages to free. The specified block must include the entire block initially reserved by VirtualAlloc, and all of the pages must be currently committed.


Working with Pages

To determine the size of a page on the current computer, use the GetSystemInfo function.

The VirtualQuery and VirtualQueryEx functions return information about a region of consecutive pages beginning at a specified address in the address space of a process. VirtualQuery returns information about memory in the calling process. VirtualQueryEx returns information about memory in a specified process and is used to support debuggers that need information about a process being debugged. The region of pages is bounded by the specified address rounded down to the nearest page boundary. It extends through all subsequent pages with the following attributes in common:

  • The state of all pages is the same: either committed, reserved, or free.
  • If the initial page is not free, all pages in the region are part of the same initial allocation of pages that were reserved by a call to VirtualAlloc.
  • The access protection of all pages is the same (that is, the PAGE_READONLY, PAGE_READWRITE, or PAGE_NOACCESS flag).

The VirtualLock function enables a process to lock one or more pages of committed memory into physical memory (RAM), preventing the system from swapping the pages out to the paging file. It can be used to ensure that critical data is accessible without disk access. Locking pages into memory is dangerous because it restricts the system's ability to manage memory. Excessive use of VirtualLock can degrade system performance by causing executable code to be swapped out to the paging file. The VirtualUnlock function unlocks memory locked by VirtualLock.

The VirtualProtect function enables a process to modify the access protection of any committed page in the address space of a process. For example, a process can allocate read-write pages to store sensitive data, and then it can change the access to read only or no access to protect against accidental overwriting. VirtualProtect is typically used with pages allocated by VirtualAlloc, but it also works with pages committed by any of the other allocation functions. However, VirtualProtect changes the protection of entire pages, and pointers returned by the other functions are not necessarily aligned on page boundaries. The VirtualProtectEx function is similar to VirtualProtect, except it changes the protection of memory in a specified process. Changing the protection is useful to debuggers in accessing the memory of a process being debugged.


Heap Functions

The heap functions enable a process to create a private heap, a block of one or more pages in the address space of the calling process. The process can then use a separate set of functions to manage the memory in that heap. There is no difference between memory allocated from a private heap and that allocated by using the other memory allocation functions.

The HeapCreate function creates a private heap object from which the calling process can allocate memory blocks by using the HeapAlloc function. HeapCreate specifies both an initial size and a maximum size for the heap. The initial size determines the number of committed, read-write pages initially allocated for the heap. The maximum size determines the total number of reserved pages. These pages create a contiguous block in the virtual address space of a process into which the heap can grow. Additional pages are automatically committed from this reserved space if requests by HeapAlloc exceed the current size of committed pages, assuming that the physical storage for it is available. Once the pages are committed, they are not decommitted until the process is terminated or until the heap is destroyed by calling the HeapDestroy function.

The memory of a private heap object is accessible only to the process that created it. If a dynamic-link library (DLL) creates a private heap, it does so in the address space of the process that called the DLL. It is accessible only to that process.

The HeapAlloc function allocates a specified number of bytes from a private heap and returns a pointer to the allocated block. The pointer identifies the block for the HeapFree function to release or for the HeapSize function to determine the size.

Memory allocated by HeapAlloc is not movable. Because the system cannot compact a private heap, the heap can become fragmented.

A possible use for the heap functions is to create a private heap when a process starts up, specifying an initial size sufficient to satisfy the memory requirements of the process. If the call to the HeapCreate function fails, the process can terminate or notify the user of the memory shortage; if it succeeds, however, the process is assured of having the memory it needs.

Memory requested by HeapCreate may or may not be contiguous. Memory allocated within a heap by HeapAlloc is contiguous. You should not write to or read from memory in a heap except that allocated by HeapAlloc, nor should you assume any relationship between two areas of memory allocated by HeapAlloc.


Access Validation Functions

The Win32 API provides a set of functions that a process can use to verify whether it has a specified type of access to a given memory address or range of addresses. The following access validation functions are available.

Function | Description
IsBadCodePtr | Determines whether the calling process has read access to the memory at the specified address.
IsBadReadPtr | Determines whether the calling process has read access to the memory at a specified range of addresses.
IsBadStringPtr | Determines whether the calling process has read access to the memory pointed to by a null-terminated string pointer. The function validates access for a specified number of characters or until it encounters the string's terminating null character.
IsBadWritePtr | Determines whether the calling process has write access to the memory at a specified range of addresses.

The IsBadHugeReadPtr and IsBadHugeWritePtr functions are also available for compatibility with 16-bit versions of Windows that distinguished between normal memory allocations and huge allocations occupying multiple segments. In 32-bit versions of Windows, these functions are equivalent to IsBadReadPtr and IsBadWritePtr.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when an access validation function indicates that the process has the desired access to the specified memory, you should use structured exception handling when attempting to access the memory. Use of structured exception handling enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception. For more information, see Structured Exception Handling.


Very Large Memory (VLM)

[This is preliminary documentation and subject to change.]

The Very Large Memory (VLM) extensions provide 64-bit addressing for very large regions of memory on Microsoft® Windows NT®. Before working with VLM, you should be familiar with memory management and file mapping.

The following sections describe VLM:

  • Advantages of VLM
  • Restrictions on VLM
  • VLM Memory Requirements
  • VLM Functions


Advantages of VLM

[This is preliminary documentation and subject to change.]

Certain data-intensive applications such as database management systems, scientific and engineering software need access to very large caches of data. In the case of very large data sets, restricting the cache to fit within an application's 2 GB of user address space is a severe restriction. In these situations, the cache is too small to properly support the application.

VLM allows applications to directly address memory using 64-bit pointers. Applications that use these extensions can have data caches larger than 2 GB. The larger caches result in better cache-hit rates and increased performance.

Windows NT has until now provided applications with a flat 32-bit virtual address space. The address space is typically split so that 2 GB of virtual address space is directly accessible to applications. The other 2 GB of virtual address space is accessible only to the Windows NT executive software. The Digital Equipment Corporation Alpha processor has a 64-bit flat address range. Under Windows NT on the Alpha, using sign extension, the application appears in the bottom 2 GB of memory, and the operating system in the top 2 GB. VLM virtual space appears in the range in between. Applications have access to 28 GB of VLM virtual space.


Restrictions on VLM

[This is preliminary documentation and subject to change.]

VLM places severe restrictions on the memory that may be addressed by 64-bit pointers. These restrictions limit the use of the VLM application programming interface (API) to certain narrowly defined situations in which applications require high-speed access to large portions of memory. The restrictions are:

  • VLM is supported only on processors that directly support native 64-bit addressing. At present, these processors include the Digital Equipment Corporation Alpha processor and specifically exclude the 80286, 80386, 80486, and Pentium processors from Intel.
  • VLM is supported only on computers that have at least 128 megabytes (MB) of physical memory.
  • The memory used by this API is "locked down" (not swapped out by the memory manager) for high-speed access to data. For more information on locking down memory, see Virtual Memory Functions.
  • All committed memory is backed by physical memory.
  • Compilers for VLM-capable processors require some modifications to expose 64-bit addressing.
  • VLM is available on Windows NT Server Enterprise Edition, version 5.0.
  • Requests for memory must be in multiples of 64 kilobytes (K).
  • Requested addresses are rounded down to the nearest multiple of 64K.
  • VLM requires Microsoft® Visual C++® version 5.0.

All committed memory must be backed by physical memory that must be available at the time of commitment; paging files are never used to back committed memory. In fact, physical memory at the time of the commitment must exceed the committed memory by at least 16 MB. However, the address space used to map virtual committed memory can be reserved.

Page faults can only occur in VLM addresses when they are being used to map in an actual data file from disk. Page faults occur only on mapped data files, and each page can only generate a fault once, when it is first accessed. After the first access, a page is locked into memory, never to be trimmed by the usual swapping process. Thus, page faults operate only to bring data into physical memory, never to swap the data out.

The Microsoft® 32-bit C/C++ Optimizing Compiler that presently supports VLM is distributed with Visual C++ 5.0 and later. Compilers for VLM-capable processors require some modifications to expose 64-bit addressing. These modifications include the new __ptr64 pointer modifier used in type definitions. The use of this modifier follows this syntax:

name-of-type * __ptr64 name-of-variable

where name-of-type is the name of the type used and name-of-variable is the name of the variable to be defined.

Compilers for VLM-capable processors must also support all the conversions to and from 32- and 64-bit pointers. Conversion support in this case means that 64-bit–to–32-bit conversions are truncated and 32-bit–to–64-bit conversions are sign-extended.

Although VLM is supported on computers with as little as 128 MB of physical memory, VLM becomes more useful as physical memory exceeds 2 GB. However, for the sake of portability, VLM can be used on computers with as little physical memory as 128 MB.


VLM Memory Requirements

[This is preliminary documentation and subject to change.]

VLM applications tend to be very memory intensive. They can unnecessarily deprive other applications of memory. To avoid doing so, your application should call the GlobalMemoryStatusVlm function. This function fills the members of a MEMORYSTATUSVLM structure. The dwMemoryLoad member and other members of this structure indicate current total memory usage.


VLM Functions

[This is preliminary documentation and subject to change.]

VLM functions are defined to operate on memory using 64-bit pointers. The VLM functions, combined with existing Win32 functions, are sufficient to support very memory-intensive applications.

The following functions allocate, free, protect, and query page-aligned blocks of memory that can be addressed through 64-bit pointers.

GlobalMemoryStatusVlm
MapViewOfFileVlm
ReadProcessMemoryVlm
UnmapViewOfFileVlm
VirtualAllocVlm
VirtualFreeVlm
VirtualProtectVlm
VirtualQueryVlm
WriteProcessMemoryVlm

The following functions copy, move, and fill memory using either 32-bit or 64-bit addresses.

CopyMemoryVlm
FillMemoryVlm
MoveMemoryVlm
ZeroMemoryVlm

The following functions move data between a noncached file and memory using 64-bit addresses and asynchronous input and output.

ReadFileScatter
ReadFileVlm
WriteFileGather
WriteFileVlm


Global and Local Functions

The global and local functions are the 16-bit Windows heap functions. Win32 memory management supports these functions for porting from 16-bit Windows, or maintaining source code compatibility with 16-bit Windows. The global and local functions are slower than the new memory management functions and do not provide as many features. Therefore, new applications should not use these functions.

A process can use the GlobalAlloc and LocalAlloc functions to allocate memory. Win32 memory management does not provide a separate local heap and global heap, as 16-bit Windows does. As a result, there is no difference between the memory objects allocated by these functions. In addition, the change from a 16-bit segmented memory model to a 32-bit virtual memory model has made some of the related global and local functions and their options unnecessary or meaningless. For example, there are no longer near and far pointers, because both local and global allocations return 32-bit virtual addresses.

Memory objects allocated by GlobalAlloc and LocalAlloc are in private, committed pages with read-write access that cannot be accessed by other processes. Memory allocated by using GlobalAlloc with the GMEM_DDESHARE flag is not actually shared globally as it is in 16-bit Windows. However, this flag is available for compatibility purposes and can be used by some applications to enhance the performance of dynamic data exchange (DDE) operations. Applications requiring shared memory for other purposes must use file-mapping objects. Multiple processes can map a view of the same file-mapping object to provide named shared memory. For more information, see File Mapping.

By using GlobalAlloc and LocalAlloc, you can allocate a block of memory of any size that can be represented by 32 bits. You are limited only by the available physical memory, including storage in the paging file on disk. In 16-bit Windows, when you allocate a fixed memory object, GlobalAlloc and LocalAlloc returns a 32-bit pointer that the calling process can immediately use to access the memory. When you allocate memory using GMEM_MOVEABLE, the return value is a handle. To get a pointer to a movable memory object, use the GlobalLock and LocalLock functions.

The actual size of the memory allocated by GlobalAlloc or LocalAlloc can be larger than the requested size. To determine the actual number of bytes allocated, use the GlobalSize or LocalSize function. If the amount allocated is greater than the amount requested, the process can use the entire amount.

The GlobalReAlloc and LocalReAlloc functions change the size, in bytes, or the attributes of a memory object allocated by GlobalAlloc and LocalAlloc. The size can increase or decrease.

The GlobalFree and LocalFree functions release memory allocated by GlobalAlloc, LocalAlloc, GlobalReAlloc, or LocalReAlloc.

Other global and local functions include the GlobalDiscard, LocalDiscard, GlobalFlags, LocalFlags, GlobalHandle, and LocalHandle functions. To discard the specified memory object without invalidating the handle, use GlobalDiscard or LocalDiscard. The handle can be used later by GlobalReAlloc or LocalReAlloc to allocate a new block of memory associated with the same handle. To return information about a specified memory object, use GlobalFlags or LocalFlags. The information includes the object's lock count and indicates whether the object is discardable or has already been discarded. To return a handle to the memory object associated with a specified pointer, use GlobalHandle or LocalHandle.


Standard C Library Functions

Win32-based applications can safely use the memory management features of the C run-time library (malloc, free, and so on) and C++ (new, delete, and so on). The C run-time library functions do not have the potential problems they have under 16-bit Windows. Memory management is no longer a problem because the system is free to manage memory by moving pages of physical memory without affecting the virtual addresses. Similarly, the distinction between near and far pointers is no longer relevant. Therefore, you can use the standard C library functions for memory management. However, the Win32 memory management functions do provide functionality that is unavailable in the C run-time library.


Using the Virtual Memory Functions

  • Reserving and Committing Memory
  • Creating Guard Pages


Reserving and Committing Memory

The following example illustrates the use of the VirtualAlloc and VirtualFree functions in reserving and committing memory as needed for a dynamic array. First, VirtualAlloc is called to reserve a block of pages with NULL specified as the base address parameter, forcing the system to determine the location of the block. Later, VirtualAlloc is called whenever it is necessary to commit a page from this reserved region, and the base address of the next page to be committed is specified.

The example uses try-except structured exception-handling syntax to commit pages from the reserved region. Whenever a page fault exception occurs during the execution of the try block, the filter function in the expression preceding the except block is executed. If the filter function can allocate another page, execution continues in the try block at the point where the exception occurred. Otherwise, the exception handler in the except block is executed. For more information, see Structured Exception Handling.

As an alternative to dynamic allocation, the process can simply commit the entire region instead of only reserving it. However, committing the region consumes physical storage that might not be needed, making it unavailable for use by other processes.

The example uses VirtualFree to free the reserved and committed pages when it is finished with them. The function is called twice: first to decommit the committed pages and again to release the entire region of reserved pages.

#define PAGELIMIT 80
#define PAGESIZE 0x1000

INT PageFaultExceptionFilter(DWORD);
VOID MyErrorExit(LPTSTR);

LPTSTR lpNxtPage;
DWORD dwPages = 0;

VOID UseDynamicVirtualAlloc(VOID)
{
    LPVOID lpvBase;
    LPTSTR lpPtr;
    BOOL bSuccess;
    DWORD i;

    // Reserve pages in the process's virtual address space.

    lpvBase = VirtualAlloc(
        NULL,               // system selects address
        PAGELIMIT*PAGESIZE, // size of allocation
        MEM_RESERVE,        // allocates reserved pages
        PAGE_NOACCESS);     // protection = no access
    if (lpvBase == NULL )
        MyErrorExit("VirtualAlloc reserve");

    lpPtr = lpNxtPage = (LPTSTR) lpvBase;

    // Use try-except structured exception handling when
    // accessing the pages. If a page fault occurs, the
    // exception filter is executed to commit another page
    // from the reserved block of pages.

    for (i=0; i < PAGELIMIT*PAGESIZE; i++)
    {
        try
        {
            // Write to memory.

            lpPtr[i] = 'a';
        }

        // If there's a page fault, commit another page and try again.

        except ( PageFaultExceptionFilter( GetExceptionCode() ) )
        {

            // This is executed only if the filter function is
            // unsuccessful in committing the next page.

          ExitProcess( GetLastError() );

      }

  }

    // Release the block of pages when you are finished using them.

    // First, decommit the committed pages.

    bSuccess = VirtualFree(
            lpvBase,          // base address of block
            dwPages*PAGESIZE, // bytes of committed pages
            MEM_DECOMMIT);    // decommit the pages

    // Release the entire block.

    if (bSuccess)
    {
        bSuccess = VirtualFree(
            lpvBase,        // base address of block
            0,              // releases the entire block
            MEM_RELEASE);   // releases the pages
    }
}

INT PageFaultExceptionFilter(DWORD dwCode)
{
    LPVOID lpvResult;

    // If the exception is not a page fault, exit.

    if (dwCode != EXCEPTION_ACCESS_VIOLATION)
    {
        printf("exception code = %d\n", dwCode);
        return EXCEPTION_EXECUTE_HANDLER;
    }

    printf("page fault\n");

    // If the reserved pages are used up, exit.

    if (dwPages >= PAGELIMIT)
    {
        printf("out of pages\n");
        return EXCEPTION_EXECUTE_HANDLER;
    }

    // Otherwise, commit another page.

    lpvResult = VirtualAlloc(
        (LPVOID) lpNxtPage, // next page to commit
        PAGESIZE,           // page size, in bytes
        MEM_COMMIT,         // alloc committed page
        PAGE_READWRITE);    // read-write access
    if (lpvResult == NULL )
    {
        printf("VirtualAlloc failed\n");
        return EXCEPTION_EXECUTE_HANDLER;
    }

    // Increment the page count, and advance lpNxtPage
    // to the next page.

    dwPages++;
    lpNxtPage += PAGESIZE;

    // Continue execution where the page fault occurred.

    return EXCEPTION_CONTINUE_EXECUTION;
}


Creating Guard Pages

A guard page provides a one-shot alarm for memory page access. This can be useful for an application that needs to monitor the growth of large dynamic data structures. For example, there are operating systems that use guard pages to implement automatic stack checking.

To create a guard page, set the PAGE_GUARD page protection modifier flag for the page. This flag can be specified, along with other page protection flags, in the functions VirtualAlloc, VirtualProtect, and VirtualProtectEx. The PAGE_GUARD flag can be used with any other page protection flag, except for the NO_ACCESS flag.

If a program attempts to access an address within a guard page, the system raises a STATUS_GUARD_PAGE (0x80000001) exception. The system also clears the PAGE_GUARD flag, removing the memory page's guard page status. The system will not stop the next attempt to access the memory page with a STATUS_GUARD_PAGE exception.

If a guard page exception occurs during a system service, the service fails and typically returns some failure status indicator. Since the system also removes the relevant memory page's guard page status, the next invocation of the same system service won't fail due to a STATUS_GUARD_PAGE exception (unless, of course, someone reestablishes the guard page).

The following short program illustrates the one-shot behavior of guard page protection, and how it can cause a system service to fail:

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

int main()
{
    LPVOID lpvAddr;
    DWORD cbSize;
    BOOL vLock;
    LPVOID commit;

    // Amount of memory to allocate.
    cbSize = 512;

    // Try to allocate some memory.
    lpvAddr = VirtualAlloc(NULL,cbSize,MEM_RESERVE,PAGE_NOACCESS);

    if(lpvAddr == NULL)
    {
        fprintf(stdout,"VirtualAlloc failed on RESERVE with %ld\n",
            GetLastError());
    }

    // Try to commit the allocated memory.
    commit =
    VirtualAlloc(NULL,cbSize,MEM_COMMIT,PAGE_READONLY|PAGE_GUARD);

    if(commit == NULL)
    {
        fprintf(stderr,"VirtualAlloc failed on COMMIT with %ld\n",
            GetLastError());
    }

    else
    {
        fprintf(stderr,"Committed %lu bytes at address %lp\n",
        cbSize,commit);
    }

    // Try to lock the committed memory.
    vLock = VirtualLock(commit,cbSize);

    if(!vLock)
    {
        fprintf(stderr,"Cannot lock at %lp, error = %lu\n",
            commit,GetLastError());
    }
    else fprintf(stderr,"Lock Achieved at %lp\n",commit);

    // Try to lock the committed memory again.
    vLock = VirtualLock(commit,cbSize);

    if(!vLock)
    {
        fprintf(stderr,"Cannot get 2nd lock at %lp, error = %lu\n",
            commit,GetLastError());
    }
    else fprintf(stderr,"2nd Lock Achieved at %lp\n",commit);

}

The output of this program looks like this:

Committed 512 bytes at address 003F0000
Cannot lock at 003F0000, error = 0x80000001
2nd Lock Achieved at 003F0000

Note The first attempt to lock the memory block fails, raising a STATUS_GUARD_PAGE exception. The second attempt succeeds, because the memory block's guard page protection has been toggled off by the first attempt.


Memory Management Reference

The following elements are used with memory management.

  • Memory Management Functions
  • Memory Management Structures


Memory Management Functions

The following functions are used in memory management.

CopyMemory
FillMemory
GetProcessHeap
GetProcessHeaps
GlobalMemoryStatus
HeapAlloc
HeapCompact
HeapCreate
HeapDestroy
HeapFree
HeapLock
HeapReAlloc
HeapSize
HeapUnlock
HeapValidate
HeapWalk
IsBadCodePtr
IsBadReadPtr
IsBadStringPtr
IsBadWritePtr
MoveMemory
VirtualAlloc
VirtualAllocEx
VirtualFree
VirtualFreeEx
VirtualLock
VirtualProtect
VirtualProtectEx
VirtualQuery
VirtualQueryEx
VirtualUnlock
ZeroMemory

VLM Functions

CopyMemoryVlm
FillMemoryVlm
GlobalMemoryStatusVlm
MapViewOfFileVlm
MoveMemoryVlm
ReadFileVlm
ReadProcessMemoryVlm
UnmapViewOfFileVlm
VirtualAllocVlm
VirtualFreeVlm
VirtualProtectVlm
VirtualQueryVlm
WriteFileVlm
WriteProcessMemoryVlm
ZeroMemoryVlm

Global and Local Functions

GlobalAlloc
GlobalDiscard
GlobalFlags
GlobalFree
GlobalHandle
GlobalLock
GlobalReAlloc
GlobalSize
GlobalUnlock
LocalAlloc
LocalDiscard
LocalFlags
LocalFree
LocalHandle
LocalLock
LocalReAlloc
LocalSize
LocalUnlock

Obsolete Functions

DefineHandleTable
GetFreeSpace
GlobalCompact
GlobalFix
GlobalLRUNewest
GlobalLRUOldest
GlobalUnfix
GlobalUnWire
GlobalWire
IsBadHugeReadPtr
IsBadHugeWritePtr
LimitEmsPages
LocalCompact
LocalShrink
LockSegment
SetSwapAreaSize
UnlockSegment


CopyMemory

The CopyMemory function copies a block of memory from one location to another.

VOID CopyMemory(
  PVOID Destination,  // pointer to address of copy destination
  CONST VOID *Source, // pointer to address of block to copy
  DWORD Length        // size, in bytes, of block to copy
);

Parameters

Destination
Pointer to the starting address of the copied block's destination.
Source
Pointer to the starting address of the block of memory to copy.
Length
Specifies the size, in bytes, of the block of memory to copy.

Return Values

This function has no return value.

Remarks

If the source and destination blocks overlap, the results are undefined. For overlapped blocks, use the MoveMemory function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Memory Management Overview, Memory Management Functions, CopyMemoryVlm, FillMemory, FillMemoryVlm, MoveMemory, MoveMemoryVlm, ZeroMemory


CopyMemoryVlm

[This is preliminary documentation and subject to change.]

The CopyMemoryVlm function copies a block of memory from one location to another, both locations being specified with 64-bit pointers.

VOID CopyMemoryVlm (
  PVOID64 Destination,  // pointer to address of copy destination
  PVOID64 Source,       // pointer to address of block to copy
  DWORD Length          // size, in bytes, of block to copy
);

Parameters

Destination
Pointer to the starting address of the copied block's destination.
Source
Pointer to the starting address of the block of memory to copy.
Length
Size, in bytes, of the block of memory to copy.

Return Values

This function has no return value.

Remarks

If the source and destination blocks overlap, the results are undefined. For overlapped blocks, use the MoveMemoryVlm function.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory-mapped view. For more information on structured exception handling, see Reading and Writing.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), CopyMemory, FillMemoryVlm, MoveMemoryVlm, ZeroMemoryVlm


DefineHandleTable

The DefineHandleTable function is obsolete. It is provided as a macro to simplify porting of 16-bit Windows-based applications. It expands to TRUE after evaluating its argument. It has no other effect.

See Also

Memory Management Overview, Memory Management Functions


FillMemory

The FillMemory function fills a block of memory with a specified value.

VOID FillMemory (
  PVOID Destination,  // pointer to block to fill
  DWORD Length,       // size, in bytes, of block to fill
  BYTE Fill           // the byte value with which to fill the block
);

Parameters

Destination
Pointer to the starting address of the block of memory to fill.
Length
Specifies the size, in bytes, of the block of memory to fill.
Fill
Specifies the byte value with which to fill the memory block.

Return Values

This function has no return value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Memory Management Overview, Memory Management Functions, CopyMemory, CopyMemoryVlm , MoveMemory, MoveMemoryVlm, ZeroMemory


FillMemoryVlm

[This is preliminary documentation and subject to change.]

The FillMemoryVlm function fills a block of memory specified with a 64-bit pointer with the indicated value.

VOID FillMemoryVlm (
  PVOID64 Destination,  // pointer to block to fill
  DWORD Length,         // size, in bytes, of block to fill
  BYTE Fill             // byte value with which to fill the block
);

Parameters

Destination
Pointer to the starting address of the block of memory to fill.
Length
Size, in bytes, of the block of memory to fill.
Fill
Byte value with which to fill the memory block.

Return Values

This function has no return value.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory-mapped view. For more information on structured exception handling, see Reading and Writing.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), CopyMemoryVlm, FillMemory, MoveMemoryVlm, ZeroMemoryVlm


GetFreeSpace

The GetFreeSpace function is obsolete. It is provided to simplify porting of 16-bit Windows-based applications. Win32-based applications should use the GlobalMemoryStatus function.

See Also

Memory Management Overview, Memory Management Functions


GetProcessHeap

The GetProcessHeap function obtains a handle to the heap of the calling process. This handle can then be used in subsequent calls to the HeapAlloc, HeapReAlloc, HeapFree, and HeapSize functions.

HANDLE GetProcessHeap(VOID)

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is a handle to the calling process's heap.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The GetProcessHeap function allows you to allocate memory from the process heap without having to first create a heap with the HeapCreate function, as shown in this example:

HeapAlloc(GetProcessHeap(), 0, dwBytes);

Note The handle obtained by calling this function should not be used in calls to the HeapDestroy function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, HeapAlloc, HeapCreate, HeapDestroy, HeapFree, HeapReAlloc, HeapSize


GetProcessHeaps

The GetProcessHeaps function obtains handles to all of the heaps that are valid for the calling process.

DWORD GetProcessHeaps(
  DWORD NumberOfHeaps,  // maximum number of heap handles buffer can
                        // receive
  PHANDLE ProcessHeaps  // pointer to buffer to receive heap handles
);

Parameters

NumberOfHeaps
Specifies the maximum number of heap handles that can be stored into the buffer pointed to by ProcessHeaps.
ProcessHeaps
Pointer to a buffer to receive an array of heap handles.

Return Values

The return value is the number of heap handles that are valid for the calling process.

If the return value is less than or equal to NumberOfHeaps, it is also the number of heap handles stored into the buffer pointed to by ProcessHeaps.

If the return value is greater than NumberOfHeaps, the buffer pointed to by ProcessHeaps is too small to hold all the valid heap handles of the calling process.The function will have stored no handles into that buffer. In this situation, use the return value to allocate a buffer that is large enough to receive the handles, and call the function again.

If the return value is zero, the function has failed, because every process has at least one valid heap, the process heap. To get extended error information, call GetLastError.

Remarks

Use the GetProcessHeap function to obtain a handle to the process heap of the calling process. The GetProcessHeaps function obtains a handle to that heap, plus handles to any additional private heaps created by calling the HeapCreate function.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetProcessHeap, HeapCreate


GlobalAlloc

The GlobalAlloc function allocates the specified number of bytes from the heap. Win32 memory management does not provide a separate local heap and global heap.

This function is provided only for compatibility with 16-bit versions of Windows.

HGLOBAL GlobalAlloc(
  UINT uFlags,    // allocation attributes
  DWORD dwBytes   // number of bytes to allocate
);

Parameters

uFlags
Specifies how to allocate memory. If zero is specified, the default is GMEM_FIXED. This value can be one or more of the following flags, except for the incompatible combinations that are specifically noted.
Flag | Meaning
GMEM_FIXED | Allocates fixed memory. The return value is a pointer.
GMEM_MOVEABLE Allocates movable memory. In Win32, memory blocks are never moved in physical memory, but they can be moved within the default heap.

The return value is a handle to the memory object. To translate the handle into a pointer, use the GlobalLock function.

This flag cannot be combined with the GMEM_FIXED flag.

GPTR | Combines the GMEM_FIXED and GMEM_ZEROINIT flags.
GHND | Combines the GMEM_MOVEABLE and GMEM_ZEROINIT flags.
GMEM_DDESHARE
GMEM_SHARE 		This flag is provided primarily for compatibility with 16-bit Windows. However, this flag may be used by some applications to enhance the performance of DDE operations and therefore can be specified if the memory is to be used for DDE. .
GMEM_DISCARDABLE Ignored. This flag is provided only for compatibility with 16-bit Windows.

In Win32, you must explicitly call the GlobalDiscard function to discard a block.

This flag cannot be combined with the GMEM_FIXED flag.

GMEM_LOWER | Ignored. This flag is provided only for compatibility with 16-bit Windows.
GMEM_NOCOMPACT | Ignored. This flag is provided only for compatibility with 16-bit Windows.
GMEM_NODISCARD | Ignored. This flag is provided only for compatibility with 16-bit Windows.
GMEM_NOT_BANKED | Ignored. This flag is provided only for compatibility with 16-bit Windows.
GMEM_NOTIFY | Ignored. This flag is provided only for compatibility with 16-bit Windows.
GMEM_ZEROINIT | Initializes memory contents to zero.

dwBytes
Specifies the number of bytes to allocate. If this parameter is zero and the uFlags parameter specifies the GMEM_MOVEABLE flag, the function returns a handle to a memory object that is marked as discarded.

Return Values

If the function succeeds, the return value is a handle to the newly allocated memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

If the heap does not contain sufficient free space to satisfy the request, GlobalAlloc returns NULL. Because NULL is used to indicate an error, virtual address zero is never allocated. It is, therefore, easy to detect the use of a NULL pointer.

Memory allocated with this function is guaranteed to be aligned on an 8-byte boundary. All memory is created with execute access; no special function is required to execute dynamically generated code.

If this function succeeds, it allocates at least the amount of memory requested. If the actual amount allocated is greater than the amount requested, the process can use the entire amount. To determine the actual number of bytes allocated, use the GlobalSize function.

To free the memory, use the GlobalFree function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalDiscard, GlobalFree, GlobalLock, GlobalSize


GlobalCompact

The GlobalCompact function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. It has no meaning in the 32-bit environment.

See Also

Memory Management Overview, Memory Management Functions


GlobalDiscard

The GlobalDiscard function discards the specified global memory block. The lock count of the memory object must be zero.

This function is provided only for compatibility with 16-bit versions of Windows.

HGLOBAL GlobalDiscard(
  HGLOBAL hglbMem  // handle to the global memory object
);

Parameters

hglbMem
Handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Values

If the function succeeds, the return value is a handle to the memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

Although GlobalDiscard discards the object's memory block, the handle to the object remains valid. The process can subsequently pass the handle to the GlobalReAlloc function to allocate another global memory block identified by the same handle.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalReAlloc


GlobalFix

The GlobalFix function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. Win32-based applications should use the VirtualLock and VirtualUnlock functions.

See Also

Memory Management Overview, Memory Management Functions


GlobalFlags

The GlobalFlags function returns information about the specified global memory object.

This function is provided only for compatibility with 16-bit versions of Windows.

UINT GlobalFlags(
  HGLOBAL hMem   // handle to the global memory object
);

Parameters

hMem
Handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Values

If the function succeeds, the return value specifies the allocation flags and the lock count for the memory object.

If the function fails, the return value is the GMEM_INVALID_HANDLE flag, indicating that the global handle is not valid. To get extended error information, call GetLastError.

Remarks

The low-order byte of the low-order word of the return value contains the lock count of the object. To retrieve the lock count from the return value, use the GMEM_LOCKCOUNT mask with the bitwise AND (&) operator. The lock count of memory objects allocated with the GMEM_FIXED flag is always zero.

The high-order byte of the low-order word of the return value indicates the allocation flags of the memory object. It can be zero or any combination of the following flags:

Flag | Meaning
GMEM_DDESHARE | This flag is provided primarily for compatibility with 16-bit Windows. However, this flag may be used by some applications to enhance the performance of DDE operations and therefore can be specified if the memory is to be used for DDE. .
GMEM_DISCARDABLE | Ignored. This flag is provided only for compatibility with 16-bit Windows. In Win32, you must explicitly call the GlobalDiscard function to discard a block.
GMEM_DISCARDED | The object's memory block has been discarded.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalDiscard, GlobalReAlloc


GlobalFree

The GlobalFree function frees the specified global memory object and invalidates its handle.

This function is provided only for compatibility with 16-bit versions of Windows.

HGLOBAL GlobalFree(
  HGLOBAL hMem   // handle to the global memory object
);

Parameters

hMem
Handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Values

If the function succeeds, the return value is NULL.

If the function fails, the return value is equal to a handle to the global memory object. To get extended error information, call GetLastError.

Remarks

If the process examines or modifies the memory after it has been freed, heap corruption may occur or an access violation exception (EXCEPTION_ACCESS_VIOLATION) may be generated.

If the hgblMem parameter is NULL, GlobalFree fails and the system generates an access violation exception.

The GlobalFree function will free a locked memory object. A locked memory object has a lock count greater than zero. The GlobalLock function locks a global memory object and increments the lock count by one. The GlobalUnlock function unlocks it and decrements the lock count by one. To get the lock count of a global memory object, use the GlobalFlags function.

If an application is running under a debug version of the system, GlobalFree will issue a message that tells you that a locked object is being freed. If you are debugging the application, GlobalFree will enter a breakpoint just before freeing a locked object. This allows you to verify the intended behavior, then continue execution.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalFlags, GlobalLock, GlobalReAlloc, GlobalUnlock


GlobalHandle

The GlobalHandle function retrieves the handle associated with the specified pointer to a global memory block.

This function is provided only for compatibility with 16-bit versions of Windows.

HGLOBAL GlobalHandle(
  LPCVOID pMem   // pointer to the global memory block
);

Parameters

pMem
Pointer to the first byte of the global memory block. This pointer is returned by the GlobalLock function.

Return Values

If the function succeeds, the return value is a handle to the specified global memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

When the GlobalAlloc function allocates a memory object with the GMEM_MOVEABLE flag, it returns a handle to the object. The GlobalLock function converts this handle into a pointer to the memory block, and GlobalHandle converts the pointer back into a handle.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalLock


GlobalLock

The GlobalLock function locks a global memory object and returns a pointer to the first byte of the object's memory block.

This function is provided only for compatibility with 16-bit versions of Windows.

LPVOID GlobalLock(
  HGLOBAL hMem   // handle to the global memory object
);

Parameters

hMem
Handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Values

If the function succeeds, the return value is a pointer to the first byte of the memory block.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, GlobalLock increments the count by one, and the GlobalUnlock function decrements the count by one. For each call that a process makes to GlobalLock for an object, it must eventually call GlobalUnlock. Locked memory will not be moved or discarded, unless the memory object is reallocated by using the GlobalReAlloc function. The memory block of a locked memory object remains locked until its lock count is decremented to zero, at which time it can be moved or discarded.

Memory objects allocated with the GMEM_FIXED flag always have a lock count of zero. For these objects, the value of the returned pointer is equal to the value of the specified handle.

If the specified memory block has been discarded or if the memory block has a zero-byte size, this function returns NULL.

Discarded objects always have a lock count of zero.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalReAlloc, GlobalUnlock


GlobalLRUNewest

The GlobalLRUNewest function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. Win32-based applications should use the VirtualLock and VirtualUnlock functions.

See Also

Memory Management Overview, Memory Management Functions


GlobalLRUOldest

The GlobalLRUOldest function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. Win32-based applications should use the VirtualLock and VirtualUnlock functions.

See Also

Memory Management Overview, Memory Management Functions


GlobalMemoryStatus

The GlobalMemoryStatus function obtains information about the computer system's current usage of both physical and virtual memory.

VOID GlobalMemoryStatus(
  LPMEMORYSTATUS lpBuffer   // pointer to the memory status structure
);

Parameters

lpBuffer
Pointer to a MEMORYSTATUS structure. The GlobalMemoryStatus function stores information about current memory availability into this structure.

Return Values

This function does not return a value.

Remarks

You can use the GlobalMemoryStatus function to determine how much memory your application can allocate without severely impacting other applications.

The information returned by the GlobalMemoryStatus function is volatile. There is no guarantee that two sequential calls to this function will return the same information.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalMemoryStatusVlm, MEMORYSTATUS


GlobalMemoryStatusVlm

[This is preliminary documentation and subject to change.]

The GlobalMemoryStatusVlm function obtains information about the computer's current usage of both physical and virtual memory.

VOID GlobalMemoryStatusVlm(
  LPMEMORYSTATUSVLM lpBuffer   // pointer to a memory status structure
);

Parameters

lpBuffer
Pointer to a MEMORYSTATUSVLM structure. GlobalMemoryStatusVlm stores information about current memory availability in this structure.

Return Values

This function does not return a value.

Remarks

You can use the GlobalMemoryStatusVlm function to determine how much memory your application can allocate without severely impacting other applications.

The information returned by the GlobalMemoryStatusVlm function is volatile. There is no guarantee that two sequential calls to this function will return the same information.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), GlobalMemoryStatus, MEMORYSTATUSVLM


GlobalReAlloc

The GlobalReAlloc function changes the size or attributes of a specified global memory object. The size can increase or decrease.

This function is provided only for compatibility with 16-bit versions of Windows.

HGLOBAL GlobalReAlloc(
  HGLOBAL hMem,  // handle to the global memory object
  DWORD dwBytes, // new size of the block
  UINT uFlags    // how to reallocate object
);

Parameters

hMem
Handle to the global memory object to be reallocated. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.
dwBytes
Specifies the new size, in bytes, of the memory block. If uFlags specifies the GMEM_MODIFY flag, this parameter is ignored.
uFlags
Specifies how to reallocate the global memory object. If the GMEM_MODIFY flag is specified, this parameter modifies the attributes of the memory object, and the dwBytes parameter is ignored. Otherwise, this parameter controls the reallocation of the memory object.

The GMEM_MODIFY flag can be combined with either or both of the following flags:
Flag | Meaning
GMEM_DISCARDABLE Ignored. This flag is provided only for compatibility with 16-bit Windows.

In Win32, you must explicitly call the GlobalDiscard function to discard a block.

In 16-bit Windows, allocates discardable memory, if the GMEM_MODIFY flag is also specified. This flag is ignored if the object was not previously allocated as movable or if the GMEM_MOVEABLE flag is not specified.
GMEM_MOVEABLE | Changes a fixed memory object to a movable memory object, if the GMEM_MODIFY flag is also specified.

If this parameter does not specify GMEM_MODIFY, it can also be any combination of the following flags:
Flag | Meaning
GMEM_NOCOMPACT | Ignored. This flag is provided only for compatibility with 16-bit Windows.
GMEM_ZEROINIT | Causes the additional memory contents to be initialized to zero if the memory object is growing in size.

Return Values

If the function succeeds, the return value is a handle to the reallocated memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

If GlobalReAlloc reallocates a movable object, the return value is a handle to the memory object. To convert the handle to a pointer, use the GlobalLock function.

If GlobalReAlloc reallocates a fixed object, the value of the handle returned is the address of the first byte of the memory block. To access the memory, a process can simply cast the return value to a pointer.

If GlobalReAlloc fails, the original memory is not freed, and the original handle and pointer are still valid.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalDiscard, GlobalLock


GlobalSize

The GlobalSize function retrieves the current size, in bytes, of the specified global memory object.

This function is provided only for compatibility with 16-bit versions of Windows.

DWORD GlobalSize(
  HGLOBAL hMem   // handle to the global memory object
);

Parameters

hMem
Handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Values

If the function succeeds, the return value is the size, in bytes, of the specified global memory object.

If the specified handle is not valid or if the object has been discarded, the return value is zero. To get extended error information, call GetLastError.

Remarks

The size of a memory block may be larger than the size requested when the memory was allocated.

To verify that the specified object's memory block has not been discarded, use the GlobalFlags function before calling GlobalSize.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalFlags, GlobalReAlloc


GlobalUnfix

The GlobalUnfix function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. It has no meaning in the 32-bit environment.

See Also

Memory Management Overview, Memory Management Functions


GlobalUnlock

The GlobalUnlock function decrements the lock count associated with a memory object that was allocated with the GMEM_MOVEABLE flag. This function has no effect on memory objects allocated with the GMEM_FIXED flag.

This function is provided only for compatibility with 16-bit versions of Windows.

BOOL GlobalUnlock(
  HGLOBAL hMem   // handle to the global memory object
);

Parameters

hMem
Handle to the global memory object. This handle is returned by either the GlobalAlloc or GlobalReAlloc function.

Return Values

If the memory object is still locked after decrementing the lock count, the return value is a nonzero value.

If the function fails, the return value is zero. To get extended error information, call GetLastError. If GetLastError returns NO_ERROR, the memory object is unlocked.

Remarks

The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, the GlobalLock function increments the count by one, and GlobalUnlock decrements the count by one. For each call that a process makes to GlobalLock for an object, it must eventually call GlobalUnlock. Locked memory will not be moved or discarded, unless the memory object is reallocated by using the GlobalReAlloc function. The memory block of a locked memory object remains locked until its lock count is decremented to zero, at which time it can be moved or discarded.

Memory objects allocated with the GMEM_FIXED flag always have a lock count of zero. If the specified memory block is fixed memory, this function returns TRUE.

If the memory object is already unlocked, GlobalUnlock returns FALSE and GetLastError reports ERROR_NOT_LOCKED.

A process should not rely on the return value to determine the number of times it must subsequently call GlobalUnlock for a memory object.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalLock, GlobalReAlloc


GlobalUnWire

The GlobalUnWire function is obsolete. Applications that need to lock a global memory object should use the GlobalLock and GlobalUnlock functions.

This function is provided only for compatibility with 16-bit versions of Windows.

See Also

Memory Management Overview, Memory Management Functions


GlobalWire

The GlobalWire function is obsolete. This function is provided only for compatibility with 16-bit versions of Windows. Win32-based applications should use the GlobalLock and GlobalUnlock functions.

See Also

Memory Management Overview, Memory Management Functions


HeapAlloc

The HeapAlloc function allocates a block of memory from a heap. The allocated memory is not movable.

LPVOID HeapAlloc(
  HANDLE hHeap,  // handle to the private heap block
  DWORD dwFlags, // heap allocation control flags
  DWORD dwBytes  // number of bytes to allocate
);

Parameters

hHeap
Specifies the heap from which the memory will be allocated. This parameter is a handle returned by the HeapCreate or GetProcessHeap function.
dwFlags
Specifies several controllable aspects of heap allocation. Specifying any of these flags will override the corresponding flag specified when the heap was created with HeapCreate. You can specify one or more of the following flags:
Flag | Meaning
HEAP_GENERATE_EXCEPTIONS | Specifies that the system will raise an exception to indicate a function failure, such as an out-of-memory condition, instead of returning NULL.
HEAP_NO_SERIALIZE Specifies that mutual exclusion will not be used while the HeapAlloc function is accessing the heap.

This flag should not be specified when accessing the process heap. The system may create additional threads within the application's process, such as a CTRL+C handler, that simultaneously access the process heap.

HEAP_ZERO_MEMORY | Specifies that the allocated memory will be initialized to zero. Otherwise, the memory is not initialized to zero.

dwBytes
Specifies the number of bytes to be allocated.

If the heap specified by the hHeap parameter is a "non-growable" heap, dwBytes must be less than 0x7FFF8. You create a non-growable heap by calling the HeapCreate function with a nonzero value.

Return Values

If the function succeeds, the return value is a pointer to the allocated memory block.

If the function fails and you have not specified HEAP_GENERATE_EXCEPTIONS, the return value is NULL.

If the function fails and you have specified HEAP_GENERATE_EXCEPTIONS, the function may generate the following exceptions:

Value | Meaning
STATUS_NO_MEMORY | The allocation attempt failed because of a lack of available memory or heap corruption.
STATUS_ACCESS_VIOLATION | The allocation attempt failed because of heap corruption or improper function parameters.

Note Heap corruption can lead to either exception. It depends upon the nature of the heap corruption.

If the function fails, it does not call SetLastError. An application cannot call GetLastError for extended error information.

Remarks

If HeapAlloc succeeds, it allocates at least the amount of memory requested. If the actual amount allocated is greater than the amount requested, the process can use the entire amount. To determine the actual size of the allocated block, use the HeapSize function.

To free a block of memory allocated by HeapAlloc, use the HeapFree function.

Memory allocated by HeapAlloc is not movable. Since the memory is not movable, it is possible for the heap to become fragmented.

Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap. Setting the HEAP_NO_SERIALIZE flag eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. The HEAP_NO_SERIALIZE flag can, therefore, be safely used only in the following situations:

  • The process has only one thread.
  • The process has multiple threads, but only one thread calls the heap functions for a specific heap.
  • The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

Windows CE: Windows CE does not support the HEAP_GENERATE_EXCEPTIONS value for the dwFlags parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetProcessHeap, HeapCreate, HeapDestroy, HeapFree, HeapReAlloc, HeapSize, SetLastError


HeapCompact

The HeapCompact function attempts to compact a specified heap. It compacts the heap by coalescing adjacent free blocks of memory and decommitting large free blocks of memory.

UINT HeapCompact(
  HANDLE hHeap,  // handle to the heap to compact
  DWORD dwFlags  // bit-flags that control heap access during
                 // function operation
);

Parameters

hHeap
Handle to the heap that the function will attempt to compact.
dwFlags
A set of bit flags that control heap access during function operation. The following bit flag has meaning:
Value | Meaning
HEAP_NO_SERIALIZE | Specifies that mutual exclusion will not be used while the HeapCompact function accesses the heap.

Return Values

If the function succeeds, the return value is the size, in bytes, of the largest committed free block in the heap. This is an unsigned integer value.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

In the unlikely case that there is absolutely no space available in the heap, the function return value is zero, and GetLastError returns the value NO_ERROR.

Remarks

There is no guarantee that an application can successfully allocate a memory block of the size returned by HeapCompact. Other threads or the commit threshold might prevent such an allocation.

Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap. Setting the HEAP_NO_SERIALIZE flag eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. The HEAP_NO_SERIALIZE flag can, therefore, be safely used only in the following situations:

  • The process has only one thread.
  • The process has multiple threads, but only one thread calls the heap functions for a specific heap.
  • The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, HeapCreate, HeapValidate


HeapCreate

The HeapCreate function creates a heap object that can be used by the calling process. The function reserves space in the virtual address space of the process and allocates physical storage for a specified initial portion of this block.

HANDLE HeapCreate(
  DWORD flOptions,      // heap allocation flag
  DWORD dwInitialSize,  // initial heap size
  DWORD dwMaximumSize   // maximum heap size
);

Parameters

flOptions
Specifies optional attributes for the new heap. These flags will affect subsequent access to the new heap through calls to the heap functions (HeapAlloc, HeapFree, HeapReAlloc, and HeapSize). You can specify one or more of the following flags:
Flag | Meaning
HEAP_GENERATE_EXCEPTIONS | Specifies that the system will raise an exception to indicate a function failure, such as an out-of-memory condition, instead of returning NULL.
HEAP_NO_SERIALIZE | Specifies that mutual exclusion will not be used when the heap functions allocate and free memory from this heap. The default, when the HEAP_NO_SERIALIZE flag is not specified, is to serialize access to the heap. Serialization of heap access allows two or more threads to simultaneously allocate and free memory from the same heap.

dwInitialSize
Specifies the initial size, in bytes, of the heap. This value determines the initial amount of physical storage that is allocated for the heap. The value is rounded up to the next page boundary. To determine the size of a page on the host computer, use the GetSystemInfo function.
dwMaximumSize
If dwMaximumSize is a nonzero value, it specifies the maximum size, in bytes, of the heap. The HeapCreate function rounds dwMaximumSize up to the next page boundary, and then reserves a block of that size in the process's virtual address space for the heap. If allocation requests made by the HeapAlloc or HeapReAlloc functions exceed the initial amount of physical storage specified by dwInitialSize, the system allocates additional pages of physical storage for the heap, up to the heap's maximum size.

In addition, if dwMaximumSize is nonzero, the heap cannot grow, and an absolute limitation arises: the maximum size of a memory block in the heap is a bit less than 0x7FFF8 bytes. Requests to allocate larger blocks will fail, even if the maximum size of the heap is large enough to contain the block.

If dwMaximumSize is zero, it specifies that the heap is growable. The heap's size is limited only by available memory. Requests to allocate blocks larger than 0x7FFF8 bytes do not automatically fail; the system calls VirtualAlloc to obtain the memory needed for such large blocks. Applications that need to allocate large memory blocks should set dwMaximumSize to zero.

Return Values

If the function succeeds, the return value is a handle to the newly created heap.

If the function fails, the return value is is NULL. To get extended error information, call GetLastError.

Remarks

The HeapCreate function creates a private heap object from which the calling process can allocate memory blocks by using the HeapAlloc function. The initial size determines the number of committed pages that are initially allocated for the heap. The maximum size determines the total number of reserved pages. These pages create a block in the process's virtual address space into which the heap can grow. If requests by HeapAlloc exceed the current size of committed pages, additional pages are automatically committed from this reserved space, assuming that the physical storage is available.

The memory of a private heap object is accessible only to the process that created it. If a dynamic-link library (DLL) creates a private heap, the heap is created in the address space of the process that called the DLL, and it is accessible only to that process.

The system uses memory from the private heap to store heap support structures, so not all of the specified heap size is available to the process. For example, if the HeapAlloc function requests 64 kilobytes (K) from a heap with a maximum size of 64K, the request may fail because of system overhead.

If the HEAP_NO_SERIALIZE flag is not specified (the simple default), the heap will serialize access within the calling process. Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap.

Setting the HEAP_NO_SERIALIZE flag eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. The HEAP_NO_SERIALIZE flag can, therefore, be safely used only in the following situations:

  • The process has only one thread.
  • The process has multiple threads, but only one thread calls the heap functions for a specific heap.
  • The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

Windows CE: Windows CE does not support the HEAP_GENERATE_EXCEPTIONS value for the flOptions parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetProcessHeap, GetProcessHeaps, GetSystemInfo, HeapAlloc, HeapDestroy, HeapFree, HeapReAlloc, HeapSize, HeapValidate, VirtualAlloc, VirtualAllocVlm


HeapDestroy

The HeapDestroy function destroys the specified heap object. HeapDestroy decommits and releases all the pages of a private heap object, and it invalidates the handle to the heap.

BOOL HeapDestroy(
  HANDLE hHeap   // handle to the heap
);

Parameters

hHeap
Specifies the heap to be destroyed. This parameter should be a heap handle returned by the HeapCreate function. Do not use the handle to the process heap returned by the GetProcessHeap function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Processes can call HeapDestroy without first calling the HeapFree function to free memory allocated from the heap.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetProcessHeap, HeapAlloc, HeapCreate, HeapFree, HeapReAlloc, HeapSize


HeapFree

The HeapFree function frees a memory block allocated from a heap by the HeapAlloc or HeapReAlloc function.

BOOL HeapFree(
  HANDLE hHeap,  // handle to the heap
  DWORD dwFlags, // heap freeing flags
  LPVOID lpMem   // pointer to the memory to free
);

Parameters

hHeap
Specifies the heap whose memory block the function frees. This parameter is a handle returned by the HeapCreate or GetProcessHeap function.
dwFlags
Specifies several controllable aspects of freeing a memory block. Only one flag is currently defined; however, all other flag values are reserved for future use. Specifying this flag will override the corresponding flag specified in the flOptions parameter when the heap was created by using the HeapCreate function:
Flag Meaning
HEAP_NO_SERIALIZE Specifies that mutual exclusion will not be used while HeapFree is accessing the heap.

This flag should not be specified when accessing the process heap. The system may create additional threads within the application's process, such as a CTRL+C handler, that simultaneously access the process heap.

lpMem
Pointer to the memory block to free. This pointer is returned by the HeapAlloc or HeapReAlloc function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. An application can call GetLastError for extended error information.

Remarks

Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap. Setting the HEAP_NO_SERIALIZE flag eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. The HEAP_NO_SERIALIZE flag can, therefore, be safely used only in the following situations:

  • The process has only one thread.
  • The process has multiple threads, but only one thread calls the heap functions for a specific heap.
  • The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetProcessHeap, HeapAlloc, HeapCreate, HeapDestroy, HeapReAlloc, HeapSize, SetLastError


HeapLock

The HeapLock function attempts to acquire the critical section object, or lock, that is associated with a specified heap.

If the function succeeds, the calling thread owns the heap lock. Only the calling thread will be able to allocate or release memory from the heap. The execution of any other thread of the calling process will be blocked if that thread attempts to allocate or release memory from the heap. Such threads will remain blocked until the thread that owns the heap lock calls the HeapUnlock function.

BOOL HeapLock(
  HANDLE hHeap   // handle to the heap to lock for exclusive thread
                 // access
);

Parameters

hHeap
Handle to the heap to lock for exclusive access by the calling thread.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The HeapLock function is primarily useful for preventing the allocation and release of heap memory by other threads while the calling thread uses the HeapWalk function.

Each call to HeapLock must be matched by a corresponding call to the HeapUnlock function. Failure to call HeapUnlock will block the execution of any other threads of the calling process that attempt to access the heap.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, HeapUnlock, HeapWalk


HeapReAlloc

The HeapReAlloc function reallocates a block of memory from a heap. This function enables you to resize a memory block and change other memory block properties. The allocated memory is not movable.

LPVOID HeapReAlloc(
  HANDLE hHeap,  // handle to a heap block
  DWORD dwFlags, // heap reallocation flags
  LPVOID lpMem,  // pointer to the memory to reallocate
  DWORD dwBytes  // number of bytes to reallocate
);

Parameters

hHeap
Heap from which the memory will be reallocated. This is a handle returned by the HeapCreate or GetProcessHeap function.
dwFlags
Specifies several controllable aspects of heap reallocation. Specifying any of these flags overrides the corresponding flag specified in the flOptions parameter when the heap was created by using the HeapCreate function. You can specify one or more of the following flags:
Flag | Meaning
HEAP_GENERATE_EXCEPTIONS | Specifies that the operating-system raises an exception to indicate a function failure, such as an out-of-memory condition, instead of returning NULL.
HEAP_NO_SERIALIZE Specifies that mutual exclusion is not used while HeapReAlloc is accessing the heap.

This flag should not be specified when accessing the process heap. The system may create additional threads within the application's process, such as a CTRL+C handler, that simultaneously access the process heap.

HEAP_REALLOC_IN_PLACE_ONLY | Specifies that there can be no movement when reallocating a memory block to a larger size. If this flag is not specified and the reallocation request is for a larger size, the function may move the block to a new location. If this flag is specified and the block cannot be enlarged without moving, the function fails, leaving the original memory block unchanged.
HEAP_ZERO_MEMORY | If the reallocation request is for a larger size, this flag specifies that the additional region of memory beyond the original size be initialized to zero. The contents of the memory block up to its original size are unaffected.

lpMem
Pointer to the block of memory that the function reallocates. This pointer is returned by an earlier call to the HeapAlloc or HeapReAlloc function.
dwBytes
New size of the memory block, in bytes. A memory block's size can be increased or decreased by using this function.

If the heap specified by the hHeap parameter is a "non-growable" heap, dwBytes must be less than 0x7FFF8. You create a non-growable heap by calling the HeapCreate function with a nonzero value.

Return Values

If the function succeeds, the return value is a pointer to the reallocated memory block.

If the function fails and you have not specified HEAP_GENERATE_EXCEPTIONS, the return value is NULL.

If the function fails and you have specified HEAP_GENERATE_EXCEPTIONS, the function may generate the following exceptions:

Value | Meaning
STATUS_NO_MEMORY | The reallocation attempt failed for lack of available memory.
STATUS_ACCESS_VIOLATION | The reallocation attempt failed because of heap corruption or improper function parameters.

If the function fails, it calls SetLastError. An application can call GetLastError for extended error information.

Remarks

If HeapReAlloc succeeds, it allocates at least the amount of memory requested. If the actual amount allocated is greater than the amount requested, the process can use the entire amount. To determine the actual size of the reallocated block, use the HeapSize function.

If HeapReAlloc fails, the original memory is not freed, and the original handle and pointer are still valid.

To free a block of memory allocated by HeapReAlloc, use the HeapFree function.

Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap. Setting the HEAP_NO_SERIALIZE flag eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. The HEAP_NO_SERIALIZE flag can, therefore, be safely used only in the following situations:

  • The process has only one thread.
  • The process has multiple threads, but only one thread calls the heap functions for a specific heap.
  • The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

Windows CE: Windows CE does not support the HEAP_GENERATE_EXCEPTIONS value for the dwFlags parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetProcessHeap, HeapAlloc, HeapCreate, HeapDestroy, HeapFree, HeapSize, SetLastError


HeapSize

The HeapSize function returns the size, in bytes, of a memory block allocated from a heap by the HeapAlloc or HeapReAlloc function.

DWORD HeapSize(
  HANDLE hHeap,  // handle to the heap
  DWORD dwFlags, // heap size control flags
  LPCVOID lpMem  // pointer to memory to return size for
);

Parameters

hHeap
Specifies the heap in which the memory block resides. This handle is returned by the HeapCreate or GetProcessHeap function.
dwFlags
Specifies several controllable aspects of accessing the memory block. Only one flag is currently defined; however, all other flag values are reserved for future use. Specifying this flag will override the corresponding flag specified in the flOptions parameter when the heap was created by using the HeapCreate function:
Value Meaning
HEAP_NO_SERIALIZE Specifies that mutual exclusion will not be used while HeapSize is accessing the heap.

This flag should not be specified when accessing the process heap. The system may create additional threads within the application's process, such as a CTRL+C handler, that simultaneously access the process heap.

lpaam
Pointer to the memory block whose size the function will obtain. This is a pointer returned by the HeapAlloc or HeapReAlloc function.

Return Values

If the function succeeds, the return value is the size, in bytes, of the allocated memory block.

If the function fails, the return value is 0xFFFFFFFF. The function does not call SetLastError. An application cannot call GetLastError for extended error information.

Remarks

Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap. Setting the HEAP_NO_SERIALIZE flag eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. The HEAP_NO_SERIALIZE flag can, therefore, be safely used only in the following situations:

  • The process has only one thread.
  • The process has multiple threads, but only one thread calls the heap functions for a specific heap.
  • The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetProcessHeap, HeapAlloc, HeapCreate, HeapDestroy, HeapFree, HeapReAlloc, SetLastError


HeapUnlock

The HeapUnlock function releases ownership of the critical section object, or lock, that is associated with a specified heap. The HeapUnlock function reverses the action of the HeapLock function.

BOOL HeapUnlock(
  HANDLE hHeap   // handle to the heap to unlock
);

Parameters

hHeap
Handle to the heap to unlock.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The HeapLock function is primarily useful for preventing the allocation and release of heap memory by other threads while the calling thread uses the HeapWalk function. The HeapUnlock function is the inverse of HeapLock.

Each call to HeapLock must be matched by a corresponding call to the HeapUnlock function. Failure to call HeapUnlock will block the execution of any other threads of the calling process that attempt to access the heap.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, HeapLock, HeapWalk


HeapValidate

The HeapValidate function attempts to validate a specified heap. The function scans all the memory blocks in the heap, and verifies that the heap control structures maintained by the heap manager are in a consistent state. You can also use the HeapValidate function to validate a single memory block within a specified heap, without checking the validity of the entire heap.

BOOL HeapValidate(
  HANDLE hHeap,  // handle to the heap of interest
  DWORD dwFlags, // bit flags that control heap access during
                 // function operation
  LPCVOID lpMem  // optional pointer to individual memory block to
                 // validate
);

Parameters

hHeap
Handle to the heap of interest. The HeapValidate function attempts to validate this heap, or a single memory block within this heap.
dwFlags
A set of bit flags that control heap access during function operation. The following bit flag has meaning:
Value | Meaning
HEAP_NO_SERIALIZE | Specifies that mutual exclusion is not used while the HeapValidate function accesses the heap.

lpMem
Pointer to a memory block within the specified heap. This parameter may be NULL.

If this parameter is NULL, the function attempts to validate the entire heap specified by hHeap.

If this parameter is not NULL, the function attempts to validate the memory block pointed to by lpMem. It does not attempt to validate the rest of the heap.

Return Values

If the specified heap or memory block is valid, the return value is nonzero.

If the specified heap or memory block is invalid, the return value is zero. On a system set up for debugging, the HeapValidate function then displays debugging messages that describe the part of the heap or memory block that is invalid, and stops at a hard-coded breakpoint so that you can examine the system to determine the source of the invalidity. The HeapValidate function does not set the thread's last error value. There is no extended error information for this function; do not call GetLastError.

Remarks

There are heap control structures for each memory block in a heap, and for the heap as a whole. When you use the HeapValidate function to validate a complete heap, it checks all of these control structures for consistency.

When you use HeapValidate to validate a single memory block within a heap, it checks only the control structures pertaining to that element. HeapValidate can only validate allocated memory blocks. Calling HeapValidate on a freed memory block will return FALSE because there are no control structures to validate.

If you want to validate the heap elements enumerated by the HeapWalk function, you should only call HeapValidate on the elements that have the PROCESS_HEAP_ENTRY_BUSY bit flag in the wFlags member of the PROCESS_HEAP_ENTRY structure. HeapValidate returns FALSE for all heap elements that do not have this bit set.

Serialization ensures mutual exclusion when two or more threads attempt to simultaneously allocate or free blocks from the same heap. There is a small performance cost to serialization, but it must be used whenever multiple threads allocate and free memory from the same heap. Setting the HEAP_NO_SERIALIZE flag eliminates mutual exclusion on the heap. Without serialization, two or more threads that use the same heap handle might attempt to allocate or free memory simultaneously, likely causing corruption in the heap. The HEAP_NO_SERIALIZE flag can, therefore, be safely used only in the following situations:

  • The process has only one thread.
  • The process has multiple threads, but only one thread calls the heap functions for a specific heap.
  • The process has multiple threads, and the application provides its own mechanism for mutual exclusion to a specific heap.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, HeapCreate, HeapWalk, PROCESS_HEAP_ENTRY


HeapWalk

The HeapWalk function enumerates the memory blocks in a specified heap.

BOOL HeapWalk(
  HANDLE hHeap,  // handle to the heap to enumerate
  LPPROCESS_HEAP_ENTRY lpEntry
                 // points to structure that maintains enumeration
                 // state information
);

Parameters

hHeap
Handle to the heap whose memory blocks you wish to enumerate.
dwFlags
Pointer to a PROCESS_HEAP_ENTRY structure that maintains state informationfor a particular heap enumeration.

If the HeapWalk function succeeds, returning the value TRUE, this structure's members contain information about the next memory block in the heap.

To initiate a heap enumeration, set the lpData field of the PROCESS_HEAP_ENTRY structure to NULL. To continue a particular heap enumeration, call the HeapWalk function repeatedly, with no changes to hHeap, lpEntry, or any of the members of the PROCESS_HEAP_ENTRY structure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

If the heap enumeration terminates successfully by reaching the end of the heap, the function returns FALSE, and GetLastError returns the error code ERROR_NO_MORE_ITEMS.

Remarks

To initiate a heap enumeration, call HeapWalk with the lpData field of the PROCESS_HEAP_ENTRY structure pointed to by lpEntry set to NULL.

To continue a heap enumeration, call HeapWalk with the same hHeap and lpEntry values, and with the PROCESS_HEAP_ENTRY structure unchanged from the preceding call to HeapWalk. Repeat this process until you have no need for further enumeration, or until the function returns FALSE and GetLastError returns ERROR_NO_MORE_ITEMS, indicating that all of the heap's memory blocks have been enumerated.

No special call of HeapWalk is needed to terminate the heap enumeration, since no enumeration state data is maintained outside the contents of the PROCESS_HEAP_ENTRY structure.

HeapWalk can fail in a multithreaded application if the heap is not locked during the heap enumeration. Use the HeapLock and HeapUnlock functions to control heap locking during heap enumeration.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, HeapLock, HeapUnlock, HeapValidate, PROCESS_HEAP_ENTRY


IsBadCodePtr

The IsBadCodePtr function determines whether the calling process has read access to the memory at the specified address.

BOOL IsBadCodePtr(
  FARPROC lpfn   // address of function
);

Parameters

lpfn
Pointer to an address in memory.

Return Values

If the calling process has read access to the specified memory, the return value is zero.

If the calling process does not have read access to the specified memory, the return value is nonzero. To get extended error information, call GetLastError.

If the application is compiled as a debugging version, and the process does not have read access to all bytes in the specified memory range, the function causes an assertion and breaks into the debugger. Leaving the debugger, the function continues as usual, and returns a nonzero value This behavior is by design, as a debugging aid.

Remarks

IsBadCodePtr checks the read access only at the specified address and does not guarantee read access to a range of memory.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has read access to the specified memory, you should use structured exception handling when attempting to access the memory. Use of structured exception handling enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, IsBadReadPtr, IsBadStringPtr, IsBadWritePtr


IsBadHugeReadPtr

The IsBadHugeReadPtr function is obsolete. It is available only for compatibility with 16-bit Windows, which distinguishes between normal memory allocations and huge allocations occupying multiple segments. In the Win32 API, this function is equivalent to the IsBadReadPtr function.

See Also

Memory Management Overview, Memory Management Functions


IsBadHugeWritePtr

The IsBadHugeWritePtr function is obsolete. It is available only for compatibility with 16-bit Windows, which distinguishes between normal memory allocations and huge allocations occupying multiple segments. In the Win32 API, this function is equivalent to the IsBadWritePtr function.

See Also

Memory Management Overview, Memory Management Functions


IsBadReadPtr

The IsBadReadPtr function verifies that the calling process has read access to the specified range of memory.

BOOL IsBadReadPtr(
  CONST VOID *lp,  // address of memory block
  UINT ucb         // size of block
);

Parameters

lp
Pointer to the first byte of the memory block.
ucb
Specifies the size, in bytes, of the memory block. If this parameter is zero, the return value is zero.

Return Values

If the calling process has read access to all bytes in the specified memory range, the return value is zero.

If the calling process does not have read access to all bytes in the specified memory range, the return value is nonzero.

If the application is compiled as a debugging version, and the process does not have read access to all bytes in the specified memory range, the function causes an assertion and breaks into the debugger. Leaving the debugger, the function continues as usual, and returns a nonzero value This behavior is by design, as a debugging aid.

Remarks

If the calling process has read access to some, but not all, of the bytes in the specified memory range, the return value is nonzero.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has read access to the specified memory, you should use structured exception handling when attempting to access the memory. Use of structured exception handling enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, IsBadCodePtr, IsBadStringPtr, IsBadWritePtr


IsBadStringPtr

The IsBadStringPtr function verifies that the calling process has read access to a range of memory pointed to by a string pointer.

BOOL IsBadStringPtr(
  LPCTSTR lpsz,  // address of string
  UINT ucchMax   // maximum size of string
);

Parameters

lpsz
Pointer to a null-terminated string, either Unicode or ASCII.
ucchMax
Specifies the maximum size, in characters, of the string. The function checks for read access in all bytes up to the string's terminating null character or up to the number of bytes specified by this parameter, whichever is smaller. If this parameter is zero, the return value is zero.

Return Values

If the calling process has read access to all bytes up to the string's terminating null character or up to the number of bytes specified by ucchMax, the return value is zero.

If the calling process does not have read access to all bytes up to the string's terminating null character or up to the number of bytes specified by ucchMax, the return value is nonzero. To get extended error information, call GetLastError

If the application is compiled as a debugging version, and the process does not have read access to all bytes in the specified memory range, the function causes an assertion and breaks into the debugger. Leaving the debugger, the function continues as usual, and returns a nonzero value This behavior is by design, as a debugging aid.

Remarks

If the calling process has read access to some, but not all, of the bytes in the specified memory range, the return value is nonzero.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has read access to the specified memory, you should use structured exception handling when attempting to access the memory. Use of structured exception handling enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Memory Management Overview, Memory Management Functions, IsBadCodePtr, IsBadReadPtr, IsBadWritePtr


IsBadWritePtr

The IsBadWritePtr function verifies that the calling process has write access to the specified range of memory.

BOOL IsBadWritePtr(
  LPVOID lp, // address of memory block
  UINT ucb   // size of block
);

Parameters

lp
Pointer to the first byte of the memory block.
ucb
Specifies the size, in bytes, of the memory block. If this parameter is zero, the return value is zero.

Return Values

If the calling process has write access to all bytes in the specified memory range, the return value is zero.

If the calling process does not have write access to all bytes in the specified memory range, the return value is nonzero. To get extended error information, call GetLastError.

If the application is compiled as a debugging version, and the process does not have write access to all bytes in the specified memory range, the function causes an assertion and breaks into the debugger. Leaving the debugger, the function continues as usual, and returns a nonzero value This behavior is by design, as a debugging aid.

Remarks

If the calling process has write access to some, but not all, of the bytes in the specified memory range, the return value is nonzero.

In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has write access to the specified memory, you should use structured exception handling when attempting to access the memory. Use of structured exception handling enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, IsBadCodePtr, IsBadHugeReadPtr, IsBadHugeWritePtr, IsBadReadPtr


LimitEmsPages

The LimitEmsPages function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. Win32-based applications do not require this function.

See Also

Memory Management Overview, Memory Management Functions


LocalAlloc

The LocalAlloc function allocates the specified number of bytes from the heap. Win32 memory management does not provide a separate local heap and global heap.

This function is provided only for compatibility with 16-bit versions of Windows.

HLOCAL LocalAlloc(
  UINT uFlags,  // allocation attributes
  UINT uBytes   // number of bytes to allocate
);

Parameters

uFlags
Specifies how to allocate memory. If zero is specified, the default is the LMEM_FIXED flag. Except for the incompatible combinations that are specifically noted, any combination of the following flags can be specified. To indicate whether the function allocates fixed or movable memory, specify one of the first six flags:
Flag | Meaning
LMEM_FIXED | Allocates fixed memory. The return value is a pointer to the memory object.
LMEM_MOVEABLE Allocates movable memory. In Win32, memory blocks are never moved in physical memory, but they can be moved within the default heap.

The return value is a handle to the memory object. To translate the handle to a pointer, use the LocalLock function.

This flag cannot be combined with the LMEM_FIXED flag.

LPTR | Combines the LMEM_FIXED and LMEM_ZEROINIT flags.
LHND | Combines the LMEM_MOVEABLE and LMEM_ZEROINIT flags.
NONZEROLHND | Same as the LMEM_MOVEABLE flag.
NONZEROLPTR | Same as the LMEM_FIXED flag.
LMEM_DISCARDABLE Ignored. This flag is provided only for compatibility with 16-bit Windows.

In Win32, you must explicitly call the LocalDiscard function to discard a block.

This flag cannot be combined with the LMEM_FIXED flag.
LMEM_NOCOMPACT | Ignored. This flag is provided only for compatibility with 16-bit Windows.
LMEM_NODISCARD | Ignored. This flag is provided only for compatibility with 16-bit Windows.
LMEM_ZEROINIT | Initializes memory contents to zero.

uBytes
Specifies the number of bytes to allocate. If this parameter is zero and the uFlags parameter specifies the LMEM_MOVEABLE flag, the function returns a handle to a memory object that is marked as discarded.

Return Values

If the function succeeds, the return value is a handle to the newly allocated memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

If the heap does not contain sufficient free space to satisfy the request, LocalAlloc returns NULL. Because NULL is used to indicate an error, virtual address zero is never allocated. It is, therefore, easy to detect the use of a NULL pointer.

If this function succeeds, it allocates at least the amount requested. If the amount allocated is greater than the amount requested, the process can use the entire amount. To determine the actual number of bytes allocated, use the LocalSize function.

To free the memory, use the LocalFree function.

Windows CE: Windows CE does not support the following uFlags flags:

LMEM_MOVEABLE

LHND

NONZEROLPTR

LMEM_DISCARDABLE

LMEM_NOCOMPACT

LMEM_NODISCARD

NONZEROLHND

The local heap for each process cannot exceed 1 megabyte. However, a process can create multiple heaps using the HeapCreate function and each of these heaps can be up to 1 megabyte.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, LocalFree, LocalLock, LocalReAlloc, LocalSize


LocalCompact

The LocalCompact function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. It has no meaning in the 32-bit environment.

See Also

Memory Management Overview, Memory Management Functions


LocalDiscard

The LocalDiscard function discards the specified local memory object. The lock count of the memory object must be zero.

This function is provided only for compatibility with 16-bit versions of Windows.

HLOCAL LocalDiscard(
  HLOCAL hlocMem   // handle to local memory object
);

Parameters

hlocMem
Handle to the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Values

If the function succeeds, the return value is a handle to the local memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

Although LocalDiscard discards the object's memory block, the handle to the object remains valid. A process can subsequently pass the handle to the LocalReAlloc function to allocate another local memory object identified by the same handle.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Memory Management Overview, Memory Management Functions, LocalAlloc, LocalReAlloc


LocalFlags

The LocalFlags function returns information about the specified local memory object.

This function is provided only for compatibility with 16-bit versions of Windows.

UINT LocalFlags(
  HLOCAL hMem   // handle to local memory object
);

Parameters

hMem
Handle to the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Values

If the function succeeds, the return value is a 32-bit value that specifies the allocation flags and the lock count for the memory object.

If the function fails, the return value is the LMEM_INVALID_HANDLE flag, indicating that the local handle is not valid. To get extended error information, call GetLastError.

Remarks

The low-order byte of the low-order word of the return value contains the lock count of the object. To retrieve the lock count from the return value, use the LMEM_LOCKCOUNT mask with the bitwise AND (&) operator. The lock count of memory objects allocated with the LMEM_FIXED flag is always zero.

The high-order byte of the low-order word of the return value indicates the allocation flags of the memory object. It can be zero or any combination of the following flags:

Value | Description
LMEM_DISCARDABLE | Ignored. This flag is provided only for compatibility with 16-bit Windows. In Win32, you must explicitly call the LocalDiscard function to discard a block.
LMEM_DISCARDED | The object's memory block has been discarded.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalFlags, LocalAlloc, LocalDiscard, LocalLock, LocalReAlloc, LocalUnlock


LocalFree

The LocalFree function frees the specified local memory object and invalidates its handle.

This function is provided only for compatibility with 16-bit versions of Windows.

HLOCAL LocalFree(
  HLOCAL hMem   // handle to local memory object
);

Parameters

hMem
Handle to the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Values

If the function succeeds, the return value is NULL.

If the function fails, the return value is equal to a handle to the local memory object. To get extended error information, call GetLastError.

Remarks

If the process tries to examine or modify the memory after it has been freed, heap corruption may occur or an access violation exception (EXCEPTION_ACCESS_VIOLATION) may be generated.

If the hMem parameter is NULL, LocalFree ignores the parameter and returns NULL.

The LocalFree function will free a locked memory object. A locked memory object has a lock count greater than zero. The LocalLock function locks a local memory object and increments the lock count by one. The LocalUnlock function unlocks it and decrements the lock count by one. To get the lock count of a local memory object, use the LocalFlags function.

If an application is running under a debug version of the system, LocalFree will issue a message that tells you that a locked object is being freed. If you are debugging the application, LocalFree will enter a breakpoint just before freeing a locked object. This allows you to verify the intended behavior, then continue execution.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalFree, LocalAlloc, LocalFlags, LocalLock, LocalReAlloc, LocalUnlock


LocalHandle

The LocalHandle function retrieves the handle associated with the specified pointer to a local memory object.

This function is provided only for compatibility with 16-bit versions of Windows.

HLOCAL LocalHandle(
  LPCVOID pMem   // pointer to the local memory object
);

Parameters

pMem
Pointer to the first byte of the local memory object. This pointer is returned by the LocalLock function.

Return Values

If the function succeeds, the return value is a handle to the specified local memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

When the LocalAlloc function allocates a local memory object with the LMEM_MOVEABLE flag, it returns a handle to the object. The LocalLock function converts this handle into a pointer to the object's memory block, and LocalHandle converts the pointer back into a handle.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, LocalAlloc, LocalLock


LocalLock

The LocalLock function locks a local memory object and returns a pointer to the first byte of the object's memory block.

This function is provided only for compatibility with 16-bit versions of Windows.

LPVOID LocalLock(
  HLOCAL hMem   // handle to the local memory object
);

Parameters

hMem
Handle to the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Values

If the function succeeds, the return value is a pointer to the first byte of the memory block.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, LocalLock increments the count by one, and the LocalUnlock function decrements the count by one. For each call that a process makes to LocalLock for an object, it must eventually call LocalUnlock. Locked memory will not be moved or discarded unless the memory object is reallocated by using the LocalReAlloc function. The memory block of a locked memory object remains locked in memory until its lock count is decremented to zero, at which time it can be moved or discarded.

Memory objects allocated with the LMEM_FIXED flag always have a lock count of zero. For these objects, the value of the returned pointer is equal to the value of the specified handle.

If the specified memory block has been discarded or if the memory block has a zero-byte size, this function returns NULL.

Discarded objects always have a lock count of zero.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, LocalAlloc, LocalFlags, LocalReAlloc, LocalUnlock


LocalReAlloc

The LocalReAlloc function changes the size or the attributes of a specified local memory object. The size can increase or decrease.

This function is provided only for compatibility with 16-bit versions of Windows.

HLOCAL LocalReAlloc(
  HLOCAL hMem,  // handle to the local memory object
  UINT uBytes,  // new size of block
  UINT uFlags   // how to reallocate object
);

Parameters

hMem
Handle to the local memory object to be reallocated. This handle is returned by either the LocalAlloc or LocalReAlloc function.
uBytes
New size, in bytes, of the memory block. If uFlags specifies the LMEM_MODIFY flag, this parameter is ignored.
uFlags
Flag that specifies how to reallocate the local memory object. If the LMEM_MODIFY flag is specified, this parameter modifies the attributes of the memory object, and the uBytes parameter is ignored. Otherwise, this parameter controls the reallocation of the memory object.

The LMEM_MODIFY flag can be combined with either or both of the following flags:
Flag | Meaning
LMEM_DISCARDABLE Ignored. This flag is provided only for compatibility with 16-bit Windows.

In Win32, you must explicitly call the LocalDiscard function to discard a block.

In 16-bit Windows, this flag allocates discardable memory if the LMEM_MODIFY flag is also specified. This flag is ignored if the object was not previously allocated as movable or if the LMEM_MOVEABLE flag is not specified.
LMEM_MOVEABLE | You cannot combine LMEM_MOVEABLE with LMEM_MODIFY to change a fixed memory object into a movable one. If you do so, the function returns an error.

If this parameter does not specify LMEM_MODIFY, this parameter can be any combination of the following flags:
Flag | Meaning
LMEM_MOVEABLE | In 16-bit Windows, if uBytes is zero, this flag discards a previously movable and discardable memory block. If the object's lock count is not zero or the block is not movable and discardable, the function fails. If uBytes is nonzero, this flag enables the system to move the reallocated block to a new location without changing the movable or fixed attribute of the memory object. If the object is fixed, the handle returned may be different from the handle specified in the hMem parameter. If the object is movable, the block can be moved without invalidating the handle, even if the object is currently locked by a previous call to the LocalLock function. To get the new address of the memory block, use LocalLock.
LMEM_NOCOMPACT | Ignored. This flag is provided only for compatibility with 16-bit Windows.
LMEM_ZEROINIT | Causes the additional memory contents to be initialized to zero if the memory object is growing in size.

Return Values

If the function succeeds, the return value is a handle to the reallocated memory object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

If LocalReAlloc fails, the original memory is not freed, and the original handle and pointer are still valid.

If LocalReAlloc reallocates a movable object, the return value is a handle to the memory object. To convert the handle to a pointer, use the LocalLock function.

If LocalReAlloc reallocates a fixed object, the value of the handle returned is the address of the first byte of the memory block. To access the memory, a process can simply cast the return value to a pointer.

Windows CE: Windows CE does not support the LMEM_DISCARDABLE and LMEM_NOCOMPACT flags for the uFlags parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, LocalAlloc, LocalFree, LocalLock


LocalShrink

The LocalShrink function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. It has no meaning in the 32-bit environment.

See Also

Memory Management Overview, Memory Management Functions


LocalSize

The LocalSize function returns the current size, in bytes, of the specified local memory object.

This function is provided only for compatibility with 16-bit versions of Windows.

UINT LocalSize(
  HLOCAL  hMem   // handle to the local memory object
);

Parameters

hMem
Handle to the local memory object. This handle is returned by the LocalAlloc, LocalReAlloc, or LocalHandle function.

Return Values

If the function succeeds, the return value is the size, in bytes, of the specified local memory object. If the specified handle is not valid or if the object has been discarded, the return value is zero. To get extended error information, call GetLastError.

Remarks

The size of a memory block may be larger than the size requested when the memory was allocated.

To verify that the specified object's memory block has not been discarded, call the LocalFlags function before calling LocalSize.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, LocalAlloc, LocalFlags, LocalHandle, LocalReAlloc


LocalUnlock

The LocalUnlock function decrements the lock count associated with a memory object that was allocated with the LMEM_MOVEABLE flag. This function has no effect on memory objects allocated with the LMEM_FIXED flag.

This function is provided only for compatibility with 16-bit versions of Windows.

BOOL LocalUnlock(
  HLOCAL hMem   // handle to the local memory object
);

Parameters

hMem
Handle to the local memory object. This handle is returned by either the LocalAlloc or LocalReAlloc function.

Return Values

If the memory object is still locked after decrementing the lock count, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. If GetLastError returns NO_ERROR, the memory object is unlocked.

Remarks

The internal data structures for each memory object include a lock count that is initially zero. For movable memory objects, the LocalLock function increments the count by one, and LocalUnlock decrements the count by one. For each call that a process makes to LocalLock for an object, it must eventually call LocalUnlock. Locked memory will not be moved or discarded unless the memory object is reallocated by using the LocalReAlloc function. The memory block of a locked memory object remains locked until its lock count is decremented to zero, at which time it can be moved or discarded.

If the memory object is already unlocked, LocalUnlock returns FALSE and GetLastError reports ERROR_NOT_LOCKED. Memory objects allocated with the LMEM_FIXED flag always have a lock count of zero and cause the ERROR_NOT_LOCKED error.

A process should not rely on the return value to determine the number of times it must subsequently call LocalUnlock for the memory block.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, LocalAlloc, LocalFlags, LocalLock, LocalReAlloc


LockSegment

The LockSegment function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. It has no meaning in the 32-bit environment.

See Also

Memory Management Overview, Memory Management Functions


MapViewOfFileVlm

[This is preliminary documentation and subject to change.]

The MapViewOfFileVlm function maps a view of a file into the address space of the calling process.

LPVOID MapViewOfFileVlm(
  HANDLE hFileMappingObject,  // file-mapping object to map into
                              // address space
  DWORD dwDesiredAccess,      // desired access mode
  DWORDLONG ulOffset,         // offset into mapping region
  DWORDLONG ulNumberOfBytesToMap,  // size of mapping in bytes
  PVOID64 lpBaseAddress       // address of region of shared memory
);

Parameters

hFileMappingObject
Handle to a file-mapping object to be mapped into the calling process's address space. The CreateFileMapping and OpenFileMapping functions return this handle. The mapped view must have been created by using CreateFileMapping with the SEC_VLM flag set in the fdwProtect parameter.
dwDesiredAccess
Type of access to the file view to be mapped and, therefore, the type of protection for the pages mapped by the file. This parameter can be one of the following values.
Value | Meaning
FILE_MAP_READ | Read-only access. The object whose handle is passed in the hFileMappingObject parameter must have been created with PAGE_READWRITE or PAGE_READONLY protection. A read-only view of the file is mapped.
FILE_MAP_WRITE | Read-write access. The hFileMappingObject object must have been created with PAGE_READWRITE protection. A read-write view of the file is mapped.

ulOffset
64-bit file offset where mapping is to begin. The ulOffset parameter must specify a 64K-aligned offset within the file to map. Specifying an address that is not a multiple of 64K is an error.
ulNumberOfBytesToMap
Number of bytes of the file to map. If the ulNumberOfBytesToMap parameter is zero, the entire file is mapped. The call to MapViewOfFileVlm fails if there is not enough address space to map the requested number of bytes.
lpBaseAddress
Base address of the point in the process's address space at which the mapping is to begin. Note that the address is rounded down to the nearest 64K boundary by the system. A value of NULL for this parameter allows the system to choose the mapping base address without consideration of calling process requirements.

Return Values

If the function succeeds, the return value is the starting address of the mapped view, after any rounding down.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

Mapping a file makes the specified portion of the file visible in the address space of the calling process.

Multiple views of a file (or of a file-mapping object and its mapped file) are said to be "coherent" if they contain identical data at a specified time. Coherence occurs if the file views are derived from the same file-mapping object. A process can duplicate a file-mapping object handle in another process by using the DuplicateHandle function. A process other than the file-mapping object's creator can open the object by name by using the OpenFileMapping function.

A mapped view of a file is not guaranteed to be coherent with a file being accessed by the ReadFile, WriteFile, ReadFileVlm or WriteFileVlm function.

A call to MapViewOfFileVlm fails if there is not enough address space to map the requested number of bytes.

Because VLM virtual space is not paged, page file size is not a concern.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory-mapped view. For more information on structured exception handling, see Reading and Writing.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), CreateFileMapping, DuplicateHandle, GetSystemInfo, MapViewOfFileEx, OpenFileMapping, ReadFile, ReadFileVlm , SYSTEM_INFO, UnmapViewOfFileVlm, WriteFile, WriteFileVlm


MoveMemory

The MoveMemory function moves a block of memory from one location to another.

VOID MoveMemory (
  PVOID Destination,  // address of move destination
  CONST VOID *Source, // address of block to move
  DWORD Length        // size, in bytes, of block to move
);

Parameters

Destination
Pointer to the starting address of the destination of the move.
Source
Pointer to the starting address of the block of memory to move.
Length
Specifies the size, in bytes, of the block of memory to move.

Return Values

This function has no return value.

Remarks

The source and destination blocks may overlap.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Memory Management Overview, Memory Management Functions, CopyMemory, CopyMemoryVlm, FillMemory, FillMemoryVlm, MoveMemoryVlm, ZeroMemory


MoveMemoryVlm

[This is preliminary documentation and subject to change.]

The MoveMemoryVlm function moves a block of memory specified with 64-bit pointers from one location to another.

VOID MoveMemoryVlm (
  PVOID64 Destination,  // address of move destination
  PVOID64 Source, // address of block to move
  DWORD Length        // size, in bytes, of block to move
);

Parameters

Destination
Pointer to the starting address of the destination of the move.
Source
Pointer to the starting address of the block of memory to move.
Length
Size, in bytes, of the block of memory to move.

Return Values

This function has no return value.

Remarks

Where the source and destination blocks overlap, the function moves the data safely.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory-mapped view. For more information on structured exception handling, see Reading and Writing.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), CopyMemoryVlm, MoveMemory, FillMemoryVlm, ZeroMemoryVlm


ReadFileVlm

[This is preliminary documentation and subject to change.]

The ReadFileVlm function reads data from a file asynchronously. ReadFileVlm is designed solely for asynchronous operation, unlike the ReadFile function, which is designed for both synchronous and asynchronous operation.

BOOL ReadFileVlm(
  HANDLE hFile,                // handle of file to read
  PVOID64 lpBuffer,            // pointer to buffer
  DWORD nNumberOfBytesToRead,  // number of bytes to read
  LPDWORD lpReserved,          // reserved; must be NULL
  LPOVERLAPPED lpOverlapped    // pointer to offset
);

Parameters

hFile
Open handle that specifies the file to read from. To open a file handle, use the CreateFile function. To specify asynchronous I/O, this file handle must have been created with the FILE_FLAG_OVERLAPPED flag. To specify noncached I/O, this file handle must have been created with the FILE_FLAG_NO_BUFFERING flag.
lpBuffer
Pointer to a buffer that receives the data read from the file. The address specified can be used to access memory in processes allocated using the VirtualAllocVlm function. Therefore, the address specified must be 64 bits or a sign-extended 32-bit address.

The buffer pointed to by the lpBuffer parameter must remain valid for the duration of the read operation. The calling process should not use this buffer until the read operation is completed.

nNumberOfBytesToRead
Number of bytes to read from the file.
lpReserved
Reserved; must be NULL.
lpOverlapped
Pointer to an OVERLAPPED data structure that supplies data to be used during the overlapped (asynchronous) read operation.

If the file specified by the hFile parameter supports byte offsets, the process that calls ReadFileVlm must specify a byte offset within the file at which reading should begin. The calling process specifies the byte offset by setting the OVERLAPPED structure's Offset and OffsetHigh members.

ReadFileVlm uses the OVERLAPPED structure's Internal and InternalHigh members. An application should not set these members.

The OVERLAPPED data structure pointed to by the lpOverlapped parameter must remain valid for the duration of the read operation. The structure should not be a variable that can go out of scope while the read operation is in progress.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

If ReadFileVlm attempts to read past the end of the file, the function returns zero, and GetLastError returns the error code ERROR_HANDLE_EOF.

Remarks

If a portion of the file specified by hFile is locked by another process and the portion read by the read operation overlaps the locked portion, a call to ReadFileVlm fails.

Accessing the input buffer while a read operation is using the buffer may lead to corruption of the data read into that buffer. Applications must not read from, write to, reallocate, or free the input buffer that a read operation is using until the read operation completes.

To determine whether an asynchronous I/O operation has completed, you can use the HasOverlappedIoCompleted macro.

The ReadFileVlm function may fail if there are too many outstanding asynchronous I/O requests. In the event of such a failure, GetLastError can return ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY.

To cancel all pending asynchronous I/O operations, use the CancelIo function. CancelIo only cancels operations issued by the calling thread for the specified file handle. I/O operations that are canceled complete with the error code ERROR_OPERATION_ABORTED.

If your application attempts to read from a floppy drive that does not contain a floppy disk, the operating system displays a message prompting the user to retry the operation. To prevent the system from displaying this message, call the SetErrorMode function with the flag SEM_NOOPENFILEERRORBOX set for the uMode parameter.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory-mapped view. For more information on structured exception handling, see Reading and Writing.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), CancelIo, CreateFile, FileIOCompletionRoutine, HasOverlappedIoCompleted, MsgWaitForMultipleObjectsEx, OVERLAPPED, ReadFile, SetErrorMode, SleepEx, VirtualAllocVlm, WaitForMultipleObjectsEx, WaitForSingleObjectEx, WriteFileVlm


ReadProcessMemoryVlm

[This is preliminary documentation and subject to change.]

The ReadProcessMemoryVlm function reads memory in a specified process.

BOOL ReadProcessMemoryVlm(
  HANDLE hProcess,  // handle to the process whose memory is read
  PVOID64 lpBaseAddress,
                    // address to start reading
  PVOID64 lpBuffer, // address of buffer to place read data
  DWORD nSize,      // number of bytes to read
  LPDWORD lpNumberOfBytesRead
                    // address of number of bytes read
);

Parameters

hProcess
Handle to the process whose memory is being read. To obtain a handle to a process, use the OpenProcess function. The handle must have PROCESS_VM_READ access to the process set when the process is opened.
lpBaseAddress
Pointer to the base address in the specified process to read. Before any data transfer occurs, the operating system verifies that all data in the base address and memory of the specified size is accessible for reading. If this is the case, the function proceeds; otherwise, the function fails. The address specified is 64 bits and can therefore be used to access memory in the process allocated using VirtualAllocVlm, or the address can be a sign-extended 32-bit address.
lpBuffer
Pointer to a buffer that receives the contents from the address space of the specified process.
nSize
Number of bytes to read from the specified process.
lpNumberOfBytesRead
Pointer to the actual number of bytes transferred into the specified buffer. If the lpNumberOfBytesRead parameter is NULL, it is ignored.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

ReadProcessMemoryVlm fails if the requested operation attempts to read an area of the process that is inaccessible. In that event, no data is transferred.

Remarks

ReadProcessMemoryVlm copies the data in the specified address range from the address space of the specified process into the specified buffer of the current process. Any process that has a handle with PROCESS_VM_READ access can call ReadProcessMemoryVlm. The process whose address space is read is typically, but not necessarily, being debugged.

The entire area to be read in a call to ReadProcessMemoryVlm must be accessible, or the function fails.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory-mapped view. For more information on structured exception handling, see Reading and Writing.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), OpenProcess, VirtualAllocVlm, WriteProcessMemoryVlm


SetSwapAreaSize

The SetSwapAreaSize function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. It has no meaning in the 32-bit environment.

See Also

Memory Management Overview, Memory Management Functions


UnlockSegment

The UnlockSegment function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. Segments have no meaning in the 32-bit environment.

See Also

Memory Management Overview, Memory Management Functions


UnmapViewOfFileVlm

[This is preliminary documentation and subject to change.]

The UnmapViewOfFileVlm function unmaps a mapped view of a file from the calling process's address space.

BOOL UnmapViewOfFileVlm(
  PVOID64 lpBaseAddress   // address of region to be unmapped
);

Parameters

lpBaseAddress
Pointer to the base address of a mapped view of a file that is to be unmapped. This value must be identical to the value returned by a previous call to the MapViewOfFileVlm function.

Return Values

If the function succeeds, the return value is nonzero, and all dirty (modified) pages within the specified range are written to disk. The write operation is performed through the usual lazy writing provided by Windows NT.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Although an application may close the file handle used to create a file mapping object prior to unmapping a view, the operating system holds the corresponding file open until the last view of the file is unmapped.

Closed files for which the last view has not yet been unmapped are held open with no sharing restrictions. This situation risks corruption of data, so it should be avoided.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), MapViewOfFileVlm, MapViewOfFileEx


VirtualAlloc

The VirtualAlloc function reserves or commits a region of pages in the virtual address space of the calling process. Memory allocated by this function is automatically initialized to zero, unless the MEM_RESET flag is set.

LPVOID VirtualAlloc(
  LPVOID lpAddress, // address of region to reserve or commit
  DWORD dwSize,     // size of region
  DWORD flAllocationType,
                    // type of allocation
  DWORD flProtect   // type of access protection
);

Parameters

lpAddress
Specifies the desired starting address of the region to allocate. If the memory is being reserved, the specified address is rounded down to the next 64-kilobyte boundary. If the memory is already reserved and is being committed, the address is rounded down to the next page boundary. To determine the size of a page on the host computer, use the GetSystemInfo function. If this parameter is NULL, the system determines where to allocate the region.
dwSize
Specifies the size, in bytes, of the region. If the lpAddress parameter is NULL, this value is rounded up to the next page boundary. Otherwise, the allocated pages include all pages containing one or more bytes in the range from lpAddress to (lpAddress+dwSize). This means that a 2-byte range straddling a page boundary causes both pages to be included in the allocated region.
flAllocationType
Specifies the type of allocation. You can specify any combination of the following flags:
Flag | Meaning
MEM_COMMIT | Allocates physical storage in memory or in the paging file on disk for the specified region of pages.
An attempt to commit an already committed page will not cause the function to fail. This means that a range of committed or decommitted pages can be committed without having to worry about a failure.
MEM_RESERVE | Reserves a range of the process's virtual address space without allocating any physical storage. The reserved range cannot be used by any other allocation operations (the malloc function, the LocalAlloc function, and so on) until it is released. Reserved pages can be committed in subsequent calls to the VirtualAlloc function.
MEM_RESET Windows NT: Specifies that memory pages within the range specified by lpAddress and dwSize will not be written to or read from the paging file.

When you set the MEM_RESET flag, you are declaring that the contents of that range are no longer important. The range is going to be overwritten, and the application does not want the memory to migrate out to or in from the paging file.

Setting this flag does not guarantee that the range operated on with MEM_RESET will contain zeroes. If you want the range to contain zeroes, decommit the memory and then recommit it.

When you set the MEM_RESET flag, the VirtualAlloc function ignores the value of fProtect. However, you must still set fProtect to a valid protection value, such as PAGE_NOACCESS.

VirtualAlloc returns an error if you set the MEM_RESET flag and the range of memory is mapped to a file. A shared view is only acceptable if it is mapped to a paging file.
MEM_TOP_DOWN | Allocates memory at the highest possible address.

flProtect
Specifies the type of access protection. If the pages are being committed, any one of the following flags can be specified, along with the PAGE_GUARD and PAGE_NOCACHE protection modifier flags, as desired:
Flag | Meaning
PAGE_READONLY | Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE | Enables both read and write access to the committed region of pages.
PAGE_EXECUTE | Enables execute access to the committed region of pages. An attempt to read or write to the committed region results in an access violation.
PAGE_EXECUTE_READ | Enables execute and read access to the committed region of pages. An attempt to write to the committed region results in an access violation.
PAGE_EXECUTE_READWRITE | Enables execute, read, and write access to the committed region of pages.
PAGE_GUARD Pages in the region become guard pages. Any attempt to read from or write to a guard page causes the system to raise a STATUS_GUARD_PAGE exception and turn off the guard page status. Guard pages thus act as a one-shot access alarm.

The PAGE_GUARD flag is a page protection modifier. An application uses it with one of the other page protection flags, with one exception: It cannot be used with PAGE_NOACCESS. When an access attempt leads the system to turn off guard page status, the underlying page protection takes over.

If a guard page exception occurs during a system service, the service typically returns a failure status indicator.
PAGE_NOACCESS | Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_NOCACHE | Allows no caching of the committed regions of pages. The hardware attributes for the physical memory should be specified as "no cache." This is not recommended for general usage. It is useful for device drivers; for example, mapping a video frame buffer with no caching. This flag is a page protection modifier, only valid when used with one of the page protections other than PAGE_NOACCESS.

Return Values

If the function succeeds, the return value is the base address of the allocated region of pages.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

VirtualAlloc can perform the following operations:

  • Commit a region of pages reserved by a previous call to the VirtualAlloc function.
  • Reserve a region of free pages.
  • Reserve and commit a region of free pages.

You can use VirtualAlloc to reserve a block of pages and then make additional calls to VirtualAlloc to commit individual pages from the reserved block. This enables a process to reserve a range of its virtual address space without consuming physical storage until it is needed.

Each page in the process's virtual address space is in one of three states:

State | Meaning
Free | The page is not committed or reserved and is not accessible to the process. VirtualAlloc can reserve, or simultaneously reserve and commit, a free page.
Reserved | The range of addresses cannot be used by other allocation functions, but the page is not accessible and has no physical storage associated with it. VirtualAlloc can commit a reserved page, but it cannot reserve it a second time. The VirtualFree function can release a reserved page, making it a free page.
Committed | Physical storage is allocated for the page, and access is controlled by a protection code. The system initializes and loads each committed page into physical memory only at the first attempt to read or write to that page. When the process terminates, the system releases the storage for committed pages. VirtualAlloc can commit an already committed page. This means that you can commit a range of pages, regardless of whether they have already been committed, and the function will not fail. VirtualFree can decommit a committed page, releasing the page's storage, or it can simultaneously decommit and release a committed page.

If the lpAddress parameter is not NULL, the function uses the lpAddress and dwSize parameters to compute the region of pages to be allocated. The current state of the entire range of pages must be compatible with the type of allocation specified by the flAllocationType parameter. Otherwise, the function fails and none of the pages are allocated. This compatibility requirement does not preclude committing an already committed page; see the preceding list.

The PAGE_GUARD protection modifier flag establishes guard pages. Guard pages act as one-shot access alarms. For more information, see Creating Guard Pages.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, HeapAlloc, VirtualAllocVlm, VirtualFree, VirtualLock, VirtualProtect, VirtualQuery


VirtualAllocEx

The VirtualAllocEx function reserves, commits, or both, a region of memory within the virtual address space of a specified process. The function initializes the memory it allocates to zero, unless the MEM_RESET flag is set.

The difference between the VirtualAllocEx function and the VirtualAlloc function is that VirtualAlloc allocates memory within the address space of the calling process, while VirtualAllocEx lets you specify a process.

LPVOID VirtualAllocEx(
  HANDLE hProcess,  // process within which to allocate memory
  LPVOID lpAddress, // desired starting address of allocation
  DWORD dwSize,     // size, in bytes, of region to allocate
  DWORD flAllocationType,
                    // type of allocation
  DWORD flProtect   // type of access protection
);

Parameters

hProcess
Handle to a process. The function allocates memory within the virtual address space of this process.

You must have PROCESS_VM_OPERATION access to the process. If you do not, the function fails.

lpAddress
Pointer that specifies a desired starting address for the region of pages that you want to allocate.

If you are reserving memory, the function rounds this address down to the nearest 64-kilobyte boundary.

If you are committing memory that is already reserved, the function rounds this address down to the nearest page boundary. To determine the size of a page on the host computer, use the GetSystemInfo function.

If lpAddress is NULL, the function determines where to allocate the region.

dwSize
Specifies the size, in bytes, of the region of memory to allocate.

If lpAddress is NULL, the function rounds dwSize up to the next page boundary.

If lpAddress is not NULL, the function allocates all pages that contain one or more bytes in the range from lpAddress to (lpAddress+dwSize). This means, for example, that a 2-byte range that straddles a page boundary causes the function to allocate both pages.

flAllocationType
A set of bit flags that specifies the type of memory allocation. You can set one or more of the following flags:
Flag | Meaning
MEM_COMMIT | The function allocates actual physical storage in memory or in the paging file on disk for the specified region of memory pages. The function initializes the memory to zero.
An attempt to commit a memory page that is already committed does not cause the function to fail. This means that you can commit a range of pages without first determining the current commitment state of each page.

If a memory page is not yet reserved, setting this flag causes the function to both reserve and commit the memory page.

MEM_RESERVE The function reserves a range of the process's virtual address space without allocating any actual physical storage in memory or in the paging file on disk.

Other memory allocation functions, such as malloc and LocalAlloc, cannot use a reserved range of memory until it is released.

You can commit reserved memory pages in subsequent calls to the VirtualAllocEx function.

MEM_RESET Windows NT: Specifies that memory pages within the range specified by lpAddress and dwSize will not be written to or read from the paging file.

When you set the MEM_RESET flag, you are declaring that the contents of that range are no longer important. The range is going to be overwritten, and the application does not want the memory to migrate out to or in from the paging file.

Setting this flag does not guarantee that the range operated on with MEM_RESET will contain zeroes. If you want the range to contain zeroes, decommit the memory and then recommit it.

When you set the MEM_RESET flag, the VirtualAllocEx function ignores the value of fProtect. However, you must still set fProtect to a valid protection value, such as PAGE_NOACCESS.

VirtualAllocEx returns an error if you set the MEM_RESET flag and the range of memory is mapped to a file. A shared view is only acceptable if it is mapped to a paging file.
MEM_TOP_DOWN | The function allocates memory at the highest possible address.

flProtect
A set of bit flags that specifies access protection for the region of pages you are allocating. You can specify one of the following flags, along with the PAGE_GUARD and PAGE_NOCACHE protection modifier flags, as desired:
Flag | Meaning
PAGE_READONLY | Enables read permission to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only permission and execute permission, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE | Enables both read and write permission to the committed region of pages.
PAGE_EXECUTE | Enables execute permission to the committed region of pages. An attempt to read or write to the committed region results in an access violation.
PAGE_EXECUTE_READ | Enables execute and read permission to the committed region of pages. An attempt to write to the committed region results in an access violation.
PAGE_EXECUTE_READWRITE | Enables execute, read, and write permission to the committed region of pages.
PAGE_GUARD Pages in the region become guard pages. Any attempt to read from or write to a guard page causes the system to raise a STATUS_GUARD_PAGE exception and turn off the guard page status. Guard pages thus act as a one-shot access alarm.

The PAGE_GUARD flag is a page protection modifier. An application uses it with one of the other page protection flags, with one exception: It cannot be used with PAGE_NOACCESS. When an access attempt leads the system to turn off guard page status, the underlying page protection takes over.

If a guard page exception occurs during a system service, the service typically returns a failure status indicator.
PAGE_NOACCESS | Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_NOCACHE | Allows no caching of the committed regions of pages. The hardware attributes for the physical memory should be specified as "no cache." This is not recommended for general usage. It is useful for device drivers; for example, mapping a video frame buffer with no caching. This flag is a page protection modifier, only valid when used with one of the page protections other than PAGE_NOACCESS.

A set of bit flags that specifies access protection for the region of pages you are allocating. You can specify one of the following flags, along with the PAGE_GUARD and PAGE_NOCACHE protection modifier flags, as desired:

Return Values

If the function succeeds, the return value is the base address of the allocated region of pages.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The VirtualAllocEx function can perform the following operations:

  • Commit a region of pages reserved by a previous call to the VirtualAllocEx function.
  • Reserve a region of free pages.
  • Reserve and commit a region of free pages.

You can use VirtualAllocEx to reserve a block of pages and then make additional calls to VirtualAllocEx to commit individual pages from the reserved block. This lets you reserve a range of a process's virtual address space without consuming physical storage until it is needed.

Each page of memory in a process's virtual address space is in one of three states:

State | Meaning
Free | The page is not committed or reserved and is not accessible to the process. The VirtualAllocEx function can reserve, or simultaneously reserve and commit, a free page.
Reserved | The page is reserved. The range of addresses cannot be used by other allocation functions, but the page is not accessible and has no physical storage associated with it. The VirtualAllocEx function can commit a reserved page, but it cannot reserve it a second time. You can use the VirtualFreeEx function to release a reserved page in a specified process, making it a free page.
Committed | Physical storage is allocated for the page, and access is controlled by a protection code. The system initializes and loads each committed page into physical memory only at the first attempt to read or write to that page. When the process terminates, the system releases the storage for committed pages. The VirtualAllocEx function can commit an already committed page. This means that you can commit a range of pages, regardless of whether they have already been committed, and the function will not fail. You can use the VirtualFreeEx function to decommit a committed page in a specified process, or to simultaneously decommit and free a committed page.

If the lpAddress parameter is not NULL, the function uses the lpAddress and dwSize parameters to compute the region of pages to be allocated. The current state of the entire range of pages must be compatible with the type of allocation specified by the flAllocationType parameter. Otherwise, the function fails and none of the pages is allocated. This compatibility requirement does not preclude committing an already committed page; see the preceding list.

The PAGE_GUARD protection modifier flag establishes guard pages. Guard pages act as one-shot access alarms. For more information, see Creating Guard Pages.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, HeapAlloc, VirtualAlloc, VirtualAllocVlm, VirtualFree, VirtualFreeEx, VirtualLock, VirtualProtect, VirtualQuery


VirtualAllocVlm

[This is preliminary documentation and subject to change.]

The VirtualAllocVlm function commits a region of pages in the virtual 64-bit address space of the indicated process.

PVOID64 VirtualAllocVlm(
  HANDLE hProcess,   // process within which to allocate memory
  PVOID64 lpAddress, // address of region to reserve or commit
  DWORDLONG ullSize, // size of region
  DWORD flAllocationType,
                     // type of allocation
  DWORD flProtect    // type of access protection
);

Parameters

hProcess
Handle to a process. VirtualAllocVlm allocates memory within the virtual address space of this process. The calling process must have had the PROCESS_VM_OPERATION flag set on a preceding call to the OpenProcess function, indicating virtual memory access to the target process, or VirtualAllocVlm fails.
lpAddress
Starting address of the region to allocate. The system rounds the specified address down to the next 64K boundary. If the lpAddress parameter is NULL, the operating system determines where to allocate the region.
ullSize
Size, in bytes, of the region to allocate. If lpAddress is NULL, this size is rounded up to the next page boundary. Otherwise, the allocated pages include all pages containing one or more bytes in the range from the value of lpAddress to the value of lpAddress plus the value of the ullSize parameter. This functionality means that a 2-byte range straddling a page boundary causes both pages to be included in the allocated region.
flAllocationType
Type of allocation. You can specify any combination of the following flags.
Value | Meaning
MEM_COMMIT | Allocates for the specified region of pages physical storage in memory or in the paging file on disk.
An attempt to commit an already committed page does not cause VirtualAllocVlm to fail. Thus, a range of committed or decommitted pages can be committed without causing a failure.
MEM_RESERVE | Reserves a range of the process's virtual address space without allocating any physical storage. The reserved range cannot be used by any other allocation operations (for example, the malloc function, the LocalAlloc function, and so on) until it is released.

flProtect
Flag that specifies the type of access for the region to be allocated. You can specify one of the following.
Value | Meaning
PAGE_READONLY | Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the operating system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE | Enables both read and write access to the committed region of pages.

Return Values

If the function succeeds, the return value is the base address of the allocated region of pages.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The VirtualAllocVlm function is used to allocate and specify an initial protection value for memory regions that can be addressed through 64-bit pointers.

Memory allocated by VirtualAllocVlm must be physically present in the system. This memory is considered locked down and unavailable to the rest of the virtual memory management system of Windows NT. Programmers using VirtualAllocVlm should understand that this function is allocating dedicated resources.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), GlobalAlloc, HeapAlloc, LocalAlloc, OpenProcess, VirtualAlloc, VirtualFreeVlm, VirtualLock, VirtualProtectVlm, VirtualQueryVlm


VirtualFree

The VirtualFree function releases or decommits (or both) a region of pages within the virtual address space of the calling process.

BOOL VirtualFree(
  LPVOID lpAddress,  // address of region of committed pages
  DWORD dwSize,      // size of region
  DWORD dwFreeType   // type of free operation
);

Parameters

lpAddress
Pointer to the base address of the region of pages to be freed. If the dwFreeType parameter includes the MEM_RELEASE flag, this parameter must be the base address returned by the VirtualAlloc function when the region of pages was reserved.
dwSize
Specifies the size, in bytes, of the region to be freed. If the dwFreeType parameter includes the MEM_RELEASE flag, this parameter must be zero. Otherwise, the region of affected pages includes all pages containing one or more bytes in the range from the lpAddress parameter to (lpAddress+dwSize). This means that a 2-byte range straddling a page boundary causes both pages to be freed.
dwFreeType
Specifies the type of free operation. One, but not both, of the following flags can be specified:
Flag | Meaning
MEM_DECOMMIT | Decommits the specified region of committed pages.
An attempt to decommit an uncommitted page will not cause the function to fail. This means that a range of committed or uncommitted pages can be decommitted without having to worry about a failure.
MEM_RELEASE | Releases the specified region of reserved pages. If this flag is specified, the dwSize parameter must be zero, or the function fails.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

VirtualFree can perform one of the following operations:

  • Decommit a region of committed or uncommitted pages.
  • Release a region of reserved pages.
  • Decommit and release a region of committed or uncommitted pages.

To release a region of pages, the entire range of pages must be in the same state (all reserved or all committed) and the entire region originally reserved by the VirtualAlloc function must be released at the same time. If only part of the pages in the original reserved region are committed, you must first call VirtualFree to decommit the committed pages and then call VirtualFree again to release the entire block.

Pages that have been released are free pages available for subsequent allocation operations. Attempting to read from or write to a free page results in an access violation exception.

VirtualFree can decommit an uncommitted page; this means that a range of committed or uncommitted pages can be decommitted without having to worry about a failure. Decommitting a page releases its physical storage, either in memory or in the paging file on disk. If a page is decommitted but not released, its state changes to reserved, and it can be committed again by a subsequent call to VirtualAlloc. Attempting to read from or write to a reserved page results in an access violation exception.

The current state of the entire range of pages must be compatible with the type of free operation specified by the dwFreeType parameter. Otherwise, the function fails and no pages are released or decommitted.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalFree, VirtualAlloc, VirtualFreeVlm


VirtualFreeEx

The VirtualFreeEx function releases, decommits, or both, a region of memory within the virtual address space of a specified process.

The difference between the VirtualFreeEx function and the VirtualFree function is that VirtualFree frees memory within the address space of the calling process, while VirtualFreeEx lets you specify a process.

BOOL VirtualFreeEx(
  HANDLE hProcess,  // process within which to free memory
  LPVOID lpAddress, // starting address of memory region to free
  DWORD dwSize,     // size, in bytes, of memory region to free
  DWORD dwFreeType  // type of free operation
);

Parameters

hProcess
Handle to a process. The function frees memory within the virtual address space of this process.

You must have PROCESS_VM_OPERATION access to this process. If you do not, the function fails.

lpAddress
Pointer to the starting address of the region of memory to free.

If the MEM_RELEASE flag is set in the dwFreeType parameter, lpAddress must be the base address returned by the VirtualAllocEx function when the region was reserved.

dwSize
Specifies the size, in bytes, of the region of memory to free.

If the MEM_RELEASE flag is set in the dwFreeType parameter, dwSize must be zero. The function frees the entire region that was reserved in the initial allocation call to VirtualAllocEx.

If the MEM_DECOMMIT flag is set, the function decommits all memory pages that contain one or more bytes in the range from the lpAddress parameter to (lpAddress+dwSize). This means, for example, that a 2-byte region of memory that straddles a page boundary causes both pages to be decommitted.

The function decommits the entire region that was reserved by VirtualAllocEx. If the following three conditions are met:

  • the MEM_DECOMMIT flag is set
  • lpAddress is the base address returned by the VirtualAllocEx function when the region was reserved
  • dwSize is zero

    The entire region the enters the reserved state.

dwFreeType
Set of bit flags that specifies the type of free operation. You must set one of the following two flags:
Flag | Meaning
MEM_DECOMMIT | The function decommits the specified region of pages. The pages enter the reserved state.
The function does not fail if you attempt to decommit an uncommitted page. This means that you can decommit a range of pages without first determining their current commitment state.
MEM_RELEASE The function releases the specified region of pages. The pages enter the free state.

If you specify this flag, dwSize must be zero, and lpAddress must point to the base address returned by the VirtualAllocEx function when the region was reserved. The function fails if either of these conditions is not met.
If any pages in the region are currently committed, the function first decommits and then releases them.

The function does not fail if you attempt to release pages that are in different states, some reserved and some committed. This means that you can release a range of pages without first determining their current commitment state.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Each page of memory in a process's virtual address space is in one of three states:

State Meaning
Free The page is neither committed nor reserved. The page is not accessible to the process. Attempting to read from or write to a free page results in an access violation exception.

You can use the VirtualFreeEx function to put reserved or committed memory pages into the free state.

Reserved The page is reserved. The range of addresses cannot be used by other allocation functions. The page is not accessible and has no physical storage associated with it. Attempting to read from or write to a free page results in an access violation exception.

You can use the VirtualFreeEx function to put committed memory pages into the reserved state, and to put reserved memory pages into the free state.

Committed The page is committed. Physical storage in memory or in the paging file on disk is allocated for the page, and access is controlled by a protection code.

The system initializes and loads each committed page into physical memory only at the first attempt to read from or write to that page.

When a process terminates, the system releases all storage for committed pages.

You can use the VirtualAllocEx function to put committed memory pages into either the reserved or free state.

The VirtualFreeEx function can perform the following operations:

  • Decommit a region of committed or uncommitted pages. After this operation, the pages are in the reserved state.
  • Release a region of reserved pages. After this operation, the pages are in the free state.
  • Decommit and release a region of committed or uncommitted pages. After this operation, the pages are in the free state.

The VirtualFreeEx function can decommit a range of pages that are in different states, some committed and some uncommitted. This means that you can decommit a range of pages without first determining the current commitment state of each page. Decommitting a page releases its physical storage, either in memory or in the paging file on disk.

If a page is decommitted but not released, its state changes to reserved. You can subsequently call VirtualAllocEx to commit it, or VirtualFreeEx to release it. Attempting to read from or write to a reserved page results in an access violation exception.

The VirtualFreeEx function can release a range of pages that are in different states, some reserved and some committed. This means that you can release a range of pages without first determining the current commitment state of each page. The entire range of pages originally reserved by the VirtualAllocEx function must be released at the same time.

If a page is released, its state changes to free, and it is available for subsequent allocation operations. Attempting to read from or write to a free page results in an access violation exception.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalAlloc, GlobalFree, VirtualAlloc, VirtualAllocEx, VirtualFree, VirtualFreeVlm


VirtualFreeVlm

[This is preliminary documentation and subject to change.]

The VirtualFreeVlm function decommits a memory region within the VLM address space of the specified process.

BOOL VirtualFreeVlm(
  HANDLE hProcess,   // process within which to free memory
  PVOID64 lpAddress, // address of region of pages to free
  DWORDLONG ullSize, // size in bytes of region
  DWORD dwFreeType   // type of free operation
);

Parameters

hProcess
Handle to a process. VirtualFreeVlm frees memory within the virtual address space of this process. The calling process must have had the PROCESS_VM_OPERATION flag set on a preceding call to the OpenProcess function, indicating virtual memory access to the target process, or VirtualFreeVlm fails.
lpAddress
Pointer to the base address of the region of the memory to free. The lpAddress parameter must point to the base address returned by the VirtualAllocVlm function when the region was reserved.
ullSize
Size, in bytes, of the region to release. If the dwFreeType parameter includes the MEM_RELEASE flag, the ullSize parameter must be zero. Otherwise, the region of affected pages includes all pages containing one or more bytes in the range from the value of lpAddress to the value of lpAddress plus the value of ullSize. This functionality means that freeing a 2-byte range straddling a page boundary causes both pages to be freed.

The release can be done only on the whole virtual space region reserved, whereas decommitting can be performed on subareas of a reserved and committed region. Decommitting an uncommitted area has no effect.

dwFreeType
Type of memory deallocation operation. You can specify one of the following flags.
Value | Meaning
MEM_DECOMMIT | Releases the specified region of pages. The pages enter the free state. If you specify this flag and ullSize contains zero, the entire region of pages is decommitted. Otherwise, you must specify lpAddress and ullSize values that are within the range returned by VirtualAllocVlm when the region was reserved. Note that MEM_DECOMMIT only results in the releasing of pages — the virtual address space remains reserved and cannot be reused unless a MEM_RELEASE flag is passed. For more information on reservation of virtual address space, see the discussion of the MEM_RESERVE flag in the VirtualAllocMem topic.
An attempt to decommit an uncommitted page does not cause VirtualFreeVlm to fail. Thus, a range of committed or uncommitted pages can be decommitted without causing a failure.
MEM_RELEASE | Releases the specified region of pages. The pages enter the free state. If you specify this flag, ullSize must be zero and lpAddress must point to the base address returned by VirtualAllocVlm when the region was reserved. VirtualFreeVlm fails if either of these conditions is not met. If VirtualFreeVlm succeeds, both the pages and the range of virtual address space are relinquished.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

VirtualFreeVlm decommits memory allocated with VirtualAllocVlm. VirtualFreeVlm can perform one of the following operations:

  • Decommit a region of committed or uncommitted pages.
  • Release a region of reserved pages.
  • Decommit and release a region of committed or uncommitted pages.

To release a region of pages, the entire range of pages must be in the same state (all reserved or all committed) and the entire region originally reserved by VirtualAllocVlm must be released at the same time. If only part of the pages in the original reserved region are committed, you must first call VirtualFreeVlm to decommit the committed pages and then call VirtualFreeVlm again to release the entire block.

Pages that have been released are free and available for subsequent allocation operations. Attempting to read from or write to a free page results in an access violation exception.

VirtualFreeVlm can decommit an uncommitted page; this means that a range of committed or uncommitted pages can be decommitted without having to worry about a failure. Decommitting a page releases its physical storage from memory. If a page is decommitted but not released, its state changes to reserved and it can be committed again by a subsequent call to VirtualAllocVlm. Attempting to read from or write to a reserved page results in an access violation exception.

The current state of the entire range of pages to be decommitted must be compatible with the type of free operation specified by the dwFreeType parameter. Otherwise, VirtualFreeVlm fails and no pages are released or decommitted.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), GlobalAlloc, GlobalFree, OpenProcess, VirtualFree, VirtualAllocVlm


VirtualLock

The VirtualLock function locks the specified region of the process's virtual address space into memory, ensuring that subsequent access to the region will not incur a page fault.

BOOL VirtualLock(
  LPVOID lpAddress,  // address of first byte of range to lock
  DWORD dwSize       // number of bytes in range to lock
);

Parameters

lpAddress
Pointer to the base address of the region of pages to be locked.
dwSize
Specifies the size, in bytes, of the region to be locked. The region of affected pages includes all pages that contain one or more bytes in the range from the lpAddress parameter to (lpAddress+dwSize). This means that a 2-byte range straddling a page boundary causes both pages to be locked.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

All pages in the specified region must be committed. Memory protected with the PAGE_NOACCESS flag cannot be locked.

Locking pages into memory may degrade the performance of the system by reducing the available RAM and forcing the system to swap out other critical pages to the paging file. By default, a process can lock a maximum of 30 pages. The default limit is intentionally small to avoid severe performance degradation. Applications that need to lock larger numbers of pages must first call the SetProcessWorkingSetSize function to increase their minimum and maximum working set sizes. The maximum number of pages that a process can lock is equal to the number of pages in its minimum working set minus a small overhead.

Pages that a process has locked remain resident even when the process is idle for extended periods.

To unlock a region of locked pages, use the VirtualUnlock function. Locked pages are automatically unlocked when the process terminates.

This function is not like the GlobalLock or LocalLock function in that it does not increment a lock count and translate a handle into a pointer. There is no lock count for virtual pages, so multiple calls to the VirtualUnlock function are never required to unlock a region of pages.

Windows 95: The VirtualLock function is implemented as a stub that has no effect and always returns a nonzero value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GlobalLock, LocalLock, SetProcessWorkingSetSize, VirtualUnlock


VirtualProtect

The VirtualProtect function changes the access protection on a region of committed pages in the virtual address space of the calling process. This function differs from VirtualProtectEx , which changes the access protection of any process.

BOOL VirtualProtect(
  LPVOID lpAddress,    // address of region of committed pages
  DWORD dwSize,        // size of the region
  DWORD flNewProtect,  // desired access protection
  PDWORD lpflOldProtect
                       // address of variable to get old protection
);

Parameters

lpAddress
Pointer to the base address of the region of pages whose access protection attributes are to be changed.

All pages in the specified region must have been allocated in a single call to the VirtualAlloc or VirtualAllocEx function. The pages cannot span adjacent regions that were allocated by separate calls to VirtualAlloc or VirtualAllocEx.

dwSize
Specifies the size, in bytes, of the region whose access protection attributes are to be changed. The region of affected pages includes all pages containing one or more bytes in the range from the lpAddress parameter to (lpAddress+dwSize). This means that a 2-byte range straddling a page boundary causes the protection attributes of both pages to be changed.
flNewProtect
Specifies the new access protection. You can specify any one of the following flags, along with the PAGE_GUARD and PAGE_NOCACHE protection modifier flags, as necessary:
Value | Meaning
PAGE_READONLY | Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE | Enables both read and write access to the committed region of pages.
PAGE_WRITECOPY | Gives copy-on-write access to the committed region of pages.
PAGE_EXECUTE | Enables execute access to the committed region of pages. An attempt to read or write to the committed region results in an access violation.
PAGE_EXECUTE_READ | Enables execute and read access to the committed region of pages. An attempt to write to the committed region results in an access violation.
PAGE_EXECUTE_READWRITE | Enables execute, read, and write access to the committed region of pages.
PAGE_EXECUTE_WRITECOPY | Enables execute, read, and write access to the committed region of pages. The pages are shared read-on-write and copy-on-write.
PAGE_GUARD Pages in the region become guard pages. Any attempt to access a guard page causes the system to raise a STATUS_GUARD_PAGE exception and turn off the guard page status. Guard pages thus act as a one-shot access alarm.

The PAGE_GUARD flag is a page protection modifier. An application uses it with one of the other page protection flags, with one exception: it cannot be used with PAGE_NOACCESS. When an access attempt leads the system to turn off guard page status, the underlying page protection takes over.

If a guard page exception occurs during a system service, the service typically returns a failure status indicator.
PAGE_NOACCESS | Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_NOCACHE | Allows no caching of the committed regions of pages. The hardware attributes for the physical memory should be specified as "no cache." This is not recommended for general usage. It is useful for device drivers; for example, mapping a video frame buffer with no caching. This flag is a page protection modifier, only valid when used with one of the page protections other than PAGE_NOACCESS.

lpflOldProtect
Pointer to a variable that the function sets to the previous access protection value of the first page in the specified region of pages. If this parameter is NULL or does not point to a valid variable, the function fails.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

You can set the access protection value on committed pages only. If the state of any page in the specified region is not committed, the function fails and returns without modifying the access protection of any pages in the specified region.

The VirtualProtect function changes the access protection of memory in the calling process, and the VirtualProtectEx function changes the access protection of memory in a specified process.

The PAGE_GUARD protection modifier flag establishes guard pages. Guard pages act as one-shot access alarms. For more information, see Creating Guard Pages.

Windows 95: You cannot use VirtualProtect on any memory region located in the shared virtual address space (from 0x80000000 through 0xBFFFFFFF).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, VirtualAlloc, VirtualProtectEx, VirtualProtectVlm


VirtualProtectEx

The VirtualProtectEx function changes the access protection on a region of committed pages in the virtual address space of a specified process. Note that this function differs from VirtualProtect, which changes the access protection on the calling process only.

BOOL VirtualProtectEx(
  HANDLE hProcess,     // handle to process
  LPVOID lpAddress,    // address of region of committed pages
  DWORD dwSize,        // size of region
  DWORD flNewProtect,  // desired access protection
  PDWORD lpflOldProtect
                       // address of variable to get old protection
);

Parameters

hProcess
Handle to the process whose memory protection is to be changed. The handle must have PROCESS_VM_OPERATION access. For more information on PROCESS_VM_OPERATION, see OpenProcess.
lpAddress
Pointer to the base address of the region of pages whose access protection attributes are to be changed.

All pages in the specified region must have been allocated in a single call to the VirtualAlloc or VirtualAllocEx function. The pages cannot span adjacent regions that were allocated by separate calls to VirtualAlloc or VirtualAllocEx.

dwSize
Specifies the size, in bytes, of the region whose access protection attributes are changed. The region of affected pages includes all pages containing one or more bytes in the range from the lpAddress parameter to (lpAddress+dwSize). This means that a 2-byte range straddling a page boundary causes the protection attributes of both pages to be changed.
flNewProtect
Specifies the new access protection. Any one of the following flags can be specified, along with the PAGE_GUARD and PAGE_NOCACHE protection modifier flags, as desired:
Value | Meaning
PAGE_READONLY | Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE | Enables both read and write access to the committed region of pages.
PAGE_WRITECOPY | Gives copy-on-write access to the committed region of pages.
PAGE_EXECUTE | Enables execute access to the committed region of pages. An attempt to read or write to the committed region results in an access violation.
PAGE_EXECUTE_READ | Enables execute and read access to the committed region of pages. An attempt to write to the committed region results in an access violation.
PAGE_EXECUTE_READWRITE | Enables execute, read, and write access to the committed region of pages.
PAGE_EXECUTE_WRITECOPY | Enables execute, read, and write access to the committed region of pages. The pages are shared read-on-write and copy-on-write.
PAGE_GUARD Pages in the region become guard pages. Any attempt to read from or write to a guard page causes the system to raise a STATUS_GUARD_PAGE exception, and turn off the guard page status. Guard pages thus act as a one-shot access alarm.

The PAGE_GUARD flag is a page protection modifier. An application uses it with one of the other page protection flags, with one exception: it cannot be used with PAGE_NOACCESS. When an access attempt leads the system to turn off guard page status, the underlying page protection takes over.

If a guard page exception occurs during a system service, the service typically returns a failure status indicator.
PAGE_NOACCESS | Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_NOCACHE | Allows no caching of the committed regions of pages. The hardware attributes for the physical memory should be set to "no cache." This is not recommended for general usage. It is useful for device drivers; for example, mapping a video frame buffer with no caching. This flag is a page protection modifier, only valid when used with one of the page protections other than PAGE_NOACCESS.

lpflOldProtect
Pointer to a variable that receives the previous access protection of the first page in the specified region of pages. If this parameter is NULL or does not point to a valid variable, the function fails.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The access protection value can be set only on committed pages. If the state of any page in the specified region is not committed, the function fails and returns without modifying the access protection of any pages in the specified region.

VirtualProtectEx is identical to the VirtualProtect function except that it changes the access protection of memory in a specified process.

The PAGE_GUARD protection modifier flag establishes guard pages. Guard pages act as one-shot access alarms. For more information, see Creating Guard Pages.

Windows 95: You cannot use VirtualProtectEx on any memory region located in the shared virtual address space (from 0x80000000 through 0xBFFFFFFF).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, VirtualAlloc, VirtualProtect, VirtualQueryEx, VirtualProtectVlm


VirtualProtectVlm

[This is preliminary documentation and subject to change.]

The VirtualProtectVlm function changes the access type for a region of memory allocated using the VirtualAllocVlm function.

BOOL VirtualProtectVlm(
  HANDLE hProcess,     // process within which to protect memory
  PVOID64 lpAddress,   // address of region of committed pages
  DWORDLONG ullSize,   // size of the region
  DWORD flNewProtect,  // desired access protection
  PDWORD lpflOldProtect
                       // address of variable to get old protection
);

Parameters

hProcess
Handle to the process whose access attributes are to be changed. The calling process must have had the PROCESS_VM_OPERATION flag set on a preceding call to the OpenProcess function, indicating virtual memory access to the target process, or VirtualProtectVlm fails.
lpAddress
Pointer to the base address of the region of pages whose access attributes are to be changed.

Only full 64-bit addresses are supported here — 32-bit sign-extended addresses are not supported. In other words, the 4 GB range surrounding address zero cannot be modified using VirtualProtectVlm.

All pages in the specified region must have been allocated in a single call to the VirtualAllocVlm function. The pages cannot span adjacent regions that were allocated by separate calls to VirtualAllocVlm.

ullSize
Size, in bytes, of the region whose access attributes are to be changed. The region of affected pages includes all pages containing one or more bytes in the range from the value of lpAddress to the value of lpAddress plus the value of the ullSize parameter. This functionality means that changing the attributes of a 2-byte range straddling a page boundary causes the access attributes of both pages to be changed.
flNewProtect
Flag that specifies the new access type. You can specify one of the following flags.
Value | Meaning
PAGE_NOACCESS | Disables all access to the committed region of pages. An attempt to read from, or write to, or execute code in the committed region results in an access violation exception.
PAGE_READONLY | Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the operating system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE | Enables both read and write access to the committed region of pages.

lpflOldProtect
Pointer to a variable that VirtualProtectVlm sets to the previous access value of the first page in the specified region of pages. If the lpflOldProtect parameter is NULL or does not point to a valid variable, VirtualProtectVlm fails.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

You can set an access value for pages that have been committed only. If any page in the specified region is not committed, VirtualProtectVlm fails and returns without modifying the access state of any pages in the specified region.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), OpenProcess, VirtualAllocVlm, VirtualProtect, VirtualProtectEx


VirtualQuery

The VirtualQuery function provides information about a range of pages in the virtual address space of the calling process.

DWORD VirtualQuery(
  LPCVOID lpAddress,                   // address of region
  PMEMORY_BASIC_INFORMATION lpBuffer,  // address of information buffer
  DWORD dwLength                       // size of buffer
);

Parameters

lpAddress
Pointer to the base address of the region of pages to be queried. This value is rounded down to the next page boundary. To determine the size of a page on the host computer, use the GetSystemInfo function.
lpBuffer
Pointer to a MEMORY_BASIC_INFORMATION structure in which information about the specified page range is returned.
dwLength
Specifies the size, in bytes, of the buffer pointed to by the lpBuffer parameter.

Return Values

The return value is the actual number of bytes returned in the information buffer.

Remarks

VirtualQuery provides information about a region of consecutive pages beginning at a specified address that share the following attributes:

  • The state of all pages is the same with the MEM_COMMIT, MEM_RESERVE, MEM_FREE, MEM_PRIVATE, MEM_MAPPED, or MEM_IMAGE flag.
  • If the initial page is not free, all pages in the region are part of the same initial allocation of pages reserved by a call to the VirtualAlloc function.
  • The access of all pages is the same with the PAGE_READONLY, PAGE_READWRITE, PAGE_NOACCESS, PAGE_WRITECOPY, PAGE_EXECUTE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_WRITECOPY, PAGE_GUARD, or PAGE_NOCACHE flag.

The function determines the attributes of the first page in the region and then scans subsequent pages until it scans the entire range of pages or until it encounters a page with a nonmatching set of attributes. The function returns the attributes and the size, in bytes, of the region of pages with matching attributes. For example, if there is a 40 megabyte (MB) region of free memory, and VirtualQuery is called on a page that is 10 MB into the region, the function will obtain a state of MEM_FREE and a size of 30 MB.

This function reports on a region of pages in the memory of the calling process, and the VirtualQueryEx function reports on a region of pages in the memory of a specified process.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetSystemInfo, MEMORY_BASIC_INFORMATION, VirtualQueryEx, VirtualQueryVlm


VirtualQueryEx

The VirtualQueryEx function provides information about a range of pages within the virtual address space of a specified process.

DWORD VirtualQueryEx(
  HANDLE hProcess,    // handle to process
  LPCVOID lpAddress,  // address of region
  PMEMORY_BASIC_INFORMATION lpBuffer,
                      // address of information buffer
  DWORD dwLength      // size of buffer
);

Parameters

hProcess
Handle to the process whose memory information is queried. The handle must have PROCESS_QUERY_INFORMATION access.
lpAddress
Pointer to the base address of the region of pages to be queried. This value is rounded down to the next page boundary. To determine the size of a page on the host computer, use the GetSystemInfo function.
lpBuffer
Pointer to a MEMORY_BASIC_INFORMATION structure in which information about the specified page range is returned.
dwLength
Specifies the size, in bytes, of the buffer pointed to by the lpBuffer parameter.

Return Values

The return value is the actual number of bytes returned in the information buffer.

Remarks

VirtualQueryEx provides information about a region of consecutive pages beginning at a specified address that share the following attributes:

  • The state of all pages is the same with the MEM_COMMIT, MEM_RESERVE, MEM_FREE, MEM_PRIVATE, MEM_MAPPED, or MEM_IMAGE flag.
  • If the initial page is not free, all pages in the region are part of the same initial allocation of pages reserved by a call to the VirtualAlloc function.
  • The access of all pages is the same with the PAGE_READONLY, PAGE_READWRITE, PAGE_NOACCESS, PAGE_WRITECOPY, PAGE_EXECUTE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_WRITECOPY, PAGE_GUARD, or PAGE_NOCACHE flag.

The VirtualQueryEx function determines the attributes of the first page in the region and then scans subsequent pages until it scans the entire range of pages, or until it encounters a page with a nonmatching set of attributes. The function returns the attributes and the size, in bytes, of the region of pages with matching attributes. For example, if there is a 40 megabyte (MB) region of free memory, and VirtualQueryEx is called on a page that is 10 MB into the region, the function will obtain a state of MEM_FREE and a size of 30 MB.

This function is identical to the VirtualQuery function, except that it enables access to information about memory in a specified process.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, GetSystemInfo, MEMORY_BASIC_INFORMATION, VirtualAlloc, VirtualProtectEx, VirtualQuery, VirtualQueryVlm


VirtualQueryVlm

[This is preliminary documentation and subject to change.]

The VirtualQueryVlm function provides information about a range of pages within the virtual address space of a specified process.

DWORD VirtualQueryVlm(
  HANDLE hProcess,    // handle of process
  PVOID64 lpAddress,  // address of region
  PMEMORY_BASIC_INFORMATION_VLM lpBuffer,
                      // address of information buffer
  DWORD dwLength      // size of buffer
);

Parameters

hProcess
Handle to the process whose memory information is to be queried. The handle must have PROCESS_QUERY_INFORMATION access.
lpAddress
Pointer to the base address of the region of pages to be queried. This value is rounded down to the next page boundary. The address specified must be 64 bits and can therefore be used to access memory for any process allocated using the VirtualAllocVlm function. If the address specified is zero, then the system sets the address to the lowest possible VLM address and begins the query from this new address.
lpBuffer
Pointer to a MEMORY_BASIC_INFORMATION_VLM structure in which information about the specified page range is returned.
dwLength
Size, in bytes, of the buffer pointed to by the lpBuffer parameter.

Return Values

If the function succeeds, the return value is the actual number of bytes returned in the buffer in the lpBuffer parameter.

If the function fails, the return value is zero.

Remarks

VirtualQueryVlm provides information about a region of consecutive pages beginning at a specified address that share the following attributes:

  • The state of all pages is the same. In other words, all pages have the MEM_COMMIT, MEM_RESERVE, MEM_FREE, MEM_PRIVATE, MEM_MAPPED, or MEM_IMAGE flag set.
  • If the initial page is not free, all pages in the region are part of the same initial allocation of pages reserved by a call to the VirtualAllocVlm function.
  • The access type of all pages is the same. In other words, all pages have the PAGE_READONLY, PAGE_READWRITE, PAGE_NOACCESS, PAGE_WRITECOPY, PAGE_EXECUTE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_WRITECOPY, PAGE_GUARD, or PAGE_NOCACHE flag set.

VirtualQueryVlm determines the attributes of the first page in the region and then scans subsequent pages. This scan continues until VirtualQueryVlm either scans the entire range of pages or encounters a page with attributes that do not match those of the first page. VirtualQueryVlm returns the attributes and the size, in bytes, of the region of pages with attributes that match those of the first page. For example, if there is a 40-MB region of free memory and VirtualQueryVlm is called for a page that is 10 MB into the region, VirtualQueryVlm retrieves a state of MEM_FREE and a size of 30 MB.

VirtualQueryVlm is identical to the VirtualQueryEx function, except that it provides information about memory allocated using VirtualAllocVlm.

VirtualQueryVlm sets all members in the lpBuffer MEMORY_BASIC_INFORMATION_VLM structure in all cases because certain members in the structure depend on the values of other members. For example, the Type member is not filled for a MEM_FREE region, and the Protect member is not filled if region queried is not committed to memory. All members are filled with useful information wherever possible.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), GetSystemInfo, MEMORY_BASIC_INFORMATION_VLM, VirtualAllocVlm, VirtualQueryEx, VirtualQuery


VirtualUnlock

The VirtualUnlock function unlocks a specified range of pages in the virtual address space of a process, enabling the system to swap the pages out to the paging file if necessary.

BOOL VirtualUnlock(
  LPVOID lpAddress,  // address of first byte of range
  DWORD dwSize       // number of bytes in range
);

Parameters

lpAddress
Pointer to the base address of the region of pages to be unlocked.
dwSize
Specifies the size, in bytes, of the region being unlocked. The region of affected pages includes all pages containing one or more bytes in the range from the lpAddress parameter to (lpAddress+dwSize). This means that a 2-byte range straddling a page boundary causes both pages to be unlocked.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

For the function to succeed, the range specified need not match a range passed to a previous call to the VirtualLock function, but all pages in the range must be locked.

Windows NT: Calling VirtualUnlock on a range of memory that is not locked releases the pages from the process's working set.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, VirtualLock


WriteFileVlm

[This is preliminary documentation and subject to change.]

The WriteFileVlm function writes data to a file. WriteFileVlm is designed solely for asynchronous operation.

BOOL WriteFileVlm(
  HANDLE hFile,                 // handle to output file
  PVOID64 lpBuffer,             // pointer to input buffer
  DWORD nNumberOfBytesToWrite,  // number of bytes to write
  LPDWORD lpReserved,           // reserved, must be NULL
  LPOVERLAPPED lpOverlapped     // pointer to async. i/o data
);

Parameters

hFile
Open handle that specifies the file to write to. The file handle must have been created (using the CreateFile function) with GENERIC_WRITE access to the file. To specify asynchronous I/O, this file handle must have been created with the FILE_FLAG_OVERLAPPED flag. To specify noncached I/O, this file handle must have been created with the FILE_FLAG_NO_BUFFERING flag.
lpBuffer
Pointer to the buffer containing the data to be written to the file. The address specified can be used to access memory in processes allocated using the VirtualAllocVlm function. Therefore, the address specified must be a 64-bit address or a sign-extended 32-bit address.

The buffer pointed to by the lpBuffer parameter must remain valid for the duration of the write operation. The calling process must not use this buffer until the write operation is completed.

nNumberOfBytesToWrite
Number of bytes to write to the file. If the nNumberOfBtyesToWrite parameter is zero, WriteFileVlm changes the time stamp of the file and does not truncate or otherwise modify the data in the file.
lpReserved
Reserved; must be NULL.
lpOverlapped
Pointer to an OVERLAPPED structure. The lpOverlapped parameter is required and must point to a valid OVERLAPPED structure. The write operation starts at the offset specified in the OVERLAPPED structure, and WriteFileVlm may return before the write operation has been completed. In this case, WriteFileVlm returns FALSE and the GetLastError function returns ERROR_IO_PENDING. This functionality allows the calling process to continue processing while the write operation is being completed. An application can use either the GetOverlappedResult or HasOverlappedIoCompleted function to retrieve I/O completion notification. An application can use the GetQueuedCompletionStatus function to retrieve I/O completion.

For files that support byte offsets, you must specify a byte offset at which to start writing to the file. You specify this offset by setting the Offset and OffsetHigh members of the OVERLAPPED structure. For files that do not support byte offsets, Offset and OffsetHigh are ignored.

WriteFileVlm uses the Internal and InternalHigh members of the OVERLAPPED structure. A process should not change the value of these members.

The OVERLAPPED data structure must remain valid for the duration of the write operation. The structure should not be a variable that can go out of scope while the write operation is pending completion.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If part of the output file is locked by another process and the specified operation writes to the locked portion, WriteFileVlm fails.

Accessing the output buffer while a write operation is using the buffer may lead to corruption of the data written from that buffer. Applications must not read from, write to, reallocate, or free the output buffer that a write operation is using until the write operation completes.

WriteFileVlm can fail returning the messages ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY if there are too many outstanding asynchronous I/O requests.

To cancel all pending asynchronous I/O operations, use the CancelIo function. CancelIo only cancels operations issued by the calling thread for the specified file handle. I/O operations that are canceled complete with the error code ERROR_OPERATION_ABORTED.

If your application attempts to write to a floppy drive that does not have a floppy disk, the operating system displays a message prompting the user to retry the operation. To prevent the system from displaying this message, call the SetErrorMode function with the SEM_NOOPENFILEERRORBOX flag set for the uMode parameter.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory-mapped view. For more information on structured exception handling, see Reading and Writing.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), CancelIo, CreateFile, FileIOCompletionRoutine, GetOverlappedResult, GetQueuedCompletionStatus, HasOverlappedIoCompleted, MsgWaitForMultipleObjectsEx, OVERLAPPED, ReadFileVlm, SetEndOfFile, SetErrorMode, SleepEx, SignalObjectAndWait, WaitForMultipleObjectsEx, WaitForSingleObjectEx, WriteFileEx


WriteProcessMemoryVlm

[This is preliminary documentation and subject to change.]

The WriteProcessMemoryVlm function writes memory in a specified process. The entire area to be written to must be accessible, or the operation fails.

BOOL WriteProcessMemoryVlm(
  HANDLE hProcess,  // handle to process whose memory is written to
  PVOID64 lpBaseAddress,
                    // address to start writing to
  PVOID64 lpBuffer,  // pointer to buffer to write data to
  DWORD nSize,      // number of bytes to write
  LPDWORD lpNumberOfBytesWritten
                    // actual number of bytes written
);

Parameters

hProcess
Handle to the process whose memory is to be modified. The handle must have PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process. For more information on PROCESS_VM_OPERATION, see OpenProcess.
lpBaseAddress
Pointer to the base address in the specified process to be written to. Before any data transfer occurs, the system verifies that all memory at the indicated base address for the specified size is accessible for write access. If the memory is not accessible for writing, no writing is done and WriteProcessMemoryVlm fails.

The address specified is 64 bits and can therefore be used to access memory in the process allocated using VirtualAllocVlm, or the address can be a sign-extended 32-bit address.

lpBuffer
Pointer to the buffer in the memory of the calling process that supplies data to be written to the address space of the specified process.
nSize
Number of bytes to write to the specified process.
lpNumberOfBytesWritten
Pointer to the actual number of bytes transferred into the specified process. The lpNumberOfBytesWritten parameter is optional. If lpNumberOfBytesWritten is NULL, it is ignored.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The function fails if the requested write operation crosses into an area of the process that is inaccessible.

Remarks

WriteProcessMemoryVlm copies the data from the specified buffer in the current process to the address range of the specified process. Any process that has a handle with PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process to be written to can call WriteProcessMemoryVlm. The process whose address space is being written to is typically, but not necessarily, being debugged.

Before any data transfer occurs, the system verifies that all memory at the given base address for the specified size is accessible for write access. If the memory is not accessible for writing, no writing is done and WriteProcessMemoryVlm fails.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory-mapped view. For more information on structured exception handling, see Reading and Writing.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), OpenProcess, ReadProcessMemoryVlm, VirtualAllocVlm


ZeroMemory

The ZeroMemory function fills a block of memory with zeros.

VOID ZeroMemory(
  PVOID Destination,
                 // address of block to fill with zeros
  DWORD Length   // size, in bytes, of block to fill with zeros
);

Parameters

Destination
Pointer to the starting address of the block of memory to fill with zeros.
Length
Specifies the size, in bytes, of the block of memory to fill with zeros.

Return Values

This function has no return value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Memory Management Overview, Memory Management Functions, CopyMemory, CopyMemoryVlm, FillMemory, FillMemoryVlm, MoveMemory, MoveMemoryVlm, ZeroMemoryVlm


ZeroMemoryVlm

[This is preliminary documentation and subject to change.]

The ZeroMemoryVlm function fills a block of memory with zeros. The memory is specified using 64-bit pointers.

VOID ZeroMemoryVlm(
  PVOID64 Destination,
                 // address of block to fill with zeros
  DWORD Length   // size, in bytes, of block to fill with zeros
);

Parameters

Destination
Pointer to the starting address of the block of memory to fill with zeros.
Length
Size, in bytes, of the block of memory to fill with zeros.

Return Values

This function has no return value.

Remarks

To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory-mapped view. For more information on structured exception handling, see Reading and Writing.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Memory Management Overview, Memory Management Functions, Very Large Memory (VLM), CopyMemoryVlm, FillMemoryVlm, MoveMemoryVlm, ZeroMemory


Memory Management Structures

The following structures are used with memory management.

MEMORY_BASIC_INFORMATION
MEMORY_BASIC_INFORMATION_VLM
MEMORYSTATUS
MEMORYSTATUSVLM
PROCESS_HEAP_ENTRY


MEMORY_BASIC_INFORMATION

The MEMORY_BASIC_INFORMATION structure contains information about a range of pages in the virtual address space of a process. The VirtualQuery and VirtualQueryEx functions use this structure.

typedef struct _MEMORY_BASIC_INFORMATION { // mbi
    PVOID BaseAddress;            // base address of region
    PVOID AllocationBase;         // allocation base address
    DWORD AllocationProtect;      // initial access protection
    DWORD RegionSize;             // size, in bytes, of region
    DWORD State;                  // committed, reserved, free
    DWORD Protect;                // current access protection
    DWORD Type;                   // type of pages
} MEMORY_BASIC_INFORMATION;
typedef MEMORY_BASIC_INFORMATION *PMEMORY_BASIC_INFORMATION;

Members

BaseAddress
Pointer to the base address of the region of pages.
AllocationBase
Pointer to the base address of a range of pages allocated by the VirtualAlloc function. The page pointed to by the BaseAddress member is contained within this allocation range.
AllocationProtect
Specifies the access protection given when the region was initially allocated. One of the following flags can be present, along with the PAGE_GUARD and PAGE_NOCACHE protection modifier flags:
Flag | Meaning
PAGE_READONLY | Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE | Enables both read and write access to the committed region of pages.
PAGE_WRITECOPY | Gives copy-on-write access to the committed region of pages.
PAGE_EXECUTE | Enables execute access to the committed region of pages. An attempt to read or write to the committed region results in an access violation.
PAGE_EXECUTE_READ | Enables execute and read access to the committed region of pages. An attempt to write to the committed region results in an access violation.
PAGE_EXECUTE_READWRITE | Enables execute, read, and write access to the committed region of pages.
PAGE_EXECUTE_WRITECOPY | Enables execute, read, and write access to the committed region of pages. The pages are shared read-on-write and copy-on-write.
PAGE_GUARD | Protects the page with the underlying page protection. However, access to the region causes a "guard page entered" condition to be raised in the subject process. This flag is a page protection modifier, only valid when used with one of the page protections other than PAGE_NOACCESS.
PAGE_NOACCESS | Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception, called a general protection (GP) fault.
PAGE_NOCACHE | Allows no caching of the committed regions of pages. The hardware attributes for the physical memory should be set to no cache. This is not recommended for general usage. It is useful for device drivers; for example, mapping a video frame buffer with no caching. This flag is a page protection modifier, only valid when used with one of the page protections other than PAGE_NOACCESS.

RegionSize
Specifies the size, in bytes, of the region beginning at the base address in which all pages have identical attributes.
State
Specifies the state of the pages in the region. One of the following states is indicated:
State | Meaning
MEM_COMMIT | Indicates committed pages for which physical storage has been allocated, either in memory or in the paging file on disk.
MEM_FREE | Indicates free pages not accessible to the calling process and available to be allocated. For free pages, the information in the AllocationBase, AllocationProtect, Protect, and Type members is undefined.
MEM_RESERVE | Indicates reserved pages where a range of the process's virtual address space is reserved without allocating any physical storage. For reserved pages, the information in the Protect member is undefined.

Protect
Specifies the access protection of the pages in the region. One of the flags listed for the AllocationProtect member is specified.
Type
Specifies the type of pages in the region. The following types are defined:
Type | Meaning
MEM_IMAGE | Indicates that the memory pages within the region are mapped into the view of an image section.
MEM_MAPPED | Indicates that the memory pages within the region are mapped into the view of a section.
MEM_PRIVATE | Indicates that the memory pages within the region are private (not shared by other processes).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnt.h.

See Also

Memory Management Overview, Memory Management Structures, VirtualAlloc, VirtualQuery, VirtualQueryEx


MEMORY_BASIC_INFORMATION_VLM

[This is preliminary documentation and subject to change.]

The MEMORY_BASIC_INFORMATION_VLM structure contains information about a range of pages in the virtual address space of a process. The VirtualQueryVlm function uses this structure.

typedef struct _MEMORY_BASIC_INFORMATION_VLM {
    union {
        PVOID64 BaseAddress;
        ULONGLONG BaseAddressAsUlongLong;
    };
    union {
        PVOID64 AllocationBase;
        ULONGLONG AllocationBaseAsUlongLong;
    };
    ULONGLONG RegionSize;
    DWORD AllocationProtect;
    DWORD State;
    DWORD Protect;
    DWORD Type;
} MEMORY_BASIC_INFORMATION_VLM, *PMEMORY_BASIC_INFORMATION_VLM;

Members

BaseAddress
Pointer to the base address of the region of pages.
AllocationBase
Pointer to the base address of a range of pages allocated by the VirtualAllocVlm function. The page pointed to by the BaseAddress member is contained within this allocation range.
RegionSize
Size, in bytes, of the region beginning at the base address in which all pages have identical attributes.
AllocationProtect
Access specified when the region was initially allocated. One of the following flags can be present, along with the PAGE_GUARD and PAGE_NOCACHE protection modifier flags.
Value | Meaning
PAGE_EXECUTE | Enables execute access to the committed region of pages. An attempt to read or write to the committed region results in an access violation.
PAGE_EXECUTE_READ | Enables execute and read access to the committed region of pages. An attempt to write to the committed region results in an access violation.
PAGE_EXECUTE_READWRITE | Enables execute, read, and write access to the committed region of pages.
PAGE_EXECUTE_WRITECOPY | Enables execute, read, and write access to the committed region of pages. The pages are shared read-on-write and copy-on-write.
PAGE_GUARD | Protects the page with the underlying page protection. However, access to the region causes a "guard page entered" condition to be raised in the subject process. This flag is a page protection modifier, only valid when used with one of the access values other than PAGE_NOACCESS.
PAGE_NOACCESS | Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region results in an access violation exception.
PAGE_NOCACHE | Allows no caching of the committed regions of pages. The hardware attributes for the physical memory should be set to no cache. This flag is not recommended for general usage. However, this flag is useful for device drivers, for example when mapping a video frame buffer with no caching. This flag is a page protection modifier, only valid when used with one of the access values other than PAGE_NOACCESS.
PAGE_READONLY | Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the operating system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation.
PAGE_READWRITE | Enables both read and write access to the committed region of pages.
PAGE_WRITECOPY | Gives copy-on-write access to the committed region of pages.

State
State of the pages in the region. You can indicate one of the following states.
Value | Meaning
MEM_COMMIT | Indicates committed pages for which physical storage has been allocated, either in memory or in the paging file on disk.
MEM_FREE | Indicates free pages not accessible to the calling process and available to be allocated. For free pages, the information in the AllocationBase, AllocationProtect, Protect, and Type members is undefined.
MEM_RESERVE | Indicates reserved pages where a range of the process's virtual address space is reserved without allocating any physical storage. For reserved pages, the information in the Protect member is undefined.

Protect
Access protection of the pages in the region. One of the flags listed for the AllocationProtect member is specified.
Type
Type of pages in the region. The following types are defined:
Value | Meaning
MEM_IMAGE | Indicates that the memory pages within the region are mapped into the view of an image section.
MEM_MAPPED | Indicates that the memory pages within the region are mapped into the view of a section.
MEM_PRIVATE | Indicates that the memory pages within the region are private (not shared by other processes).

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Memory Management Overview, Memory Management Structures, Very Large Memory (VLM), MEMORY_BASIC_INFORMATION, VirtualAllocVlm, VirtualQueryVlm


MEMORYSTATUS

The MEMORYSTATUS structure contains information about the current state of both physical and virtual memory. The GlobalMemoryStatus function stores information into a MEMORYSTATUS structure.

typedef struct _MEMORYSTATUS { // mst
    DWORD dwLength;        // sizeof(MEMORYSTATUS)
    DWORD dwMemoryLoad;    // percent of memory in use
    DWORD dwTotalPhys;     // bytes of physical memory
    DWORD dwAvailPhys;     // free physical memory bytes
    DWORD dwTotalPageFile; // bytes of paging file
    DWORD dwAvailPageFile; // free bytes of paging file
    DWORD dwTotalVirtual;  // user bytes of address space
    DWORD dwAvailVirtual;  // free user bytes
} MEMORYSTATUS, *LPMEMORYSTATUS;

Members

dwLength
The size in bytes of the MEMORYSTATUS data structure. You do not need to set this member before calling the GlobalMemoryStatus function; the function sets it.
dwMemoryLoad
Specifies a number between 0 and 100 that gives a general idea of current memory utilization, in which 0 indicates no memory use and 100 indicates full memory use.
dwTotalPhys
Indicates the total number of bytes of physical memory.
dwAvailPhys
Indicates the number of bytes of physical memory available.
dwTotalPageFile
Indicates the total number of bytes that can be stored in the paging file. Note that this number does not represent the actual physical size of the paging file on disk.
dwAvailPageFile
Indicates the number of bytes available in the paging file.
dwTotalVirtual
Indicates the total number of bytes that can be described in the user mode portion of the virtual address space of the calling process.
dwAvailVirtual
Indicates the number of bytes of unreserved and uncommitted memory in the user mode portion of the virtual address space of the calling process.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.

See Also

Memory Management Overview, Memory Management Structures, GlobalMemoryStatus


MEMORYSTATUSVLM

[This is preliminary documentation and subject to change.]

The MEMORYSTATUSVLM structure contains information about the current state of both physical and virtual memory. The GlobalMemoryStatusVlm function stores information in a MEMORYSTATUSVLM structure.

typedef struct _MEMORYSTATUSVLM {
    DWORD dwLength;             // sizeof(MEMORYSTATUSVLM)
    DWORD dwMemoryLoad;         // percent of memory in use
    DWORDLONG ullTotalPhys;     // bytes of physical memory
    DWORDLONG ullAvailPhys;     // free physical memory bytes
    DWORDLONG ullTotalPageFile; // bytes of paging file
    DWORDLONG ullAvailPageFile; // free bytes of paging file
    DWORDLONG ullTotalVirtual;  // user bytes of address space
    DWORDLONG ullAvailVirtual;  // free user bytes
    DWORDLONG ullAvailExtendedVirtual;
} MEMORYSTATUSVLM, *LPMEMORYSTATUSVLM;

Members

dwLength
Size, in bytes, of the MEMORYSTATUSVLM data structure. You do not need to set this member before calling the GlobalMemoryStatusVlm function; GlobalMemoryStatusVlm sets it.
dwMemoryLoad
Number between 0 and 100 that gives a general idea of current memory utilization, in which 0 indicates no memory use and 100 indicates full memory use.
ullTotalPhys
Total number of bytes of physical memory.
ullAvailPhys
Number of bytes of physical memory available.
ullTotalPageFile
Total number of bytes that can be stored in the paging file. Note that this number does not represent the actual physical size of the paging file on disk.
ullAvailPageFile
Number of bytes available in the paging file.
ullTotalVirtual
Total number of bytes that can be described in the user mode portion of the virtual address space of the calling process.
ullAvailVirtual
Number of bytes of unreserved and uncommitted memory in the user mode portion of the virtual address space of the calling process.
ullAvailExtendedVirtual
Number of bytes of unreserved and uncommitted memory in the VLM portion of the virtual address space of the calling process. The total memory available in VLM space is 28 GB.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Memory Management Overview, Memory Management Structures, Very Large Memory (VLM), MEMORYSTATUS, GlobalMemoryStatus, GlobalMemoryStatusVlm


PROCESS_HEAP_ENTRY

The PROCESS_HEAP_ENTRY structure contains information about a heap element. The HeapWalk function uses a PROCESS_HEAP_ENTRY structure to enumerate the elements of a heap.

typedef struct _PROCESS_HEAP_ENTRY {
    PVOID lpData;
    DWORD cbData;
    BYTE cbOverhead;
    BYTE iRegionIndex;
    WORD wFlags;
    union {
        struct {
            HANDLE hMem;
            DWORD dwReserved[ 3 ];
        } Block;
        struct {
            DWORD dwCommittedSize;
            DWORD dwUnCommittedSize;
            LPVOID lpFirstBlock;
            LPVOID lpLastBlock;
        } Region;
    };
} PROCESS_HEAP_ENTRY;

Members

lpData
Pointer to the data portion of the heap element.

To initiate a HeapWalk heap enumeration, set lpData to NULL.

If the PROCESS_HEAP_REGION bit flag is set in the wFlags member, lpData points to the first virtual address used by the region.

If the PROCESS_HEAP_UNCOMMITTED_RANGE bit flag is set in wFlags, lpData points to the beginning of the range of uncommitted memory.

cbData
Specifies the size, in bytes, of the data portion of the heap element.

If the PROCESS_HEAP_REGION bit flag is set in wFlags, cbData specifies the total size, in bytes, of the address space that is reserved for this region.

If the PROCESS_HEAP_UNCOMMITTED_RANGE bit flag is set in wFlags, cbData specifies the size, in bytes, of the range of uncommitted memory.

cbOverhead
Specifies the size, in bytes, of the data used by the system to maintain information about the heap element. These overhead bytes are in addition to the cbData bytes of the data portion of the heap element.

If the PROCESS_HEAP_REGION bit flag is set in wFlags, cbOverhead specifies the size, in bytes, of the heap control structures that describe the region.

If the PROCESS_HEAP_UNCOMMITTED_RANGE bit flag is set in wFlags, cbOverhead specifies the size, in bytes, of the control structures that describe this uncommitted range.

iRegionIndex
Handle to the heap region that contains the heap element. A heap consists of one or more regions of virtual memory, each with a unique region index.

In the first heap entry returned for most heap regions, HeapWalk sets the PROCESS_HEAP_REGION flag in the wFlags member. When this flag is set, the members of the Region structure contain additional information about the region.

The HeapAlloc function sometimes uses the VirtualAlloc function to allocate large blocks from a growable heap. The heap manager treats such a large block allocation as a separate region with a unique region index. HeapWalk does not set the PROCESS_HEAP_REGION flag in the heap entry returned for a large block region, so the members of the Region structure are not valid. You can use the VirtualQuery function to get additional information about a large block region.

wFlags
A set of bit flags that specify properties of the heap element. Some of these flags affect the meaning of other members of this PROCESS_HEAP_ENTRY data structure. The following bit-flag constants are defined:
Value Meaning
PROCESS_HEAP_REGION If this flag is set, the heap element is located at the beginning of a region of contiguous virtual memory in use by the heap.

If this flag is set, the lpData member of the structure points to the first virtual address used by the region; the cbData member specifies the total size, in bytes, of the address space that is reserved for this region; and the cbOverhead member specifies the size, in bytes, of the heap control structures that describe the region.

If this flag is set, the Region structure becomes valid. The dwCommittedSize, dwUnCommittedSize, lpFirstBlock, and lpLastBlock members of the structure contain additional information about the region.
PROCESS_HEAP_UNCOMMITTED_RANGE If this flag is set, the heap element is located in a range of uncommitted memory within the heap region.

If this flag is set, the lpData member points to the beginning of the range of uncommitted memory; the cbData member specifies the size, in bytes, of the range of uncommitted memory; and the cbOverhead member specifies the size, in bytes, of the control structures that describe this uncommitted range.
PROCESS_HEAP_ENTRY_BUSY If this flag is set, the heap element is an allocated block.

If both this flag and the PROCESS_HEAP_ENTRY_MOVEABLE flag are set, the Block structure becomes valid. The hMem member of the Block structure contains a handle to the allocated, moveable memory block.

PROCESS_HEAP_ENTRY_MOVEABLE This flag is only valid if the PROCESS_HEAP_ENTRY_BUSY flag is set, indicating that the heap element is an allocated block.

If this flag is valid and set, the block was allocated with the LMEM_MOVEABLE or GMEM_MOVEABLE flag, and the Block structure becomes valid. The hMem member of the Block structure contains a handle to the allocated, moveable memory block.

PROCESS_HEAP_ENTRY_DDESHARE This flag is only valid if the PROCESS_HEAP_ENTRY_BUSY flag is set, indicating that the heap element is an allocated block.

If this flag is valid and set, the block was allocated with the GMEM_DDESHARE flag. For a discussion of the GMEM_DDESHARE flag, see GlobalAlloc.

Block
This structure is valid only if both the PROCESS_HEAP_ENTRY_BUSY and PROCESS_HEAP_ENTRY_MOVEABLE flags in wFlags are set.

The members of the Block structure are as follows:
Member | Description
hMem | Contains a handle to the allocated, moveable memory block.
dwReserved | Reserved; not used.

Region
This structure is valid only if the PROCESS_HEAP_REGION flag is set in the wFlags member.

The members of the Region structure are as follows:
Member | Description
dwCommittedSize Specifies the number of bytes in the heap region that are currently committed as free memory blocks, busy memory blocks, or heap control structures.

This is an optional field that is set to zero if the number of committed bytes is not available.
dwUnCommittedSize Specifies the number of bytes in the heap region that are currently uncommitted.

This is an optional field that is set to zero if the number of uncommitted bytes is not available.

lpFirstBlock | Pointer to the first valid memory block in this heap region.
lpLastBlock | Pointer to the first invalid memory block in thisheap region.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Memory Management Overview, Memory Management Structures, GlobalAlloc, HeapAlloc, HeapWalk, VirtualAlloc, VirtualQuery


Registry

The registry is a system-defined database that applications and system components use to store and retrieve configuration data.


About the Registry

The registry stores data in binary files. To manipulate registry data, an application must use the registry functions. This overview describes the registry and the functions that applications use to access and manipulate the data stored there. The data stored in the registry varies according to the platform that is used. This overview contains a description of registry entries that can exist on any platform.


Structure of the Registry

The registry stores data in a hierarchically structured tree. Each node in the tree is called a key. Each key can contain both subkeys and data entries called values. Sometimes, the presence of a key is all the data that an application requires; other times, an application opens a key and uses the values associated with the key. A key can have any number of values, and the values can be in any form.

Each key has a name consisting of one or more printable ANSI characters — that is, characters ranging from values 32 through 127. Key names cannot include a space, a backslash (\), or a wildcard character (* or ?). Key names beginning with a period (.) are reserved. The name of each subkey is unique with respect to the key that is immediately above it in the hierarchy. Key names are not localized into other languages, although values may be.


Registry Storage Space

Although there are few technical limits to the type and size of data an application can store in the registry, certain practical guidelines exist to promote system efficiency. An application should store configuration and initialization data in the registry, but other kinds of data should be stored elsewhere.

Generally, data consisting of more than one or two kilobytes (K) should be stored as a file and referred to by using a key in the registry rather than being stored as a value. Instead of duplicating large pieces of data in the registry, an application should save the data as a file and refer to the file. Executable binary code should never be stored in the registry.

A value entry uses much less registry space than a key. To save space, an application should group similar data together as a structure and store the structure as a value rather than storing each of the structure members as a separate key. (Storing the data in binary form allows an application to store data in one value that would otherwise be made up of several incompatible types.)


Predefined Keys

An application must open a key before it can add data to the registry. To open a key, an application must supply a handle to another key in the registry that is already open. The system defines standard handles that are always open. An application can use these predefined handles as entry points to the registry.

The system provides two predefined keys at the root of the registry: HKEY_LOCAL_MACHINE and HKEY_USERS. In addition, the system defines HKEY_CLASSES_ROOT (a subkey of HKEY_LOCAL_MACHINE) and HKEY_CURRENT_USER (a subkey of HKEY_USERS). These registry handles are valid for all Win32 implementations of the registry, although the use of the handles may vary from platform to platform. In addition, other predefined handles have been defined for specific platforms.

Predefined keys help an application navigate in the registry and make it possible to develop tools that allow a system administrator to manipulate categories of data. Applications that add data to the registry should always work within the framework of predefined keys, so administrative tools can find and use the new data.

The following predefined keys are used as entry points to the registry.

Entry point | Use
HKEY_CLASSES_ROOT | Registry entries subordinate to this key define types (or classes) of documents and the properties associated with those types. Data stored under this key is used by shell applications and by object linking and embedding (OLE) applications.
HKEY_CURRENT_USER | Registry entries subordinate to this key define the preferences of the current user. These preferences include the settings of environment variables, data about program groups, colors, printers, network connections, and application preferences.
HKEY_DYN_DATA | Windows 95 and Windows 98: Registry entries subordinate to this key allow you to collect performance data.
HKEY_LOCAL_MACHINE | Registry entries subordinate to this key define the physical state of the computer, including data about the bus type, system memory, and installed hardware and software.
HKEY_PERFORMANCE_DATA | Windows NT: Registry entries subordinate to this key allow you to access performance data. The data is not actually stored in the registry; the registry functions cause the system to collect the data from its source.
HKEY_USERS | Registry entries subordinate to this key define the default user configuration for new users on the local computer and the user configuration for the current user.

The use of HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, and HKEY_USERS varies depending on the implementation of the registry.


Categories of Data

Before putting data into the registry, an application should divide the data into two categories: computer-specific data and user-specific data. By making this distinction, an application can support multiple users, and yet locate user-specific data over a network and use that data in different locations, allowing location-independent user profile data. (A user profile is a set of configuration data saved for every user.)

When the application is installed, it should record the computer-specific data under the HKEY_LOCAL_MACHINE key. In particular, it should create keys for the company name, product name, and version number, as shown in the following example:

HKEY_LOCAL_MACHINE\Software\MyCompany\MyProduct\1.0

If the application supports OLE, it should record that data under HKEY_LOCAL_MACHINE\Software\Classes.

An application should record user-specific data under the HKEY_CURRENT_USER key, as shown in the following example:

HKEY_CURRENT_USER\Software\MyCompany\MyProduct\1.0\...


Opening, Creating, and Closing Keys

Before an application can add data to the registry, it must create or open a key. To create or open a key, an application always refers to the key as a subkey of a currently open key. The following predefined keys are always open: HKEY_LOCAL_MACHINE, HKEY_CLASSES_ROOT, HKEY_USERS, and HKEY_CURRENT_USER. An application uses the RegOpenKey or RegOpenKeyEx function to open a key and the RegCreateKey or RegCreateKeyEx function to create a key.

An application can use the RegCloseKey function to close a key and write the data it contains into the registry. RegCloseKey does not necessarily write the data to the registry before returning; it can take as much as several seconds for the cache to be flushed to the hard disk. If an application must explicitly write registry data to the hard disk, it can use the RegFlushKey function. RegFlushKey, however, uses many system resources and should be called only when absolutely necessary.


Writing and Deleting Registry Data

An application can use either the RegSetValue or RegSetValueEx function to associate a value and its data with a key. RegSetValue works only with strings (values having the REG_SZ type). RegSetValueEx, however, can write values with any type of data. Either of these functions can create a key and its value at the same time.

To delete a value from a key, an application can use the RegDeleteValue function. To delete a key, it can use the RegDeleteKey function. A deleted key is not removed until the last handle to it has been closed. Subkeys and values cannot be created under a deleted key.

To change a key's security information, an application can use the RegSetKeySecurity function.


Retrieving Data from the Registry

To retrieve data from the registry, an application typically enumerates the subkeys of a key until it finds a particular one and then retrieves data from the value or values associated with it. An application can call either the RegEnumKey or RegEnumKeyEx function to enumerate the subkeys of a given key. RegEnumKeyEx returns a subkey and its class, but RegEnumKey returns only the subkey, not the class.

To retrieve detailed data about a particular subkey, an application can call the RegQueryInfoKey function. The RegGetKeySecurity function retrieves a copy of the security descriptor protecting a key.

An application can use the RegEnumValue function to enumerate the values for a given key, and the RegQueryValue or RegQueryValueEx function to retrieve a particular value for a key. An application typically calls RegEnumValue to determine the value names and then RegQueryValueEx to retrieve the data for the names.

RegQueryValue and RegQueryValueEx differ in how they treat unexpanded references to environment variables. If an unnamed value contains an unexpanded environment variable (for example, %PATH%), RegQueryValue expands the variable into the storage buffer provided as one of its parameters. RegQueryValueEx, however, does not expand these references. (Applications can also use the ExpandEnvironmentStrings function to expand environment variables.)


Registry Files

Applications can save part of the registry in a file and then load the contents of the file back into the registry. A registry file is useful when a large amount of data is being manipulated, when many entries are being made in the registry, or when the data is transitory and must be loaded and then unloaded again. Applications that back up and restore parts of the registry are likely to use registry files.

To save a key and its subkeys and values to a registry file, an application can call the RegSaveKey function. To write the registry file back to the registry, an application can use the RegLoadKey, RegReplaceKey, or RegRestoreKey function.

RegLoadKey loads registry data from a specified file into a specified subkey under HKEY_USERS or HKEY_LOCAL_MACHINE on the calling application's computer or on a remote computer. The function creates the specified subkey if it does not already exist. After calling this function, an application can use the RegUnLoadKey function to restore the registry to its previous state.

RegReplaceKey replaces a key and all its subkeys and values in the registry with the data contained in a specified file. The new data takes effect the next time the system is started.

RegRestoreKey loads registry data from a specified file into a specified key on the calling application's computer or on a remote computer. This function replaces the subkeys and values below the specified key with the subkeys and values that follow the top-level key in the file.


Using the Registry

The following example demonstrates the use of the RegQueryInfoKey, RegEnumKey, and RegEnumValue functions. The hKey parameter passed to each function is a handle to an open key. This key must be opened before the function call and closed afterward.

// QueryKey - enumerates the subkeys of a given key and the associated
//    values and then copies the information about the keys and values
//    into a pair of edit controls and list boxes.
// hDlg - dialog box that contains the edit controls and list boxes
// hKey - key whose subkeys and values are to be enumerated

VOID QueryKey(HWND hDlg, HANDLE hKey)
{
    CHAR     achKey[MAX_PATH];
    CHAR     achClass[MAX_PATH] = "";  // buffer for class name
    DWORD    cchClassName = MAX_PATH;  // length of class string
    DWORD    cSubKeys;                 // number of subkeys
    DWORD    cbMaxSubKey;              // longest subkey size
    DWORD    cchMaxClass;              // longest class string
    DWORD    cValues;              // number of values for key
    DWORD    cchMaxValue;          // longest value name
    DWORD    cbMaxValueData;       // longest value data
    DWORD    cbSecurityDescriptor; // size of security descriptor
    FILETIME ftLastWriteTime;      // last write time

    DWORD i, j;
    DWORD retCode, retValue;

    CHAR  achValue[MAX_VALUE_NAME];
    DWORD cchValue = MAX_VALUE_NAME;
    CHAR  achBuff[80];

    // Get the class name and the value count.
    RegQueryInfoKey(hKey,        // key handle
        achClass,                // buffer for class name
        &cchClassName,           // length of class string
        NULL,                    // reserved
        &cSubKeys,               // number of subkeys
        &cbMaxSubKey,            // longest subkey size
        &cchMaxClass,            // longest class string
        &cValues,                // number of values for this key
        &cchMaxValue,            // longest value name
        &cbMaxValueData,         // longest value data
        &cbSecurityDescriptor,   // security descriptor
        &ftLastWriteTime);       // last write time

    SetDlgItemText(hDlg, IDE_CLASS, achClass);
    SetDlgItemInt(hDlg, IDE_CVALUES, cValues, FALSE);

    SendMessage(GetDlgItem(hDlg, IDL_LISTBOX),
        LB_ADDSTRING, 0, (LONG) "..");

    // Enumerate the child keys, looping until RegEnumKey fails. Then
    // get the name of each child key and copy it into the list box.

    SetCursor(LoadCursor(NULL, IDC_WAIT));
    for (i = 0, retCode = ERROR_SUCCESS;
            retCode == ERROR_SUCCESS; i++)
    {
        retCode = RegEnumKey(hKey, i, achKey, MAX_PATH);
        if (retCode == (DWORD)ERROR_SUCCESS)
        {
            SendMessage(GetDlgItem(hDlg, IDL_LISTBOX),
                LB_ADDSTRING, 0, (LONG) achKey);
        }
    }
    SetCursor(LoadCursor (NULL, IDC_ARROW));

    // Enumerate the key values.
    SetCursor(LoadCursor(NULL, IDC_WAIT));

    if (cValues)
    {
        for (j = 0, retValue = ERROR_SUCCESS;
                j < cValues; j++)
        {
            cchValue = MAX_VALUE_NAME;
            achValue[0] = '\0';
            retValue = RegEnumValue(hKey, j, achValue,
                &cchValue,
                NULL,
                NULL,    // &dwType,
                NULL,    // &bData,
                NULL);   // &bcData

            if (retValue != (DWORD) ERROR_SUCCESS &&
                    retValue != ERROR_INSUFFICIENT_BUFFER)
            {
                wsprintf (achBuff,
                    "Line:%d 0 based index = %d, retValue = %d, "
                     "ValueLen = %d",
                     __LINE__, j, retValue, cchValue);
                MessageBox (hDlg, achBuff, "Debug", MB_OK);
            }

            achBuff[0] = '\0';

            // Add each value to a list box.
            if (!lstrlen(achValue))
                lstrcpy(achValue, "<NO NAME>");
            wsprintf(achBuff, "%d) %s ", j, achValue);
            SendMessage(GetDlgItem(hDlg,IDL_LISTBOX2),
                LB_ADDSTRING, 0, (LONG) achBuff);
        }

    SetCursor(LoadCursor(NULL, IDC_ARROW));
}


Registry Reference

The following elements are used with the registry.

  • Registry Functions
  • Registry Structures


Registry Functions

The following functions are used with the registry:

RegCloseKey
RegConnectRegistry
RegCreateKey
RegCreateKeyEx
RegDeleteKey
RegDeleteValue
RegEnumKey
RegEnumKeyEx
RegEnumValue
RegFlushKey
RegGetKeySecurity
RegLoadKey
RegNotifyChangeKeyValue
RegOpenKey
RegOpenKeyEx
RegQueryInfoKey
RegQueryMultipleValues
RegQueryValue
RegQueryValueEx
RegReplaceKey
RegRestoreKey
RegSaveKey
RegSetKeySecurity
RegSetValue
RegSetValueEx
RegUnLoadKey

Obsolete Functions

GetPrivateProfileInt
GetPrivateProfileSection
GetPrivateProfileSectionNames
GetPrivateProfileString
GetPrivateProfileStruct
GetProfileInt
GetProfileSection
GetProfileString
WritePrivateProfileSection
WritePrivateProfileString
WritePrivateProfileStruct
WriteProfileSection
WriteProfileString


GetPrivateProfileInt

The GetPrivateProfileInt function retrieves an integer associated with a key in the specified section of the given initialization file. This function is provided for compatibility with 16-bit Windows-based applications. Win32-based applications should store initialization information in the registry.

UINT GetPrivateProfileInt(
  LPCTSTR lpAppName,  // address of section name
  LPCTSTR lpKeyName,  // address of key name
  INT nDefault,       // return value if key name is not found
  LPCTSTR lpFileName  // address of initialization filename
);

Parameters

lpAppName
Pointer to a null-terminated string containing the section name in the initialization file.
lpKeyName
Pointer to the null-terminated string containing the key name whose value is to be retrieved. This value is in the form of a string; the GetPrivateProfileInt function converts the string into an integer and returns the integer.
nDefault
Specifies the default value to return if the key name cannot be found in the initialization file.
lpFileName
Pointer to a null-terminated string that names the initialization file. If this parameter does not contain a full path to the file, the system searches for the file in the Windows directory.

Return Values

The return value is the integer equivalent of the string following the specified key name in the specified initialization file. If the key is not found, the return value is the specified default value. If the value of the key is less than zero, the return value is zero.

Remarks

The function searches the file for a key that matches the name specified by the lpKeyName parameter under the section name specified by the lpAppName parameter. A section in the initialization file must have the following form:

[section]
key=value
.
.
.

The GetPrivateProfileInt function is not case-sensitive; the strings in lpAppName and lpKeyName can be a combination of uppercase and lowercase letters.

An application can use the GetProfileInt function to retrieve an integer value from the WIN.INI file.

Windows NT: Calls to private profile functions may be mapped to the registry instead of to the specified initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
Windows NT\CurrentVersion\IniFileMapping

This mapping is likely if an application modifies system-component initialization files, such as CONTROL.INI, SYSTEM.INI, and WINFILE.INI. In these cases, the GetPrivateProfileInt function retrieves information from the registry, not from the initialization file; the change in the storage location has no effect on the function's behavior.

The Win32 profile functions (Get/WriteProfile*, Get/WritePrivateProfile*) use the following steps to locate initialization information:

  1. Look in the registry for the name of the initialization file, say MYFILE.INI, under IniFileMapping:

    HKEY_LOCAL_MACHINE\Software\Microsoft\
    Windows NT\CurrentVersion\IniFileMapping\myfile.ini

  2. Look for the section name specified by lpAppName. This will be a named value under myfile.ini, or a subkey of myfile.ini, or will not exist.
  3. If the section name specified by lpAppName is a named value under myfile.ini, then that value specifies where in the registry you will find the keys for the section.
  4. If the section name specified by lpAppName is a subkey of myfile.ini, then named values under that subkey specify where in the registry you will find the keys for the section. If the key you are looking for does not exist as a named value, then there will be an unnamed value (shown as <No Name>) that specifies the default location in the registry where you will find the key.
  5. If the section name specified by lpAppName does not exist as a named value or as a subkey under myfile.ini, then there will be an unnamed value (shown as <No Name>) under myfile.ini that specifies the default location in the registry where you will find the keys for the section.
  6. If there is no subkey for MYFILE.INI, or if there is no entry for the section name, then look for the actual MYFILE.INI on the disk and read its contents.

When looking at values in the registry that specify other registry locations, there are several prefixes that change the behavior of the .INI file mapping:

  • ! - this character forces all writes to go both to the registry and to the .INI file on disk.
  • # - this character causes the registry value to be set to the value in the Windows 3.1 .INI file when a new user logs in for the first time after setup.
  • @ - this character prevents any reads from going to the .INI file on disk if the requested data is not found in the registry.
  • USR: - this prefix stands for HKEY_CURRENT_USER, and the text after the prefix is relative to that key.
  • SYS: - this prefix stands for HKEY_LOCAL_MACHINE\SOFTWARE, and the text after the prefix is relative to that key.

See Also

Registry Overview, Registry Functions, GetProfileInt, WritePrivateProfileString


GetPrivateProfileSection

The GetPrivateProfileSection function retrieves all of the keys and values for the specified section from an initialization file. This function is provided for compatibility with 16-bit applications written for Windows. Win32-based applications should store initialization information in the registry.

Windows 95: The specified profile section must not exceed 32K.

Windows NT: The specified profile section has no size limit.

DWORD GetPrivateProfileSection(
  LPCTSTR lpAppName,        // address of section name
  LPTSTR lpReturnedString,  // address of return buffer
  DWORD nSize,              // size of return buffer
  LPCTSTR lpFileName        // address of initialization filename
);

Parameters

lpAppName
Pointer to a null-terminated string containing the section name in the initialization file.
lpReturnedString
Pointer to a buffer that receives the key name and value pairs associated with the named section. The buffer is filled with one or more null-terminated strings; the last string is followed by a second null character.
nSize
Specifies the size, in characters, of the buffer pointed to by the lpReturnedString parameter.

Windows 95: The maximum buffer size is 32,767 characters.

lpFileName
Pointer to a null-terminated string that names the initialization file. If this parameter does not contain a full path to the file, the system searches for the file in the Windows directory.

Return Values

The return value specifies the number of characters copied to the buffer, not including the terminating null character. If the buffer is not large enough to contain all the key name and value pairs associated with the named section, the return value is equal to nSize minus two.

Remarks

The data in the buffer pointed to by the lpReturnedString parameter consists of one or more null-terminated strings, followed by a final null character. Each string has the following format:

key=string

The GetPrivateProfileSection function is not case-sensitive; the string pointed to by the lpAppName parameter can be a combination of uppercase and lowercase letters.

This operation is atomic; no updates to the specified initialization file are allowed while the key name and value pairs for the section are being copied to the buffer pointed to by the lpReturnedString parameter.

Windows NT: Calls to private profile functions may be mapped to the registry instead of to the specified initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
Windows NT\CurrentVersion\IniFileMapping

This mapping is likely if an application modifies system-component initialization files, such as CONTROL.INI, SYSTEM.INI, and WINFILE.INI. In these cases, the GetPrivateProfileSection function retrieves information from the registry, not from the initialization file; the change in the storage location has no effect on the function's behavior.

The Win32 profile functions (Get/WriteProfile*, Get/WritePrivateProfile*) use the following steps to locate initialization information:

  1. Look in the registry for the name of the initialization file, say MYFILE.INI, under IniFileMapping:

    HKEY_LOCAL_MACHINE\Software\Microsoft\
    Windows NT\CurrentVersion\IniFileMapping\myfile.ini

  2. Look for the section name specified by lpAppName. This will be a named value under myfile.ini, or a subkey of myfile.ini, or will not exist.
  3. If the section name specified by lpAppName is a named value under myfile.ini, then that value specifies where in the registry you will find the keys for the section.
  4. If the section name specified by lpAppName is a subkey of myfile.ini, then named values under that subkey specify where in the registry you will find the keys for the section. If the key you are looking for does not exist as a named value, then there will be an unnamed value (shown as <No Name>) that specifies the default location in the registry where you will find the key.
  5. If the section name specified by lpAppName does not exist as a named value or as a subkey under myfile.ini, then there will be an unnamed value (shown as <No Name>) under myfile.ini that specifies the default location in the registry where you will find the keys for the section.
  6. If there is no subkey for MYFILE.INI, or if there is no entry for the section name, then look for the actual MYFILE.INI on the disk and read its contents.

When looking at values in the registry that specify other registry locations, there are several prefixes that change the behavior of the .INI file mapping:

  • ! - this character forces all writes to go both to the registry and to the .INI file on disk.
  • # - this character causes the registry value to be set to the value in the Windows 3.1 .INI file when a new user logs in for the first time after setup.
  • @ - this character prevents any reads from going to the .INI file on disk if the requested data is not found in the registry.
  • USR: - this prefix stands for HKEY_CURRENT_USER, and the text after the prefix is relative to that key.
  • SYS: - this prefix stands for HKEY_LOCAL_MACHINE\SOFTWARE, and the text after the prefix is relative to that key.

See Also

Registry Overview, Registry Functions, GetProfileSection, WritePrivateProfileSection


GetPrivateProfileSectionNames

The GetPrivateProfileSectionNames function retrieves the names of all sections in an initialization file. This function is provided for compatibility with 16-bit Windows-based applications. Win32-based applications should store initialization information in the registry.

DWORD GetPrivateProfileSectionNames(
  LPTSTR lpszReturnBuffer,  // address of return buffer
  DWORD nSize,              // size of return buffer
  LPCTSTR lpFileName        // address of initialization filename
);

Parameters

lpszReturnBuffer
Pointer to a buffer that receives the section names associated with the named file. The buffer is filled with one or more null-terminated strings; the last string is followed by a second null character.
nSize
Specifies the size, in characters, of the buffer pointed to by the lpszReturnBuffer parameter.
lpFileName
Pointer to a null-terminated string that names the initialization file. If this parameter is NULL, the function searches the WIN.INI file. If this parameter does not contain a full path to the file, the system searches for the file in the Windows directory.

Return Values

The return value specifies the number of characters copied to the specified buffer, not including the terminating null character. If the buffer is not large enough to contain all the section names associated with the specified initialization file, the return value is equal to the length specified by nSize minus two.

Remarks

This operation is atomic; no updates to the initialization file are allowed while the section names are being copied to the buffer.

Calls to profile functions might be mapped to the registry instead of to the initialization files. When the operation has been mapped, the GetPrivateProfileSectionNames function retrieves information from the registry, not from the initialization file; the change in the storage location has no effect on the function's behavior.

The Win32 profile functions (Get/WriteProfile*, Get/WritePrivateProfile*) use the following steps to locate initialization information:

  1. Look in the registry for the name of the initialization file, say MYFILE.INI, under IniFileMapping:

    HKEY_LOCAL_MACHINE\Software\Microsoft\
    Windows NT\CurrentVersion\IniFileMapping\myfile.ini

  2. Look for the section name specified by lpAppName. This will be a named value under myfile.ini, or a subkey of myfile.ini, or will not exist.
  3. If the section name specified by lpAppName is a named value under myfile.ini, then that value specifies where in the registry you will find the keys for the section.
  4. If the section name specified by lpAppName is a subkey of myfile.ini, then named values under that subkey specify where in the registry you will find the keys for the section. If the key you are looking for does not exist as a named value, then there will be an unnamed value (shown as <No Name>) that specifies the default location in the registry where you will find the key.
  5. If the section name specified by lpAppName does not exist as a named value or as a subkey under myfile.ini, then there will be an unnamed value (shown as <No Name>) under myfile.ini that specifies the default location in the registry where you will find the keys for the section.
  6. If there is no subkey for MYFILE.INI, or if there is no entry for the section name, then look for the actual MYFILE.INI on the disk and read its contents.

When looking at values in the registry that specify other registry locations, there are several prefixes that change the behavior of the .INI file mapping:

  • ! - this character forces all writes to go both to the registry and to the .INI file on disk.
  • # - this character causes the registry value to be set to the value in the Windows 3.1 .INI file when a new user logs in for the first time after setup.
  • @ - this character prevents any reads from going to the .INI file on disk if the requested data is not found in the registry.
  • USR: - this prefix stands for HKEY_CURRENT_USER, and the text after the prefix is relative to that key.
  • SYS: - this prefix stands for HKEY_LOCAL_MACHINE\SOFTWARE, and the text after the prefix is relative to that key.

See Also

Registry Overview, Registry Functions, GetPrivateProfileSection, WritePrivateProfileSection


GetPrivateProfileString

The GetPrivateProfileString function retrieves a string from the specified section in an initialization file. This function is provided for compatibility with 16-bit Windows-based applications. Win32-based applications should store initialization information in the registry.

DWORD GetPrivateProfileString(
  LPCTSTR lpAppName,        // points to section name
  LPCTSTR lpKeyName,        // points to key name
  LPCTSTR lpDefault,        // points to default string
  LPTSTR lpReturnedString,  // points to destination buffer
  DWORD nSize,              // size of destination buffer
  LPCTSTR lpFileName        // points to initialization filename
);

Parameters

lpAppName
Pointer to a null-terminated string that specifies the section containing the key name. If this parameter is NULL, the GetPrivateProfileString function copies all section names in the file to the supplied buffer.
lpKeyName
Pointer to the null-terminated string containing the key name whose associated string is to be retrieved. If this parameter is NULL, all key names in the section specified by the lpAppName parameter are copied to the buffer specified by the lpReturnedString parameter.
lpDefault
Pointer to a null-terminated default string. If the lpKeyName key cannot be found in the initialization file, GetPrivateProfileString copies the default string to the lpReturnedString buffer. This parameter cannot be NULL.

Avoid specifying a default string with trailing blank characters. The function inserts a null character in the lpReturnedString buffer to strip any trailing blanks.

Windows 95: Although lpDefault is declared as a constant parameter, the system strips any trailing blanks by inserting a null character into the lpDefault string before copying it to the lpReturnedString buffer.

Windows NT: The system does not modify the lpDefault string. This means that if the default string contains trailing blanks, the lpReturnedString and lpDefault strings will not match when compared using the lstrcmp function.

lpReturnedString
Pointer to the buffer that receives the retrieved string.
nSize
Specifies the size, in characters, of the buffer pointed to by the lpReturnedString parameter.
lpFileName
Pointer to a null-terminated string that names the initialization file. If this parameter does not contain a full path to the file, the system searches for the file in the Windows directory.

Return Values

The return value is the number of characters copied to the buffer, not including the terminating null character.

If neither lpAppName nor lpKeyName is NULL and the supplied destination buffer is too small to hold the requested string, the string is truncated and followed by a null character, and the return value is equal to nSize minus one.

If either lpAppName or lpKeyName is NULL and the supplied destination buffer is too small to hold all the strings, the last string is truncated and followed by two null characters. In this case, the return value is equal to nSize minus two.

Remarks

The GetPrivateProfileString function searches the specified initialization file for a key that matches the name specified by the lpKeyName parameter under the section heading specified by the lpAppName parameter. If it finds the key, the function copies the corresponding string to the buffer. If the key does not exist, the function copies the default character string specified by the lpDefault parameter. A section in the initialization file must have the following form:

[section]
key=string
.
.
.

If lpAppName is NULL, GetPrivateProfileString copies all section names in the specified file to the supplied buffer. If lpKeyName is NULL, the function copies all key names in the specified section to the supplied buffer. An application can use this method to enumerate all of the sections and keys in a file. In either case, each string is followed by a null character and the final string is followed by a second null character. If the supplied destination buffer is too small to hold all the strings, the last string is truncated and followed by two null characters.

If the string associated with lpKeyName is enclosed in single or double quotation marks, the marks are discarded when the GetPrivateProfileString function retrieves the string.

The GetPrivateProfileString function is not case-sensitive; the strings can be a combination of uppercase and lowercase letters.

To retrieve a string from the WIN.INI file, use the GetProfileString function.

Windows NT: Calls to private profile functions may be mapped to the registry instead of to the specified initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
Windows NT\CurrentVersion\IniFileMapping

This mapping is likely if an application modifies system-component initialization files, such as CONTROL.INI, SYSTEM.INI, and WINFILE.INI. In these cases, the GetPrivateProfileString function retrieves information from the registry, not from the initialization file; the change in the storage location has no effect on the function's behavior.

The Win32 profile functions (Get/WriteProfile*, Get/WritePrivateProfile*) use the following steps to locate initialization information:

  1. Look in the registry for the name of the initialization file, say MYFILE.INI, under IniFileMapping:

    HKEY_LOCAL_MACHINE\Software\Microsoft\
    Windows NT\CurrentVersion\IniFileMapping\myfile.ini

  2. Look for the section name specified by lpAppName. This will be a named value under myfile.ini, or a subkey of myfile.ini, or will not exist.
  3. If the section name specified by lpAppName is a named value under myfile.ini, then that value specifies where in the registry you will find the keys for the section.
  4. If the section name specified by lpAppName is a subkey of myfile.ini, then named values under that subkey specify where in the registry you will find the keys for the section. If the key you are looking for does not exist as a named value, then there will be an unnamed value (shown as <No Name>) that specifies the default location in the registry where you will find the key.
  5. If the section name specified by lpAppName does not exist as a named value or as a subkey under myfile.ini, then there will be an unnamed value (shown as <No Name>) under myfile.ini that specifies the default location in the registry where you will find the keys for the section.
  6. If there is no subkey for MYFILE.INI, or if there is no entry for the section name, then look for the actual MYFILE.INI on the disk and read its contents.

When looking at values in the registry that specify other registry locations, there are several prefixes that change the behavior of the .INI file mapping:

  • ! - this character forces all writes to go both to the registry and to the .INI file on disk.
  • # - this character causes the registry value to be set to the value in the Windows 3.1 .INI file when a new user logs in for the first time after setup.
  • @ - this character prevents any reads from going to the .INI file on disk if the requested data is not found in the registry.
  • USR: - this prefix stands for HKEY_CURRENT_USER, and the text after the prefix is relative to that key.
  • SYS: - this prefix stands for HKEY_LOCAL_MACHINE\SOFTWARE, and the text after the prefix is relative to that key.

See Also

Registry Overview, Registry Functions, GetProfileString, WritePrivateProfileString


GetPrivateProfileStruct

The GetPrivateProfileStruct function retrieves the data associated with the specified key in the given section of an initialization file. As it retrieves the data, the function calculates a checksum and compares it with the checksum calculated by the WritePrivateProfileStruct function when the data was added to the file.

Win32-based applications should store initialization information in the registry.

BOOL GetPrivateProfileStruct(
  LPCTSTR lpszSection,  // address of section name
  LPCTSTR lpszKey,      // address of key name
  LPVOID lpStruct,      // address of return buffer
  UINT uSizeStruct,     // size of return buffer
  LPCTSTR szFile        // address of initialization filename
);

Parameters

lpszSection
Pointer to a null-terminated string containing the section name in the initialization file.
lpszKey
Pointer to the null-terminated string containing the key name whose data is to be retrieved.
lpStruct
Pointer to the buffer that receives the data associated with the file, section, and key names.
uSizeStruct
Specifies the size, in bytes, of the buffer pointed to by the lpStruct parameter.
szFile
Pointer to a null-terminated string that names the initialization file. If this parameter does not contain a full path to the file, the system searches for the file in the Windows directory.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Remarks

A section in the initialization file must have the following form:

[section]
key=data
.
.
.

Calls to private profile functions might be mapped to the registry instead of to the specified initialization files. This mapping is likely if an application modifies system-component initialization files, such as CONTROL.INI, SYSTEM.INI, and WINFILE.INI. In these cases, the GetPrivateProfileStruct function retrieves information from the registry, not from the initialization file; the change in the storage location has no effect on the function's behavior.

The Win32 profile functions (Get/WriteProfile*, Get/WritePrivateProfile*) use the following steps to locate initialization information:

  1. Look in the registry for the name of the initialization file, say MYFILE.INI, under IniFileMapping:

    HKEY_LOCAL_MACHINE\Software\Microsoft\
    Windows NT\CurrentVersion\IniFileMapping\myfile.ini

  2. Look for the section name specified by lpAppName. This will be a named value under myfile.ini, or a subkey of myfile.ini, or will not exist.
  3. If the section name specified by lpAppName is a named value under myfile.ini, then that value specifies where in the registry you will find the keys for the section.
  4. If the section name specified by lpAppName is a subkey of myfile.ini, then named values under that subkey specify where in the registry you will find the keys for the section. If the key you are looking for does not exist as a named value, then there will be an unnamed value (shown as <No Name>) that specifies the default location in the registry where you will find the key.
  5. If the section name specified by lpAppName does not exist as a named value or as a subkey under myfile.ini, then there will be an unnamed value (shown as <No Name>) under myfile.ini that specifies the default location in the registry where you will find the keys for the section.
  6. If there is no subkey for MYFILE.INI, or if there is no entry for the section name, then look for the actual MYFILE.INI on the disk and read its contents.

When looking at values in the registry that specify other registry locations, there are several prefixes that change the behavior of the .INI file mapping:

  • ! - this character forces all writes to go both to the registry and to the .INI file on disk.
  • # - this character causes the registry value to be set to the value in the Windows 3.1 .INI file when a new user logs in for the first time after setup.
  • @ - this character prevents any reads from going to the .INI file on disk if the requested data is not found in the registry.
  • USR: - this prefix stands for HKEY_CURRENT_USER, and the text after the prefix is relative to that key.
  • SYS: - this prefix stands for HKEY_LOCAL_MACHINE\SOFTWARE, and the text after the prefix is relative to that key.

See Also

Registry Overview, Registry Functions, WritePrivateProfileStruct


GetProfileInt

The GetProfileInt function retrieves an integer from the specified key name in the given section of the WIN.INI file. This function is provided for compatibility with 16-bit Windows-based applications. Win32-based applications should store initialization information in the registry.

UINT GetProfileInt(
  LPCTSTR lpAppName,  // address of section name
  LPCTSTR lpKeyName,  // address of key name
  INT nDefault        // default value if key name is not found
);

Parameters

lpAppName
Pointer to a null-terminated string that specifies the section containing the key name.
lpKeyName
Pointer to the null-terminated string containing the key name whose value is to be retrieved. This value is in the form of a string; the GetProfileInt function converts the string into an integer and returns the integer.
nDefault
Specifies the default value to return if the key name cannot be found in the initialization file.

Return Values

The return value is the integer equivalent of the string following the key name in WIN.INI. If the function cannot find the key, the return value is the default value. If the value of the key is less than zero, the return value is zero.

Remarks

If the key name consists of digits followed by characters that are not numeric, the function returns only the value of the digits. For example, the function returns 102 for the following line: KeyName=102abc.

Windows NT: Calls to profile functions may be mapped to the registry instead of to the initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
Windows NT\CurrentVersion\IniFileMapping

When the operation has been mapped, the GetProfileInt function retrieves information from the registry, not from the initialization file; the change in the storage location has no effect on the function's behavior.

The Win32 profile functions (Get/WriteProfile*, Get/WritePrivateProfile*) use the following steps to locate initialization information:

  1. Look in the registry for the name of the initialization file, say MYFILE.INI, under IniFileMapping:

    HKEY_LOCAL_MACHINE\Software\Microsoft\
    Windows NT\CurrentVersion\IniFileMapping\myfile.ini

  2. Look for the section name specified by lpAppName. This will be a named value under myfile.ini, or a subkey of myfile.ini, or will not exist.
  3. If the section name specified by lpAppName is a named value under myfile.ini, then that value specifies where in the registry you will find the keys for the section.
  4. If the section name specified by lpAppName is a subkey of myfile.ini, then named values under that subkey specify where in the registry you will find the keys for the section. If the key you are looking for does not exist as a named value, then there will be an unnamed value (shown as <No Name>) that specifies the default location in the registry where you will find the key.
  5. If the section name specified by lpAppName does not exist as a named value or as a subkey under myfile.ini, then there will be an unnamed value (shown as <No Name>) under myfile.ini that specifies the default location in the registry where you will find the keys for the section.
  6. If there is no subkey for MYFILE.INI, or if there is no entry for the section name, then look for the actual MYFILE.INI on the disk and read its contents.

When looking at values in the registry that specify other registry locations, there are several prefixes that change the behavior of the .INI file mapping:

  • ! - this character forces all writes to go both to the registry and to the .INI file on disk.
  • # - this character causes the registry value to be set to the value in the Windows 3.1 .INI file when a new user logs in for the first time after setup.
  • @ - this character prevents any reads from going to the .INI file on disk if the requested data is not found in the registry.
  • USR: - this prefix stands for HKEY_CURRENT_USER, and the text after the prefix is relative to that key.
  • SYS: - this prefix stands for HKEY_LOCAL_MACHINE\SOFTWARE, and the text after the prefix is relative to that key.

See Also

Registry Overview, Registry Functions, GetPrivateProfileInt, WriteProfileString


GetProfileSection

The GetProfileSection function retrieves all of the keys and values for the specified section of the WIN.INI file. This function is provided for compatibility with 16-bit Windows-based applications. Win32-based applications should store initialization information in the registry.

Windows 95: The specified profile section must not exceed 32K.

Windows NT: The specified profile section has no size limit.

DWORD GetProfileSection(
  LPCTSTR lpAppName,        // address of section name
  LPTSTR lpReturnedString,  // address of return buffer
  DWORD nSize               // size of return buffer
);

Parameters

lpAppName
Pointer to a null-terminated string containing the section name in the WIN.INI file.
lpReturnedString
Pointer to a buffer that receives the keys and values associated with the named section. The buffer is filled with one or more null-terminated strings; the last string is followed by a second null character.
nSize
Specifies the size, in characters, of the buffer pointed to by the lpReturnedString parameter.

Windows 95: The maximum buffer size is 32,767 characters.

Return Values

The return value specifies the number of characters copied to the specified buffer, not including the terminating null character. If the buffer is not large enough to contain all the keys and values associated with the named section, the return value is equal to the length specified by nSize minus two.

Remarks

The format of the returned keys and values is one or more null-terminated strings, followed by a final null character. Each string has the following form:

key=string

The GetProfileSection function is not case-sensitive; the strings can be a combination of uppercase and lowercase letters.

This operation is atomic; no updates to the WIN.INI file are allowed while the keys and values for the section are being copied to the buffer.

Windows NT: Calls to profile functions may be mapped to the registry instead of to the initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
Windows NT\CurrentVersion\IniFileMapping

When the operation has been mapped, the GetProfileSection function retrieves information from the registry, not from the initialization file; the change in the storage location has no effect on the function's behavior.

The Win32 profile functions (Get/WriteProfile*, Get/WritePrivateProfile*) use the following steps to locate initialization information:

  1. Look in the registry for the name of the initialization file, say MYFILE.INI, under IniFileMapping:

    HKEY_LOCAL_MACHINE\Software\Microsoft\
    Windows NT\CurrentVersion\IniFileMapping\myfile.ini

  2. Look for the section name specified by lpAppName. This will be a named value under myfile.ini, or a subkey of myfile.ini, or will not exist.
  3. If the section name specified by lpAppName is a named value under myfile.ini, then that value specifies where in the registry you will find the keys for the section.
  4. If the section name specified by lpAppName is a subkey of myfile.ini, then named values under that subkey specify where in the registry you will find the keys for the section. If the key you are looking for does not exist as a named value, then there will be an unnamed value (shown as <No Name>) that specifies the default location in the registry where you will find the key.
  5. If the section name specified by lpAppName does not exist as a named value or as a subkey under myfile.ini, then there will be an unnamed value (shown as <No Name>) under myfile.ini that specifies the default location in the registry where you will find the keys for the section.
  6. If there is no subkey for MYFILE.INI, or if there is no entry for the section name, then look for the actual MYFILE.INI on the disk and read its contents.

When looking at values in the registry that specify other registry locations, there are several prefixes that change the behavior of the .INI file mapping:

  • ! - this character forces all writes to go both to the registry and to the .INI file on disk.
  • # - this character causes the registry value to be set to the value in the Windows 3.1 .INI file when a new user logs in for the first time after setup.
  • @ - this character prevents any reads from going to the .INI file on disk if the requested data is not found in the registry.
  • USR: - this prefix stands for HKEY_CURRENT_USER, and the text after the prefix is relative to that key.
  • SYS: - this prefix stands for HKEY_LOCAL_MACHINE\SOFTWARE, and the text after the prefix is relative to that key.

See Also

Registry Overview, Registry Functions, GetPrivateProfileSection, WriteProfileSection


GetProfileString

The GetProfileString function retrieves the string associated with the specified key in the given section of the WIN.INI file. This function is provided for compatibility with 16-bit Windows-based applications. Win32-based applications should store initialization information in the registry.

DWORD GetProfileString(
  LPCTSTR lpAppName,        // address of section name
  LPCTSTR lpKeyName,        // address of key name
  LPCTSTR lpDefault,        // address of default string
  LPTSTR lpReturnedString,  // address of destination buffer
  DWORD nSize               // size of destination buffer
);

Parameters

lpAppName
Pointer to a null-terminated string that specifies the section containing the key. If this parameter is NULL, the function copies all section names in the file to the supplied buffer.
lpKeyName
Pointer to a null-terminated string containing the key name whose associated string is to be retrieved. If this parameter is NULL, the function copies all keys in the given section to the supplied buffer. Each string is followed by a null character, and the final string is followed by a second null character.
lpDefault
Pointer to a null-terminated default string. If the lpKeyName key cannot be found in the initialization file, GetProfileString copies the default string to the lpReturnedString buffer. This parameter cannot be NULL.

Avoid specifying a default string with trailing blank characters. The function inserts a null character in the lpReturnedString buffer to strip any trailing blanks.

Windows 95: Although lpDefault is declared as a constant parameter, the system strips any trailing blanks by inserting a null character into the lpDefault string before copying it to the lpReturnedString buffer.

Windows NT: The system does not modify the lpDefault string. This means that if the default string contains trailing blanks, the lpReturnedString and lpDefault strings will not match when compared using the lstrcmp function.

lpReturnedString
Pointer to a buffer that receives the character string.
nSize
Specifies the size, in characters, of the buffer pointed to by the lpReturnedString parameter.

Return Values

The return value is the number of characters copied to the buffer, not including the null-terminating character.

If neither lpAppName nor lpKeyName is NULL and the supplied destination buffer is too small to hold the requested string, the string is truncated and followed by a null character, and the return value is equal to nSize minus one.

If either lpAppName or lpKeyName is NULL and the supplied destination buffer is too small to hold all the strings, the last string is truncated and followed by two null characters. In this case, the return value is equal to nSize minus two.

Remarks

If the string associated with the lpKeyName parameter is enclosed in single or double quotation marks, the marks are discarded when the GetProfileString function returns the string.

The GetProfileString function is not case-sensitive; the strings can contain a combination of uppercase and lowercase letters.

A section in the WIN.INI file must have the following form:

[section]
key=string
.
.
.

An application can use the GetPrivateProfileString function to retrieve a string from a specified initialization file.

The lpDefault parameter must point to a valid string, even if the string is empty (that is, even if its first character is a null character).

Windows NT: Calls to profile functions may be mapped to the registry instead of to the initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\
Windows NT\CurrentVersion\IniFileMapping

When the operation has been mapped, the GetProfileString function retrieves information from the registry, not from the initialization file; the change in the storage location has no effect on the function's behavior.

The Win32 profile functions (Get/WriteProfile*, Get/WritePrivateProfile*) use the following steps to locate initialization information:

  1. Look in the registry for the name of the initialization file, say MYFILE.INI, under IniFileMapping:

    HKEY_LOCAL_MACHINE\Software\Microsoft\
    Windows NT\CurrentVersion\IniFileMapping\myfile.ini

  2. Look for the section name specified by lpAppName. This will be a named value under myfile.ini, or a subkey of myfile.ini, or will not exist.
  3. If the section name specified by lpAppName is a named value under myfile.ini, then that value specifies where in the registry you will find the keys for the section.
  4. If the section name specified by lpAppName is a subkey of myfile.ini, then named values under that subkey specify where in the registry you will find the keys for the section. If the key you are looking for does not exist as a named value, then there will be an unnamed value (shown as <No Name>) that specifies the default location in the registry where you will find the key.
  5. If the section name specified by lpAppName does not exist as a named value or as a subkey under myfile.ini, then there will be an unnamed value (shown as <No Name>) under myfile.ini that specifies the default location in the registry where you will find the keys for the section.
  6. If there is no subkey for MYFILE.INI, or if there is no entry for the section name, then look for the actual MYFILE.INI on the disk and read its contents.

When looking at values in the registry that specify other registry locations, there are several prefixes that change the behavior of the .INI file mapping:

  • ! - this character forces all writes to go both to the registry and to the .INI file on disk.
  • # - this character causes the registry value to be set to the value in the Windows 3.1 .INI file when a new user logs in for the first time after setup.
  • @ - this character prevents any reads from going to the .INI file on disk if the requested data is not found in the registry.
  • USR: - this prefix stands for HKEY_CURRENT_USER, and the text after the prefix is relative to that key.
  • SYS: - this prefix stands for HKEY_LOCAL_MACHINE\SOFTWARE, and the text after the prefix is relative to that key.

See Also

Registry Overview, Registry Functions, GetPrivateProfileString, WriteProfileString


RegCloseKey

The RegCloseKey function releases a handle to the specified key.

LONG RegCloseKey(
  HKEY hKey   // handle to key to close
);

Parameters

hKey
Handle to the open key to close.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

The handle for a specified key should not be used after it has been closed, because it will no longer be valid. Key handles should not be left open any longer than necessary.

The RegCloseKey function does not necessarily write information to the registry before returning; it can take as much as several seconds for the cache to be flushed to the hard disk. If an application must explicitly write registry information to the hard disk, it can use the RegFlushKey function. RegFlushKey, however, uses many system resources and should be called only when necessary.

Windows CE: The RegCloseKey function always writes information to the registry before returning, eliminating the need to flush keys in the Windows CE registry.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.

See Also

Registry Overview, Registry Functions, RegCreateKey, RegCreateKeyEx, RegDeleteKey, RegFlushKey, RegOpenKey, RegOpenKeyEx, RegSetValue, RegSetValueEx


RegConnectRegistry

The RegConnectRegistry function establishes a connection to a predefined registry handle on another computer.

LONG RegConnectRegistry(
  LPTSTR lpMachineName,
                    // address of name of remote computer
  HKEY hKey,        // predefined registry handle
  PHKEY phkResult   // address of buffer for remote registry handle
);

Parameters

lpMachineName
Pointer to a null-terminated string containing the name of the remote computer. The string has the following form:

\\computername

If lpMachineName is NULL, the local computer name is used.

hKey
Specifies the one of the following predefined registry handles on the remote computer.

HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA, if the remote computer is running Windows NT
Windows 95 and Windows 98: HKEY_DYN_DATA, if the remote computer is running Windows 95 or Windows 98
Windows 95 and Windows 98: HKEY_CURRENT_CONFIG, if the remote computer is running Windows 95 or Windows 98

You cannot specify the HKEY_CLASSES_ROOT or HKEY_CURRENT_USER value for this parameter.

phkResult
Pointer to a variable that receives a key handle identifying the predefined handle on the remote computer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

When a handle returned by RegConnectRegistry is no longer needed, it should be closed by calling RegCloseKey.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegCloseKey


RegCreateKey

The RegCreateKey function creates the specified key. If the key already exists in the registry, the function opens it. This function is provided for compatibility with Windows version 3.1. Win32-based applications should use the RegCreateKeyEx function.

LONG RegCreateKey(
  HKEY hKey,        // handle to an open key
  LPCTSTR lpSubKey, // address of name of subkey to open
  PHKEY phkResult   // address of buffer for opened handle
);

Parameters

hKey
Handle to a currently open key or one of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

The key opened or created by the RegCreateKey function is a subkey of the key identified by hKey.

lpSubKey
Pointer to a null-terminated string specifying the name of a key that this function opens or creates. This key must be a subkey of the key identified by the hKey parameter.

If hKey is one of the predefined keys, lpSubKey may be NULL. In that case, the handle returned by using phkResult is the same hKey handle passed in to the function.

phkResult
Pointer to a variable that receives a handle to the opened or created key. When you no longer need the returned handle, call the RegCloseKey function to close it.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

An application can use the RegCreateKey function to create several keys at once. For example, an application can create a subkey four levels deep at the same time as the three preceding subkeys by specifying a string of the following form for the lpSubKey parameter:

subkey1\subkey2\subkey3\subkey4

The key identified by the hKey parameter must have been opened with KEY_CREATE_SUB_KEY access (KEY_WRITE access includes KEY_CREATE_SUB_KEY access).

If the lpSubKey parameter is the address of an empty string, the function opens and then passes back the key identified by the hKey parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegCloseKey, RegCreateKeyEx, RegDeleteKey, RegOpenKey, RegOpenKeyEx, RegSetValue


RegCreateKeyEx

The RegCreateKeyEx function creates the specified key. If the key already exists in the registry, the function opens it.

LONG RegCreateKeyEx(
  HKEY hKey,                // handle to an open key
  LPCTSTR lpSubKey,         // address of subkey name
  DWORD Reserved,           // reserved
  LPTSTR lpClass,           // address of class string
  DWORD dwOptions,          // special options flag
  REGSAM samDesired,        // desired security access
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
                            // address of key security structure
  PHKEY phkResult,          // address of buffer for opened handle
  LPDWORD lpdwDisposition   // address of disposition value buffer
);

Parameters

hKey
Handle to a currently open key or one of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

The key opened or created by the RegCreateKeyEx function is a subkey of the key identified by the hKey parameter.

lpSubKey
Pointer to a null-terminated string specifying the name of a subkey that this function opens or creates. The subkey specified must be a subkey of the key identified by the hKey parameter. This subkey must not begin with the backslash character ('\'). This parameter cannot be NULL.
Reserved
Reserved; must be zero.
lpClass
Pointer to a null-terminated string that specifies the class (object type) of this key. This parameter is ignored if the key already exists.
dwOptions
Specifies special options for the key. This parameter can be one of the following values.
Value | Meaning
REG_OPTION_NON_VOLATILE | This key is not volatile; this is the default. The information is stored in a file and is preserved when the system is restarted. The RegSaveKey function saves keys that are not volatile.
REG_OPTION_VOLATILE Windows NT: This key is volatile; the information is stored in memory and is not preserved when the system is restarted. The RegSaveKey function does not save volatile keys. This flag is ignored if the key already exists.

Windows 95: This value is ignored. If REG_OPTION_VOLATILE is specified, the RegCreateKeyEx function creates a nonvolatile key and returns ERROR_SUCCESS.
REG_OPTION_BACKUP_RESTORE | Windows NT: If this flag is set, the function ignores the samDesired parameter and attempts to open the key with the access required to backup or restore the key. If the calling thread has the SE_BACKUP_NAME privilege enabled, the key is opened with ACCESS_SYSTEM_SECURITY and KEY_READ access. If the calling thread has the SE_RESTORE_NAME privilege enabled, the key is opened with ACCESS_SYSTEM_SECURITY and KEY_WRITE access. If both privileges are enabled, the key has the combined accesses for both privileges.

samDesired
Specifies an access mask that specifies the desired security access for the new key. This parameter can be a combination of the following values:
Value | Meaning
KEY_ALL_ACCESS | Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, KEY_CREATE_SUB_KEY, KEY_CREATE_LINK, and KEY_SET_VALUE access.
KEY_CREATE_LINK | Permission to create a symbolic link.
KEY_CREATE_SUB_KEY | Permission to create subkeys.
KEY_ENUMERATE_SUB_KEYS | Permission to enumerate subkeys.
KEY_EXECUTE | Permission for read access.
KEY_NOTIFY | Permission for change notification.
KEY_QUERY_VALUE | Permission to query subkey data.
KEY_READ | Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY access.
KEY_SET_VALUE | Permission to set subkey data.
KEY_WRITE | Combination of KEY_SET_VALUE and KEY_CREATE_SUB_KEY access.

lpSecurityAttributes
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpSecurityAttributes is NULL, the handle cannot be inherited.

Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new key. If lpSecurityAttributes is NULL, the key gets a default security descriptor.

phkResult
Pointer to a variable that receives a handle to the opened or created key. When you no longer need the returned handle, call the RegCloseKey function to close it.
lpdwDisposition
Pointer to a variable that receives one of the following disposition values:
Value | Meaning
REG_CREATED_NEW_KEY | The key did not exist and was created.
REG_OPENED_EXISTING_KEY | The key existed and was simply opened without being changed.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

The key that the RegCreateKeyEx function creates has no values. An application can use the RegSetValue or RegSetValueEx function to set key values.

The key identified by the hKey parameter must have been opened with KEY_CREATE_SUB_KEY access. To open the key, use the RegCreateKeyEx or RegOpenKeyEx function.

An application cannot create a key under HKEY_USERS or HKEY_LOCAL_MACHINE.

An application can use RegCreateKeyEx to temporarily lock a portion of the registry. When the locking process creates a new key, it receives the disposition value REG_CREATED_NEW_KEY, indicating that it "owns" the lock. Another process attempting to create the same key receives the disposition value REG_OPENED_EXISTING_KEY, indicating that another process already owns the lock.

Windows CE: The dwOptions and samDesired parameters are ignored and should be set to zero to ensure compatibility with future versions of Windows CE.

The lpSecurityAttributes parameter should be set to NULL. Windows CE automatically assigns the key a default security descriptor.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegCloseKey, RegCreateKey, RegDeleteKey, RegOpenKey, RegOpenKeyEx, RegSaveKey, SECURITY_ATTRIBUTES


RegDeleteKey

Windows 95: The RegDeleteKey function deletes a subkey and all its descendants.

Windows NT: The RegDeleteKey function deletes the specified subkey. The subkey to be deleted must not have subkeys.

LONG RegDeleteKey(
  HKEY hKey,         // handle to open key
  LPCTSTR lpSubKey   // address of name of subkey to delete
);

Parameters

hKey
Handle to a currently open key or one of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

The key specified by the lpSubKey parameter must be a subkey of the key identified by hKey.

lpSubKey
Pointer to a null-terminated string specifying the name of the key to delete. This parameter cannot be NULL.

Windows NT: The specified key must not have subkeys.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

If the function succeeds, RegDeleteKey removes the specified key from the registry. The entire key, including all of its values, is removed.

To open the key, use the RegCreateKeyEx or RegOpenKeyEx function. Do not use the RegCreateKey or RegOpenKey functions.

Windows CE: With Windows CE, you can not RegDeleteKey a key which an application currently has open.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegCloseKey, RegCreateKeyEx, RegOpenKeyEx


RegDeleteValue

The RegDeleteValue function removes a named value from the specified registry key.

LONG RegDeleteValue(
  HKEY hKey,            // handle to key
  LPCTSTR lpValueName   // address of value name
);

Parameters

hKey
Handle to a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

lpValueName
Pointer to a null-terminated string that names the value to remove. If this parameter is NULL or points to an empty string, the value set by the RegSetValue function is removed.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

The key identified by the hKey parameter must have been opened with KEY_SET_VALUE access (KEY_WRITE access includes KEY_SET_VALUE access).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegSetValue, RegSetValueEx


RegEnumKey

The RegEnumKey function enumerates subkeys of the specified open registry key. The function retrieves the name of one subkey each time it is called. This function is provided for compatibility with Windows version 3.1. Win32-based applications should use the RegEnumKeyEx function.

LONG RegEnumKey(
  HKEY hKey,     // handle to key to query
  DWORD dwIndex, // index of subkey to query
  LPTSTR lpName, // address of buffer for subkey name
  DWORD cbName   // size of subkey buffer
);

Parameters

hKey
Handle to a currently open key or one of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

The keys returned are relative to the key identified by hKey.

dwIndex
Specifies the index of the subkey to retrieve. This value should be zero for the first call to the RegEnumKey function and then incremented for subsequent calls.

Because subkeys are not ordered, any new subkey will have an arbitrary index. This means that the function may return subkeys in any order.

lpName
Pointer to a buffer that receives the name of the subkey, including the terminating null character. This function copies only the name of the subkey, not the full key hierarchy, to the buffer.
cbName
Specifies the size, in characters, of the buffer pointed to by the lpName parameter, in characters. To determine the required buffer size, use the RegQueryInfoKey function to determine the size of the largest subkey for the key identified by the hKey parameter. The maximum required buffer size is (MAX_PATH + 1) characters.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

To enumerate subkeys, an application should initially call the RegEnumKey function with the dwIndex parameter set to zero. The application should then increment the dwIndex parameter and call the RegEnumKey function until there are no more subkeys (until the function returns ERROR_NO_MORE_ITEMS).

The application can also set dwIndex to the index of the last key on the first call to the function and decrement the index until the subkey with index 0 is enumerated. To retrieve the index of the last subkey, use the RegQueryInfoKey.

While an application is using the RegEnumKey function, it should not make calls to any registration functions that might change the key being queried.

The key identified by the hKey parameter must have been opened with KEY_ENUMERATE_SUB_KEYS access (KEY_READ access includes KEY_ENUMERATE_SUB_KEYS access). To open the key, use the RegCreateKeyEx or RegOpenKeyEx function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegCloseKey, RegCreateKeyEx, RegDeleteKey, RegEnumKeyEx, RegOpenKeyEx, RegQueryInfoKey, RegQueryValue


RegEnumKeyEx

The RegEnumKeyEx function enumerates subkeys of the specified open registry key. The function retrieves information about one subkey each time it is called. Unlike the RegEnumKey function, RegEnumKeyEx retrieves the class name of the subkey and the time it was last modified.

LONG RegEnumKeyEx(
  HKEY hKey,          // handle to key to enumerate
  DWORD dwIndex,      // index of subkey to enumerate
  LPTSTR lpName,      // address of buffer for subkey name
  LPDWORD lpcbName,   // address for size of subkey buffer
  LPDWORD lpReserved, // reserved
  LPTSTR lpClass,     // address of buffer for class string
  LPDWORD lpcbClass,  // address for size of class buffer
  PFILETIME lpftLastWriteTime
                      // address for time key last written to
);

Parameters

hKey
Handle to a currently open key or one of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

The enumerated keys are subkeys of the key identified by hKey.

dwIndex
Specifies the index of the subkey to retrieve. This parameter should be zero for the first call to the RegEnumKeyEx function and then incremented for subsequent calls.

Because subkeys are not ordered, any new subkey will have an arbitrary index. This means that the function may return subkeys in any order.

lpName
Pointer to a buffer that receives the name of the subkey, including the terminating null character. The function copies only the name of the subkey, not the full key hierarchy, to the buffer.
lpcbName
Pointer to a variable that specifies the size, in characters, of the buffer specified by the lpName parameter. This size should include the terminating null character. When the function returns, the variable pointed to by lpcbName contains the number of characters stored in the buffer. The count returned does not include the terminating null character.
lpReserved
Reserved; must be NULL.
lpClass
Pointer to a buffer that contains the class of the enumerated subkey when the function returns. This parameter can be NULL if the class is not required.
lpcbClass
Pointer to a variable that specifies the size, in characters, of the buffer specified by the lpClass parameter. The size should include the terminating null character. When the function returns, lpcbClass contains the number of characters stored in the buffer. The count returned does not include the terminating null character. This parameter can be NULL only if lpClass is NULL.
lpftLastWriteTime
Pointer to a variable that receives the time the enumerated subkey was last written to.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

To enumerate subkeys, an application should initially call the RegEnumKeyEx function with the dwIndex parameter set to zero. The application should then increment the dwIndex parameter and call RegEnumKeyEx until there are no more subkeys (until the function returns ERROR_NO_MORE_ITEMS).

The application can also set dwIndex to the index of the last subkey on the first call to the function and decrement the index until the subkey with the index 0 is enumerated. To retrieve the index of the last subkey, use the RegQueryInfoKey function.

While an application is using the RegEnumKeyEx function, it should not make calls to any registration functions that might change the key being enumerated.

The key identified by hKey must have been opened with KEY_ENUMERATE_SUB_KEYS access (KEY_READ includes KEY_ENUMERATE_SUB_KEYS). Use the RegCreateKeyEx or RegOpenKeyEx function to open the key.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegCreateKeyEx, RegDeleteKey, RegEnumKey, RegOpenKeyEx, RegQueryInfoKey


RegEnumValue

The RegEnumValue function enumerates the values for the specified open registry key. The function copies one indexed value name and data block for the key each time it is called.

LONG RegEnumValue(
  HKEY hKey,              // handle to key to query
  DWORD dwIndex,          // index of value to query
  LPTSTR lpValueName,     // address of buffer for value string
  LPDWORD lpcbValueName,  // address for size of value buffer
  LPDWORD lpReserved,     // reserved
  LPDWORD lpType,         // address of buffer for type code
  LPBYTE lpData,          // address of buffer for value data
  LPDWORD lpcbData        // address for size of data buffer
);

Parameters

hKey
Handle to a currently open key or one of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

The enumerated values are associated with the key identified by hKey.

dwIndex
Specifies the index of the value to retrieve. This parameter should be zero for the first call to the RegEnumValue function and then be incremented for subsequent calls.

Because values are not ordered, any new value will have an arbitrary index. This means that the function may return values in any order.

lpValueName
Pointer to a buffer that receives the name of the value, including the terminating null character.
lpcbValueName
Pointer to a variable that specifies the size, in characters, of the buffer pointed to by the lpValueName parameter. This size should include the terminating null character. When the function returns, the variable pointed to by lpcbValueName contains the number of characters stored in the buffer. The count returned does not include the terminating null character.
lpReserved
Reserved; must be NULL.
lpType
Pointer to a variable that receives the type code for the value entry. The type code can be one of the following values:
Value | Meaning
REG_BINARY | Binary data in any form.
REG_DWORD | A 32-bit number.
REG_DWORD_LITTLE_ENDIAN A 32-bit number in little-endian format. This is equivalent to REG_DWORD.

In little-endian format, a multi-byte value is stored in memory from the lowest byte (the "little end") to the highest byte. For example, the value 0x12345678 is stored as (0x78 0x56 0x34 0x12) in little-endian format.

Windows NT, Windows 95, and Windows 98 are designed to run on little-endian computer architectures. A user may connect to computers that have big-endian architectures, such as some UNIX systems.

REG_DWORD_BIG_ENDIAN A 32-bit number in big-endian format.

In big-endian format, a multi-byte value is stored in memory from the highest byte (the "big end") to the lowest byte. For example, the value 0x12345678 is stored as (0x12 0x34 0x56 0x78) in big-endian format.
REG_EXPAND_SZ | A null-terminated string that contains unexpanded references to environment variables (for example, "%PATH%"). It will be a Unicode or ANSI string depending on whether you use the Unicode or ANSI functions. To expand the environment variable references, use the ExpandEnvironmentStrings function.
REG_LINK | A Unicode symbolic link.
REG_MULTI_SZ | An array of null-terminated strings, terminated by two null characters.
REG_NONE | No defined value type.
REG_RESOURCE_LIST | A device-driver resource list.
REG_SZ | A null-terminated string. It will be a Unicode or ANSI string, depending on whether you use the Unicode or ANSI functions.

The lpType parameter can be NULL if the type code is not required.

lpData
Pointer to a buffer that receives the data for the value entry. This parameter can be NULL if the data is not required.
lpcbData
Pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the lpData parameter. When the function returns, the variable pointed to by the lpcbData parameter contains the number of bytes stored in the buffer. This parameter can be NULL, only if lpData is NULL.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

To enumerate values, an application should initially call the RegEnumValue function with the dwIndex parameter set to zero. The application should then increment dwIndex and call the RegEnumValue function until there are no more values (until the function returns ERROR_NO_MORE_ITEMS).

The application can also set dwIndex to the index of the last value on the first call to the function and decrement the index until the value with index 0 is enumerated. To retrieve the index of the last value, use the RegQueryInfoKey function.

While using RegEnumValue, an application should not call any registration functions that might change the key being queried.

The key identified by the hKey parameter must have been opened with KEY_QUERY_VALUE access. To open the key, use the RegCreateKeyEx or RegOpenKeyEx function.

To determine the maximum size of the name and data buffers, use the RegQueryInfoKey function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegCreateKeyEx, RegEnumKey, RegEnumKeyEx, RegOpenKeyEx, RegQueryInfoKey


RegFlushKey

The RegFlushKey function writes all the attributes of the specified open key into the registry.

LONG RegFlushKey(
  HKEY hKey   // handle to key to write
);

Parameters

hKey
Handle to a currently open key or one of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

It is not necessary to call RegFlushKey to change a key. Registry changes are flushed to disk by the registry using its lazy flusher. Registry changes are also flushed to disk at system shutdown.

Unlike RegCloseKey, the RegFlushKey function returns only when all the data has been written to the registry.

The RegFlushKey function may also write out parts of or all of the other keys. Calling this function excessively can have a negative effect on an application's performance.

An application should only call RegFlushKey if it requires absolute certainty that registry changes are on disk. In general, RegFlushKey rarely, if ever, need be used.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.

See Also

Registry Overview, Registry Functions, RegCloseKey, RegDeleteKey


RegLoadKey

The RegLoadKey function creates a subkey under HKEY_USER or HKEY_LOCAL_MACHINE and stores registration information from a specified file into that subkey. This registration information is in the form of a hive. A hive is a discrete body of keys, subkeys, and values that is rooted at the top of the registry hierarchy. A hive is backed by a single file and .LOG file.

LONG RegLoadKey(
  HKEY hKey,       // handle to open key
  LPCTSTR lpSubKey,
                   // address of name of subkey
  LPCTSTR lpFile   // address of filename for registry information
);

Parameters

hKey
Specifies the key where the subkey will be created. This can be a predefined reserved handle value, or a handle returned by a call to RegConnectRegistry. The predefined reserved handle values are:

HKEY_LOCAL_MACHINE
HKEY_USERS

This function always loads information at the top of the registry hierarchy. The HKEY_CLASSES_ROOT and HKEY_CURRENT_USER handle values cannot be specified for this parameter, because they represent subsets of the HKEY_LOCAL_MACHINE and HKEY_USERS handle values, respectively.

lpSubKey
Pointer to a null-terminated string that specifies the name of the key to be created under hKey. This subkey is where the registration information from the file will be loaded.
lpFile
Pointer to a null-terminated string containing the name of a file that has registration information. This file must have been created with the RegSaveKey function.

Windows 95: RegLoadKey does not support long file names. If the desired file has a long file name, use the short file name to load it.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

If hKey is a handle returned by RegConnectRegistry, then the path specified in lpFile is relative to the remote computer.

Windows NT: The calling process must have the SE_RESTORE_NAME privilege. For more information about privileges, see Privileges.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegConnectRegistry, RegDeleteKey, RegReplaceKey, RegRestoreKey, RegSaveKey, RegUnloadKey


RegNotifyChangeKeyValue

The RegNotifyChangeKeyValue function notifies the caller about changes to the attributes or contents of a specified registry key. Note that the function does not notify the caller if the specified key is deleted.

LONG RegNotifyChangeKeyValue(
  HKEY hKey,             // handle to key to watch
  BOOL bWatchSubtree,    // flag for subkey notification
  DWORD dwNotifyFilter,  // changes to be reported
  HANDLE hEvent,         // handle to signaled event
  BOOL fAsynchronous     // flag for asynchronous reporting
);

Parameters

hKey
Handle to a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

bWatchSubtree
Specifies a flag that indicates whether to report changes in the specified key and all of its subkeys or only in the specified key. If this parameter is TRUE, the function reports changes in the key and its subkeys. If the parameter is FALSE, the function reports changes only in the key.
dwNotifyFilter
Specifies a set of flags that control which changes should be reported. This parameter can be a combination of the following values:
Value | Meaning
REG_NOTIFY_CHANGE_NAME | Notify the caller if a subkey is added or deleted.
REG_NOTIFY_CHANGE_ATTRIBUTES | Notify the caller of changes to the attributes of the key, such as the security descriptor information.
REG_NOTIFY_CHANGE_LAST_SET | Notify the caller of changes to a value of the key. This can include adding or deleting a value, or changing an existing value.
REG_NOTIFY_CHANGE_SECURITY | Notify the caller of changes to the security descriptor of the key.

hEvent
Handle to an event. If the fAsynchronous parameter is TRUE, the function returns immediately and changes are reported by signaling this event. If fAsynchronous is FALSE, hEvent is ignored.
fAsynchronous
Specifies a flag that indicates how the function reports changes. If this parameter is TRUE, the function returns immediately and reports changes by signaling the specified event. When this parameter is FALSE, the function does not return until a change has occurred.

If hEvent does not specify a valid event, the fAsynchronous parameter cannot be TRUE.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

If the key identified by the hKey parameter is closed, the event is signaled. This means that an application should not depend on the key being open after returning from a wait operation on the event.

RegNotifyChangeKeyValue does not work with remote handles. If RegNotifyChangeKeyValue is called with an hKey value that is a remote handle, it returns ERROR_INVALID_HANDLE.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.

See Also

Registry Overview, Registry Functions, RegDeleteKey, RegEnumKey, RegEnumKeyEx, RegEnumValue, RegQueryInfoKey, RegQueryValue, RegQueryValueEx


RegOpenKey

The RegOpenKey function opens the specified key. This function is provided for compatibility with Windows version 3.1. Win32-based applications should use the RegOpenKeyEx function.

LONG RegOpenKey(
  HKEY hKey,        // handle to open key
  LPCTSTR lpSubKey, // address of name of subkey to open
  PHKEY phkResult   // address of handle to open key
);

Parameters

hKey
Handle to a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

The key opened by the RegOpenKey function is a subkey of the key identified by hKey.

lpSubKey
Pointer to a null-terminated string containing the name of the key to open. This key must be a subkey of the key identified by the hKey parameter. If this parameter is NULL or a pointer to an empty string, the function returns the same handle that was passed in.
phkResult
Pointer to a variable that receives a handle to the opened key. When you no longer need the returned handle, call the RegCloseKey function to close it.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

The RegOpenKey function uses the default security access mask to open a key. If opening the key requires a different mask, the function fails, returning ERROR_ACCESS_DENIED. An application should use the RegOpenKeyEx function to specify an access mask in this situation.

Unlike the RegCreateKey function, RegOpenKey does not create the specified key if the key does not exist in the database.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegCloseKey, RegCreateKey, RegCreateKeyEx, RegDeleteKey, RegOpenKeyEx


RegOpenKeyEx

The RegOpenKeyEx function opens the specified key.

LONG RegOpenKeyEx(
  HKEY hKey,         // handle to open key
  LPCTSTR lpSubKey,  // address of name of subkey to open
  DWORD ulOptions,   // reserved
  REGSAM samDesired, // security access mask
  PHKEY phkResult    // address of handle to open key
);

Parameters

hKey
Handle to a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

lpSubKey
Pointer to a null-terminated string containing the name of the subkey to open. If this parameter is NULL or a pointer to an empty string, the function will open a new handle to the key identified by the hKey parameter. In this case, the function will not close the handles previously opened.
ulOptions
Reserved; must be zero.
samDesired
Specifies an access mask that describes the desired security access for the new key. This parameter can be a combination of the following values:
Value | Meaning
KEY_ALL_ACCESS | Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, KEY_CREATE_SUB_KEY, KEY_CREATE_LINK, and KEY_SET_VALUE access.
KEY_CREATE_LINK | Permission to create a symbolic link.
KEY_CREATE_SUB_KEY | Permission to create subkeys.
KEY_ENUMERATE_SUB_KEYS | Permission to enumerate subkeys.
KEY_EXECUTE | Permission for read access.
KEY_NOTIFY | Permission for change notification.
KEY_QUERY_VALUE | Permission to query subkey data.
KEY_READ | Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY access.
KEY_SET_VALUE | Permission to set subkey data.
KEY_WRITE | Combination of KEY_SET_VALUE and KEY_CREATE_SUB_KEY access.

phkResult
Pointer to a variable that receives a handle to the opened key. When you no longer need the returned handle, call the RegCloseKey function to close it.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

Unlike the RegCreateKeyEx function, the RegOpenKeyEx function does not create the specified key if the key does not exist in the registry.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegCloseKey, RegCreateKeyEx, RegDeleteKey, RegOpenKey


RegQueryInfoKey

The RegQueryInfoKey function retrieves information about a specified registry key.

LONG RegQueryInfoKey(
  HKEY hKey,                // handle to key to query
  LPTSTR lpClass,           // address of buffer for class string
  LPDWORD lpcbClass,        // address of size of class string buffer
  LPDWORD lpReserved,       // reserved
  LPDWORD lpcSubKeys,       // address of buffer for number of
                            // subkeys
  LPDWORD lpcbMaxSubKeyLen,  // address of buffer for longest subkey
                             // name length
  LPDWORD lpcbMaxClassLen,  // address of buffer for longest class
                            // string length
  LPDWORD lpcValues,        // address of buffer for number of value
                            // entries
  LPDWORD lpcbMaxValueNameLen,  // address of buffer for longest
                                // value name length
  LPDWORD lpcbMaxValueLen,  // address of buffer for longest value
                            // data length
  LPDWORD lpcbSecurityDescriptor,
                            // address of buffer for security
                            // descriptor length
  PFILETIME lpftLastWriteTime   // address of buffer for last write
                                // time
);

Parameters

hKey
Handle to a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

lpClass
Pointer to a buffer that receives the key's class name. This parameter can be NULL.
lpcbClass
Pointer to a variable that specifies the size, in characters, of the buffer pointed to by the lpClass parameter. This size should include the terminating null character. When the function returns, this variable contains the length of the class string stored in the buffer. The count returned does not include the terminating null character. If the buffer is not big enough, the function returns ERROR_MORE_DATA, and the variable contains the size of the string, in characters, without counting the null character.

If lpClass is NULL, lpcbClass can be NULL.

Windows NT: If the lpClass parameter is a valid address, but the lpcbClass parameter is not (for example, it is NULL), the function returns ERROR_INVALID_PARAMETER.

Windows 95: If the lpClass parameter is a valid address, but the lpcbClass parameter is not (for example, it is NULL), the function returns ERROR_SUCCESS instead of ERROR_INVALID_PARAMETER. To ensure compatibility with other platforms, verify that lpcbClass is valid before calling the function.

lpReserved
Reserved; must be NULL.
lpcSubKeys
Pointer to a variable that receives the number of subkeys contained by the specified key. This parameter can be NULL.
lpcbMaxSubKeyLen
Pointer to a variable that receives the length, in characters, of the key's subkey with the longest name. The count returned does not include the terminating null character. This parameter can be NULL.
lpcbMaxClassLen
Pointer to a variable that receives the length, in characters, of the longest string specifying a subkey class. The count returned does not include the terminating null character. This parameter can be NULL.
lpcValues
Pointer to a variable that receives the number of values associated with the key. This parameter can be NULL.
lpcbMaxValueNameLen
Pointer to a variable that receives the length, in characters, of the key's longest value name. The count returned does not include the terminating null character. This parameter can be NULL.
lpcbMaxValueLen
Pointer to a variable that receives the length, in bytes, of the longest data component among the key's values. This parameter can be NULL.
lpcbSecurityDescriptor
Pointer to a variable that receives the length, in bytes, of the key's security descriptor. This parameter can be NULL.
lpftLastWriteTime
Pointer to a FILETIME structure. This parameter can be NULL.

Windows NT: The function sets the members of the FILETIME structure to indicate the last time that the key or any of its value entries was modified.

Windows 95: The function sets the members of the FILETIME structure to zero. This is because the system does not keep track of registry key last write time information.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

The key identified by the hKey parameter must have been opened with KEY_QUERY_VALUE access (KEY_READ access includes KEY_QUERY_VALUE access).

Windows CE: The lpcbMaxValueData and lpcbSecurityDescriptor parameters are not used and must be set to NULL.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, FILETIME, RegDeleteKey, RegEnumKey, RegEnumKeyEx, RegEnumValue, RegQueryValue, RegQueryValueEx


RegQueryMultipleValues

The RegQueryMultipleValues function retrieves the type and data for a list of value names associated with an open registry key.

LONG RegQueryMultipleValues(
  HKEY hKey,         // handle to key to query
  PVALENT val_list,  // pointer to array of value entry structures
  DWORD num_vals,    // size of array of value entry structures
  LPTSTR lpValueBuf, // pointer to buffer for value information
  LPDWORD ldwTotsize // pointer to size of value buffer
);

Parameters

hKey
Handle to a currently open key or any of the pre-defined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

val_list
Pointer to an array of VALENT structures that describe one or more value entries. On input, the ve_valuename member of each structure must contain a pointer to the name of a value to retrieve. The function fails if any of the specified values do not exist in the specified key.

If the function succeeds, each element of the array contains the information for the specified value.

num_vals
Specifies the number of elements in the val_list array.
lpValueBuf
Pointer to a buffer. If the function succeeds, the buffer receives the data for each value.

If lpValueBuf is NULL, the function returns success, and ldwTotsize returns the required size, in bytes, of the buffer.

ldwTotsize
Pointer to a value that specifies the size, in bytes, of the buffer pointed to by the lpValueBuf parameter. If the function succeeds, ldwTotsize returns the number of bytes copied to the buffer. If the function fails because the buffer is too small, ldwTotsize receives the required size, in bytes.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is one of the following error codes:

Value | Meaning
ERROR_CANTREAD | RegQueryMultipleValues cannot instantiate or access the provider of the dynamic key.
ERROR_MORE_DATA | The buffer pointed to by lpValueBuf was too small. In this case, ldwTotsize returns the required buffer size.
ERROR_TRANSFER_TOO_LONG | The total length of the requested data (size of the val_list array + ldwTotSize) is more than the system limit of one megabyte.

Remarks

The RegQueryMultipleValues function allows an application to query one or more values of a static or dynamic key. If the target key is a static key, the system provides all of the values in an atomic fashion. To prevent excessive serialization, the aggregate data returned by the function can not exceed one megabyte.

If the target key is a dynamic key, its provider must provide all the values in an atomic fashion. This means the provider should fill the results buffer synchronously, providing a consistent view of all the values in the buffer while avoiding excessive serialization. The provider can provide at most one megabyte of total output data during an atomic call to this function.

RegQueryMultipleValues is supported remotely; that is, the hKey parameter passed to the function can refer to a remote computer.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, VALENT


RegQueryValue

The RegQueryValue function retrieves the data associated with the default or unnamed value of a specified registry key. The data must be a null-terminated string.

This function is provided for compatibility with Windows version 3.1. Win32-based applications should use the RegQueryValueEx function.

LONG RegQueryValue(
  HKEY hKey,       // handle to key to query
  LPCTSTR lpSubKey,
                   // name of subkey to query
  LPTSTR lpValue,  // buffer for returned string
  PLONG lpcbValue  // receives size of returned string
);

Parameters

hKey
Handle to a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

lpSubKey
Pointer to a null-terminated string containing the name of the subkey of the hKey parameter for which the default value is retrieved. If this parameter is NULL or points to an empty string, the function retrieves the default value for the key identified by hKey.
lpValue
Pointer to a buffer that receives the null-terminated string associated with the default value of the specified key.

If lpValue is NULL, and lpcbValue is non-NULL, the function returns ERROR_SUCCESS, and stores the size of the data, in bytes, in the variable pointed to by lpcbValue. This lets an application determine the best way to allocate a buffer for the value's data.

lpcbValue
Pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the lpValue parameter. When the function returns, this variable contains the size of the data copied to lpValue, including the terminating null character.

If the buffer specified by lpValue parameter is not large enough to hold the data, the function returns the value ERROR_MORE_DATA, and stores the required buffer size, in bytes, into the variable pointed to by lpcbValue.

In all cases the value returned in lpcbValue includes the size of the terminating null character in the string.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

The key identified by the hKey parameter must have been opened with KEY_QUERY_VALUE access (KEY_READ access includes KEY_QUERY_VALUE access).

If the ANSI version of this function is used (either by explicitly calling RegQueryValueA or by not defining UNICODE before including the WINDOWS.H file), this function converts the stored Unicode string to an ANSI string before copying it to the buffer specified by the lpValue parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegEnumKey, RegEnumKeyEx, RegEnumValue, RegQueryInfoKey, RegQueryValueEx, RegSetValue, RegSetValueEx


RegQueryValueEx

The RegQueryValueEx function retrieves the type and data for a specified value name associated with an open registry key.

LONG RegQueryValueEx(
  HKEY hKey,           // handle to key to query
  LPTSTR lpValueName,  // address of name of value to query
  LPDWORD lpReserved,  // reserved
  LPDWORD lpType,      // address of buffer for value type
  LPBYTE lpData,       // address of data buffer
  LPDWORD lpcbData     // address of data buffer size
);

Parameters

hKey
Handle to a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

lpValueName
Pointer to a null-terminated string containing the name of the value to query.

If lpValueName is NULL or an empty string, "", the function retrieves the type and data for the key's unnamed or default value, if any.

Windows 95 and Windows 98: Every key has a default value that initially does not contain data. On Windows 95, the default value type is always REG_SZ. On Windows 98, the type of a key's default value is initially REG_SZ, but RegSetValueEx can specify a default value with a different type.

Windows NT: Keys do not automatically have an unnamed or default value. Unnamed values can be of any type.

lpReserved
Reserved; must be NULL.
lpType
Pointer to a variable that receives the type of data associated with the specified value. The value returned through this parameter will be one of the following:
Value | Meaning
REG_BINARY | Binary data in any form.
REG_DWORD | A 32-bit number.
REG_DWORD_LITTLE_ENDIAN A 32-bit number in little-endian format. This is equivalent to REG_DWORD.

In little-endian format, a multi-byte value is stored in memory from the lowest byte (the "little end") to the highest byte. For example, the value 0x12345678 is stored as (0x78 0x56 0x34 0x12) in little-endian format.

Windows NT, Windows 95, and Windows 98 are designed to run on little-endian computer architectures. A user may connect to computers that have big-endian architectures, such as some UNIX systems.

REG_DWORD_BIG_ENDIAN A 32-bit number in big-endian format.

In big-endian format, a multi-byte value is stored in memory from the highest byte (the "big end") to the lowest byte. For example, the value 0x12345678 is stored as (0x12 0x34 0x56 0x78) in big-endian format.
REG_EXPAND_SZ | A null-terminated string that contains unexpanded references to environment variables (for example, "%PATH%"). It will be a Unicode or ANSI string depending on whether you use the Unicode or ANSI functions. To expand the environment variable references, use the ExpandEnvironmentStrings function.
REG_LINK | A Unicode symbolic link.
REG_MULTI_SZ | An array of null-terminated strings, terminated by two null characters.
REG_NONE | No defined value type.
REG_RESOURCE_LIST | A device-driver resource list.
REG_SZ | A null-terminated string. It will be a Unicode or ANSI string depending on whether you use the Unicode or ANSI functions.

The lpType parameter can be NULL if the type is not required.

lpData
Pointer to a buffer that receives the value's data. This parameter can be NULL if the data is not required.
lpcbData
Pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the lpData parameter. When the function returns, this variable contains the size of the data copied to lpData.

If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, then lpcbData will also include the size of the terminating null character.

The lpcbData parameter can be NULL only if lpData is NULL.

If the buffer specified by lpData parameter is not large enough to hold the data, the function returns the value ERROR_MORE_DATA, and stores the required buffer size, in bytes, into the variable pointed to by lpcbData.

If lpData is NULL, and lpcbData is non-NULL, the function returns ERROR_SUCCESS, and stores the size of the data, in bytes, in the variable pointed to by lpcbData. This lets an application determine the best way to allocate a buffer for the value's data.

Window NT: If hKey specifies HKEY_PERFORMANCE_DATA and the lpData buffer is too small, RegQueryValueEx returns ERROR_MORE_DATA but lpcbData does not return the required buffer size. This is because the size of the performance data can change from one call to the next. In this case, you must increase the buffer size and call RegQueryValueEx again passing the updated buffer size in the lpcbData parameter. Repeat this until the function succeeds. You need to maintain a separate variable to keep track of the buffer size, because the value returned by lpcbData is unpredictable.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

The key identified by hKey must have been opened with KEY_QUERY_VALUE access. To open the key, use the RegCreateKeyEx or RegOpenKeyEx function.

If the value data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, and the ANSI version of this function is used (either by explicitly calling RegQueryValueExA or by not defining UNICODE before including the WINDOWS.H file), this function converts the stored Unicode string to an ANSI string before copying it to the buffer pointed to by lpData.

Window NT: When calling the RegQueryValueEx function with hKey set to the HKEY_PERFORMANCE_DATA handle and a value string of a specified object, the returned data structure sometimes has unrequested objects. Don't be surprised; this is normal behavior. When calling the RegQueryValueEx function, you should always expect to walk the returned data structure to look for the requested object.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, ExpandEnvironmentStrings, RegCreateKeyEx, RegEnumKey, RegEnumKeyEx, RegEnumValue, RegOpenKeyEx, RegQueryInfoKey, RegQueryValue


RegReplaceKey

The RegReplaceKey function replaces the file backing a key and all its subkeys with another file, so that when the system is next started, the key and subkeys will have the values stored in the new file.

LONG RegReplaceKey(
  HKEY hKey,         // handle to open key
  LPCTSTR lpSubKey,  // address of name of subkey
  LPCTSTR lpNewFile, // address of filename for file with new data
  LPCTSTR lpOldFile  // address of filename for backup file
);

Parameters

hKey
Handle to a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpSubKey
Pointer to a null-terminated string containing the name of a key whose subkeys and values are replaced by this function. This key must be a subkey of the key identified by the hKey parameter. This parameter can be NULL.

The selected key must be the root of a hive; that is, it must be an immediate descendent of HKEY_LOCAL_MACHINE or HKEY_USERS.

lpNewFile
Pointer to a null-terminated string containing the name of the file with registration information. This file is typically created by using the RegSaveKey function.
lpOldFile
Pointer to a null-terminated string containing the name of a file that receives a backup copy of the registry information being replaced.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

The file specified by the lpNewFile parameter remains open until the system is restarted.

If hKey is a handle returned by RegConnectRegistry, then the paths specified in lpNewFile and lpOldFile are relative to the remote computer.

Windows NT: The calling process must have the SE_RESTORE_NAME privilege. For more information about privileges, see Privileges.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegConnectRegistry, RegDeleteKey, RegLoadKey, RegRestoreKey, RegSaveKey


RegRestoreKey

The RegRestoreKey function reads the registry information in a specified file and copies it over the specified key. This registry information may be in the form of a key and multiple levels of subkeys.

LONG RegRestoreKey(
  HKEY hKey,      // handle to key where restore begins
  LPCTSTR lpFile, // address of filename containing saved tree
  DWORD dwFlags   // optional flags
);

Parameters

hKey
Handle to a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

Any information contained in this key and its descendent keys is overwritten by the information in the file pointed to by the lpFile parameter.

lpFile
Pointer to a null-terminated string containing the name of the file with registry information. This file is typically created by using the RegSaveKey function.
dwFlags
Specifies a flag indicating whether the key is volatile. (A volatile key is valid only until the next time the system is started.) This parameter is optional; if no value is specified, the key is not volatile.

This parameter can be the REG_WHOLE_HIVE_VOLATILE flag set. Instead of restoring the given key, this flag causes a new, volatile (memory only) set of registry information to be created. (A hive is a large set of registry information, typically containing all of the pertinent information for part of the system. For example, HKEY_LOCAL_MACHINE\Hardware is a volatile hive.)

If REG_WHOLE_HIVE_VOLATILE is specified, the key identified by the hKey parameter must be either the HKEY_USERS or HKEY_LOCAL_MACHINE value.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

If any subkeys of the hKey parameter are open, RegRestoreKey fails. The function also fails if the calling process does not have the SE_RESTORE_NAME privilege. For more information about privileges, see Privileges.

This function replaces the keys and values below the specified key with the keys and values that are subsidiary to the top-level key in the file, no matter what the name of the top-level key in the file might be. For example, hKey might identify a key A with subkeys B and C, while the lpFile parameter specifies a file containing key X with subkeys Y and Z. After a call to RegRestoreKey, the registry would contain key A with subkeys Y and Z. The value entries of A would be replaced by the value entries of X.

The new information in the file specified by lpFile overwrites the contents of the key specified by the hKey parameter, except for the key name.

If hKey represents a key in a remote computer, the path described by lpFile is relative to the remote computer.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegDeleteKey, RegLoadKey, RegReplaceKey, RegSaveKey


RegSaveKey

The RegSaveKey function saves the specified key and all of its subkeys and values to a new file.

LONG RegSaveKey(
  HKEY hKey,       // handle to key where save begins
  LPCTSTR lpFile,  // address of filename to save to
  LPSECURITY_ATTRIBUTES lpSecurityAttributes
                   // address of security structure
);

Parameters

hKey
Specifies a handle to the key where the save operation is to begin, or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

lpFile
Pointer to a null-terminated string containing the name of the file in which the specified key and subkeys are saved.

Windows 95: RegSaveKey does not support long file names. To save a registry hive to a file with a long file name, first save the hive to a short file name, then rename the resulting file to its long file name.

Windows NT: If the file already exists, the function fails with the ERROR_ALREADY_EXISTS error.

Windows 95: If the file already exists, the function fails with the ERROR_REGISTRY_IO_FAILED error.

Windows NT: If the string does not include a path, the file is created in the current directory of the calling process for a local key, or in the %systemroot%\system32 directory for a remote key.

Windows 95: If the string does not include a path, the file is created in the Windows root directory for local and remote keys. See GetWindowsDirectory.

lpSecurityAttributes
Windows NT: Pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new file. If lpSecurityAttributes is NULL, the file gets a default security descriptor.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

If hKey represents a key on a remote computer, the path described by lpFile is relative to the remote computer.

The RegSaveKey function saves only nonvolatile keys. It does not save volatile keys. A key is made volatile or nonvolatile at its creation; see RegCreateKeyEx.

You can use the file created by RegSaveKey in subsequent calls to the RegLoadKey, RegReplaceKey, or RegRestoreKey functions. If RegSaveKey fails part way through its operation, the file will be corrupt and subsequent calls to RegLoadKey, RegReplaceKey, or RegRestoreKey for the file will fail.

Windows NT: The new file has the archive attribute.

Windows 95: The new file has the archive, hidden, read-only, and system attributes.

Windows NT: The calling process must have the SE_BACKUP_NAME privilege enabled. For more information about privileges, see Privileges.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegCreateKeyEx, RegDeleteKey, RegLoadKey, RegReplaceKey, RegRestoreKey, SECURITY_ATTRIBUTES


RegSetValue

The RegSetValue function sets the data for the default or unnamed value of a specified registry key. The data must be a text string.

This function is provided for compatibility with Windows version 3.1. Win32-based applications should use the RegSetValueEx function, which allows you to set any number of named values of any data type.

LONG RegSetValue(
  HKEY hKey,         // handle to key to set value for
  LPCTSTR lpSubKey,  // address of subkey name
  DWORD dwType,      // type of value
  LPCTSTR lpData,    // address of value data
  DWORD cbData       // size of value data
);

Parameters

hKey
Handle to a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

lpSubKey
Pointer to a null-terminated string containing the name of a subkey of the hKey parameter. The function sets the default value of the specified subkey. If this parameter is NULL or points to an empty string, the function sets the default value of the key identified by hKey.
dwType
Specifies the type of information to be stored. This parameter must be the REG_SZ type. To store other data types, use the RegSetValueEx function.
lpData
Pointer to a null-terminated string containing the data to set for the default value of the specified key.
cbData
Specifies the length, in bytes, of the string pointed to by the lpData parameter, not including the terminating null character.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

If the key specified by the lpSubKey parameter does not exist, the RegSetValue function creates it.

Value lengths are limited by available memory. Long values (more than 2048 bytes) should be stored as files with the filenames stored in the registry. This helps the registry perform efficiently.

The key identified by the hKey parameter must have been opened with KEY_SET_VALUE access. To open the key, use the RegCreateKeyEx or RegOpenKeyEx function. If the ANSI version of this function is used (either by explicitly calling RegSetValueA or by not defining UNICODE before including the WINDOWS.H file), the lpData parameter must be an ANSI character string. The string is converted to Unicode before it is stored in the registry.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegCreateKeyEx, RegFlushKey, RegOpenKeyEx, RegQueryValue, RegQueryValueEx, RegSetValueEx


RegSetValueEx

The RegSetValueEx function sets the data and type of a specified value under a registry key.

LONG RegSetValueEx(
  HKEY hKey,           // handle to key to set value for
  LPCTSTR lpValueName, // name of the value to set
  DWORD Reserved,      // reserved
  DWORD dwType,        // flag for value type
  CONST BYTE *lpData,  // address of value data
  DWORD cbData         // size of value data
);

Parameters

hKey
Handle to a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT: HKEY_PERFORMANCE_DATA
Windows 95 and Windows 98: HKEY_DYN_DATA

lpValueName
Pointer to a string containing the name of the value to set. If a value with this name is not already present in the key, the function adds it to the key.

If lpValueName is NULL or an empty string, "", the function sets the type and data for the key's unnamed or default value.

Windows 95 and Windows 98: On Windows 95, the type of a key's default value is always REG_SZ, so the dwType parameter must specify REG_SZ for an unnamed value. On Windows 98, an unnamed value can be of any type.

Windows NT: Registry keys do not have default values, but they can have one unnamed value, which can be of any type.

Reserved
Reserved; must be zero.
dwType
Specifies the type of information to be stored as the value's data. This parameter can be one of the following values:
Value | Meaning
REG_BINARY | Binary data in any form.
REG_DWORD | A 32-bit number.
REG_DWORD_LITTLE_ENDIAN A 32-bit number in little-endian format. This is equivalent to REG_DWORD.

In little-endian format, a multi-byte value is stored in memory from the lowest byte (the "little end") to the highest byte. For example, the value 0x12345678 is stored as (0x78 0x56 0x34 0x12) in little-endian format.

Windows NT, Windows 95, and Windows 98 are designed to run on little-endian computer architectures. A user may connect to computers that have big-endian architectures, such as some UNIX systems.

REG_DWORD_BIG_ENDIAN A 32-bit number in big-endian format.

In big-endian format, a multi-byte value is stored in memory from the highest byte (the "big end") to the lowest byte. For example, the value 0x12345678 is stored as (0x12 0x34 0x56 0x78) in big-endian format.
REG_EXPAND_SZ | A null-terminated string that contains unexpanded references to environment variables (for example, "%PATH%"). It will be a Unicode or ANSI string depending on whether you use the Unicode or ANSI functions. To expand the environment variable references, use the ExpandEnvironmentStrings function.
REG_LINK | A Unicode symbolic link.
REG_MULTI_SZ | An array of null-terminated strings, terminated by two null characters.
REG_NONE | No defined value type.
REG_RESOURCE_LIST | A device-driver resource list.
REG_SZ A null-terminated string. It will be a Unicode or ANSI string depending on whether you use the Unicode or ANSI functions.

Do not use the REG_SZ type to store hard-coded paths to the system root directory or to the drive containing the system files. Instead, use the REG_EXPAND_SZ type with environment variables such as "%SystemRoot%". This ensures that the path will be up-to-date even if the user remaps the system drive to a different drive letter.

lpData
Pointer to a buffer containing the data to be stored with the specified value name.
cbData
Specifies the size, in bytes, of the information pointed to by the lpData parameter. If the data is of type REG_SZ, REG_EXPAND_SZ, or REG_MULTI_SZ, cbData must include the size of the terminating null character.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

Value lengths are limited by available memory. Long values (more than 2048 bytes) should be stored as files with the filenames stored in the registry. This helps the registry perform efficiently. Application elements such as icons, bitmaps, and executable files should be stored as files and not be placed in the registry.

The key identified by the hKey parameter must have been opened with KEY_SET_VALUE access. To open the key, use the RegCreateKeyEx or RegOpenKeyEx function.

If dwType is the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type and the ANSI version of this function is used (either by explicitly calling RegSetValueExA or by not defining UNICODE before including the WINDOWS.H file), the data pointed to by the lpData parameter must be an ANSI character string. The string is converted to Unicode before it is stored in the registry.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegCreateKeyEx, RegFlushKey, RegOpenKeyEx, RegQueryValue, RegQueryValueEx, RegSetValue


RegUnLoadKey

The RegUnLoadKey function unloads the specified key and subkeys from the registry.

LONG RegUnLoadKey(
  HKEY hKey,         // handle to open key
  LPCTSTR lpSubKey   // address of name of subkey to unload
);

Parameters

hKey
Specifies the key to be unloaded. This can be a predefined reserved handle value, or a handle returned by a call to RegConnectRegistry. The predefined reserved handle values are:

HKEY_LOCAL_MACHINE
HKEY_USERS

lpSubKey
Pointer to a null-terminated string containing the name of the subkey to be unloaded. The key referred to by the lpSubKey parameter must have been created by using the RegLoadKey function.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

This function removes a hive from the registry but does not modify the file containing the registry information. A hive is a discrete body of keys, subkeys, and values that is rooted at the top of the registry hierarchy.

Windows NT: The calling process must have the SE_RESTORE_NAME privilege. For more information about privileges, see Privileges.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Registry Overview, Registry Functions, RegConnectRegistry, RegDeleteKey, RegLoadKey, RegRestoreKey


WritePrivateProfileSection

The WritePrivateProfileSection function replaces the keys and values under the specified section in an initialization file.

This function is provided for compatibility with 16-bit Windows-based applications. Win32-based applications should store initialization information in the registry.

BOOL WritePrivateProfileSection(
  LPCTSTR lpAppName,  // pointer to string with section name
  LPCTSTR lpString,   // pointer to string with data
  LPCTSTR lpFileName  // pointer to string with filename
);

Parameters

lpAppName
Pointer to a null-terminated string containing the name of the section in which data is written. This section name is typically the name of the calling application.
lpString
Pointer to a buffer containing the new key names and associated values that are written to the named section.
lpFileName
Pointer to a null-terminated string containing the name of the initialization file. If this parameter does not contain a full path for the file, the function searches the Windows directory for the file. If the file does not exist and lpFileName does not contain a full path, the function creates the file in the Windows directory. The function does not create a file if lpFileName contains the full path and filename of a file that does not exist.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The data in the buffer pointed to by the lpString parameter consists of one or more null-terminated strings, followed by a final null character. Each string has the following form:

key=string

The WritePrivateProfileSection function is not case-sensitive; the string pointed to by the lpAppName parameter can be a combination of uppercase and lowercase letters.

If no section name matches the string pointed to by the lpAppName parameter, WritePrivateProfileSection creates the section at the end of the specified initialization file and initializes the new section with the specified key name and value pairs.

WritePrivateProfileSection deletes the existing keys and values for the named section and inserts the key names and values in the buffer pointed to by the lpString parameter. The function does not attempt to correlate old and new key names; if the new names appear in a different order from the old names, any comments associated with preexisting keys and values in the initialization file will probably be associated with incorrect keys and values.

This operation is atomic; no operations that read from or write to the specified initialization file are allowed while the information is being written.

Windows 95: Windows 95 keeps a cached version of WIN.INI to improve performance. If all three parameters are NULL, the function flushes the cache. The function always returns FALSE after flushing the cache, regardless of whether the flush succeeds or fails.

Windows NT: Windows NT maps most .INI file references to the registry, using the mapping defined under the following registry key:

HKEY_LOCAL_MACHINE\Software\Microsoft\
Windows NT\CurrentVersion\IniFileMapping

This mapping is likely if an application modifies system-component initialization files, such as CONTROL.INI, SYSTEM.INI, and WINFILE.INI. In this case, the WritePrivateProfileSection function writes information to the registry, not to the initialization file; the change in the storage location has no effect on the function's behavior.

The Win32 profile functions (Get/WriteProfile*, Get/WritePrivateProfile*) use the following steps to locate initialization information:

  1. Look in the registry for the name of the initialization file, say MYFILE.INI, under IniFileMapping:

    HKEY_LOCAL_MACHINE\Software\Microsoft\
    Windows NT\CurrentVersion\IniFileMapping\myfile.ini

  2. Look for the section name specified by lpAppName. This will be a named value under myfile.ini, or a subkey of myfile.ini, or will not exist.
  3. If the section name specified by lpAppName is a named value under myfile.ini, then that value specifies where in the registry you will find the keys for the section.
  4. If the section name specified by lpAppName is a subkey of myfile.ini, then named values under that subkey specify where in the registry you will find the keys for the section. If the key you are looking for does not exist as a named value, then there will be an unnamed value (shown as <No Name>) that specifies the default location in the registry where you will find the key.
  5. If the section name specified by lpAppName does not exist as a named value or as a subkey under myfile.ini, then there will be an unnamed value (shown as <No Name>) under myfile.ini that specifies the default location in the registry where you will find the keys for the section.
  6. If there is no subkey for MYFILE.INI, or if there is no entry for the section name, then look for the actual MYFILE.INI on the disk and read its contents.

When looking at values in the registry that specify other registry locations, there are several prefixes that change the behavior of the .INI file mapping:

  • ! - this character forces all writes to go both to the registry and to the .INI file on disk.
  • # - this character causes the registry value to be set to the value in the Windows 3.1 .INI file when a new user logs in for the first time after setup.
  • @ - this character prevents any reads from going to the .INI file on disk if the requested data is not found in the registry.
  • USR: - this prefix stands for HKEY_CURRENT_USER, and the text after the prefix is relative to that key.
  • SYS: - this prefix stands for HKEY_LOCAL_MACHINE\SOFTWARE, and the text after the prefix is relative to that key.

See Also

Registry Overview, Registry Functions, GetPrivateProfileSection, RegCreateKeyEx, RegSetValueEx, WriteProfileSection


WritePrivateProfileString

The WritePrivateProfileString function copies a string into the specified section of the specified initialization file.

This function is provided for compatibility with 16-bit Windows-based applications. WIn32-based applications should store initialization information in the registry.

BOOL WritePrivateProfileString(
  LPCTSTR lpAppName,  // pointer to section name
  LPCTSTR lpKeyName,  // pointer to key name
  LPCTSTR lpString,   // pointer to string to add
  LPCTSTR lpFileName  // pointer to initialization filename
);

Parameters

lpAppName
Pointer to a null-terminated string containing the name of the section to which the string will be copied. If the section does not exist, it is created. The name of the section is case-independent; the string can be any combination of uppercase and lowercase letters.
lpKeyName
Pointer to the null-terminated string containing the name of the key to be associated with a string. If the key does not exist in the specified section, it is created. If this parameter is NULL, the entire section, including all entries within the section, is deleted.
lpString
Pointer to a null-terminated string to be written to the file. If this parameter is NULL, the key pointed to by the lpKeyName parameter is deleted.

Windows 95: The system does not support the use of the TAB (\t) character as part of this parameter.

lpFileName
Pointer to a null-terminated string that names the initialization file.

Return Values

If the function successfully copies the string to the initialization file, the return value is nonzero.

If the function fails, or if it flushes the cached version of the most recently accessed initialization file, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows 95: Windows 95 keeps a cached version of WIN.INI to improve performance. If all three parameters are NULL, the function flushes the cache. The function always returns FALSE after flushing the cache, regardless of whether the flush succeeds or fails.

A section in the initialization file must have the following form:

[section]
key=string
      .
      .
      .

If the lpFileName parameter does not contain a full path and filename for the file, WritePrivateProfileString searches the Windows directory for the file. If the file does not exist, this function creates the file in the Windows directory.

If lpFileName contains a full path and filename and the file does not exist, WriteProfileString creates the file. The specified directory must already exist.

Windows NT: Windows NT maps most .INI file references to the registry, using the mapping defined under the following registry key:

HKEY_LOCAL_MACHINE\Software\Microsoft\
Windows NT\CurrentVersion\IniFileMapping

Windows NT keeps a cache for the IniFileMapping registry key. Calling WritePrivateProfileStringW with the value of all arguments set to NULL will cause Windows NT to refresh its cache of the IniFileMappingKey for the specified .INI file.

The Win32 profile functions (Get/WriteProfile*, Get/WritePrivateProfile*) use the following steps to locate initialization information:

  1. Look in the registry for the name of the initialization file, say MYFILE.INI, under IniFileMapping:

    HKEY_LOCAL_MACHINE\Software\Microsoft\
    Windows NT\CurrentVersion\IniFileMapping\myfile.ini

  2. Look for the section name specified by lpAppName. This will be a named value under myfile.ini, or a subkey of myfile.ini, or will not exist.
  3. If the section name specified by lpAppName is a named value under myfile.ini, then that value specifies where in the registry you will find the keys for the section.
  4. If the section name specified by lpAppName is a subkey of myfile.ini, then named values under that subkey specify where in the registry you will find the keys for the section. If the key you are looking for does not exist as a named value, then there will be an unnamed value (shown as <No Name>) that specifies the default location in the registry where you will find the key.
  5. If the section name specified by lpAppName does not exist as a named value or as a subkey under myfile.ini, then there will be an unnamed value (shown as <No Name>) under myfile.ini that specifies the default location in the registry where you will find the keys for the section.
  6. If there is no subkey for MYFILE.INI, or if there is no entry for the section name, then look for the actual MYFILE.INI on the disk and read its contents.

When looking at values in the registry that specify other registry locations, there are several prefixes that change the behavior of the .INI file mapping:

  • ! - this character forces all writes to go both to the registry and to the .INI file on disk.
  • # - this character causes the registry value to be set to the value in the Windows 3.1 .INI file when a new user logs in for the first time after setup.
  • @ - this character prevents any reads from going to the .INI file on disk if the requested data is not found in the registry.
  • USR: - this prefix stands for HKEY_CURRENT_USER, and the text after the prefix is relative to that key.
  • SYS: - this prefix stands for HKEY_LOCAL_MACHINE\SOFTWARE, and the text after the prefix is relative to that key.

An application using the WritePrivateProfileStringW function to enter .INI file information into the registry should follow these guidelines:

  • Ensure that no .INI file of the specified name exists on the system.
  • Ensure that there is a key entry in the registry that specifies the .INI file. This entry should be under the path HKEY_LOCAL_MACHINE\SOFTWARE \Microsoft\Windows NT\CurrentVersion\IniFileMapping.
  • Specify a value for that .INI file key entry that specifies a section. That is to say, an application must specify a section name, as it would appear within an .INI file or registry entry. Here is an example: [My Section].
  • For system files, specify SYS for an added value.
  • For application files, specify USR within the added value. Here is an example: "My Section: USR: App Name\Section". And, since USR indicates a mapping under HKEY_CURRENT_USER, the application should also create a key under HKEY_CURRENT_USER that specifies the application name listed in the added value. For the example just given, that would be "App Name".
  • After following the preceding steps, an application setup program should call WritePrivateProfileStringW with the first three parameters set to NULL, and the fourth parameter set to the INI filename. For example:
    WritePrivateProfileStringW( NULL, NULL, NULL, L"appname.ini" );
  • Such a call causes the mapping of an .INI file to the registry to take effect before the next system reboot. The system rereads the mapping information into shared memory. A user will not have to reboot their computer after installing an application in order to have future invocations of the application see the mapping of the .INI file to the registry.

The following sample code illustrates the preceding guidelines and is based on several assumptions:

  • There is an application named App Name.
  • That application uses an .INI file named APPNAME.INI.
  • There is a section in the .INI file that we want to look like this:
    [Section1]
  FirstKey = It all worked out okay.
  SecondKey = By golly, it works.
  ThirdKey = Another test.
  • The user will not have to reboot the system in order to have future invocations of the application see the mapping of the .INI file to the registry.

Here is the sample code :

// include files
#include <stdio.h>
#include <windows.h>

// a main function
main()

{
  // local variables
  CHAR inBuf[80];
  HKEY  hKey1, hKey2;
  DWORD  dwDisposition;
  LONG   lRetCode;

  // try to create the .INI file key
  lRetCode = RegCreateKeyEx ( HKEY_LOCAL_MACHINE,
                              "SOFTWARE\\Microsoft\\Windows NT
                               \\CurrentVersion\\IniFileMapping\\appname.ini",
                              0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE,
                              NULL, &hKey1,
                              &dwDisposition);

  // if we failed, note it, and leave
  if (lRetCode != ERROR_SUCCESS){
    printf ("Error in creating appname.ini key\n");
    return (0) ;
    }

  // try to set a section value
  lRetCode = RegSetValueEx ( hKey1,
                             "Section1",
                             0,
                             REG_SZ,
                             "USR:App Name\\Section1",
                             20);

  // if we failed, note it, and leave
  if (lRetCode != ERROR_SUCCESS) {
    printf ( "Error in setting Section1 value\n");
    return (0) ;
    }

  // try to create an App Name key
  lRetCode = RegCreateKeyEx ( HKEY_CURRENT_USER,
                              "App Name",
                              0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE,
                              NULL, &hKey2,
                              &dwDisposition);

  // if we failed, note it, and leave
  if (lRetCode != ERROR_SUCCESS) {
    printf ("Error in creating App Name key\n");
    return (0) ;
    }

  // force the system to re-read the mapping into shared memory
  //    so that future invocations of the application will see it
  //    without the user having to reboot the system
  WritePrivateProfileStringW( NULL, NULL, NULL, L"appname.ini" );

  // if we get this far, all has gone well
  // let's write some added values
  WritePrivateProfileString ("Section1", "FirstKey",
                             "It all worked out okay.", "appname.ini");
  WritePrivateProfileString ("Section1", "SecondKey",
                             "By golly, it works.", "appname.ini");
  WritePrivateProfileSection ("Section1", "ThirdKey = Another Test.",
                              "appname.ini");

  // let's test our work
  GetPrivateProfileString ("Section1", "FirstKey",
                           "Bogus Value: Get didn't work", inBuf, 80,
                           "appname.ini");
  printf ("%s", inBuf);

  // okay, we are outta here
  return(0);

}

See Also

Registry Overview, Registry Functions, GetPrivateProfileString, WriteProfileString


WritePrivateProfileStruct

The WritePrivateProfileStruct function copies data into the specified key in the given section of an initialization file. As it copies the data, the function calculates a checksum and appends it to the end of the data. The GetPrivateProfileStruct function uses the checksum to ensure the integrity of the data. This function is provided for compatibility with 16-bit Windows-based applications. Win32-based applications should store initialization information in the registry.

BOOL WritePrivateProfileStruct(
  LPCTSTR lpszSection,
                    // pointer to section name
  LPCTSTR lpszKey,  // pointer to key name
  LPVOID lpStruct,  // pointer to buffer that contains data to add
  UINT uSizeStruct, // size, in bytes, of the buffer
  LPCTSTR szFile    // pointer to initialization filename
);

Parameters

lpszSection
Pointer to a null-terminated string containing the name of the section to which the string will be copied. If the section does not exist, it is created. The name of the section is case independent, the string can be any combination of uppercase and lowercase letters.
lpszKey
Pointer to the null-terminated string containing the name of the key to be associated with a string. If the key does not exist in the specified section, it is created. If this parameter is NULL, the entire section, including all keys and entries within the section, is deleted.
lpStruct
Pointer to a buffer that contains the data to copy. If this parameter is NULL, the given key is deleted.
uSizeStruct
Specifies the size, in bytes, of the buffer pointed to by the lpStruct parameter.
szFile
Pointer to a null-terminated string that names the initialization file. If this parameter is NULL, the given information is copied into the WIN.INI file.

Return Values

If the function successfully copies the string to the initialization file, the return value is nonzero.

If the function fails, or if it flushes the cached version of the most recently accessed initialization file, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows 95: Windows 95 keeps a cached version of WIN.INI to improve performance. If all three parameters are NULL, the function flushes the cache. The function always returns FALSE after flushing the cache, regardless of whether the flush succeeds or fails.

A section in the initialization file must have the following form:

[section]
key=string
      .
      .
      .

If the szFile parameter does not contain a full path and filename for the file, WritePrivateProfileString searches the Windows directory for the file. If the file does not exist, this function creates the file in the Windows directory.

If szFile contains a full path and filename and the file does not exist, WriteProfileString creates the file. The specified directory must already exist.

Windows NT: The Win32 profile functions (Get/WriteProfile*, Get/WritePrivateProfile*) use the following steps to locate initialization information:

  1. Look in the registry for the name of the initialization file, say MYFILE.INI, under IniFileMapping:

    HKEY_LOCAL_MACHINE\Software\Microsoft\
    Windows NT\CurrentVersion\IniFileMapping\myfile.ini

  2. Look for the section name specified by lpAppName. This will be a named value under myfile.ini, or a subkey of myfile.ini, or will not exist.
  3. If the section name specified by lpAppName is a named value under myfile.ini, then that value specifies where in the registry you will find the keys for the section.
  4. If the section name specified by lpAppName is a subkey of myfile.ini, then named values under that subkey specify where in the registry you will find the keys for the section. If the key you are looking for does not exist as a named value, then there will be an unnamed value (shown as <No Name>) that specifies the default location in the registry where you will find the key.
  5. If the section name specified by lpAppName does not exist as a named value or as a subkey under myfile.ini, then there will be an unnamed value (shown as <No Name>) under myfile.ini that specifies the default location in the registry where you will find the keys for the section.
  6. If there is no subkey for MYFILE.INI, or if there is no entry for the section name, then look for the actual MYFILE.INI on the disk and read its contents.

When looking at values in the registry that specify other registry locations, there are several prefixes that change the behavior of the .INI file mapping:

  • ! - this character forces all writes to go both to the registry and to the .INI file on disk.
  • # - this character causes the registry value to be set to the value in the Windows 3.1 .INI file when a new user logs in for the first time after setup.
  • @ - this character prevents any reads from going to the .INI file on disk if the requested data is not found in the registry.
  • USR: - this prefix stands for HKEY_CURRENT_USER, and the text after the prefix is relative to that key.
  • SYS: - this prefix stands for HKEY_LOCAL_MACHINE\SOFTWARE, and the text after the prefix is relative to that key.

See Also

Registry Overview, Registry Functions, GetPrivateProfileString, WriteProfileString


WriteProfileSection

The WriteProfileSection function replaces the contents of the specified section in the WIN.INI file with the specified keys and values.

This function is provided for compatibility with 16-bit Windows applications. Win32-based applications should store initialization information in the registry.

BOOL WriteProfileSection(
  LPCTSTR lpAppName, // pointer to section name
  LPCTSTR lpString   // pointer to buffer with data
);

Parameters

lpAppName
Pointer to a null-terminated string containing the name of the section in which data is written. This section name is typically the name of the calling application.
lpString
Pointer to a buffer containing the new key names and associated values that are written to the named section.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows 95: If there is no section in WIN.INI that matches the specified section name, WriteProfileSection creates the section at the end of the file and initializes the new section with the key name and value pairs specified in the lpString parameter.

Keys and values in the lpString buffer consist of one or more null-terminated strings, followed by a final null character. Each string has the following form:

key=string

The WriteProfileSection function is not case-sensitive; the strings can be a combination of uppercase and lowercase letters.

WriteProfileSection deletes the existing keys and values for the named section and inserts the key names and values in the buffer pointed to by lpString. The function does not attempt to correlate old and new key names; if the new names appear in a different order from the old names, any comments associated with preexisting keys and values in the initialization file will probably be associated with incorrect keys and values.

This operation is atomic; no other operations that read from or write to the initialization file are allowed while the information is being written.

Windows NT: Windows NT maps most .INI file references to the registry, using the mapping defined under the following registry key:

HKEY_LOCAL_MACHINE\Software\Microsoft\
Windows NT\CurrentVersion\IniFileMapping

When the operation has been mapped, the WriteProfileSection function writes information to the registry, not to the initialization file; the change in the storage location has no effect on the function's behavior.

The Win32 profile functions (Get/WriteProfile*, Get/WritePrivateProfile*) use the following steps to locate initialization information:

  1. Look in the registry for the name of the initialization file, say MYFILE.INI, under IniFileMapping:

    HKEY_LOCAL_MACHINE\Software\Microsoft\
    Windows NT\CurrentVersion\IniFileMapping\myfile.ini

  2. Look for the section name specified by lpAppName. This will be a named value under myfile.ini, or a subkey of myfile.ini, or will not exist.
  3. If the section name specified by lpAppName is a named value under myfile.ini, then that value specifies where in the registry you will find the keys for the section.
  4. If the section name specified by lpAppName is a subkey of myfile.ini, then named values under that subkey specify where in the registry you will find the keys for the section. If the key you are looking for does not exist as a named value, then there will be an unnamed value (shown as <No Name>) that specifies the default location in the registry where you will find the key.
  5. If the section name specified by lpAppName does not exist as a named value or as a subkey under myfile.ini, then there will be an unnamed value (shown as <No Name>) under myfile.ini that specifies the default location in the registry where you will find the keys for the section.
  6. If there is no subkey for MYFILE.INI, or if there is no entry for the section name, then look for the actual MYFILE.INI on the disk and read its contents.

When looking at values in the registry that specify other registry locations, there are several prefixes that change the behavior of the .INI file mapping:

  • ! - this character forces all writes to go both to the registry and to the .INI file on disk.
  • # - this character causes the registry value to be set to the value in the Windows 3.1 .INI file when a new user logs in for the first time after setup.
  • @ - this character prevents any reads from going to the .INI file on disk if the requested data is not found in the registry.
  • USR: - this prefix stands for HKEY_CURRENT_USER, and the text after the prefix is relative to that key.
  • SYS: - this prefix stands for HKEY_LOCAL_MACHINE\SOFTWARE, and the text after the prefix is relative to that key.

See Also

Registry Overview, Registry Functions, GetProfileSection, WritePrivateProfileSection


WriteProfileString

The WriteProfileString function copies a string into the specified section of the WIN.INI file.

This function is provided for compatibility with 16-bit Windows-based applications. Win32-based applications should store initialization information in the registry.

BOOL WriteProfileString(
  LPCTSTR lpAppName, // pointer to section name
  LPCTSTR lpKeyName, // pointer to key name
  LPCTSTR lpString   // pointer to string to write
);

Parameters

lpAppName
Pointer to a null-terminated string that specifies the section to which the string is to be copied. If the section does not exist, it is created. The name of the section is not case-sensitive; the string can be any combination of uppercase and lowercase letters.
lpKeyName
Pointer to a null-terminated string containing the key to be associated with the string. If the key does not exist in the specified section, it is created. If this parameter is NULL, the entire section, including all entries in the section, is deleted.
lpString
Pointer to a null-terminated string to be written to the file. If this parameter is NULL, the key pointed to by the lpKeyName parameter is deleted.

Windows 95: The system does not support the use of the TAB (\t) character as part of this parameter.

Return Values

If the function successfully copies the string to the WIN.INI file, the return value is nonzero.

If the function fails, or if it flushes the cached version of WIN.INI, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows 95: Windows 95 keeps a cached version of WIN.INI to improve performance. If all three parameters are NULL, the function flushes the cache. The function always returns FALSE after flushing the cache, regardless of whether the flush succeeds or fails.

A section in the WIN.INI file must have the following form:

[section]
key=string
    .
    .
    .

Windows NT: Windows NT maps most .INI file references to the registry, using the mapping defined under the following registry key:

HKEY_LOCAL_MACHINE\Software\Microsoft\
Windows NT\CurrentVersion\IniFileMapping

When the operation has been mapped, the WriteProfileString function writes information to the registry, not to the initialization file; the change in the storage location has no effect on the function's behavior.

The Win32 profile functions (Get/WriteProfile*, Get/WritePrivateProfile*) use the following steps to locate initialization information:

  1. Look in the registry for the name of the initialization file, say MYFILE.INI, under IniFileMapping:

    HKEY_LOCAL_MACHINE\Software\Microsoft\
    Windows NT\CurrentVersion\IniFileMapping\myfile.ini

  2. Look for the section name specified by lpAppName. This will be a named value under myfile.ini, or a subkey of myfile.ini, or will not exist.
  3. If the section name specified by lpAppName is a named value under myfile.ini, then that value specifies where in the registry you will find the keys for the section.
  4. If the section name specified by lpAppName is a subkey of myfile.ini, then named values under that subkey specify where in the registry you will find the keys for the section. If the key you are looking for does not exist as a named value, then there will be an unnamed value (shown as <No Name>) that specifies the default location in the registry where you will find the key.
  5. If the section name specified by lpAppName does not exist as a named value or as a subkey under myfile.ini, then there will be an unnamed value (shown as <No Name>) under myfile.ini that specifies the default location in the registry where you will find the keys for the section.
  6. If there is no subkey for MYFILE.INI, or if there is no entry for the section name, then look for the actual MYFILE.INI on the disk and read its contents.

When looking at values in the registry that specify other registry locations, there are several prefixes that change the behavior of the .INI file mapping:

  • ! - this character forces all writes to go both to the registry and to the .INI file on disk.
  • # - this character causes the registry value to be set to the value in the Windows 3.1 .INI file when a new user logs in for the first time after setup.
  • @ - this character prevents any reads from going to the .INI file on disk if the requested data is not found in the registry.
  • USR: - this prefix stands for HKEY_CURRENT_USER, and the text after the prefix is relative to that key.
  • SYS: - this prefix stands for HKEY_LOCAL_MACHINE\SOFTWARE, and the text after the prefix is relative to that key.

See Also

Registry Overview, Registry Functions, GetProfileString, WritePrivateProfileString


Registry Structures

The following structure is used with the registry.

VALENT


VALENT

The VALENT structure contains information about a registry value. The RegQueryMultipleValues function uses this structure.

typedef struct value_ent {
    LPTSTR   ve_valuename;
    DWORD ve_valuelen;
    DWORD ve_valueptr;
    DWORD ve_type;
}VALENT;

Members

ve_valuename
Pointer to a null-terminated string. Before calling RegQueryMultipleValues, set this member to point to the name of a value to retrieve.
ve_valuelen
Specifies the size, in bytes, of the data pointed to by ve_valueptr.
ve_valueptr
Pointer to the data for the value entry. This is a pointer to the value's data returned in the lpValueBuf buffer filled in by RegQueryMultipleValues.
ve_type
Specifies the type code for the value entry. The type code can be one of the following values:
Value | Meaning
REG_BINARY | Binary data in any form.
REG_DWORD | A 32-bit number.
REG_DWORD_LITTLE_ENDIAN A 32-bit number in little-endian format. This is equivalent to REG_DWORD.

In little-endian format, a multi-byte value is stored in memory from the lowest byte (the "little end") to the highest byte. For example, the value 0x12345678 is stored as (0x78 0x56 0x34 0x12) in little-endian format.

Windows NT, Windows 95, and Windows 98 are designed to run on little-endian computer architectures. A user may connect to computers that have big-endian architectures, such as some UNIX systems.

REG_DWORD_BIG_ENDIAN A 32-bit number in big-endian format.

In big-endian format, a multi-byte value is stored in memory from the highest byte (the "big end") to the lowest byte. For example, the value 0x12345678 is stored as (0x12 0x34 0x56 0x78) in big-endian format.
REG_EXPAND_SZ | A null-terminated string that contains unexpanded references to environment variables (for example, "%PATH%"). It will be a Unicode or ANSI string depending on whether you use the Unicode or ANSI functions. To expand the environment variable references, use the ExpandEnvironmentStrings function.
REG_LINK | A Unicode symbolic link.
REG_MULTI_SZ | An array of null-terminated strings, terminated by two null characters.
REG_NONE | No defined value type.
REG_RESOURCE_LIST | A device-driver resource list.
REG_SZ | A null-terminated string. It will be a Unicode or ANSI string, depending on whether you use the Unicode or ANSI functions.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Registry Overview, Registry Structures, RegQueryMultipleValues


String Manipulation

The overview describes the string manipulation functions and explains how to use them in your Win32-based applications.


About String Manipulation

The string manipulation functions give Win32-based applications the means to copy, compare, sort, format, and convert character strings as well as the means to determine the character type of each character in a string. All the string manipulation functions support the single-byte, double-byte, and Unicode character sets if these character sets are supported by the operating system on which the application is run.


Win32 String Functions

Many Win32 string functions duplicate or enhance familiar string-manipulation functions from the standard C run-time (CRT) library. Many of the enhancements enable Win32 functions to work with Unicode or extended character sets. For example, the functions in the following table are identical to standard C functions except that the Win32 functions are enhanced for use with Unicode.

Win32 Function | Standard CRT function
lstrcat | strcat
lstrcmp | strcmp
lstrcmpi | strcmpi
lstrcpy | strcpy
lstrlen | strlen

The strlen function, for example, always returns the number of bytes in a string, but the lstrlen function returns the number of characters, regardless of whether the characters are 1 or 2 bytes wide.

The following Win32 functions differ from standard C functions such as tolower and toupper in that they operate on any character in a character set. By using the CharLower function, for example, a Win32-based application can convert an uppercase U with an umlaut (Ü) to lowercase (ü). For more information about character sets, see Single-byte Character Sets.

Function | Description
CharLower | Converts a character or string to lowercase.
CharLowerBuff | Converts a character string to lowercase.
CharNext | Moves to the next character in a string.
CharPrev | Moves to the preceding character in a string.
CharUpper | Converts a character or string to uppercase.
CharUpperBuff | Converts a string to uppercase.

The following Win32 functions make determinations about a character based on the semantics of the language selected by the user. These functions are Unicode enabled.

Function | Description
IsCharAlpha | Determines whether a character is alphabetic.
IsCharAlphaNumeric | Determines whether a character is alphanumeric.
IsCharLower | Determines whether a character is lowercase.
IsCharUpper | Determines whether a character is uppercase.

The wsprintf and wvsprintf functions are extensions to the standard C functions sprintf and vsprintf. The Win32 versions support format specifications unique to Unicode.


String Resources

An application that maintains character strings in resources can be translated into new languages with minimum effort. Instead of searching for strings in the source modules, you can simply translate the strings in the resource file and relink the application. In addition, using string resources simplifies creation of Unicode and non-Unicode versions of the application from the same source files.

The LoadString function loads a string resource from an application's executable file. The FormatMessage function loads a string resource and interprets formatting options that may be embedded in the string.

Win32-based resources in binary form are stored in Unicode format. When loading resources, applications can use the Unicode version of the resource functions (LoadStringW, for example) to obtain resources as Unicode data.


String Manipulation Reference

The following elements are used with string manipulation.

  • String Manipulation Functions


String Manipulation Functions

The following functions are used with string manipulation.

CharLower
CharLowerBuff
CharNext
CharNextExA
CharPrev
CharPrevExA
CharToOem
CharToOemBuff
CharUpper
CharUpperBuff
CompareString
FoldString
FormatMessage
GetStringTypeA
GetStringTypeEx
GetStringTypeW
IsCharAlpha
IsCharAlphaNumeric
IsCharLower
IsCharUpper
LoadString
lstrcat
lstrcmp
lstrcmpi
lstrcpy
lstrcpyn
lstrlen
MultiByteToWideChar
OemToChar
OemToCharBuff
WideCharToMultiByte
wsprintf
wvsprintf

Obsolete Functions

AnsiLower
AnsiLowerBuff
AnsiNext
AnsiPrev
AnsiToOem
AnsiToOemBuff
AnsiUpper
AnsiUpperBuff
OemToAnsi
OemToAnsiBuff


AnsiLower

The AnsiLower function is obsolete.

For compatibility with 16-bit versions of Windows, this function is implemented as a macro that calls the CharLower function, which should be used for new Win32-based applications.

See Also

String Manipulation Overview, String Manipulation Functions


AnsiLowerBuff

The AnsiLowerBuff function is obsolete.

For compatibility with 16-bit versions of Windows, this function is implemented as a macro that calls the CharLowerBuff function, which should be used for new Win32-based applications.

See Also

String Manipulation Overview, String Manipulation Functions


AnsiNext

The AnsiNext function is obsolete.

For compatibility with 16-bit versions of Windows, this function is implemented as a macro that calls the CharNext function, which should be used for new Win32-based applications.

See Also

String Manipulation Overview, String Manipulation Functions


AnsiPrev

The AnsiPrev function is obsolete.

For compatibility with 16-bit versions of Windows, this function is implemented as a macro that calls the CharPrev function, which should be used for new Win32-based applications.

See Also

String Manipulation Overview, String Manipulation Functions


AnsiToOem

The AnsiToOem function is obsolete.

For compatibility with 16-bit versions of Windows, this function is implemented as a macro that calls the CharToOem function, which should be used for new Win32-based applications.

See Also

String Manipulation Overview, String Manipulation Functions


AnsiToOemBuff

The AnsiToOemBuff function is obsolete.

For compatibility with 16-bit versions of Windows, this function is implemented as a macro that calls the CharToOemBuff function, which should be used for new Win32-based applications.

See Also

String Manipulation Overview, String Manipulation Functions


AnsiUpper

The AnsiUpper function is obsolete.

For compatibility with 16-bit versions of Windows, this function is implemented as a macro that calls the CharUpper function, which should be used for new Win32-based applications.

See Also

String Manipulation Overview, String Manipulation Functions


AnsiUpperBuff

The AnsiUpperBuff function is obsolete.

For compatibility with 16-bit versions of Windows, this function is implemented as a macro that calls the CharUpperBuff function, which should be used for new Win32-based applications.

See Also

String Manipulation Overview, String Manipulation Functions


CharLower

The CharLower function converts a character string or a single character to lowercase. If the operand is a character string, the function converts the characters in place.

LPTSTR CharLower(
  LPTSTR lpsz   // single character or pointer to string
);

Parameters

lpsz
Pointer to a null-terminated string or specifies a single character. If the high-order word of this parameter is zero, the low-order word must contain a single character to be converted.

Return Values

If the operand is a character string, the function returns a pointer to the converted string. Since the string is converted in place, the return value is equal to lpsz.

If the operand is a single character, the return value is a 32-bit value whose high-order word is zero, and low-order word contains the converted character.

There is no indication of success or failure. Failure is rare. There is no extended error information for this function; do not call GetLastError.

Remarks

Windows NT: To make the conversion, the function uses the language driver for the current language selected by the user at setup or by using the Control Panel. If no language has been selected, Windows NT completes the conversion by using internal default mapping. The conversion is made based on the code page associated with the process locale.

Windows 95: The function makes the conversion based on the information associated with the user's default locale, which is the locale selected by the user at setup or by using the Control Panel. Windows 95 does not have language drivers.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, CharLowerBuff, CharUpper, CharUpperBuff


CharLowerBuff

The CharLowerBuff function converts uppercase characters in a buffer to lowercase characters. The function converts the characters in place.

DWORD CharLowerBuff(
  LPTSTR lpsz,      // pointer to buffer containing characters to
                    // process
  DWORD cchLength   // number of bytes or characters to process
);

Parameters

lpsz
Pointer to a buffer containing one or more characters to process.
cchLength
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the buffer pointed to by lpsz.

The function examines each character, and converts uppercase characters to lowercase characters. The function examines the number of bytes or characters indicated by cchLength, even if one or more characters are null characters.

Return Values

The return value is the number of bytes (ANSI version) or characters (Unicode version) processed. For example, if CharLowerBuff("Acme of Operating Systems", 10) succeeds, the return value is 10.

Remarks

Windows NT: To make the conversion, the function uses the language driver for the current language selected by the user at setup or by using the Control Panel. If no language has been selected, Windows NT completes the conversion by using internal default mapping. The conversion is made based on the code page associated with the process locale.

Windows 95: The function makes the conversion based on the information associated with the user's default locale, which is the locale selected by the user at setup or by using the Control Panel. Windows 95 does not have language drivers.

Windows CE: Windows CE supports only the Unicode version of this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, CharLower, CharUpper, CharUpperBuff


CharNext

The CharNext function returns a pointer to the next character in a string.

LPTSTR CharNext(
  LPCTSTR lpsz   // pointer to current character
);

Parameters

lpsz
Pointer to a character in a null-terminated string.

Return Values

The return value is a pointer to the next character in the string, or to the terminating null character if at the end of the string.

If lpsz points to the terminating null character, the return value is equal to lpsz.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, CharNextExA, CharPrev


CharNextExA

The CharNextExA function retrieves the pointer to the next character in a string. This function can handle strings consisting of either single- or multi-byte characters.

LPSTR CharNextExA(
  WORD CodePage,          // identifier of the code page
  LPCSTR lpCurrentChar,   // pointer to current character
  DWORD dwFlags           // reserved; must be zero
);

Parameters

CodePage
Identifier of the code page to use to check lead-byte ranges. Can be one of the code-page values provided in the "Code-Page Identifiers" table in Unicode and Character Set Constants or one of the following predefined values:
Value | Meaning
0 | Use system default ANSI code page.
CP_ACP | Use system default ANSI code page.
CP_OEMCP | Use system default OEM code page.

lpCurrentChar
Pointer to a character in a null-terminated string.
dwFlags
Reserved; must be zero.

Return Values

The return value is a pointer to the next character in the string, or to the terminating null character if at the end of the string.

If lpCurrentChar points to the terminating null character, the return value is equal to lpCurrentChar.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

String Manipulation Overview, String Manipulation Functions, CharNext, CharPrevExA


CharPrev

The CharPrev function returns a pointer to the preceding character in a string.

LPTSTR CharPrev(
  LPCTSTR lpszStart,    // pointer to first character
  LPCTSTR lpszCurrent   // pointer to current character
);

Parameters

lpszStart
Pointer to the beginning of the string.
lpszCurrent
Pointer to a character in a null-terminated string.

Return Values

The return value is a pointer to the preceding character in the string, or to the first character in the string if the lpszCurrent parameter equals the lpszStart parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.01 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, CharNext, CharPrevExA


CharPrevExA

The CharPrevExA function retrieves the pointer to the preceding character in a string. This function can handle strings consisting of either single- or multi-byte characters.

LPSTR CharPrevExA(
  WORD CodePage,          // identifier of code page
  LPCSTR lpStart,         // pointer to first character
  LPCSTR lpCurrentChar,   // pointer to current character
  DWORD dwFlags           // reserved; must be zero
);

Parameters

CodePage
Identifier of the code page to use to check lead-byte ranges. Can be one of the code-page values provided in the "Code-Page Identifiers" table in Unicode and Character Set Constants or one of the following predefined values:
Value | Meaning
0 | Use system default ANSI code page.
CP_ACP | Use system default ANSI code page.
CP_OEMCP | Use system default OEM code page.

lpStart
Pointer to the beginning of the string.
lpCurrentChar
Pointer to a character in a null-terminated string.
dwFlags
Reserved; must be zero.

Return Values

The return value is a pointer to the preceding character in the string, or to the first character in the string if the lpCurrentChar parameter equals the lpStart parameter.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

String Manipulation Overview, String Manipulation Functions, CharNextExA, CharPrev


CharToOem

The CharToOem function translates a string into the OEM-defined character set. (OEM stands for original equipment manufacturer.)

BOOL CharToOem(
  LPCTSTR lpszSrc,  // pointer to string to translate
  LPSTR lpszDst     // pointer to translated string
);

Parameters

lpszSrc
Pointer to the null-terminated string to translate.
lpszDst
Pointer to the buffer for the translated string. If the CharToOem function is being used as an ANSI function, the string can be translated in place by setting the lpszDst parameter to the same address as the lpszSrc parameter. This cannot be done if CharToOem is being used as a wide-character function.

Return Values

The return value is always nonzero.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, CharToOemBuff, OemToChar, OemToCharBuff


CharToOemBuff

The CharToOemBuff function translates a specified number of characters in a string into the OEM-defined character set. (OEM stands for original equipment manufacturer.)

BOOL CharToOemBuff(
  LPCTSTR lpszSrc,    // pointer to string to translate
  LPSTR lpszDst,      // pointer to translated string
  DWORD cchDstLength  // length of string to translate, in characters
);

Parameters

lpszSrc
Pointer to the null-terminated string to translate.
lpszDst
Pointer to the buffer for the translated string. If the CharToOemBuff function is being used as an ANSI function, the string can be translated in place by setting the lpszDst parameter to the same address as the lpszSrc parameter. This cannot be done if CharToOemBuff is being used as a wide-character function.
cchDstLength
Specifies the number of characters to translate in the string identified by the lpszSrc parameter.

Return Values

The return value is always nonzero.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, CharToOem, OemToChar, OemToCharBuff


CharUpper

The CharUpper function converts a character string or a single character to uppercase. If the operand is a character string, the function converts the characters in place.

LPTSTR CharUpper(
  LPTSTR lpsz   // single character or pointer to string
);

Parameters

lpsz
Pointer to a null-terminated string or specifies a single character. If the high-order word of this parameter is zero, the low-order word must contain a single character to be converted.

Return Values

If the operand is a character string, the function returns a pointer to the converted string. Since the string is converted in place, the return value is equal to lpsz.

If the operand is a single character, the return value is a 32-bit value whose high-order word is zero, and low-order word contains the converted character.

There is no indication of success or failure. Failure is rare. There is no extended error information for this function; do no call GetLastError.

Remarks

Windows NT: To make the conversion, the function uses the language driver for the current language selected by the user at setup or by using the Control Panel. If no language has been selected, Windows NT completes the conversion by using internal default mapping. The conversion is made based on the code page associated with the process locale.

Windows 95: The function makes the conversion based on the information associated with the user's default locale, which is the locale selected by the user at setup or by using the Control Panel. Windows 95 does not have language drivers.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, CharLower, CharLowerBuff, CharUpperBuff


CharUpperBuff

The CharUpperBuff function converts lowercase characters in a buffer to uppercase characters. The function converts the characters in place.

DWORD CharUpperBuff(
  LPTSTR lpsz,      // pointer to buffer containing characters to process
  DWORD cchLength   // number of characters to process
);

Parameters

lpsz
Pointer to a buffer containing one or more characters to process.
cchLength
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the buffer pointed to by lpsz.

The function examines each character, and converts lowercase characters to uppercase characters. The function examines the number of bytes or characters indicated by cchLength, even if one or more characters are null characters.

Return Values

The return value is the number of bytes (ANSI version) or characters (Unicode version) processed.

For example, if CharUpperBuff("Zenith of API Sets", 10) succeeds, the return value is 10.

Remarks

Windows NT: To make the conversion, the function uses the language driver for the current language selected by the user at setup or by using the Control Panel. If no language has been selected, Windows NT completes the conversion by using internal default mapping. The conversion is made based on the code page associated with the process locale.

Windows 95: The function makes the conversion based on the information associated with the user's default locale, which is the locale selected by the user at setup or by using the Control Panel. Windows 95 does not have language drivers.

Windows CE: Windows CE supports only the Unicode version of this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, CharLower, CharLowerBuff, CharUpper


CompareString

The CompareString function compares two character strings, using the locale specified by the given identifier as the basis for the comparison.

int CompareString(
  LCID Locale,       // locale identifier
  DWORD dwCmpFlags,  // comparison-style options
  LPCTSTR lpString1, // pointer to first string
  int cchCount1,     // size, in bytes or characters, of first string
  LPCTSTR lpString2, // pointer to second string
  int cchCount2      // size, in bytes or characters, of second string
);

Parameters

Locale
Specifies the locale used for the comparison. This parameter can be one of the following predefined locale identifiers:
Value | Meaning
LOCALE_SYSTEM_DEFAULT | The system's default locale.
LOCALE_USER_DEFAULT | The current user's default locale.

This parameter can also be a locale identifier created by the MAKELCID macro.

dwCmpFlags
A set of flags that indicate how the function compares the two strings. By default, these flags are not set. This parameter can specify zero to get the default behavior, or it can be any combination of the following values:
Value | Meaning
NORM_IGNORECASE | Ignore case.
NORM_IGNOREKANATYPE | Do not differentiate between Hiragana and Katakana characters. Corresponding Hiragana and Katakana characters compare as equal.
NORM_IGNORENONSPACE | Ignore nonspacing characters.
NORM_IGNORESYMBOLS | Ignore symbols.
NORM_IGNOREWIDTH | Do not differentiate between a single-byte character and the same character as a double-byte character.
SORT_STRINGSORT | Treat punctuation the same as symbols.

lpString1
Pointer to the first string to be compared.
cchCount1
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the string pointed to by the lpString1 parameter. If this parameter is – 1, the string is assumed to be null terminated and the length is calculated automatically.
lpString2
Pointer to the second string to be compared.
cchCount2
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the string pointed to by the lpString2 parameter. If this parameter is – 1, the string is assumed to be null terminated and the length is calculated automatically.

Return Values

If the function succeeds, the return value is one of the following values:

Value | Meaning
CSTR_LESS_THAN | The string pointed to by the lpString1 parameter is less in lexical value than the string pointed to by the lpString2 parameter.
CSTR_EQUAL | The string pointed to by lpString1 is equal in lexical value to the string pointed to by lpString2.
CSTR_GREATER_THAN | The string pointed to by lpString1 is greater in lexical value than the string pointed to by lpString2.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER

Remarks

Notice that if the return value is 2, the two strings are "equal" in the collation sense, though not necessarily identical.

To maintain the C run-time convention of comparing strings, the value 2 can be subtracted from a nonzero return value. The meaning of < 0, ==0 and > 0 is then consistent with the C run times.

If the two strings are of different lengths, they are compared up to the length of the shortest one. If they are equal to that point, then the return value will indicate that the longer string is greater. For more information about locale identifiers, see Locale Identifiers.

Typically, strings are compared using what is called a "word sort" technique. In a word sort, all punctuation marks and other nonalphanumeric characters, except for the hyphen and the apostrophe, come before any alphanumeric character. The hyphen and the apostrophe are treated differently than the other nonalphanumeric symbols, in order to ensure that words such as "coop" and "co-op" stay together within a sorted list.

If the SORT_STRINGSORT flag is specified, strings are compared using what is called a "string sort" technique. In a string sort, the hyphen and apostrophe are treated just like any other nonalphanumeric symbols: they come before the alphanumeric symbols.

The following table shows a list of words sorted both ways:

Word Sort | String Sort | Word Sort | String Sort
billet | bill's | t-ant | t-ant
bills | billet | tanya | t-aria
bill's | bills | t-aria | tanya
cannot | can't | sued | sue's
cant | cannot | sues | sued
can't | cant | sue's | sues
con | co-op | went | we're
coop | con | were | went
co-op | coop | we're | were

The lstrcmp and lstrcmpi functions use a word sort. The CompareString and LCMapString functions default to using a word sort, but use a string sort if their caller sets the SORT_STRINGSORT flag.

The CompareString function is optimized to run at the highest speed when dwCmpFlags is set to 0 or NORM_IGNORECASE, and cchCount1 and cchCount2 have the value -1.

The CompareString function ignores Arabic Kashidas during the comparison. Thus, if two strings are identical save for the presence of Kashidas, CompareString returns a value of 2; the strings are considered "equal" in the collation sense, though they are not necessarily identical.

Windows CE: Windows CE does not support the ANSI version of this function.

Windows CE does not support the following values for the dwCmpFlags parameter:

NORM_IGNOREKANATYPE

NORM_IGNORENONSPACE

NORM_IGNORESYMBOLS

NORM_IGNOREWIDTH

The dwCmpflags parameter always includes the SORT_STRINGSORT value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, FoldString, GetSystemDefaultLCID, GetUserDefaultLCID, LCMapString, lstrcmp, lstrcmpi, MAKELCID


FoldString

The FoldString function maps one string to another, performing a specified transformation option.

int FoldString(
  DWORD dwMapFlags,  // mapping transformation options
  LPCTSTR lpSrcStr,  // pointer to source string
  int cchSrc,        // size of source string, in bytes or characters
  LPTSTR lpDestStr,  // pointer to destination buffer
  int cchDest        // size of destination buffer, in bytes or characters
);

Parameters

dwMapFlags
A set of bit flags that indicate the type of transformation to be used during mapping. This value can be a combination of the following bit-flag constants:
Option | Meaning
MAP_FOLDCZONE | Fold compatibility zone characters into standard Unicode equivalents. For information about compatibility zone characters, see the following Remarks section.
MAP_FOLDDIGITS | Map all digits to Unicode characters 0 through 9.
MAP_PRECOMPOSED | Map accented characters to precomposed characters, in which the accent and base character are combined into a single character value. This value cannot be combined with MAP_COMPOSITE.
MAP_COMPOSITE | Map accented characters to composite characters, in which the accent and base character are represented by two character values. This value cannot be combined with MAP_PRECOMPOSED.
MAP_EXPAND_LIGATURES | Expand all ligature characters so that they are represented by their two-character equivalent. For example, the ligature 'æ' expands to the two characters 'a' and 'e'. This value cannot be combined with MAP_PRECOMPOSED or MAP_COMPOSITE.

lpSrcStr
Pointer to the string to be mapped.
cchSrc
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the lpSrcStr buffer. If cchSrc is –1, lpSrcStr is assumed to be null-terminated, and the length is calculated automatically.
lpDestStr
Pointer to the buffer to store the mapped string.
cchDest
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the lpDestStr buffer. If cchDest is zero, the function returns the number of bytes or characters required to hold the mapped string, and the buffer pointed to by lpDestStr is not used.

Return Values

If the function succeeds, the return value is the number of bytes (ANSI version) or characters (Unicode version) written to the destination buffer, or if the cchDest parameter is zero, the number of bytes or characters required to hold the mapped string.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INSUFFICIENT_BUFFER
ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER

Remarks

The mapped string is null-terminated if the source string is null-terminated.

The lpSrcStr and lpDestStr pointers must not be the same. If they are the same, the function fails and GetLastError returns ERROR_INVALID_PARAMETER.

The compatibility zone in Unicode consists of characters in the range 0xF900 through 0xFFEF that are assigned to characters from other character-encoding standards but are actually variants of characters that are already in Unicode. The compatibility zone is used to support round-trip mapping to these standards. Applications can use the MAP_FOLDCZONE flag to avoid supporting the duplication of characters in the compatibility zone.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, LCMapString, CompareString


FormatMessage

The FormatMessage function formats a message string. The function requires a message definition as input. The message definition can come from a buffer passed into the function. It can come from a message table resource in an already-loaded module. Or the caller can ask the function to search the system's message table resource(s) for the message definition. The function finds the message definition in a message table resource based on a message identifier and a language identifier. The function copies the formatted message text to an output buffer, processing any embedded insert sequences if requested.

DWORD FormatMessage(
  DWORD dwFlags,      // source and processing options
  LPCVOID lpSource,   // pointer to  message source
  DWORD dwMessageId,  // requested message identifier
  DWORD dwLanguageId, // language identifier for requested message
  LPTSTR lpBuffer,    // pointer to message buffer
  DWORD nSize,        // maximum size of message buffer
  va_list *Arguments  // pointer to array of message inserts
);

Parameters

dwFlags
Contains a set of bit flags that specify aspects of the formatting process and how to interpret the lpSource parameter. The low-order byte of dwFlags specifies how the function handles line breaks in the output buffer. The low-order byte can also specify the maximum width of a formatted output line.

You can specify a combination of the following bit flags:
Value Meaning
FORMAT_MESSAGE_ALLOCATE_BUFFER
Specifies that the lpBuffer parameter is a pointer to a PVOID pointer, and that the nSize parameter specifies the minimum number of bytes (ANSI version) or characters (Unicode version) to allocate for an output message buffer. The function allocates a buffer large enough to hold the formatted message, and places a pointer to the allocated buffer at the address specified by lpBuffer. The caller should use the LocalFree function to free the buffer when it is no longer needed.
FORMAT_MESSAGE_IGNORE_INSERTS
Specifies that insert sequences in the message definition are to be ignored and passed through to the output buffer unchanged. This flag is useful for fetching a message for later formatting. If this flag is set, the Arguments parameter is ignored.
FORMAT_MESSAGE_FROM_STRING
Specifies that lpSource is a pointer to a null-terminated message definition. The message definition may contain insert sequences, just as the message text in a message table resource may. Cannot be used with FORMAT_MESSAGE_FROM_HMODULE or FORMAT_MESSAGE_FROM_SYSTEM.
FORMAT_MESSAGE_FROM_HMODULE
Specifies that lpSource is a module handle containing the message-table resource(s) to search. If this lpSource handle is NULL, the current process's application image file will be searched. Cannot be used with FORMAT_MESSAGE_FROM_STRING.
FORMAT_MESSAGE_FROM_SYSTEM
Specifies that the function should search the system message-table resource(s) for the requested message. If this flag is specified with FORMAT_MESSAGE_FROM_HMODULE, the function searches the system message table if the message is not found in the module specified by lpSource. Cannot be used with FORMAT_MESSAGE_FROM_STRING.

If this flag is specified, an application can pass the result of the GetLastError function to retrieve the message text for a system-defined error.
FORMAT_MESSAGE_ARGUMENT_ARRAY
Specifies that the Arguments parameter is not a va_list structure, but instead is just a pointer to an array of 32-bit values that represent the arguments.

The low-order byte of dwFlags can specify the maximum width of a formatted output line. Use the FORMAT_MESSAGE_MAX_WIDTH_MASK constant and bitwise Boolean operations to set and retrieve this maximum width value.

The following table shows how FormatMessage interprets the value of the low-order byte.
Value | Meaning
0 | There are no output line width restrictions. The function stores line breaks that are in the message definition text into the output buffer.
A nonzero value other than FORMAT_MESSAGE_MAX_WIDTH_MASK | The nonzero value is the maximum number of characters in an output line. The function ignores regular line breaks in the message definition text. The function never splits a string delimited by white space across a line break. The function stores hard-coded line breaks in the message definition text into the output buffer. Hard-coded line breaks are coded with the %n escape sequence.
FORMAT_MESSAGE_MAX_WIDTH_MASK | The function ignores regular line breaks in the message definition text. The function stores hard-coded line breaks in the message definition text into the output buffer. The function generates no new line breaks.

lpSource
Specifies the location of the message definition. The type of this parameter depends upon the settings in the dwFlags parameter.
dwFlags Setting | Parameter Type
FORMAT_MESSAGE_FROM_HMODULE | lpSource is an hModule of the module that contains the message table to search.
FORMAT_MESSAGE_FROM_STRING | lpSource is an LPTSTR that points to unformatted message text. It will be scanned for inserts and formatted accordingly.

If neither of these flags is set in dwFlags, then lpSource is ignored.

dwMessageId
Specifies the 32-bit message identifier for the requested message. This parameter is ignored if dwFlags includes FORMAT_MESSAGE_FROM_STRING.
dwLanguageId
Specifies the 32-bit language identifier for the requested message. This parameter is ignored if dwFlags includes FORMAT_MESSAGE_FROM_STRING.

If you pass a specific LANGID in this parameter, FormatMessage will return a message for that LANGID only. If the function cannot find a message for that LANGID, it returns ERROR_RESOURCE_LANG_NOT_FOUND. If you pass in zero, FormatMessage looks for a message for LANGIDs in the following order:

  1. Language neutral
  2. Thread LANGID, based on the thread's locale value
  3. User default LANGID, based on the user's default locale value
  4. System default LANGID, based on the system default locale value
  5. US English

If FormatMessage doesn't find a message for any of the preceding LANGIDs, it returns any language message string that is present. If that fails, it returns ERROR_RESOURCE_LANG_NOT_FOUND.

lpBuffer
Pointer to a buffer for the formatted (and null-terminated) message. If dwFlags includes FORMAT_MESSAGE_ALLOCATE_BUFFER, the function allocates a buffer using the LocalAlloc function, and places the pointer to the buffer at the address specified in lpBuffer.
nSize
If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag is not set, this parameter specifies the maximum number of bytes (ANSI version) or characters (Unicode version) that can be stored in the output buffer. If FORMAT_MESSAGE_ALLOCATE_BUFFER is set, this parameter specifies the minimum number of bytes or characters to allocate for an output buffer.
Arguments
Pointer to an array of 32-bit values that are used as insert values in the formatted message. A %1 in the format string indicates the first value in the Arguments array; a %2 indicates the second argument; and so on.

The interpretation of each 32-bit value depends on the formatting information associated with the insert in the message definition. The default is to treat each value as a pointer to a null-terminated string.

By default, the Arguments parameter is of type va_list*, which is a language- and implementation-specific data type for describing a variable number of arguments. If you do not have a pointer of type va_list*, then specify the FORMAT_MESSAGE_ARGUMENT_ARRAY flag and pass a pointer to an array of 32-bit values; those values are input to the message formatted as the insert values. Each insert must have a corresponding element in the array.

Windows 95: No single insertion string may exceed 1023 characters in length.

Return Values

If the function succeeds, the return value is the number of bytes (ANSI version) or characters (Unicode version) stored in the output buffer, excluding the terminating null character.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The FormatMessage function can be used to obtain error message strings for the system error codes returned by GetLastError, as shown in the following sample code.

LPVOID lpMsgBuf;
FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER |
    FORMAT_MESSAGE_FROM_SYSTEM |
    FORMAT_MESSAGE_IGNORE_INSERTS,
    NULL,
    GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    (LPTSTR) &lpMsgBuf,
    0,
    NULL
);
// Process any inserts in lpMsgBuf.
// ...
// Display the string.
MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );

Within the message text, several escape sequences are supported for dynamically formatting the message. These escape sequences and their meanings are shown in the following table. All escape sequences start with the percent character (%).

Escape Sequence | Meaning
%0 | Terminates a message text line without a trailing newline character. This escape sequence can be used to build up long lines or to terminate the message itself without a trailing newline character. It is useful for prompt messages.
%n!printf format string! | Identifies an insert. The value of n can be in the range 1 through 99. The printf format string (which must be bracketed by exclamation marks) is optional and defaults to !s! if not specified.
 | The printf format string can contain the * specifier for either the precision or the width component. If * is specified for one component, the FormatMessage function uses insert %n+1; it uses %n+2 if * is specified for both components.
 | Floating-point printf format specifiers — e, E, f, and g — are not supported. The workaround is to to use the sprintf function to format the floating-point number into a temporary buffer, then use that buffer as the insert string.

Any other nondigit character following a percent character is formatted in the output message without the percent character. Following are some examples:

Format string | Resulting output
%% | A single percent sign in the formatted message text.
%n | A hard line break when the format string occurs at the end of a line. This format string is useful when FormatMessage is supplying regular line breaks so the message fits in a certain width.
%space | A space in the formatted message text. This format string can be used to ensure the appropriate number of trailing spaces in a message text line.
%. | A single period in the formatted message text. This format string can be used to include a single period at the beginning of a line without terminating the message text definition.
%! | A single exclamation point in the formatted message text. This format string can be used to include an exclamation point immediately after an insert without its being mistaken for the beginning of a printf format string.

Windows CE: The FormatMessage function requires a message definition as input. The message definition can come from a buffer passed into the function. It can come from a message table resource in an already loaded module. Or the caller can ask the function to search the system's message table resources for the message definition. FormatMessage finds the message definition in a message table resource based on a message identifier and a language identifier. FormatMessage copies the formatted message text to an output buffer, processing any embedded insert sequences if requested.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, LoadString, LocalFree


GetStringTypeA

The GetStringTypeA function returns character-type information for the characters in the specified source string. For each character in the string, the function sets one or more bits in the corresponding 16-bit element of the output array. Each bit identifies a given character type, such as whether the character is a letter, a digit, or neither.

BOOL GetStringTypeA(
  LCID Locale,       // locale identifer
  DWORD dwInfoType,  // information-type options
  LPCSTR lpSrcStr,   // pointer to the source string
  int cchSrc,        // size, in bytes, of the source string
  LPWORD lpCharType  // pointer to the buffer for output
);

Parameters

Locale
Specifies the locale identifier. This value uniquely defines the ANSI code page to use to translate the string pointed to by lpSrcStr from ANSI to Unicode. The function then analyzes each Unicode character for character type information.

This parameter can be a locale identifier created by the MAKELCID macro, or one of the following predefined values:
LOCALE_SYSTEM_DEFAULT | Default system locale
LOCALE_USER_DEFAULT | Default user locale

Note that the Locale parameter does not exist in the GetStringTypeW function. Because of that parameter difference, an application cannot automatically invoke the proper A or W version of GetStringType* through the use of the #define UNICODE switch. An application can circumvent this limitation by using GetStringTypeEx, which is the recommended Win32 function.

dwInfoType
Specifies the type of character information the user wants to retrieve. The various types are divided into different levels (see the following Remarks section for a list of the information included in each type). This parameter can specify one of the following character type flags:
CT_CTYPE1 | Retrieve character type information.
CT_CTYPE2 | Retrieve bidirectional layout information.
CT_CTYPE3 | Retrieve text processing information.

lpSrcStr
Pointer to the string for which character types are requested. If cchSrc is –1, the string is assumed to be null terminated. This must be an ANSI string. Note that this can be a double-byte character set (DBCS) string if the locale is appropriate for DBCS.
cchSrc
Specifies the size, in bytes, of the string pointed to by the lpSrcStr parameter. If this count includes a null terminator, the function returns character type information for the null terminator. If this value is –1, the string is assumed to be null terminated and the length is calculated automatically.
lpCharType
Pointer to an array of 16-bit values. The length of this array must be large enough to receive one 16-bit value for each character in the source string. When the function returns, this array contains one word corresponding to each character in the source string.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER

Remarks

The lpSrcStr and lpCharType pointers must not be the same. If they are the same, the function fails and GetLastError returns ERROR_INVALID_PARAMETER.

The Locale parameter is only used to perform string conversion to Unicode. It has nothing to do with the CTYPEs the function returns. The CTYPEs are solely determined by Unicode code points, and do not vary on a locale basis. For example, Greek letters are C1_ALPHA for any Locale value.

The character-type bits are divided into several levels. The information for one level can be retrieved by a single call to this function. Each level is limited to 16 bits of information so that the other mapping routines, which are limited to 16 bits of representation per character, can also return character-type information.

The character types supported by this function include the following.

Ctype 1
These types support ANSI C and POSIX (LC_CTYPE) character-typing functions. A combination of these values is returned in the array pointed to by the lpCharType parameter when the dwInfoType parameter is set to CT_CTYPE1.
Name | Value | Meaning
C1_UPPER | 0x0001 | Uppercase
C1_LOWER | 0x0002 | Lowercase
C1_DIGIT | 0x0004 | Decimal digits
C1_SPACE | 0x0008 | Space characters
C1_PUNCT | 0x0010 | Punctuation
C1_CNTRL | 0x0020 | Control characters
C1_BLANK | 0x0040 | Blank characters
C1_XDIGIT | 0x0080 | Hexadecimal digits
C1_ALPHA | 0x0100 | Any linguistic character: alphabetic, syllabary, or ideographic

The following character types are either constant or computable from basic types and do not need to be supported by this function.

Type | Description
Alphanumeric | Alphabetic characters and digits (C1_ALPHA and C1_DIGIT)
Printable | Graphic characters and blanks (all C1_* types except C1_CNTRL)

Ctype 2
These types support proper layout of Unicode text. The direction attributes are assigned so that the bidirectional layout algorithm standardized by Unicode produces accurate results. These types are mutually exclusive. For more information about the use of these attributes, see The Unicode Standard: Worldwide Character Encoding, Volumes 1 and 2, Addison Wesley Publishing Company: 1991, 1992, ISBN 0201567881.
Name | Value | Meaning
Strong
C2_LEFTTORIGHT | 0x0001 | Left to right
C2_RIGHTTOLEFT | 0x0002 | Right to left
Weak
C2_EUROPENUMBER | 0x0003 | European number, European digit
C2_EUROPESEPARATOR | 0x0004 | European numeric separator
C2_EUROPETERMINATOR | 0x0005 | European numeric terminator
C2_ARABICNUMBER | 0x0006 | Arabic number
C2_COMMONSEPARATOR | 0x0007 | Common numeric separator
Neutral
C2_BLOCKSEPARATOR | 0x0008 | Block separator
C2_SEGMENTSEPARATOR | 0x0009 | Segment separator
C2_WHITESPACE | 0x000A | White space
C2_OTHERNEUTRAL | 0x000B | Other neutrals
Not applicable
C2_NOTAPPLICABLE | 0x0000 | No implicit directionality (for example, control codes)

Ctype 3
These types are intended to be placeholders for extensions to the POSIX types required for general text processing or for the standard C library functions. A combination of these values is returned when dwInfoType is set to CT_CTYPE3.
Name | Value | Meaning
C3_NONSPACING | 0x0001 | Nonspacing mark
C3_DIACRITIC | 0x0002 | Diacritic nonspacing mark
C3_VOWELMARK | 0x0004 | Vowel nonspacing mark
C3_SYMBOL | 0x0008 | Symbol
C3_KATAKANA | 0x0010 | Katakana character
C3_HIRAGANA | 0x0020 | Hiragana character
C3_HALFWIDTH | 0x0040 | Half-width character
C3_FULLWIDTH | 0x0080 | Full-width character
C3_IDEOGRAPH | 0x0100 | Ideographic character
C3_KASHIDA | 0x0200 | Arabic Kashida character
C3_LEXICAL | 0x0400 | Punctuation which is counted as part of the word (Kashida, hyphen, feminine/masculine ordinal indicators, equal sign, and so forth)
C3_ALPHA | 0x8000 | All linguistic characters (alphabetic, syllabary, and ideographic)
Not applicable
C3_NOTAPPLICABLE | 0x0000 | Not applicable

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

String Manipulation Overview, String Manipulation Functions, GetLocaleInfo, GetStringTypeEx, GetStringTypeW


GetStringTypeEx

The GetStringTypeEx function returns character-type information for the characters in the specified source string. For each character in the string, the function sets one or more bits in the corresponding 16-bit element of the output array. Each bit identifies a given character type, such as whether the character is a letter, a digit, or neither.

Unlike its close relatives GetStringTypeA and GetStringTypeW, GetStringTypeEx exhibits appropriate A or W behavior through the use of the #define UNICODE switch. It is the recommended Win32 function.

BOOL GetStringTypeEx(
  LCID Locale,       // locale identifer
  DWORD dwInfoType,  // information-type options
  LPCTSTR lpSrcStr,  // pointer to source string
  int cchSrc,        // size, in bytes or characters, of source string
  LPWORD lpCharType  // pointer to buffer for output
);

Parameters

Locale
Specifies the locale identifier. This value uniquely defines the ANSI code page to use to translate the string pointed to by lpSrcStr from ANSI to Unicode. The function then analyzes each Unicode character for character type information. Note that the W version of this function ignores this parameter.

This parameter can be a locale identifier created by the MAKELCID macro, or one of the following predefined values:
LOCALE_SYSTEM_DEFAULT | Default system locale
LOCALE_USER_DEFAULT | Default user locale

dwInfoType
Specifies the type of character information the user wants to retrieve. The various types are divided into different levels (see the following Remarks section for a list of the information included in each type). This parameter can specify one of the following character type flags:
CT_CTYPE1 | Retrieve character type information.
CT_CTYPE2 | Retrieve bidirectional layout information.
CT_CTYPE3 | Retrieve text processing information.

lpSrcStr
Pointer to the string for which character types are requested. If cchSrc is –1, the string is assumed to be null terminated. This must be a Unicode string for the W version of this function, and an ANSI string for the A version. Note that for the A version, this can be a double-byte character set (DBCS) string if the locale is appropriate for DBCS.
cchSrc
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the string pointed to by the lpSrcStr parameter. If this count includes a null terminator, the function returns character type information for the null terminator. If this value is –1, the string is assumed to be null terminated and the length is calculated automatically.
lpCharType
Pointer to an array of 16-bit values. The length of this array must be large enough to receive one 16-bit value for each character in the source string. When the function returns, this array contains one word corresponding to each character in the source string.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER

Remarks

The GetStringTypeEx function exists to circumvent a limitation caused by the difference in parameters of GetStringTypeA and GetStringTypeW. That parameter difference prevents an application from automatically invoking the proper A or W version of GetStringType* through the use of the #define UNICODE switch. GetStringTypeEx, on the other hand, behaves properly as regards that switch. Thus, it is the recommended Win32 function.

The Locale parameter is only used to perform string conversion to Unicode. It has nothing to do with the CTYPEs the function returns. The CTYPEs are solely determined by Unicode code points, and do not vary on a locale basis. For example, Greek letters are C1_ALPHA for any Locale value.

The lpSrcStr and lpCharType pointers must not be the same. If they are the same, the function fails and GetLastError returns ERROR_INVALID_PARAMETER.

The character-type bits are divided into several levels. The information for one level can be retrieved by a single call to this function. Each level is limited to 16 bits of information so that the other mapping routines, which are limited to 16 bits of representation per character, can also return character-type information.

The character types supported by this function include the following.

Ctype 1
These types support ANSI C and POSIX (LC_CTYPE) character-typing functions. A combination of these values is returned in the array pointed to by the lpCharType parameter when the dwInfoType parameter is set to CT_CTYPE1.
Name | Value | Meaning
C1_UPPER | 0x0001 | Uppercase
C1_LOWER | 0x0002 | Lowercase
C1_DIGIT | 0x0004 | Decimal digits
C1_SPACE | 0x0008 | Space characters
C1_PUNCT | 0x0010 | Punctuation
C1_CNTRL | 0x0020 | Control characters
C1_BLANK | 0x0040 | Blank characters
C1_XDIGIT | 0x0080 | Hexadecimal digits
C1_ALPHA | 0x0100 | Any linguistic character: alphabetic, syllabary, or ideographic

The following character types are either constant or computable from basic types and do not need to be supported by this function.

Type | Description
Alphanumeric | Alphabetic characters and digits (C1_ALPHA and C1_DIGIT)
Printable | Graphic characters and blank (all C1_* types except C1_CNTRL)

Ctype 2
These types support proper layout of Unicode text. The direction attributes are assigned so that the bidirectional layout algorithm standardized by Unicode produces accurate results. These types are mutually exclusive. For more information about the use of these attributes, see The Unicode Standard: Worldwide Character Encoding, Volumes 1 and 2, Addison Wesley Publishing Company: 1991, 1992, ISBN 0201567881.
Name | Value | Meaning
Strong
C2_LEFTTORIGHT | 0x0001 | Left to right
C2_RIGHTTOLEFT | 0x0002 | Right to left
Weak
C2_EUROPENUMBER | 0x0003 | European number, European digit
C2_EUROPESEPARATOR | 0x0004 | European numeric separator
C2_EUROPETERMINATOR | 0x0005 | European numeric terminator
C2_ARABICNUMBER | 0x0006 | Arabic number
C2_COMMONSEPARATOR | 0x0007 | Common numeric separator
Neutral
C2_BLOCKSEPARATOR | 0x0008 | Block separator
C2_SEGMENTSEPARATOR | 0x0009 | Segment separator
C2_WHITESPACE | 0x000A | White space
C2_OTHERNEUTRAL | 0x000B | Other neutrals
Not applicable
C2_NOTAPPLICABLE | 0x0000 | No implicit directionality (for example, control codes)

Ctype 3
These types are intended to be placeholders for extensions to the POSIX types required for general text processing or for the standard C library functions. A combination of these values is returned when dwInfoType is set to CT_CTYPE3.
Name | Value | Meaning
C3_NONSPACING | 0x0001 | Nonspacing mark
C3_DIACRITIC | 0x0002 | Diacritic nonspacing mark
C3_VOWELMARK | 0x0004 | Vowel nonspacing mark
C3_SYMBOL | 0x0008 | Symbol
C3_KATAKANA | 0x0010 | Katakana character
C3_HIRAGANA | 0x0020 | Hiragana character
C3_HALFWIDTH | 0x0040 | Half-width character
C3_FULLWIDTH | 0x0080 | Full-width character
C3_IDEOGRAPH | 0x0100 | Ideographic character
C3_KASHIDA | 0x0200 | Arabic Kashida character
C3_LEXICAL | 0x0400 | Punctuation which is counted as part of the word (Kashida, hyphen, feminine/masculine ordinal indicators, equal sign, and so forth)
C3_ALPHA | 0x8000 | All linguistic characters (alphabetic, syllabary, and ideographic)
Not applicable
C3_NOTAPPLICABLE | 0x0000 | Not applicable

Windows CE: Windows CE supports only the Unicode version of GetStringTypeEx which ignores the Locale parameter.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, GetLocaleInfo, GetStringTypeA, GetStringTypeW


GetStringTypeW

The GetStringTypeW function returns character-type information for the characters in the specified source string. For each character in the string, the function sets one or more bits in the corresponding 16-bit element of the output array. Each bit identifies a given character type, such as whether the character is a letter, a digit, or neither.

BOOL GetStringTypeW(
  DWORD dwInfoType,  // information-type options
  LPCWSTR lpSrcStr,  // pointer to source string
  int cchSrc,        // number of characters in string
  LPWORD lpCharType  // pointer to buffer for output
);

Parameters

dwInfoType
Specifies the type of character information the user wants to retrieve. The various types are divided into different levels (see the following Remarks section for a list of the information included in each type). This parameter can specify one of the following character type flags:
CT_CTYPE1 | Retrieve character type information.
CT_CTYPE2 | Retrieve bidirectional layout information.
CT_CTYPE3 | Retrieve text processing information.

lpSrcStr
Pointer to the string for which character types are requested. If cchSrc is –1, the string is assumed to be null terminated. This must be a Unicode string.
cchSrc
Specifies the size, in characters, of the string pointed to by the lpSrcStr parameter. If this count includes a null terminator, the function returns character type information for the null terminator. If this value is –1, the string is assumed to be null terminated and the length is calculated automatically.
lpCharType
Pointer to an array of 16-bit values. The length of this array must be large enough to receive one 16-bit value for the number of characters specified in the cchSrc parameter. When the function returns, this array contains one word corresponding to each Unicode character in the source string.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER

Remarks

Note that the GetStringTypeA function has one more parameter than the GetStringTypeW function: GetStringTypeA has a first parameter that is an LCID named Locale. This parameter does not exist in the GetStringTypeW function. Because of that parameter difference, an application cannot automatically invoke the proper A or W version of GetStringType* through the use of the #define UNICODE switch. An application can circumvent this limitation by using GetStringTypeEx; it is the recommended Win32 function.

The lpSrcStr and lpCharType pointers must not be the same. If they are the same, the function fails and GetLastError returns ERROR_INVALID_PARAMETER.

The character-type bits are divided into several levels. The information for one level can be retrieved by a single call to this function. Each level is limited to 16 bits of information so that the other mapping routines, which are limited to 16 bits of representation per character, can also return character-type information.

The character types supported by this function include the following.

Ctype 1
These types support ANSI C and POSIX (LC_CTYPE) character-typing functions. A combination of these values is returned in the array pointed to by the lpCharType parameter when the dwInfoType parameter is set to CT_CTYPE1.
Name | Value | Meaning
C1_UPPER | 0x0001 | Uppercase
C1_LOWER | 0x0002 | Lowercase
C1_DIGIT | 0x0004 | Decimal digits
C1_SPACE | 0x0008 | Space characters
C1_PUNCT | 0x0010 | Punctuation
C1_CNTRL | 0x0020 | Control characters
C1_BLANK | 0x0040 | Blank characters
C1_XDIGIT | 0x0080 | Hexadecimal digits
C1_ALPHA | 0x0100 | Any linguistic character: alphabetic, syllabary, or ideographic

The following character types are either constant or computable from basic types and do not need to be supported by this function.

Type | Description
Alphanumeric | Alphabetic characters and digits (C1_ALPHA and C1_DIGIT)
Printable | Graphic characters and blanks (all C1_* types except C1_CNTRL)

Ctype 2
These types support proper layout of Unicode text. The direction attributes are assigned so that the bidirectional layout algorithm standardized by Unicode produces accurate results. These types are mutually exclusive. For more information about the use of these attributes, see The Unicode Standard: Worldwide Character Encoding, Volumes 1 and 2, Addison Wesley Publishing Company: 1991, 1992, ISBN 0201567881.
Name | Value | Meaning
Strong
C2_LEFTTORIGHT | 0x0001 | Left to right
C2_RIGHTTOLEFT | 0x0002 | Right to left
Weak
C2_EUROPENUMBER | 0x0003 | European number, European digit
C2_EUROPESEPARATOR | 0x0004 | European numeric separator
C2_EUROPETERMINATOR | 0x0005 | European numeric terminator
C2_ARABICNUMBER | 0x0006 | Arabic number
C2_COMMONSEPARATOR | 0x0007 | Common numeric separator
Neutral
C2_BLOCKSEPARATOR | 0x0008 | Block separator
C2_SEGMENTSEPARATOR | 0x0009 | Segment separator
C2_WHITESPACE | 0x000A | White space
C2_OTHERNEUTRAL | 0x000B | Other neutrals
Not applicable
C2_NOTAPPLICABLE | 0x0000 | No implicit directionality (for example, control codes)

Ctype 3
These types are intended to be placeholders for extensions to the POSIX types required for general text processing or for the standard C library functions. A combination of these values is returned when dwInfoType is set to CT_CTYPE3.
Name | Value | Meaning
C3_NONSPACING | 0x0001 | Nonspacing mark
C3_DIACRITIC | 0x0002 | Diacritic nonspacing mark
C3_VOWELMARK | 0x0004 | Vowel nonspacing mark
C3_SYMBOL | 0x0008 | Symbol
C3_KATAKANA | 0x0010 | Katakana character
C3_HIRAGANA | 0x0020 | Hiragana character
C3_HALFWIDTH | 0x0040 | Half-width character
C3_FULLWIDTH | 0x0080 | Full-width character
C3_IDEOGRAPH | 0x0100 | Ideographic character
C3_KASHIDA | 0x0200 | Arabic Kashida character
C3_LEXICAL | 0x0400 | Punctuation which is counted as part of the word (Kashida, hyphen, feminine/masculine ordinal indicators, equal sign, and so forth)
C3_ALPHA | 0x8000 | All linguistic characters (alphabetic, syllabary, and ideographic)
Not applicable
C3_NOTAPPLICABLE | 0x0000 | Not applicable

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

String Manipulation Overview, String Manipulation Functions, GetLocaleInfo, GetStringTypeA, GetStringTypeEx


IsCharAlpha

The IsCharAlpha function determines whether a character is an alphabetic character. This determination is based on the semantics of the language selected by the user during setup or by using Control Panel.

BOOL IsCharAlpha(
  TCHAR ch   // character to test
);

Parameters

ch
Specifies the character to be tested.

Return Values

If the character is alphabetic, the return value is nonzero.

If the character is not alphabetic, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows CE: Windows CE supports only the Unicode version of this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, IsCharAlphaNumeric


IsCharAlphaNumeric

The IsCharAlphaNumeric function determines whether a character is either an alphabetic or a numeric character. This determination is based on the semantics of the language selected by the user during setup or by using Control Panel.

BOOL IsCharAlphaNumeric(
  TCHAR ch   // character to test
);

Parameters

ch
Specifies the character to be tested.

Return Values

If the character is alphanumeric, the return value is nonzero.

If the character is not alphanumeric, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows CE: Windows CE supports only the Unicode version of this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, IsCharAlpha


IsCharLower

The IsCharLower function determines whether a character is lowercase. This determination is based on the semantics of the language selected by the user during setup or by using Control Panel.

BOOL IsCharLower(
  TCHAR ch   // character to test
);

Parameters

ch
Specifies the character to be tested.

Return Values

If the character is lowercase, the return value is nonzero.

If the character is not lowercase, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows CE: Windows CE supports only the Unicode version of this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, IsCharUpper


IsCharUpper

The IsCharUpper function determines whether a character is uppercase. This determination is based on the semantics of the language selected by the user during setup or by using Control Panel.

BOOL IsCharUpper(
  TCHAR ch   // character to test
);

Parameters

ch
Specifies the character to be tested.

Return Values

If the character is uppercase, the return value is nonzero.

If the character is not uppercase, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows CE: Windows CE supports only the Unicode version of this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, IsCharLower


LoadString

The LoadString function loads a string resource from the executable file associated with a specified module, copies the string into a buffer, and appends a terminating null character.

int LoadString(
  HINSTANCE hInstance,  // handle to module containing string resource
  UINT uID,             // resource identifier
  LPTSTR lpBuffer,      // pointer to buffer for resource
  int nBufferMax        // size of buffer
);

Parameters

hInstance
Handle to an instance of the module whose executable file contains the string resource.
uID
Specifies the integer identifier of the string to be loaded.
lpBuffer
Pointer to the buffer to receive the string.
nBufferMax
Specifies the size of the buffer in bytes (ANSI version) or characters (Unicode version). The string is truncated and null terminated if it is longer than the number of characters specified.

Return Values

If the function succeeds, the return value is the number of bytes (ANSI version) or characters (Unicode version) copied into the buffer, not including the null-terminating character, or zero if the string resource does not exist. To get extended error information, call GetLastError.

Remarks

Windows CE: If lpBuffer is set to NULL, the return value is a pointer to the requested string. The caller should cast the return value to an LPCTSTR. This pointer points directly to the resource, so the string is read-only. The length of the string, not including any NULL terminator, can be found in the word preceding the string.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, FormatMessage, LoadAccelerators, LoadBitmap, LoadCursor, LoadIcon, LoadMenu, LoadMenuIndirect


lstrcat

The lstrcat function appends one string to another.

LPTSTR lstrcat(
  LPTSTR lpString1,  // pointer to buffer for concatenated strings
  LPCTSTR lpString2  // pointer to string to add to string1
);

Parameters

lpString1
Pointer to a null-terminated string. The buffer must be large enough to contain both strings.
lpString2
Pointer to the null-terminated string to be appended to the string specified in the lpString1 parameter.

Return Values

If the function succeeds, the return value is a pointer to the buffer.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, lstrcmp, lstrcmpi, lstrcpy, lstrlen


lstrcmp

The lstrcmp function compares two character strings. The comparison is case sensitive.

int lstrcmp(
  LPCTSTR lpString1,  // pointer to first string
  LPCTSTR lpString2   // pointer to second string
);

Parameters

lpString1
Pointer to the first null-terminated string to be compared.
lpString2
Pointer to the second null-terminated string to be compared.

Return Values

If the string pointed to by lpString1 is less than the string pointed to by lpString2, the return value is negative. If the string pointed to by lpString1 is greater than the string pointed to by lpString2, the return value is positive. If the strings are equal, the return value is zero.

Remarks

The lstrcmp function compares two strings by checking the first characters against each other, the second characters against each other, and so on until it finds an inequality or reaches the ends of the strings.

The function returns the difference of the values of the first unequal characters it encounters. For example, lstrcmp determines that "abcz" is greater than "abcdefg" and returns the difference of z and d.

The language (locale) selected by the user at setup time, or via the control panel, determines which string is greater (or whether the strings are the same). If no language (locale) is selected, the system performs the comparison by using default values.

With a double-byte character set (DBCS) version of the system, this function can compare two DBCS strings.

The Win32 lstrcmp function uses a word sort, rather than a string sort. A word sort treats hyphens and apostrophes differently than it treats other symbols that are not alphanumeric, in order to ensure that words such as "coop" and "co-op" stay together within a sorted list. Note that in 16-bit versions of Windows, lstrcmp uses a string sort. For a detailed discussion of word sorts and string sorts, see the Remarks section of the reference page for the CompareString function .

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, CompareString, lstrcat, lstrcmpi, lstrcpy, lstrlen


lstrcmpi

The lstrcmpi function compares two character strings. The comparison is not case sensitive.

int lstrcmpi(
  LPCTSTR lpString1,  // pointer to first string
  LPCTSTR lpString2   // pointer to second string
);

Parameters

lpString1
Pointer to the first null-terminated string to be compared.
lpString2
Pointer to the second null-terminated string to be compared.

Return Values

If the string pointed to by lpString1 is less than the string pointed to by lpString2, the return value is negative. If the string pointed to by lpString1 is greater than the string pointed to by lpString2, the return value is positive. If the strings are equal, the return value is zero.

Remarks

The lstrcmpi function compares two strings by checking the first characters against each other, the second characters against each other, and so on until it finds an inequality or reaches the ends of the strings.

The function returns the difference of the values of the first unequal characters it encounters. For example, lstrcmpi determines that "abcz" is greater than "abcdefg" and returns the difference of z and d.

The language (locale) selected by the user at setup time, or by using the control panel, determines which string is greater (or whether the strings are the same). If no language (locale) is selected, the system performs the comparison by using default values.

For some locales, the lstrcmpi function may be insufficient. If this occurs, use CompareString to ensure proper comparison. For example, in Japan call CompareString with the IGNORE_CASE, IGNORE_KANATYPE, and IGNORE_WIDTH values to achieve the most appropriate non-exact string comparison. The IGNORE_KANATYPE and IGNORE_WIDTH values are ignored in non-Asian locales, so you can set these values for all locales and be guaranteed to have a culturally correct "insensitive" sorting regardless of the locale. Note that specifying these values slows performance, so use them only when necessary.

With a double-byte character set (DBCS) version of the system, this function can compare two DBCS strings.

The Win32 lstrcmpi function uses a word sort, rather than a string sort. A word sort treats hyphens and apostrophes differently than it treats other symbols that are not alphanumeric, in order to ensure that words such as "coop" and "co-op" stay together within a sorted list. Note that in 16-bit versions of Windows, lstrcmpi uses a string sort. For a detailed discussion of word sorts and string sorts, see the Remarks section of the reference page for the CompareString function .

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, CompareString, lstrcat, lstrcmp, lstrcpy, lstrlen


lstrcpy

The lstrcpy function copies a string to a buffer.

LPTSTR lstrcpy(
  LPTSTR lpString1,  // pointer to buffer
  LPCTSTR lpString2  // pointer to string to copy
);

Parameters

lpString1
Pointer to a buffer to receive the contents of the string pointed to by the lpString2 parameter. The buffer must be large enough to contain the string, including the terminating null character.
lpString2
Pointer to the null-terminated string to be copied.

Return Values

If the function succeeds, the return value is a pointer to the buffer.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

With a double-byte character set (DBCS) version of the system, this function can be used to copy a DBCS string.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, lstrcat, lstrcmp, lstrcmpi, lstrlen


lstrcpyn

The lstrcpyn function copies a specified number of characters from a source string into a buffer.

LPTSTR lstrcpyn(
  LPTSTR lpString1,  // pointer to target buffer
  LPCTSTR lpString2, // pointer to source string
  int iMaxLength     // number of bytes or characters to copy
);

Parameters

lpString1
Pointer to a buffer into which the function copies characters. The buffer must be large enough to contain the number of bytes (ANSI version) or characters (Unicode version) specified by iMaxLength, including room for a terminating null character.
lpString2
Pointer to a null-terminated string from which the function copies characters.
iMaxLength
Specifies the number bytes (ANSI version) or characters (Unicode version) to be copied from the string pointed to by lpString2 into the buffer pointed to by lpString1, including a terminating null character.

Return Values

If the function succeeds, the return value is a pointer to the buffer.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

Note that the buffer pointed to by lpString1 must be large enough to include a terminating null character, and the string length value specified by iMaxLength includes room for a terminating null character. Thus, the following code

TCHAR chBuffer[512] ;

lstrcpyn(chBuffer, "abcdefghijklmnop", 4) ;

copies the string "abc", followed by a terminating null character, to chBuffer.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, lstrcat, lstrcmp, lstrcmpi, lstrcpy, lstrlen


lstrlen

The lstrlen function returns the length in bytes (ANSI version) or characters (Unicode version) of the specified string (not including the terminating null character).

int lstrlen(
  LPCTSTR lpString   // pointer to string to count
);

Parameters

lpString
Pointer to a null-terminated string.

Return Values

The return value specifies the length of the string in bytes (ANSI version) or characters (Unicode version).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows and Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, lstrcat, lstrcmp, lstrcmpi, lstrcpy


OemToAnsi

The OemToAnsi function is obsolete.

For compatibility with 16-bit versions of Windows, this function is implemented as a macro that calls the OemToChar function, which should be used for new Win32-based applications.

See Also

String Manipulation Overview, String Manipulation Functions


OemToAnsiBuff

The OemToAnsiBuff function is obsolete.

For compatibility with 16-bit versions of Windows, this function is implemented as a macro that calls the OemToCharBuff function, which should be used for Win32-based applications.

See Also

String Manipulation Overview, String Manipulation Functions


OemToChar

The OemToChar function translates a string from the OEM-defined character set into either an ANSI or a wide-character string. (OEM stands for original equipment manufacturer.)

BOOL OemToChar(
  LPCSTR lpszSrc,  // pointer to string to translate
  LPTSTR lpszDst   // pointer to buffer for translated string
);

Parameters

lpszSrc
Pointer to a null-terminated string of characters from the OEM-defined character set.
lpszDst
Pointer to the buffer for the translated string. If the OemToChar function is being used as an ANSI function, the string can be translated in place by setting the lpszDst parameter to the same address as the lpszSrc parameter. This cannot be done if OemToChar is being used as a wide-character function.

Return Values

The return value is always nonzero.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, CharToOem, CharToOemBuff, OemToCharBuff


OemToCharBuff

The OemToCharBuff function translates a specified number of characters in a string from the OEM-defined character set into either an ANSI or a wide-character string. (OEM stands for original equipment manufacturer.)

BOOL OemToCharBuff(
  LPCSTR lpszSrc,      // pointer to string to translate
  LPTSTR lpszDst,      // pointer to buffer for translated string
  DWORD cchDstLength   // size of buffer
);

Parameters

lpszSrc
Pointer to a buffer containing one or more characters from the OEM-defined character set.
lpszDst
Pointer to the buffer for the translated string. If the OemToCharBuff function is being used as an ANSI function, the string can be translated in place by setting the lpszDst parameter to the same address as the lpszSrc parameter. This cannot be done if the OemToCharBuff function is being used as a wide-character function.
cchDstLength
Specifies the number of characters to translate in the buffer identified by the lpszSrc parameter.

Return Values

The return value is always nonzero.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, CharToOem, CharToOemBuff, OemToChar


wsprintf

The wsprintf function formats and stores a series of characters and values in a buffer. Any arguments are converted and copied to the output buffer according to the corresponding format specification in the format string. The function appends a terminating null character to the characters it writes, but the return value does not include the terminating null character in its character count.

int wsprintf(
  LPTSTR lpOut,    // pointer to buffer for output
  LPCTSTR lpFmt,   // pointer to format-control string
  ...              // optional arguments
);

Parameters

lpOut
Pointer to a buffer to receive the formatted output. The maximum size of the buffer is 1024 bytes.
lpFmt
Pointer to a null-terminated string that contains the format-control specifications. In addition to ordinary ASCII characters, a format specification for each argument appears in this string. For more information about the format specification, see the Remarks section.
...
Specifies one or more optional arguments. The number and type of argument parameters depend on the corresponding format-control specifications in the lpFmt parameter.

Return Values

If the function succeeds, the return value is the number of characters stored in the output buffer, not counting the terminating null character.

If the function fails, the return value is less than the length of the format-control string. To get extended error information, call GetLastError.

Remarks

The format-control string contains format specifications that determine the output format for the arguments following the lpFmt parameter. Format specifications, discussed below, always begin with a percent sign (%). If a percent sign is followed by a character that has no meaning as a format field, the character is not formatted (for example, %% produces a single percent-sign character).

The format-control string is read from left to right. When the first format specification (if any) is encountered, it causes the value of the first argument after the format-control string to be converted and copied to the output buffer according to the format specification. The second format specification causes the second argument to be converted and copied, and so on. If there are more arguments than format specifications, the extra arguments are ignored. If there are not enough arguments for all of the format specifications, the results are undefined.

A format specification has the following form:

%[-][#][0][width][.precision]type

Each field is a single character or a number signifying a particular format option. The type characters that appear after the last optional format field determine whether the associated argument is interpreted as a character, a string, or a number. The simplest format specification contains only the percent sign and a type character (for example, %s). The optional fields control other aspects of the formatting. Following are the optional and required fields and their meanings:

Field | Meaning
– | Pad the output with blanks or zeros to the right to fill the field width, justifying output to the left. If this field is omitted, the output is padded to the left, justifying it to the right.
# | Prefix hexadecimal values with 0x (lowercase) or 0X (uppercase).
0 | Pad the output value with zeros to fill the field width. If this field is omitted, the output value is padded with blank spaces.
width | Copy the specified minimum number of characters to the output buffer. The width field is a nonnegative integer. The width specification never causes a value to be truncated; if the number of characters in the output value is greater than the specified width, or if the width field is not present, all characters of the value are printed, subject to the precision specification.
.precision | For numbers, copy the specified minimum number of digits to the output buffer. If the number of digits in the argument is less than the specified precision, the output value is padded on the left with zeros. The value is not truncated when the number of digits exceeds the specified precision. If the specified precision is 0 or omitted entirely, or if the period (.) appears without a number following it, the precision is set to 1.
 | For strings, copy the specified maximum number of characters to the output buffer.
type | Output the corresponding argument as a character, a string, or a number. This field can be any of the following character sequences:

Sequence | Insert
c | A single character. This sequence is interpreted as type WCHAR when the calling application uses the #define UNICODE compile flag and as type CHAR otherwise.
C | A single character. This sequence is interpreted as type CHAR when the calling application uses the #define UNICODE compile flag and as type WCHAR otherwise.
d | A signed decimal integer argument. This sequence is equivalent to the i sequence.
hc, hC | A single character. The wsprintf function ignores character arguments with a numeric value of zero. This sequence is always interpreted as type CHAR, even when the calling application uses the #define UNICODE compile flag.
hd | A signed short integer argument.
hs, hS | A string. This sequence is always interpreted as type LPSTR, even when the calling application uses the #define UNICODE compile flag.
hu | An unsigned short integer argument.
i | A signed decimal integer. This sequence is equivalent to the d sequence.
lc, lC | A single character. The wsprintf function ignores character arguments with a numeric value of zero. This sequence is always interpreted as type WCHAR, even when the calling application does not use the #define UNICODE compile flag.
ld | A long signed decimal integer. This sequence is equivalent to the li sequence.
li | A long signed decimal integer. This sequence is equivalent to the ld sequence.
ls, lS | A string. This sequence is always interpreted as type LPWSTR, even when the calling application does not use the #define UNICODE compile flag. This sequence is equivalent to the ws sequence.
lu | A long unsigned integer.
lx, lX | A long unsigned hexadecimal integer in lowercase or uppercase.
s | A string. This sequence is interpreted as type LPWSTR when the calling application uses the #define UNICODE compile flag and as type LPSTR otherwise.
S | A string. This sequence is interpreted as type LPSTR when the calling application uses the #define UNICODE compile flag and as type LPWSTR otherwise.
u | An unsigned integer argument.
x, X | An unsigned hexadecimal integer in lowercase or uppercase.

Note Unlike other Win32 functions, wsprintf uses the C calling convention (_cdecl), rather than the Pascal calling convention. As a result, it is the responsibility of the calling process to pop arguments off the stack, and arguments are pushed on the stack from right to left. In C-language modules, the C compiler performs this task.

Windows CE: Windows CE supports only the Unicode version of wsprintf.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, wvsprintf


wvsprintf

The wvsprintf function formats and stores a series of characters and values in a buffer. The items pointed to by the argument list are converted and copied to an output buffer according to the corresponding format specification in the format-control string. The function appends a terminating null character to the characters it writes, but the return value does not include the terminating null character in its character count.

int wvsprintf(
  LPTSTR lpOutput,  // pointer to buffer for output
  LPCTSTR lpFormat, // pointer to format-control string
  va_list arglist   // variable list of format-control arguments
);

Parameters

lpOutput
Pointer to a buffer to receive the formatted output.
lpFormat
Pointer to a null-terminated string that contains the format-control specifications. In addition to ordinary ASCII characters, a format specification for each argument appears in this string. For more information about the format specification, see wsprintf.
arglist
A variable argument list; each element of the list specifies an argument for the format-control string. The number, type, and interpretation of the arguments depend on the corresponding format-control specifications in the lpFmt parameter.

Return Values

If the function succeeds, the return value is the number of characters stored in the buffer, not counting the terminating null character.

If the function fails, the return value is less than the length of the format-control string. To get extended error information, call GetLastError.

Remarks

The function copies the format-control string into the output buffer character by character, starting with the first character in the string. When it encounters a format specification in the string, the function retrieves the value of the next available argument (starting with the first argument in the list), converts that value into the specified format, and copies the result to the output buffer. The function continues to copy characters and expand format specifications in this way until it reaches the end of the format-control string. If there are more arguments than format specifications, the extra arguments are ignored. If there are not enough arguments for all of the format specifications, the results are undefined.

Windows CE: Windows CE supports only the Unicode version of wvsprintf.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

String Manipulation Overview, String Manipulation Functions, wsprintf


Time

Microsoft® Windows® and Microsoft® Windows NT® provide a variety of date and time functions to retrieve and set the date and time for the system and individual files. This overview describes how to use these functions to examine and modify dates and times.

For information, see the following overviews:

  • File I/O
  • File Systems


About Time

The Win32 API supports five time formats. Time-related functions return time in one of these formats. The Win32 API includes functions to convert between time formats for ease of comparison and display. The Win32 API also provides functions to convert certain time formats based on the time zone. The following table summarizes the time formats.

Format | Type | Description
System | SYSTEMTIME | Year, month, day, hour, second, and millisecond, taken from the internal hardware clock.
File | FILETIME | 100-nanosecond intervals since January 1, 1601.
Local | SYSTEMTIME or FILETIME | A system time or file time converted to the system's local time zone.
MS-DOS | WORD | A packed 16-bit word for the date, another for the time.
Windows | DWORD | The number of milliseconds since the system booted; a quantity that cycles every 49.7 days.

For more information, see the following topics.

  • System Time
  • Local Time
  • File Times
  • MS-DOS Date and Time
  • Windows Time


System Time

System time is the current date and time of day. The system keeps time so that your applications have ready access to accurate time. When the system first starts, it sets the system time to a value based on the real-time clock of the computer and then regularly updates the time.

The system bases system time on coordinated universal time (UTC). UTC-based time is loosely defined as the current date and time of day in Greenwich, England. You can retrieve the system time by using the GetSystemTime function. GetSystemTime copies the time to a SYSTEMTIME structure that contains individual members for month, day, year, weekday, hour, minute, second, and milliseconds. It is easy to display this format to a user.

You can set the system time by using the SetSystemTime function. SetSystemTime assumes you have specified a UTC-based time. If you change the system time, you should send the WM_TIMECHANGE message to all top-level windows by using the SendMessage function.

The GetSystemTimeAdjustment and SetSystemTimeAdjustment functions synchronize the time-of-day clock with another time source using a periodic time adjustment applied at each clock interrupt.


Local Time

While the system uses UTC-based time internally, your applications will generally display the local time — the date and time of day for your time zone. Therefore, to ensure correct results, you must be aware of whether a function expects to receive a UTC-based time or a local time, and whether the function returns a UTC-based time or a local time.

You can retrieve the local time by using the GetLocalTime function. GetLocalTime converts the system time to a local time based on the current time-zone settings and copies the result to a SYSTEMTIME structure. You can set the system time by using the SetLocalTime function. SetLocalTime assumes you have specified a local time and converts to UTC before setting the system time.

Windows NT: When you call SetLocalTime, Windows NT uses the current time zone information, including the Daylight Saving Time setting, to perform the conversion. Note that Windows NT uses the Daylight Saving Time setting of the current time, not the new time you are setting. Therefore, to ensure the correct result, call SetLocalTime again, now that the Daylight Saving Time setting is set for the new time.

The current time-zone settings control how the system converts between UTC and local time. You can retrieve the current time-zone settings by using the GetTimeZoneInformation function. The function copies the setting to a TIME_ZONE_INFORMATION structure and returns a value indicating whether local time is currently in standard or daylight-savings time. You can set the time-zone settings by using the SetTimeZoneInformation function.

To convert a UTC-based time stored in a SYSTEMTIME structure to a local time, use the SystemTimeToTzSpecificLocalTime function. SystemTimeToTzSpecifcLocalTime uses the current settings for the time zone and daylight saving time. Therefore, if it is daylight saving time, this function will take daylight saving time into account, even if the time you are converting is in standard time.


File Times

A file time represents the specific date and time at which a given file was created, last accessed, or last written to. The system records file times whenever applications create, access, and write to files. The system records the times using a 64-bit value specifying the number of 100-nanosecond intervals that have elapsed since 12:00 a.m. January 1, 1601 (UTC). Writing to a file changes the last write time; writing to or reading from the file (including running an executable file) changes the last access time.

Note Not all file systems can record creation and last access time. In particular, the file allocation table (FAT) file system records only last-write times.

You can retrieve the file times for a given file by using the GetFileTime function. GetFileTime copies the creation, last access, and last write times to individual FILETIME structures. Each structure consists of two 32-bit values that combine to form the single 64-bit value. You can also retrieve the file times by using the FindFirstFile and FindNextFile functions. These functions copy the times to FILETIME structures in a WIN32_FIND_DATA structure.

You can set the file times for a file by using the SetFileTime function. This function lets you modify creation, last access, and last write times without changing the content of the file. You can compare the times of different files by using the CompareFileTime function. The function compares two file times and returns a value indicating which time is greater or returns zero if the times are equal.

To make a file time more meaningful to a user, you can extract the month, day, year, and time of day from a file time by using the FileTimeToSystemTime function. FileTimeToSystemTime converts the file time and copies the individual values for date and time of day to a SYSTEMTIME structure.

The system records all file times in UTC-based times, but you can convert a file time to the local time for your time zone by using the FileTimeToLocalFileTime function. Before displaying a file time to a user, applications typically convert the file time to local time, then extract the month, day, year and time of day using FileTimeToSystemTime.

If you plan to modify file times for given files, you can convert a date and time of day to a file time by using the SystemTimeToFileTime function. You can also obtain the system time FILETIME structure by calling the GetSystemTimeAsFileTime function.

If the original date and time of day are given in the local time for your time zone, you can convert the resulting file time to UTC by using the LocalFileTimeToFileTime function. Always make sure the file times you set using SetFileTime are valid UTC-based times. The FileTimeToLocalFileTime and LocalFileTimeToFileTime functions use the current settings for the time zone and daylight saving time. Therefore, if it is daylight saving time, these functions will take daylight saving time into account, even if the time you are converting is in standard time.


MS-DOS Date and Time

MS-DOS date and MS-DOS time are packed 16-bit values that specify the month, day, year, and time of day an MS-DOS file was last written to. MS-DOS records the date and time whenever an MS-DOS application creates or writes to a file. MS-DOS applications retrieve this date and time using MS-DOS functions. When you use the GetFileTime function to retrieve the file times for files that were created by MS-DOS, GetFileTime automatically converts MS-DOS dates and times to UTC-based times.

If you encounter an MS-DOS date and time that has not been converted, you can convert it to a UTC-based time by using the DosDateTimeToFileTime function. This function copies the converted date and time to a FILETIME structure. You can convert the value back to an MS-DOS date and time by using the FileTimeToDosDateTime function.


Windows Time

Windows time is the number of milliseconds elapsed since the system started running. This format exists primarily for backward compatibility with 16-bit Windows. To ensure that applications designed for 16-bit Windows continue to run successfully, the GetTickCount function returns the current Windows time.

You typically use GetTickCount to compare the current Windows time with the time returned by the GetMessageTime function. GetMessageTime returns the Windows time when the given message was created. GetTickCount is limited to the resolution of the system timer.

Windows NT 3.5 and later: The system timer runs at approximately 10ms.

Windows NT 3.1: The system timer runs at approximately 16ms.

Windows 95 and later: The system timer runs at approximately 55ms.

If you need a higher resolution timer, use a multimedia timer or a high-resolution timer.

Windows time is stored as a 32-bit value, which means the system can record no more than 2^32 millisecond intervals before the 32-bit value overflows to zero. This is approximately 49.7 days. If you use Windows time, check for the overflow condition when comparing times.

Windows NT: You can use the System Up Time performance counter to obtain the time elapsed since the computer was started.


Using Time

  • Retrieving the last-write time
  • Changing a file time to the current time
  • Setting the system time
  • Converting a time_t value to a file time


Retrieving the Last-Write Time

The following example uses the GetFileTime function to retrieve the last-write time for a file. It converts the time to local time based on the current time-zone settings, and creates a date and time string that can be shown to the user.

// GetLastWriteTime - retrieves the last-write time and converts the
//                   time to a string
// Return value - TRUE if successful, FALSE otherwise
// hFile      - must be a valid file handle
// lpszString - address of buffer to receive string

BOOL GetLastWriteTime(HANDLE hFile, LPSTR lpszString)
{
    FILETIME ftCreate, ftAccess, ftWrite, ftLocal;
    SYSTEMTIME stCreate;

    // Retrieve the file times for the file.
    if (!GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite))
        return FALSE;

    // Convert the last-write time to local time.
    if (!FileTimeToLocalFileTime(&ftWrite, &ftLocal))
        return FALSE;

    // Convert the local file time from UTC to system time.
    FileTimeToSystemTime(&ftLocal, &stCreate);

    // Build a string showing the date and time.
    wsprintf(lpszString, "%02d/%02d/%d  %02d:%02d",
        stCreate.wDay, stCreate.wMonth, stCreate.wYear,
        stCreate.wHour, stCreate.wMinute);

    return TRUE;
}


Changing a File Time to the Current Time

The following example sets the last-write time for a file to the current system time using the SetFileTime function.

// SetFileToCurrentTime - sets last write time to current system time
// Return value - TRUE if successful, FALSE otherwise
// hFile  - must be a valid file handle

BOOL SetFileToCurrentTime(HANDLE hFile)
{
    FILETIME ft;
    SYSTEMTIME st;
    BOOL f;

    GetSystemTime(&st);              // gets current time
    SystemTimeToFileTime(&st, &ft);  // converts to file time format
    f = SetFileTime(hf,              // sets last-write time for file
        (LPFILETIME) NULL, (LPFILETIME) NULL, &ft);

    return f;
}


Setting the System Time

The following example sets the system time using the SetSystemTime function.

// SetNewTime - sets system time
// Return value - TRUE if successful, FALSE otherwise
// hour     - new hour (0-23)
// minutes  - new minutes (0-59)

BOOL SetNewTime(WORD hour, WORD minutes)
{
    SYSTEMTIME st;
    char *pc;

    GetSystemTime(&st);       // gets current time
    st.wHour = hour;          // adjusts hours
    st.wMinute = minutes;     // and minutes
    if (!SetSystemTime(&st))  // sets system time
        return FALSE;
    return TRUE;
}


Converting a time_t Value to a File Time

The time functions included in the C run-time use the time_t type to represent the number of seconds elapsed since midnight, January 1, 1970. The following example converts a time_t value to a file time, using the Int32x32To64 function.

void TimetToFileTime( time_t t, LPFILETIME pft )
{
    LONGLONG ll = Int32x32To64(t, 10000000) + 116444736000000000;
    pft->dwLowDateTime = (DWORD) ll;
    pft->dwHighDateTime = ll >>32;
}

After you have obtained a file time, you can convert this value to system time using the FileTimeToSystemTime function.


Time Reference

The following elements are used with time.

  • Time Functions
  • Time Structures
  • Time Messages


Time Functions

The following functions are used with time.

CompareFileTime
DosDateTimeToFileTime
FileTimeToDosDateTime
FileTimeToLocalFileTime
FileTimeToSystemTime
GetFileTime
GetLocalTime
GetSystemTime
GetSystemTimeAdjustment
GetSystemTimeAsFileTime
GetTickCount
GetTimeZoneInformation
LocalFileTimeToFileTime
SetFileTime
SetLocalTime
SetSystemTime
SetSystemTimeAdjustment
SetTimeZoneInformation
SystemTimeToFileTime
SystemTimeToTzSpecificLocalTime

Obsolete Functions

GetCurrentTime


CompareFileTime

The CompareFileTime function compares two 64-bit file times.

LONG CompareFileTime(
  CONST FILETIME *lpFileTime1,  // pointer to first file time
  CONST FILETIME *lpFileTime2   // pointer to second file time
);

Parameters

lpFileTime1
Pointer to a FILETIME structure that specifies the first 64-bit file time.
lpFileTime2
Pointer to a FILETIME structure that specifies the second 64-bit file time.

Return Values

The return value is one of the following values:

Value | Meaning
–1 | First file time is less than second file time.
0 | First file time is equal to second file time.
+1 | First file time is greater than second file time.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, GetFileTime, FILETIME


DosDateTimeToFileTime

The DosDateTimeToFileTime function converts MS-DOS date and time values to a 64-bit file time.

BOOL DosDateTimeToFileTime(
  WORD wFatDate,          // 16-bit MS-DOS date
  WORD wFatTime,          // 16-bit MS-DOS time
  LPFILETIME lpFileTime   // pointer to buffer for 64-bit file time
);

Parameters

wFatDate
Specifies the MS-DOS date. The date is a packed 16-bit value with the following format:
Bits | Contents
0–4 | Day of the month (1–31)
5–8 | Month (1 = January, 2 = February, and so on)
9–15 | Year offset from 1980 (add 1980 to get actual year)

wFatTime
Specifies the MS-DOS time. The time is a packed 16-bit value with the following format:
Bits | Contents
0–4 | Second divided by 2
5–10 | Minute (0–59)
11–15 | Hour (0–23 on a 24-hour clock)

lpFileTime
Pointer to a FILETIME structure to receive the converted 64-bit file time.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, FILETIME, FileTimeToDosDateTime, FileTimeToSystemTime, SystemTimeToFileTime


FileTimeToDosDateTime

The FileTimeToDosDateTime function converts a 64-bit file time to MS-DOS date and time values.

BOOL FileTimeToDosDateTime(
  CONST FILETIME *lpFileTime,
                     // pointer to 64-bit file time
  LPWORD lpFatDate,  // pointer to variable for MS-DOS date
  LPWORD lpFatTime   // pointer to variable for MS-DOS time
);

Parameters

lpFileTime
Pointer to a FILETIME structure containing the 64-bit file time to convert to MS-DOS date and time format.
lpFatDate
Pointer to a variable to receive the MS-DOS date. The date is a packed 16-bit value with the following format:
Bits | Contents
0–4 | Day of the month (1–31)
5–8 | Month (1 = January, 2 = February, etc.)
9–15 | Year offset from 1980 (add 1980 to get actual year)

lpFatTime
Pointer to a variable to receive the MS-DOS time. The time is a packed 16-bit value with the following format:
Bits | Contents
0–4 | Second divided by 2
5–10 | Minute (0–59)
11–15 | Hour (0–23 on a 24-hour clock)

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The MS-DOS date format can represent only dates between 1/1/1980 and 12/31/2107; this conversion fails if the input file time is outside this range.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, DosDateTimeToFileTime, FileTimeToSystemTime, SystemTimeToFileTime


FileTimeToLocalFileTime

The FileTimeToLocalFileTime function converts a file time based on the Coordinated Universal Time (UTC) to a local file time.

BOOL FileTimeToLocalFileTime(
  CONST FILETIME *lpFileTime,  // pointer to UTC file time to convert
  LPFILETIME lpLocalFileTime   // pointer to converted file time
);

Parameters

lpFileTime
Pointer to a FILETIME structure containing the UTC-based file time to be converted into a local file time.
lpLocalFileTime
Pointer to a FILETIME structure to receive the converted local file time. This parameter cannot be the same as the lpFileTime parameter.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

FileTimeToLocalFileTime uses the current settings for the time zone and daylight saving time. Therefore, if it is daylight saving time, this function will take daylight saving time into account, even if the time you are converting is in standard time.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, FILETIME, LocalFileTimeToFileTime


FileTimeToSystemTime

The FileTimeToSystemTime function converts a 64-bit file time to system time format.

BOOL FileTimeToSystemTime(
  CONST FILETIME *lpFileTime,  // pointer to file time to convert
  LPSYSTEMTIME lpSystemTime    // pointer to structure to receive
                               // system time
);

Parameters

lpFileTime
Pointer to a FILETIME structure containing the file time to convert to system date and time format.

The FileTimeToSystemTime function only works with FILETIME values that are less than 0x8000000000000000. The function fails with values equal to or greater than that.

lpSystemTime
Pointer to a SYSTEMTIME structure to receive the converted file time.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

As noted above, the function fails for FILETIME values that are equal to or greater than 0x8000000000000000.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, DosDateTimeToFileTime, FILETIME, FileTimeToDosDateTime, SYSTEMTIME, SystemTimeToFileTime


GetCurrentTime

The GetCurrentTime is obsolete. This function is provided only for compatibility with 16-bit versions of Windows. Win32-based applications should use the GetTickCount function or look up the System Up Time counter in the performance data in the registry key HKEY_PERFORMANCE_DATA.

See Also

Time Overview, Time Functions


GetFileTime

The GetFileTime function retrieves the date and time that a file was created, last accessed, and last modified.

BOOL GetFileTime(
  HANDLE hFile,                 // handle to the file
  LPFILETIME lpCreationTime,    // address of creation time
  LPFILETIME lpLastAccessTime,  // address of last access time
  LPFILETIME lpLastWriteTime    // address of last write time
);

Parameters

hFile
Handle to the files for which to get dates and times. The file handle must have been created with GENERIC_READ access to the file.
lpCreationTime
Pointer to a FILETIME structure to receive the date and time the file was created. This parameter can be NULL if the application does not require this information.
lpLastAccessTime
Pointer to a FILETIME structure to receive the date and time the file was last accessed. The last access time includes the last time the file was written to, read from, or, in the case of executable files, run. This parameter can be NULL if the application does not require this information.
lpLastWriteTime
Pointer to a FILETIME structure to receive the date and time the file was last written to. This parameter can be NULL if the application does not require this information.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The FAT and NTFS file systems support the file creation, last access, and last write time values.

Windows 95: The precision of the time for a file in a FAT file system is 2 seconds. The time precision for files in other file systems, such as those connected through a network depends on the file system but may also be limited by the remote device.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, FILETIME, GetFileSize, GetFileType, SetFileTime


GetLocalTime

The GetLocalTime function retrieves the current local date and time.

VOID GetLocalTime(
  LPSYSTEMTIME lpSystemTime   // address of system time structure
);

Parameters

lpSystemTime
Pointer to a SYSTEMTIME structure to receive the current local date and time.

Return Values

This function does not return a value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, GetSystemTime, SetLocalTime, SYSTEMTIME


GetSystemTime

The GetSystemTime function retrieves the current system date and time. The system time is expressed in Coordinated Universal Time (UTC).

VOID GetSystemTime(
  LPSYSTEMTIME lpSystemTime   // address of system time structure
);

Parameters

lpSystemTime
Pointer to a SYSTEMTIME structure to receive the current system date and time.

Return Values

This function does not return a value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, GetLocalTime, GetSystemTimeAdjustment, SetSystemTime, SYSTEMTIME


GetSystemTimeAdjustment

The GetSystemTimeAdjustment function determines whether the system is applying periodic time adjustments to its time-of-day clock at each clock interrupt, along with the value and period of any such adjustments. Note that the period of such adjustments is equivalent to the time period between clock interrupts.

BOOL GetSystemTimeAdjustment(
  PDWORD lpTimeAdjustment,  // size, in 100-nanosecond units, of a
                            // periodic time adjustment
  PDWORD lpTimeIncrement,   // time, in 100-nanosecond units, between
                            // periodic time adjustments
  PBOOL lpTimeAdjustmentDisabled
                            // whether periodic time adjustment is
                            // disabled or enabled
);

Parameters

lpTimeAdjustment
Pointer to a DWORD that the function sets to the number of 100-nanosecond units added to the time-of-day clock at each periodic time adjustment.
lpTimeIncrement
Pointer to a DWORD that the function sets to the interval, counted in 100-nanosecond units, between periodic time adjustments. This interval is the time period between a system's clock interrupts.
lpTimeAdjustmentDisabled
Pointer to a BOOL that the function sets to indicate whether periodic time adjustment is in effect.

A value of TRUE indicates that periodic time adjustment is disabled. At each clock interrupt, the system merely adds the interval between clock interrupts to the time-of-day clock. The system is free, however, to adjust its time-of-day clock using other techniques. Such other techniques may cause the time-of-day clock to noticeably jump when adjustments are made.

A value of FALSE indicates that periodic time adjustment is being used to adjust the time-of-day clock. At each clock interrupt, the system adds the time increment specified by SetSystemTimeAdjustment's dwTimeIncrement parameter to the time-of-day clock. The system will not interfere with the time adjustment scheme, and will not attempt to synchronize time of day on its own via other techniques.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The GetSystemTimeAdjustment and SetSystemTimeAdjustment functions support algorithms that want to synchronize the time-of-day clock, reported by GetSystemTime and GetLocalTime, with another time source using a periodic time adjustment applied at each clock interrupt.

When periodic time adjustment is in effect, the system adds an adjusting value to the time-of-day clock at a periodic interval, at each clock interrupt. The GetSystemTimeAdjustment function lets a caller determine whether periodic time adjustment is enabled, and if it is, obtain the amount of each adjustment and the time between adjustments. The SetSystemTimeAdjustment function lets a caller enable or disable periodic time adjustment, and set the value of the adjusting increment.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, SetSystemTimeAdjustment, GetSystemTime, GetLocalTime


GetSystemTimeAsFileTime

The GetSystemTimeAsFileTime function obtains the current system date and time. The information is in Coordinated Universal Time (UTC) format.

VOID GetSystemTimeAsFileTime(
  LPFILETIME lpSystemTimeAsFileTime   // pointer to a file time
                                      // structure
);

Parameters

lpSystemTimeAsFileTime
Pointer to a FILETIME structure to receive the current system date and time in UTC format.

Return Values

This function does not return a value.

Remarks

The GetSystemTimeAsFileTime function is equivalent to the following code sequence:

FILETIME ft;
SYSTEMTIME st;
GetSystemTime(&st);
SystemTimeToFileTime(&st,&ft);

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, FILETIME, GetSystemTime, SYSTEMTIME, SystemTimeToFileTime


GetTickCount

The GetTickCount function retrieves the number of milliseconds that have elapsed since the system was started. It is limited to the resolution of the system timer. If you need a higher resolution timer, use a multimedia timer or a high-resolution timer.

DWORD GetTickCount(VOID)

Parameters

This function has no parameters.

Return Values

The return value is the number of milliseconds that have elapsed since the system was started.

Remarks

The following table describes the resolution of the system timer.

System | Resolution
Windows NT 3.5 and later | The system timer runs at approximately 10ms.
Windows NT 3.1 | The system timer runs at approximately 16ms.
Windows 95 and later | The system timer runs at approximately 55ms.

The elapsed time is stored as a DWORD value. Therefore, the time will wrap around to zero if the system is run continuously for 49.7 days.

Windows NT: To obtain the time elapsed since the computer was started, look up the System Up Time counter in the performance data in the registry key HKEY_PERFORMANCE_DATA. The value returned is an 8-byte value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions


GetTimeZoneInformation

The GetTimeZoneInformation function retrieves the current time-zone parameters. These parameters control the translations between Coordinated Universal Time (UTC) and local time.

DWORD GetTimeZoneInformation(
  LPTIME_ZONE_INFORMATION lpTimeZoneInformation   // address of
                                                  // time-zone settings
);

Parameters

lpTimeZoneInformation
Pointer to a TIME_ZONE_INFORMATION structure to receive the current time-zone parameters.

Return Values

If the function succeeds, the return value is one of the following values:

Value | Meaning
TIME_ZONE_ID_UNKNOWN | The system cannot determine the current time zone. This error is also returned if you call the SetTimeZoneInformation function and supply the bias values but no transition dates. Windows NT: This value is returned if daylight savings time is not used in the current time zone, because there are no transition dates.
TIME_ZONE_ID_STANDARD | The system is operating in the range covered by the StandardDate member of the TIME_ZONE_INFORMATION structure. Windows 95: This value is returned if daylight savings time is not used in the current time zone, because there are no transition dates.
TIME_ZONE_ID_DAYLIGHT | The system is operating in the range covered by the DaylightDate member of the TIME_ZONE_INFORMATION structure.

If the function fails, the return value is TIME_ZONE_ID_INVALID. To get extended error information, call GetLastError.

Remarks

All translations between UTC time and local time are based on the following formula:

UTC = local time + bias

The bias is the difference, in minutes, between UTC time and local time.

Windows CE: The GetTimeZoneInformation function always returns TIME_ZONE_ID_UNKNOWN.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, SetTimeZoneInformation, TIME_ZONE_INFORMATION


LocalFileTimeToFileTime

The LocalFileTimeToFileTime function converts a local file time to a file time based on the Coordinated Universal Time (UTC).

BOOL LocalFileTimeToFileTime(
  CONST FILETIME *lpLocalFileTime,
                          // address of local file time to convert
  LPFILETIME lpFileTime   // address of converted file time
);

Parameters

lpLocalFileTime
Pointer to a FILETIME structure that specifies the local file time to be converted into a UTC-based file time.
lpFileTime
Pointer to a FILETIME structure to receive the converted UTC-based file time. This parameter cannot be the same as the lpLocalFileTime parameter.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, use the GetLastError function.

Remarks

LocalFileTimeToFileTime uses the current settings for the time zone and daylight saving time. Therefore, if it is daylight saving time, this function will take daylight saving time into account, even if the time you are converting is in standard time.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, FILETIME, FileTimeToLocalFileTime


SetFileTime

The SetFileTime function sets the date and time that a file was created, last accessed, or last modified.

BOOL SetFileTime(
  HANDLE hFile,                      // handle to the file
  CONST FILETIME *lpCreationTime,    // time the file was created
  CONST FILETIME *lpLastAccessTime,  // time the file was last
                                     // accessed
  CONST FILETIME *lpLastWriteTime    // time the file was last written
);

Parameters

hFile
Handle to the file for which to set the dates and times. The file handle must have been created with GENERIC_WRITE access to the file.
lpCreationTime
Pointer to a FILETIME structure that contains the date and time the file was created. This parameter can be NULL if the application does not need to set this information.
lpLastAccessTime
Pointer to a FILETIME structure that contains the date and time the file was last accessed. The last access time includes the last time the file was written to, read from, or (in the case of executable files) run. This parameter can be NULL if the application does not need to set this information.
lpLastWriteTime
Pointer to a FILETIME structure that contains the date and time the file was last written to. This parameter can be NULL if the application does not want to set this information.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The FAT and NTFS file systems support the file creation, last access, and last write time values.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, FILETIME, GetFileSize, GetFileTime, GetFileType


SetLocalTime

The SetLocalTime function sets the current local time and date.

BOOL SetLocalTime(
  CONST SYSTEMTIME *lpSystemTime   // address of local time to set
);

Parameters

lpSystemTime
Pointer to a SYSTEMTIME structure that contains the current local date and time.

The wDayOfWeek member of the SYSTEMTIME structure is ignored.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows NT: The system uses UTC internally. Therefore, when you call SetLocalTime, Windows NT uses the current time zone information, including the Daylight Saving Time setting, to perform the conversion. Note that Windows NT uses the Daylight Saving Time setting of the current time, not the new time you are setting. Therefore, calling SetLocalTime again, now that the Daylight Saving Time setting is set for the new time, will guarantee the correct result.

Windows NT: The SetLocalTime function fails if the calling process does not have the SE_SYSTEMTIME_NAME privilege. This privilege is disabled by default. Use the AdjustTokenPrivileges function to enable this privilege and again to disable it after the time has been set. For more information about security privileges, see Privileges.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, AdjustTokenPrivileges, GetLocalTime, GetSystemTime, SetSystemTimeAdjustment, SYSTEMTIME


SetSystemTime

The SetSystemTime function sets the current system time and date. The system time is expressed in Coordinated Universal Time (UTC).

BOOL SetSystemTime(
  CONST SYSTEMTIME *lpSystemTime   // address of system time to set
);

Parameters

lpSystemTime
Pointer to a SYSTEMTIME structure that contains the current system date and time.

The wDayOfWeek member of the SYSTEMTIME structure is ignored.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows NT: The SetSystemTime function enables the SE_SYSTEMTIME_NAME privilege before changing the system time. This privilege is disabled by default. For more information about security privileges, see Privileges.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, GetSystemTime, SetSystemTimeAdjustment, SYSTEMTIME


SetSystemTimeAdjustment

The SetSystemTimeAdjustment function tells the system to enable or disable periodic time adjustments to its time of day clock. Such time adjustments are used to synchronize the time of day with some other source of time information. When periodic time adjustments are enabled, they are applied at each clock interrupt.

BOOL SetSystemTimeAdjustment(
  DWORD dwTimeAdjustment,  // size, in 100-nanosecond units, of a
                           // periodic time adjustment
  BOOL bTimeAdjustmentDisabled
                           // whether periodic time adjustment is to
                           // be disabled or enabled
);

Parameters

dwTimeAdjustment
Specifies the number of 100-nanosecond units added to the time-of-day clock at each clock interrupt if periodic time adjustment is enabled.
bTimeAdjustmentDisabled
Specifies the time adjustment mode that the system is to use. Periodic system time adjustments can be disabled or enabled.

A value of TRUE specifies that periodic time adjustment is to be disabled. The system is free to adjust time of day using its own internal mechanisms. The value of dwTimeAdjustment is ignored. The system's internal adjustment mechanisms may cause the time-of-day clock to jump noticeably when adjustments are made.

A value of FALSE specifies that periodic time adjustment is to be enabled, and will be used to adjust the time-of-day clock. The system will not interfere with the time adjustment scheme, and will not attempt to synchronize time of day on its own. The system will add the value of dwTimeAdjustment to the time of day at each clock interrupt.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. One way the function can fail is if the caller does not possess the SE_SYSTEMTIME_NAME privilege.

Remarks

The GetSystemTimeAdjustment and SetSystemTimeAdjustment functions support algorithms that synchronize the time-of-day clock, reported via GetSystemTime and GetLocalTime, with another time source using a periodic time adjustment.

The SetSystemTimeAdjustment function supports two modes of time synchronization: time-adjustment – disabled and time-adjustment – enabled.

In the first mode, bTimeAdjustmentDisabled is set to FALSE. At each clock interrupt, the system adds the value of dwTimeAdjustment to the time of day. The clock interrupt rate may be determined by calling GetSystemTimeAdjustment, and looking at the returned value of the DWORD value pointed to by lpTimeIncrement.

In the second mode, bTimeAdjustmentDisabled is set to TRUE. At each clock interrupt, the system adds the interval between clock interrupts to the time of day. No adjustment to that interval is made. The system is free to periodically refresh the time-of-day clock using other techniques. Such other techniques may cause the time-of-day clock to jump noticeably when adjustments are made.

An application must have system-time privilege (the SE_SYSTEMTIME_NAME privilege) for this function to succeed. The SE_SYSTEMTIME_NAME privilege is disabled by default. Use the AdjustTokenPrivileges function to enable the privilege before calling SetSystemTimeAdjustment, and then to disable the privilege after the SetSystemTimeAdjustment call.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, AdjustTokenPrivileges, GetSystemTimeAdjustment, SetLocalTime, SetSystemTime, SystemTimeToTzSpecificLocalTime


SetTimeZoneInformation

The SetTimeZoneInformation function sets the current time-zone parameters. These parameters control translations from Coordinated Universal Time (UTC) to local time.

BOOL SetTimeZoneInformation(
  CONST TIME_ZONE_INFORMATION *lpTimeZoneInformation   // address of
                                                       // time-zone
                                                       // settings
);

Parameters

lpTimeZoneInformation
Pointer to a TIME_ZONE_INFORMATION structure that contains the time-zone parameters to set.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

All translations between UTC and local time are based on the following formula:

UTC = local time + bias

The bias is the difference, in minutes, between UTC and local time.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, GetTimeZoneInformation, TIME_ZONE_INFORMATION


SystemTimeToFileTime

The SystemTimeToFileTime function converts a system time to a file time.

BOOL SystemTimeToFileTime(
  CONST SYSTEMTIME *lpSystemTime,
                          // address of system time to convert
  LPFILETIME lpFileTime   // address of buffer for converted file
                          // time
);

Parameters

lpSystemTime
Pointer to a SYSTEMTIME structure that contains the time to be converted.

The wDayOfWeek member of the SYSTEMTIME structure is ignored.

lpFileTime
Pointer to a FILETIME structure to receive the converted system time.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, DosDateTimeToFileTime, FILETIME, FileTimeToDosDateTime, FileTimeToSystemTime, SYSTEMTIME


SystemTimeToTzSpecificLocalTime

The SystemTimeToTzSpecificLocalTime function converts a Coordinated Universal Time (UTC) to a specified time zone's corresponding local time.

BOOL SystemTimeToTzSpecificLocalTime(
  LPTIME_ZONE_INFORMATION lpTimeZoneInformation,
                            // pointer to time zone of interest
  LPSYSTEMTIME lpUniversalTime,
                            // pointer to universal time of interest
  LPSYSTEMTIME lpLocalTime  // pointer to structure to receive local
                            // time
);

Parameters

lpTimeZoneInformation
Pointer to a TIME_ZONE_INFORMATION structure that specifies the time zone of interest.

If lpTimeZoneInformation is NULL, the function uses the currently active time zone.

lpUniversalTime
Pointer to a SYSTEMTIME structure that specifies a UTC. The function converts this universal time to the specified time zone's corresponding local time.
lpLocalTime
Pointer to a SYSTEMTIME structure that receives the local time information.

Return Values

If the function succeeds, the return value is nonzero, and the function sets the members of the SYSTEMTIME structure pointed to by lpLocalTime to the appropriate local time values.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

SystemTimeToTzSpecifcLocalTime uses the current settings for the time zone and daylight saving time. Therefore, if it is daylight saving time, this function will take daylight saving time into account, even if the time you are converting is in standard time.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Time Overview, Time Functions, GetSystemTime, GetTimeZoneInformation, SYSTEMTIME, TIME_ZONE_INFORMATION


Time Structures

The following structures are used with time.

FILETIME
SYSTEMTIME
TIME_ZONE_INFORMATION


FILETIME

The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601.

typedef struct _FILETIME { // ft
    DWORD dwLowDateTime;
    DWORD dwHighDateTime;
} FILETIME;

Members

dwLowDateTime
Specifies the low-order 32 bits of the file time.
dwHighDateTime
Specifies the high-order 32 bits of the file time.

Remarks

It is not recommended that you add and subtract values from the FILETIME structure to obtain relative times. Instead, you should

  • Copy the resulting FILETIME structure to a LARGE_INTEGER structure.
  • Use normal 64-bit arithmetic on the LARGE_INTEGER value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.

See Also

Time Overview, Time Structures, CompareFileTime, GetFileTime, LARGE_INTEGER


SYSTEMTIME

The SYSTEMTIME structure represents a date and time using individual members for the month, day, year, weekday, hour, minute, second, and millisecond.

typedef struct _SYSTEMTIME {  // st
    WORD wYear;
    WORD wMonth;
    WORD wDayOfWeek;
    WORD wDay;
    WORD wHour;
    WORD wMinute;
    WORD wSecond;
    WORD wMilliseconds;
} SYSTEMTIME;

Members

wYear
Specifies the current year.
wMonth
Specifies the current month; January = 1, February = 2, and so on.
wDayOfWeek
Specifies the current day of the week; Sunday = 0, Monday = 1, and so on.
wDay
Specifies the current day of the month.
wHour
Specifies the current hour.
wMinute
Specifies the current minute.
wSecond
Specifies the current second.
wMilliseconds
Specifies the current millisecond.

Remarks

It is not recommended that you add and subtract values from the SYSTEMTIME structure to obtain relative times. Instead, you should

  • Convert the SYSTEMTIME structure to a FILETIME structure.
  • Copy the resulting FILETIME structure to a LARGE_INTEGER structure.
  • Use normal 64-bit arithmetic on the LARGE_INTEGER value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.

See Also

Time Overview, Time Structures, FILETIME, GetSystemTime, LARGE_INTEGER, SetSystemTime


TIME_ZONE_INFORMATION

The TIME_ZONE_INFORMATION structure specifies information specific to the time zone.

typedef struct _TIME_ZONE_INFORMATION { // tzi
    LONG       Bias;
    WCHAR      StandardName[ 32 ];
    SYSTEMTIME StandardDate;
    LONG       StandardBias;
    WCHAR      DaylightName[ 32 ];
    SYSTEMTIME DaylightDate;
    LONG       DaylightBias;
} TIME_ZONE_INFORMATION;

Members

Bias
Specifies the current bias, in minutes, for local time translation on this computer. The bias is the difference, in minutes, between Coordinated Universal Time (UTC) and local time. All translations between UTC and local time are based on the following formula:

UTC = local time + bias

This member is required.

StandardName
Specifies a null-terminated string associated with standard time on this operating system. For example, this parameter could contain "EST" to indicate Eastern Standard Time. This string is not used by the operating system, so anything stored there by using the SetTimeZoneInformation function is returned unchanged by the GetTimeZoneInformation function. This string can be empty.
StandardDate
Specifies a SYSTEMTIME structure that contains a date and local time when the transition from daylight time to standard time occurs on this operating system. If this date is not specified, the wMonth member in the SYSTEMTIME structure must be zero. If this date is specified, the DaylightDate value in the TIME_ZONE_INFORMATION structure must also be specified.

This member supports two date formats. Absolute format specifies an exact date and time when standard time begins. In this form, the wYear, wMonth, wDay, wHour, wMinute, wSecond, and wMilliseconds members of the SYSTEMTIME structure are used to specify an exact date.

Day-in-month format is specified by setting the wYear member to zero, setting the wDayOfWeek member to an appropriate weekday, and using a wDay value in the range 1 through 5 to select the correct day in the month. Using this notation, the first Sunday in April can be specified, as can the last Thursday in October (5 is equal to "the last").

StandardBias
Specifies a bias value to be used during local time translations that occur during standard time. This member is ignored if a value for the StandardDate member is not supplied.

This value is added to the value of the Bias member to form the bias used during standard time. In most time zones, the value of this member is zero.

DaylightName
Specifies a null-terminated string associated with daylight time on this operating system. For example, this parameter could contain "PDT" to indicate Pacific Daylight Time. This string is not used by the operating system, so anything stored there by using the SetTimeZoneInformation function is returned unchanged by the GetTimeZoneInformation function. This string can be empty.
DaylightDate
Specifies a SYSTEMTIME structure that contains a date and local time when the transition from standard time to daylight time occurs on this operating system. If this date is not specified, the wMonth member in the SYSTEMTIME structure must be zero. If this date is specified, the StandardDate value in the TIME_ZONE_INFORMATION structure must also be specified. This member supports the absolute and day-in-month time formats described for the StandardDate member.
DaylightBias
Specifies a bias value to be used during local time translations that occur during daylight time. This member is ignored if a value for the DaylightDate member is not supplied.

This value is added to the value of the Bias member to form the bias used during daylight time. In most time zones, the value of this member is – 60.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.

See Also

Time Overview, Time Structures, GetTimeZoneInformation, SetTimeZoneInformation, SYSTEMTIME


Time Messages

The following message is used with time.

WM_TIMECHANGE


WM_TIMECHANGE

Windows NT 5.0 and later: An application should not broadcast this message, because the system will broadcast this message when the application changes the system time.

Windows NT 4.0 and earlier: An application should send the WM_TIMECHANGE message to all top-level windows after changing the system time.

Windows 95: An application should send the WM_TIMECHANGE message to all top-level windows after changing the system time.

WM_TIMECHANGE
wParam = 0; // not used, must be zero
lParam = 0; // not used, must be zero

Parameters

This message has no parameters.

Return Values

An application should return zero if it processes this message.

Remarks

To send the WM_TIMECHANGE message to all top-level windows, an application can use the SendMessage function with the hwnd parameter set to HWND_TOPMOST.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Time Overview, Time Messages, SendMessage


Timers

A timer is an internal routine that repeatedly measures a specified interval, in milliseconds.


About Timers

Each time the specified interval (or time-out value) for a given timer elapses, the system notifies the window associated with the timer. Because the accuracy of a timer depends on the system clock rate and how often the application retrieves messages from the message queue, the time-out value is only approximate.

If you need a timer with higher precision, use the high-resolution timer. For more information, see High-Resolution Timer. If you need to be notified when a timer elapses, use the waitable timers. For more information, see Waitable Timer Objects.


Creating a Timer

A Win32-based application creates a timer by using the SetTimer function. A new timer starts timing the interval as soon as it is created. An application can change a timer's time-out value by using SetTimer and can destroy a timer by using the KillTimer function. To use system resources efficiently, applications should destroy timers that are no longer necessary.

Each timer has a unique identifier. When creating a timer, an application can either specify an identifier or have the system create a unique value. The first parameter of a WM_TIMER message contains the identifier of the timer that posted the message.

If you specify a window handle in the call to SetTimer, the application associates the timer with that window. Whenever the time-out value for the timer elapses, the system posts a WM_TIMER message to the window associated with the timer. If no window handle is given in the call to SetTimer, the application that created the timer must monitor its message queue for WM_TIMER messages and dispatch them to the appropriate window. If you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.


High-Resolution Timer

A counter is a general term used in programming to refer to an incrementing variable. Some systems include a high-resolution performance counter that provides high-resolution elapsed times.

If a high-resolution performance counter exists on the system, the QueryPerformanceFrequency function can be used to express the frequency, in counts per second. The value of the count is processor dependent. On some processors, for example, the count might be the cycle rate of the processor clock.

The QueryPerformanceCounter function retrieves the current value of the high-resolution performance counter (if one exists on the system). By calling this function at the beginning and end of a section of code, an application essentially uses the counter as a high-resolution timer. For example, suppose that QueryPerformanceFrequency indicates that the frequency of the high-resolution performance counter is 50,000 counts per second. If the application calls QueryPerformanceCounter immediately before and immediately after the section of code to be timed, the counter values might be 1500 counts and 3500 counts, respectively. These values would indicate that .04 seconds (2000 counts) elapsed while the code executed.


Using Timers

  • Creating a timer
  • Destroying a timer
  • Using timer functions to create a mousetrap


Example: Creating a Timer

The following example uses the SetTimer function to create two timers. The first timer is set for every 10 seconds, the second for every 5 minutes.

// Set two timers.

SetTimer(hwnd,             // handle of main window
    IDT_TIMER1,            // timer identifier
    10000,                 // 10-second interval
    (TIMERPROC) NULL);     // no timer callback

SetTimer(hwnd,             // handle of main window
    IDT_TIMER2,            // timer identifier
    300000,                // 5-minute interval
    (TIMERPROC) NULL);     // no timer callback

To process the WM_TIMER messages generated by these timers, add a WM_TIMER case statement to the window procedure for the hwnd parameter.

case WM_TIMER:

    switch (wParam)
{
        case IDT_TIMER1:

            // Process the 10-second timer.

             return 0;

        case IDT_TIMER2:

            // Process the 5-minute timer.

            return 0;
    }

An application can also create a timer whose WM_TIMER messages are processed not by the main window procedure but by an application-defined callback function, as in the following code sample, which creates a timer and uses the callback function MyTimerProc to process the timer's WM_TIMER messages.

// Set the timer.

SetTimer(hwnd,                // handle of main window
    IDT_TIMER3,               // timer identifier
    5000,                     // 5-second interval
    (TIMERPROC) MyTimerProc); // timer callback

The calling convention for MyTimerProc must be based on the TimerProc callback function.

If your application creates a timer without specifying a window handle, your application must monitor the message queue for WM_TIMER messages and dispatch them to the appropriate window.

HWND hwndTimer;   // handle of window for timer messages
MSG msg;          // message structure

    while (GetMessage(&msg, // message structure
            NULL,           // handle of window to receive the message
            NULL,           // lowest message to examine
            NULL))          // highest message to examine
    {

        // Post WM_TIMER messages to the hwndTimer procedure.

        if (msg.message == WM_TIMER)
        {
            msg.hwnd = hwndTimer;
        }

        TranslateMessage(&msg); // translates virtual-key codes
        DispatchMessage(&msg);  // dispatches message to window
    }


Destroying a Timer

Applications should use the KillTimer function to destroy timers that are no longer necessary. The following example destroys the timers identified by the constants IDT_TIMER1, IDT_TIMER2, and IDT_TIMER3.

// Destroy the timers.

KillTimer(hwnd, IDT_TIMER1);
KillTimer(hwnd, IDT_TIMER2);
KillTimer(hwnd, IDT_TIMER3);


Using Timer Functions to Create a Mousetrap

Sometimes it is necessary to prevent more input while you have a cursor on the screen. One way to accomplish this is to create a special routine that traps mouse input until a specific event occurs. Many developers refer to this routine as "building a mousetrap."

The following example uses the SetTimer and KillTimer functions to create a simple mousetrap. SetTimer creates a timer that sends a WM_TIMER message every 10 seconds. Each time the application receives a WM_TIMER message, it records the cursor location. If the current location is the same as the previous location and the application's main window is minimized, the application moves the cursor to the icon. When the application closes, KillTimer stops the timer.

HICON hIcon1;               // icon handle
POINT ptOld;                // previous cursor location
UINT uResult;               // SetTimer's return value
HINSTANCE hinstance;        // handle of current instance

//
// Perform application initialization here.
//

wc.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(400));
wc.hCursor = LoadCursor(hinstance, MAKEINTRESOURCE(200));

// Record the initial cursor position.

GetCursorPos(&ptOld);

// Set the timer for the mousetrap.

uResult = SetTimer(hwnd,             // handle of main window
    IDT_MOUSETRAP,                   // timer identifier
    10000,                           // 10-second interval
    (TIMERPROC) NULL);               // no timer callback

if (uResult == 0)
{
    ErrorHandler("No timer is available.");
}

LONG APIENTRY MainWndProc(
    HWND hwnd,          // handle of main window
    UINT message,       // type of message
    WPARAM  wParam,        // additional information
    LPARAM  lParam)        // additional information
{

    HDC hdc;        // handle of device context
    POINT pt;       // current cursor location
    RECT rc;        // location of minimized window

    switch (message)
    {
        //
        // Process other messages.
        //

        case WM_TIMER:
        // If the window is minimized, compare the current
        // cursor position with the one from 10 seconds
        // earlier. If the cursor position has not changed,
        // move the cursor to the icon.

            if (IsIconic(hwnd))
            {
                GetCursorPos(&pt);

                if ((pt.x == ptOld.x) && (pt.y == ptOld.y))
                {
                    GetWindowRect(hwnd, &rc);
                    SetCursorPos(rc.left, rc.top);
                }
                else
                {
                    ptOld.x = pt.x;
                    ptOld.y = pt.y;
                }
            }

            return 0;

        case WM_DESTROY:

        // Destroy the timer.

            KillTimer(hwnd, IDT_MOUSETRAP);
            PostQuitMessage(0);
            break;

        //
        // Process other messages.
        //

}

Although the following example also creates a mousetrap, it processes the WM_TIMER message through the application-defined callback function MyTimerProc, rather than through the application's message queue.

UINT uResult;               // SetTimer's return value
HICON hIcon1;               // icon handle
POINT ptOld;                // previous cursor location
HINSTANCE hinstance;        // handle of current instance

//
// Perform application initialization here.
//

wc.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(400));
wc.hCursor = LoadCursor(hinstance, MAKEINTRESOURCE(200));

// Record the current cursor position.

GetCursorPos(&ptOld);

// Set the timer for the mousetrap.

uResult = SetTimer(hwnd,      // handle of main window
    IDT_MOUSETRAP,            // timer identifier
    10000,                    // 10-second interval
    (TIMERPROC) MyTimerProc); // timer callback

if (uResult == 0)
{
    ErrorHandler("No timer is available.");
}

LONG APIENTRY MainWndProc(
    HWND hwnd,          // handle of main window
    UINT message,       // type of message
    WPARAM  wParam,        // additional information
    LPARAM   lParam)        // additional information
{

    HDC hdc;        // handle of device context

    switch (message)
    {
    //
    // Process other messages.
    //

        case WM_DESTROY:
        // Destroy the timer.

            KillTimer(hwnd, IDT_MOUSETRAP);
            PostQuitMessage(0);
            break;

        //
        // Process other messages.
        //

}

// MyTimerProc is an application-defined callback function that
// processes WM_TIMER messages.

VOID CALLBACK MyTimerProc(
    HWND hwnd,        // handle of window for timer messages
    UINT message,     // WM_TIMER message
    UINT idTimer,     // timer identifier
    DWORD dwTime)     // current system time
{

    RECT rc;
    POINT pt;

    // If the window is minimized, compare the current
    // cursor position with the one from 10 seconds earlier.
    // If the cursor position has not changed, move the
    // cursor to the icon.

    if (IsIconic(hwnd))
    {
        GetCursorPos(&pt);

        if ((pt.x == ptOld.x) && (pt.y == ptOld.y))
        {
            GetWindowRect(hwnd, &rc);
            SetCursorPos(rc.left, rc.top);
        }
        else
        {
            ptOld.x = pt.x;
            ptOld.y = pt.y;
        }
    }
}


Timer Reference

The following elements are used with timers.

  • Timer Functions
  • Timer Messages


Timer Functions

The following functions are used with timers.

KillTimer
QueryPerformanceCounter
QueryPerformanceFrequency
SetTimer
TimerProc


KillTimer

The KillTimer function destroys the specified timer.

BOOL KillTimer(
  HWND hWnd,      // handle of window that installed timer
  UINT uIDEvent   // timer identifier
);

Parameters

hWnd
Handle to the window associated with the specified timer. This value must be the same as the hWnd value passed to the SetTimer function that created the timer.
uIDEvent
Specifies the timer to be destroyed. If the window handle passed to SetTimer is valid, this parameter must be the same as the uIDEvent value passed to SetTimer. If the application calls SetTimer with hWnd set to NULL, this parameter must be the timer identifier returned by SetTimer.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The KillTimer function does not remove WM_TIMER messages already posted to the message queue.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Timers Overview, Timer Functions, SetTimer, WM_TIMER


QueryPerformanceCounter

The QueryPerformanceCounter function retrieves the current value of the high-resolution performance counter, if one exists.

BOOL QueryPerformanceCounter(
  LARGE_INTEGER *lpPerformanceCount   // pointer to counter value
);

Parameters

lpPerformanceCount
Pointer to a variable that the function sets, in counts, to the current performance-counter value. If the installed hardware does not support a high-resolution performance counter, this parameter can be to zero.

Return Values

If the installed hardware supports a high-resolution performance counter, the return value is nonzero.

If the installed hardware does not support a high-resolution performance counter, the return value is zero.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Timers Overview, Timer Functions, QueryPerformanceFrequency


QueryPerformanceFrequency

The QueryPerformanceFrequency function retrieves the frequency of the high-resolution performance counter, if one exists.

BOOL QueryPerformanceFrequency(
  LARGE_INTEGER *lpFrequency   // address of current frequency
);

Parameters

lpFrequency
Pointer to a variable that the function sets, in counts per second, to the current performance-counter frequency. If the installed hardware does not support a high-resolution performance counter, this parameter can be to zero.

Return Values

If the installed hardware supports a high-resolution performance counter, the return value is nonzero.

If the installed hardware does not support a high-resolution performance counter, the return value is zero.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Timers Overview, Timer Functions, QueryPerformanceCounter


SetTimer

The SetTimer function creates a timer with the specified time-out value.

UINT SetTimer(
  HWND hWnd,              // handle of window for timer messages
  UINT nIDEvent,          // timer identifier
  UINT uElapse,           // time-out value
  TIMERPROC lpTimerFunc   // address of timer procedure
);

Parameters

hWnd
Handle to the window to be associated with the timer. This window must be owned by the calling thread. If this parameter is NULL, no window is associated with the timer and the nIDEvent parameter is ignored.
nIDEvent
Specifies a nonzero timer identifier. If the hWnd parameter is NULL, this parameter is ignored.
uElapse
Specifies the time-out value, in milliseconds.
lpTimerFunc
Pointer to the function to be notified when the time-out value elapses. For more information about the function, see TimerProc.

If lpTimerFunc is NULL, the system posts a WM_TIMER message to the application queue. The hwnd member of the message's MSG structure contains the value of the hWnd parameter.

Return Values

If the function succeeds, the return value is an integer identifying the new timer. An application can pass this value, or the string identifier, if it exists, to the KillTimer function to destroy the timer.

If the function fails to create a timer, the return value is zero. To get extended error information, call GetLastError.

Remarks

An application can process WM_TIMER messages by including a WM_TIMER case statement in the window procedure or by specifying a TimerProc callback function when creating the timer. When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.

The wParam parameter of the WM_TIMER message contains the value of the nIDEvent parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Timers Overview, Timer Functions, KillTimer, MSG, TimerProc, WM_TIMER


TimerProc

The TimerProc function is an application-defined callback function that processes WM_TIMER messages. The TIMERPROC type defines a pointer to this callback function. TimerProc is a placeholder for the application-defined function name.

VOID CALLBACK TimerProc(
  HWND hwnd,     // handle of window for timer messages
  UINT uMsg,     // WM_TIMER message
  UINT idEvent,  // timer identifier
  DWORD dwTime   // current system time
);

Parameters

hwnd
Handle to the window associated with the timer.
uMsg
Specifies the WM_TIMER message.
idEvent
Specifies the timer's identifier.
dwTime
Specifies the number of milliseconds that have elapsed since the system was started. This is the value returned by the GetTickCount function.

Return Values

This function does not return a value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 98 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Timers Overview, Timer Functions, GetTickCount, KillTimer, SetTimer, WM_TIMER


Timer Messages

The following message is used with timers.

WM_TIMER


WM_TIMER

The WM_TIMER message is posted to the installing thread's message queue when a timer expires. You can process the message by providing a WM_TIMER case in the window procedure. Otherwise, the default window procedure will call the TimerProc callback function specified in the call to the SetTimer function used to install the timer.

WM_TIMER
wTimerID = wParam;             // timer identifier
tmprc = (TIMERPROC *) lParam;  // address of timer callback

Parameters

wTimerID
Value of wParam. Specifies the timer identifier.
tmprc
Value of lParam. Points to an application-defined callback function that was passed to the SetTimer function when the timer was installed.

Return Values

An application should return zero if it processes this message.

Remarks

The WM_TIMER message is a low-priority message. The GetMessage and PeekMessage functions retrieve this message only when no other higher-priority messages are in the thread's message queue.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.

See Also

Timers Overview, Timer Messages, GetMessage, PeekMessage, SetTimer, TimerProc


Tool Help Library

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


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 == (HANDLE)-1)
        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 == (HANDLE)-1)
        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 == (HANDLE)-1)
        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
Specifies portions of the system to include in the snapshot. This parameter can be one of the following:
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
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 Value

Returns an open handle to the specified snapshot if successful or – 1 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.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.
Import 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,
  DWORD th32HeapID
);

Parameters

lphe
Pointer to a HEAPENTRY32 structure.
th32ProcessID
Identifier of the process context that owns the heap.
th32HeapID
Identifier of the heap to enumerate.

Return Value

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.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.
Import Library: Use kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions


Heap32ListFirst

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

BOOL WINAPI Heap32ListFirst(
  HANDLE hSnapshot,
  LPHEAPLIST32 lphl
);

Parameters

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

Return Value

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.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.
Import Library: Use kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions


Heap32ListNext

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

BOOL WINAPI Heap32ListNext(
  HANDLE hSnapshot,
  LPHEAPLIST32 lphl
);

Parameters

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

Return Value

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.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.
Import 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
Pointer to a HEAPENTRY32 structure.

Return Value

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.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.
Import 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
Handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
lpme
Pointer to a MODULEENTRY32 structure.

Return Value

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.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.
Import Library: Use kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions


Module32Next

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

BOOL WINAPI Module32Next(
  HANDLE hSnapshot,
  LPMODULEENTRY32 lpme
);

Parameters

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

Return Value

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.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.
Import 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
Handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
lppe
Pointer to a PROCESSENTRY32 structure.

Return Value

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.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.
Import Library: Use kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions


Process32Next

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

BOOL WINAPI Process32Next(
  HANDLE hSnapshot,
  LPPROCESSENTRY32 lppe
);

Parameters

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

Return Value

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.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.
Import 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
Handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
lpte
Pointer to a THREADENTRY32 structure.

Return Value

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.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.
Import Library: Use kernel32.lib.

See Also

Tool Help Library Overview, Tool Help Functions


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
Handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
lpte
Pointer to a THREADENTRY32 structure.

Return Value

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.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.
Import 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,
  DWORD cbRead,
  LPDWORD lpNumberOfBytesRead
);

Parameters

th32ProcessID
Identifier of the process whose memory is being copied. This parameter can be zero to copy the memory of the current process.
lpBaseAddress
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
Pointer to a buffer that receives the contents of the address space of the specified process.
cbRead
Number of bytes to read from the specified process.
lpNumberOfBytesRead
Number of bytes copied to the specified buffer. If this parameter is NULL, it is ignored.

Return Value

Returns TRUE if successful.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.
Import Library: Use kernel32.lib.


Tool Help Structures

The following structures are used with tool help services:

HEAPENTRY32
HEAPLIST32
MODULEENTRY32
PROCESSENTRY32
THREADENTRY32

See Also

Tool Help Library Overview, Tool Help Functions


HEAPENTRY32

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

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

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:
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.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.

See Also

Tool Help Library Overview, Tool Help Structures


HEAPLIST32

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

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

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:
HF32_DEFAULT Process's default heap

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
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;
    char    szModule[MAX_MODULE_NAME32 + 1];
    char    szExePath[MAX_PATH];
} MODULEENTRY32;
typedef MODULEENTRY32 *  PMODULEENTRY32;
typedef MODULEENTRY32 *  LPMODULEENTRY32;

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 modBaseAddr and hModule are valid only in the context of the process specified by th32ProcessID.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.

See Also

Tool Help Library Overview, Tool Help Structures


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;
    DWORD th32DefaultHeapID;
    DWORD th32ModuleID;
    DWORD cntThreads;
    DWORD th32ParentProcessID;
    LONG  pcPriClassBase;
    DWORD dwFlags;
    char szExeFile[MAX_PATH];
} PROCESSENTRY32;
typedef PROCESSENTRY32 *  PPROCESSENTRY32;
typedef PROCESSENTRY32 *  LPPROCESSENTRY32;

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.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
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;
typedef THREADENTRY32 *  LPTHREADENTRY32;

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 1 point below normal priority for the priority class.
THREAD_PRIORITY_NORMAL | Indicates normal priority for the priority class.
THREAD_PRIORITY_ABOVE_
NORMAL 		Indicates 1 point above normal priority for the priority class.
THREAD_PRIORITY_HIGHEST | Indicates 2 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.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in tlhelp32.h.

See Also

Tool Help Library Overview, Tool Help Structures


Device Input and Output

Win32-based applications use a device input and output control to communicate with a device driver. This overview discusses device handles, which identify the device being accessed, and device control codes, which specify the action the driver is to perform.


About Device Input and Output

The DeviceIoControl function provides a device input and output control (IOCTL) interface through which an application can communicate directly with a device driver. The DeviceIoControl function is a general-purpose interface that can send control codes to a variety of devices.

This overview discusses the following topics:

  • Device handles
  • Device control codes


Device Handles

A DeviceIoControl call specifies a handle to a device driver to identify the device being accessed. You can use the CreateFile function to get a device driver handle.

The CreateFile call must specify either the name of a device or the name of the driver associated with a device. To specify a device name, the lpszname parameter of CreateFile specifies a string with the format

\\.\DeviceName

The types of devices that you can open and the method that you must use to specify them in the CreateFile function depend on the Win32 platform on which your application is running.

Windows NT: The DeviceIoControl function can open a handle to a specific device. For example, to open a handle to the logical drive A:, specify "\\\\.\\a:". Alternatively, you can use the names "\\\\.\\PhysicalDrive0", "\\\\.\\PhysicalDrive1", and so on, to open handles to the physical drives on a system.

Windows 95 and Windows 98: For Win32-based applications, DeviceIoControl must specify a handle to a virtual device driver. For example, to open a handle to the system VxD, specify "\\\\.\\vwin32".

The CreateFile call should specify the FILE_SHARE_READ and FILE_SHARE_WRITE access flags when opening a handle to a device driver. However, when opening a communications resource, such as a serial port, CreateFile must specify exclusive access. Other CreateFile parameters are used as follows when opening a device handle:

  • The fdwCreate parameter must specify the OPEN_EXISTING flag.
  • The hTemplateFile parameter must be NULL.
  • The fdwAttrsAndFlags parameter can specify FILE_FLAG_OVERLAPPED to indicate that the returned handle can be used in overlapped (asynchronous) I/O operations.


Device Control Codes

An application can use the DeviceIoControl function to send a control code to a device driver. The control code specifies the action that the driver is to perform. For example, a control code can ask a device driver to return information about the corresponding device, or direct the driver to carry out an action on the device, such as formatting a disk.

A number of standard control codes are defined in the Win32 header files. For a list of standard control codes, see the DeviceIoControl topic. In addition, device drivers can define their own device-specific control codes. The types of control codes you can specify depend on the device being accessed and the Win32 platform on which your application is running.

Windows NT: Applications can use the standard control codes or device-specific control codes to perform direct input and output operations on a floppy disk drive, hard disk drive, tape drive, or CD-ROM drive.

Windows 95 and Windows 98: Win32-based applications cannot use the standard control codes in the SDK header files. These applications are restricted to using the control codes supported by the virtual device driver being accessed. For example, the system VxD, VWIN32.VXD, supports the input and output control (IOCTL) functions originally provided by MS-DOS Interrupt 21h.

The control code specified in a DeviceIoControl call determines the values that must be specified for the other DeviceIoControl parameters. For example, a Win32-based application can specify the IOCTL_DISK_FORMAT_TRACKS control code. In this case, the lpvInBuffer parameter must point to a filled-in FORMAT_PARAMETERS structure, and the nInBufferSize parameter must specify the size of the structure.


Using Device Input and Output Control

  • Calling DeviceIoControl on Windows NT
  • Calling DeviceIoControl on Windows 95


Calling DeviceIoControl on Windows NT

On Windows NT, an application can use the DeviceIoControl function to perform direct input and output operations on, or retrieve information about, a floppy disk drive, hard disk drive, tape drive, or CD-ROM drive. The following example demonstrates how to retrieve information about the first physical drive in the system. It uses the CreateFile function to obtain the device handle to the first physical drive, and then uses the DeviceIoControl function with the IOCTL_DISK_GET_DRIVE_GEOMETRY control code to fill a DISK_GEOMETRY structure with information about the drive.

BOOL GetDriveGeometry(DISK_GEOMETRY *pdg)
{
    HANDLE hDevice;
    BOOL fResult;
    DWORD cb;

    hDevice = CreateFile("\\\\.\\PhysicalDrive0",
        0, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL, OPEN_EXISTING, 0, NULL);

    if (hDevice == NULL)
        return FALSE;

    fResult = DeviceIoControl(hDevice,
        IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
        pdg, sizeof(*pdg), &cb, (LPOVERLAPPED) NULL);

    if (!fResult)
        return FALSE;

    CloseHandle(hDevice);
}

This example succeeds only when it runs on Windows NT, for two reasons:

  • The standard device input/output control codes are available only on Windows NT, and
  • On Windows 95, an application must specify a virtual device driver in the CreateFile function — not a specific device.


Calling DeviceIoControl on Windows 95

A Win32-based application running on Windows 95 and Windows 98 can use the DeviceIoControl function to send control codes directly to a virtual device driver (VxD). Any VxD can support any number of control codes, or none at all.

The system VxD, VWIN32.VXD, supports the input and output control (IOCTL) functions originally provided by MS-DOS Interrupt 21h. The following example shows how to call Get Media ID (Interrupt 21h Function 440Dh Minor Code 66h) from a Win32-based application:

#define VWIN32_DIOC_DOS_IOCTL 1

typedef struct _DEVIOCTL_REGISTERS
{
    DWORD reg_EBX;
    DWORD reg_EDX;
    DWORD reg_ECX;
    DWORD reg_EAX;
    DWORD reg_EDI;
    DWORD reg_ESI;
    DWORD reg_Flags;
} DEVIOCTL_REGISTERS, *PDEVIOCTL_REGISTERS;

typedef struct _MID
{
    WORD  midInfoLevel;
    DWORD midSerialNum;
    BYTE  midVolLabel[11];
    BYTE  midFileSysType[8];
} MID, *PMID;

BOOL GetMediaID(PMID pmid, UINT nDrive)
{
    DEVIOCTL_REGISTERS reg;

    reg.reg_EAX = 0x440D;       // IOCTL for block devices
    reg.reg_EBX = nDrive;       // zero-based drive ID
    reg.reg_ECX = 0x0866;       // Get Media ID command
    reg.reg_EDX = (DWORD) pmid; // receives media ID info

    if (!DoIOCTL(&reg))
        return FALSE;

    if (reg.reg_Flags & 0x8000) // error if carry flag set
        return FALSE;

    return TRUE;
}

BOOL DoIOCTL(PDEVIOCTL_REGISTERS preg)
{
    HANDLE hDevice;

    BOOL fResult;
    DWORD cb;

    preg->reg_Flags = 0x8000; // assume error (carry flag set)

    hDevice = CreateFile("\\\\.\\vwin32",
        GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
        (LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);

    if (hDevice == (HANDLE) INVALID_HANDLE_VALUE)
        return FALSE;
    else
    {
        fResult = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL,
            preg, sizeof(*preg), preg, sizeof(*preg), &cb, 0);

        if (!fResult)
            return FALSE;
    }

    CloseHandle(hDevice);

    return TRUE;
}


Device Input and Output Reference

The following elements are used with device input and output.

  • Device Input and Output Functions
  • Device Input and Output Operations
  • Device Input and Output Structures
  • Device Input and Output Enumeration Types


Device Input and Output Functions

The following function is used with device input and output.

DeviceIoControl


DeviceIoControl

The DeviceIoControl function sends a control code directly to a specified device driver, causing the corresponding device to perform the specified operation.

BOOL DeviceIoControl(
  HANDLE hDevice,              // handle to device of interest
  DWORD dwIoControlCode,       // control code of operation to perform
  LPVOID lpInBuffer,           // pointer to buffer to supply input data
  DWORD nInBufferSize,         // size, in bytes, of input buffer
  LPVOID lpOutBuffer,          // pointer to buffer to receive output data
  DWORD nOutBufferSize,        // size, in bytes, of output buffer
  LPDWORD lpBytesReturned,     // pointer to variable to receive byte count
  LPOVERLAPPED lpOverlapped    // pointer to structure for asynchronous operation
);

Parameters

hDevice
Handle to the device that is to perform the operation. Call the CreateFile function to obtain a device handle.
dwIoControlCode
Specifies the control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. The following values are defined:
Value | Meaning
FSCTL_ALLOW_EXTENDED_DASD_IO | Signals the file system driver not to perform any I/O boundary checks on partition read or write calls. Instead, boundary checks are performed by the device driver.
FSCTL_DELETE_REPARSE_POINT | Deletes a reparse point for a file or directory.
FSCTL_DISMOUNT_VOLUME | Dismounts a volume.
FSCTL_ENABLE_UPGRADE | Enables or disables upgrading an NTFS volume to NTFS version 5.
FSCTL_GET_COMPRESSION | Obtains the compression state of a file or directory
FSCTL_GET_HFS_INFORMATION | Returns Macintosh Finder information about the file associated with the input handle.
FSCTL_GET_REPARSE_POINT | Returns reparse point data for a file or directory.
FSCTL_LOCK_VOLUME | Locks a volume.
FSCTL_QUERY_ALLOCATED_RANGES | Scans a file for ranges of the file for which disk space is allocated.
FSCTL_QUERY_FAT_BPB | Returns the first 36 bytes of a FAT16 or FAT12 volume.
FSCTL_READ_COMPRESSION | Reserved for future use.
FSCTL_SET_COMPRESSION | Sets the compression state of a file or directory.
FSCTL_SET_REPARSE_POINT | Sets a reparse point on a file or directory.
FSCTL_SET_SPARSE | Marks a file as a sparse file.
FSCTL_SET_ZERO_DATA | Sets a range of a files bytes to zeroes.
FSCTL_UNLOCK_VOLUME | Unlocks a volume.
FSCTL_WRITE_COMPRESSION | Reserved for future use.
IOCTL_DISK_CHECK_VERIFY | Obsolete. Use IOCTL_STORAGE_CHECK_VERIFY
IOCTL_DISK_EJECT_MEDIA | Obsolete. Use IOCTL_STORAGE_EJECT_MEDIA
IOCTL_DISK_FORMAT_TRACKS | Formats a contiguous set of disk tracks.
IOCTL_DISK_GET_DRIVE_GEOMETRY | Obtains information on the physical disk's geometry.
IOCTL_DISK_GET_DRIVE_LAYOUT | Provides information about each partition on a disk.
IOCTL_DISK_GET_MEDIA_TYPES | Obsolete. Use IOCTL_STORAGE_GET_MEDIA_TYPES
IOCTL_DISK_GET_PARTITION_INFO | Obtains disk partition information.
IOCTL_DISK_LOAD_MEDIA | Obsolete. Use IOCTL_STORAGE_LOAD_MEDIA
IOCTL_DISK_MEDIA_REMOVAL | Obsolete. Use IOCTL_STORAGE_MEDIA_REMOVAL
IOCTL_DISK_PERFORMANCE | Provides disk performance information.
IOCTL_DISK_REASSIGN_BLOCKS | Maps disk blocks to spare-block pool.
IOCTL_DISK_SET_DRIVE_LAYOUT | Partitions a disk.
IOCTL_DISK_SET_PARTITION_INFO | Sets the disk partition type.
IOCTL_DISK_VERIFY | Performs logical format of a disk extent.
IOCTL_SERIAL_LSRMST_INSERT | Enables or disables placement of a line and modem status data into the data stream.
IOCTL_STORAGE_CHECK_VERIFY | Checks for change in a removable-media device.
IOCTL_STORAGE_EJECT_MEDIA | Ejects media from a SCSI device.
IOCTL_STORAGE_GET_MEDIA_TYPES | Obtains information about media support.
IOCTL_STORAGE_LOAD_MEDIA | Loads media into a device.
IOCTL_STORAGE_MEDIA_REMOVAL | Enables or disables the media eject mechanism.

For more detailed information on each control code, see its topic. In particular, each topic provides details on the usage of the lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, and lpBytesReturned parameters.

lpInBuffer
Pointer to a buffer that contains the data required to perform the operation.

This parameter can be NULL if the dwIoControlCode parameter specifies an operation that does not require input data.

nInBufferSize
Size, in bytes, of the buffer pointed to by lpInBuffer.
lpOutBuffer
Pointer to a buffer that receives the operation's output data.

This parameter can be NULL if the dwIoControlCode parameter specifies an operation that does not produce output data.

nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer.
lpBytesReturned
Pointer to a variable that receives the size, in bytes, of the data stored into the buffer pointed to by lpOutBuffer.

If lpOverlapped is NULL, lpBytesReturned cannot be NULL. Even when an operation produces no output data, and lpOutBuffer can be NULL, the DeviceIoControl function makes use of the variable pointed to by lpBytesReturned. After such an operation, the value of the variable is without meaning.

If lpOverlapped is not NULL, lpBytesReturned can be NULL. If this is an overlapped operation, you can get the number of bytes returned by calling GetOverlappedResult. If hDevice is associated with an I/O completion port, you can get the number of bytes returned by calling GetQueuedCompletionStatus.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or an error occurs.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If hDevice was opened with FILE_FLAG_OVERLAPPED and the lpOverlapped parameter points to an OVERLAPPED structure, DeviceIoControl is performed as an overlapped (asynchronous) operation. In this case, the OVERLAPPED structure must contain a handle to a manual-reset event object created by a call to the CreateEvent function. For more information on manual-reset event objects, see Synchronization.

Windows CE: No specific values are defined for the dwIoControlCode parameter. However, the writer of a custom device driver can define IOCTL_XXXX control codes, per the CTL_CODE macro. These control codes can then be advertised, and an application can use these control codes with DeviceIoControl to perform the driver-specific functions.

The lpOverlapped parameter is ignored and should be NULL.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Device Input and Output Overview, Device Input and Output Functions, CreateEvent, CreateFile, GetOverlappedResult, GetQueuedCompletionStatus, OVERLAPPED


Device Input and Output Operations

The following DeviceIoControl operations are used with reparse points.

FSCTL_DELETE_REPARSE_POINT
FSCTL_GET_REPARSE_POINT
FSCTL_SET_REPARSE_POINT

The following DeviceIoControl operations are used with sparse files.

FSCTL_QUERY_ALLOCATED_RANGES
FSCTL_SET_SPARSE
FSCTL_SET_ZERO_DATA

The following operations are used with device input and output.

FSCTL_ALLOW_EXTENDED_DASD_IO

FSCTL_DISMOUNT_VOLUME
FSCTL_ENABLE_UPGRADE
FSCTL_GET_COMPRESSION
FSCTL_GET_HFS_INFORMATION
FSCTL_LOCK_VOLUME
FSCTL_SET_COMPRESSION
FSCTL_UNLOCK_VOLUME
IOCTL_DISK_FORMAT_TRACKS
IOCTL_DISK_GET_DRIVE_GEOMETRY
IOCTL_DISK_GET_DRIVE_LAYOUT
IOCTL_DISK_GET_PARTITION_INFO
IOCTL_DISK_PERFORMANCE
IOCTL_DISK_REASSIGN_BLOCKS
IOCTL_DISK_SET_DRIVE_LAYOUT
IOCTL_DISK_SET_PARTITION_INFO
IOCTL_DISK_VERIFY
IOCTL_SERIAL_LSRMST_INSERT
IOCTL_STORAGE_CHECK_VERIFY
IOCTL_STORAGE_EJECT_MEDIA
IOCTL_STORAGE_GET_MEDIA_TYPES
IOCTL_STORAGE_LOAD_MEDIA
IOCTL_STORAGE_MEDIA_REMOVAL

Obsolete Operations

FSCTL_QUERY_FAT_BPB
IOCTL_DISK_CHECK_VERIFY
IOCTL_DISK_EJECT_MEDIA
IOCTL_DISK_GET_MEDIA_TYPES
IOCTL_DISK_LOAD_MEDIA
IOCTL_DISK_MEDIA_REMOVAL


FSCTL_ALLOW_EXTENDED_DASD_IO

[This is preliminary documentation and subject to change.]

The FSCTL_ALLOW_EXTENDED_DASD_IO operation signals the file system driver not to perform any I/O boundary checks on partition read or write calls. Instead, boundary checks are performed by the device driver. To perform this operation, call the DeviceIoControl function with the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  FSCTL_ALLOW_EXTENDED_DASD_IO,  // dwIoControlCode, control code of
                           // operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the logical volume (partition) on which extended read or write operations are to be allowed. To obtain a device handle, call the CreateFile function with the FILE_SHARE_READ and FILE_SHARE_WRITE flags in the dwShareMode parameter. The process must have Administrator privileges to read from or write to the partition.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which to perform it. Use FSCTL_ALLOW_EXTENDED_DASD_IO for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to the output buffer. Not used; must be NULL.
nOutBuffer
Size, in bytes, of the output buffer. Not used; must be zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

A call using the FSCTL_ALLOW_EXTENDED_DASD_IO control code should only be used with great caution by programmers familiar with the underlying structure of a hard drive and file system. Improper use or inaccurate checking in subsequent write operations to the partition can result in damage to data on the partition, or destruction of the entire partition.

The FSCTL_ALLOW_EXTENDED_DASD_IO operation, an extended Direct Access to Storage Device (DASD) operation, is used to signal the file system driver not to perform any I/O boundary checks on read or write calls made with the specified handle. FSCTL_ALLOW_EXTENDED_DASD_IO allows access to hidden sectors, a part of the partition that might exist between the first sector of the partition (the boot parameter block) and the first useful sector of the partition. FSCTL_ALLOW_EXTENDED_DASD_IO also allows access to lost clusters, which might exist between the last useful cluster and the end of the partition.

I/O requests after a FSCTL_ALLOW_EXTENDED_DASD_IO operation are passed directly to the device driver. If these subsequent calls request data beyond the partition boundary, the driver causes them to fail.

For the implications of overlapped I/O on an FSCTL_ALLOW_EXTENDED_DASD_IO operation, see the Remarks section of DeviceIoControl.

To obtain a handle to a partition, pass in the CreateFile parameter lpFileName a value of the following form:

\\.\X:

where X is the drive letter.

The application calling CreateFile must also specify the FILE_SHARE_READ and FILE_SHARE_WRITE flags in the dwShareMode parameter of CreateFile. For more information, see the Disk Devices section in CreateFile.

To determine the partition structure of the drive and to determine if Windows NT recognizes the partition, use the IOCTL_DISK_GET_DRIVE_LAYOUT operation. For similar information on a single partition, use the IOCTL_DISK_GET_PARTITION_INFO operation. To determine the size of a cluster, use the GetDiskFreeSpaceEx or GetDiskFreeSpace function, as appropriate.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

CreateFile, DeviceIoControl, GetDiskFreeSpace, GetDiskFreeSpaceEx, IOCTL_DISK_GET_DRIVE_LAYOUT, IOCTL_DISK_GET_PARTITION_INFO, OVERLAPPED


FSCTL_DELETE_REPARSE_POINT

[This is preliminary documentation and subject to change.]

The FSCTL_DELETE_REPARSE_POINT operation deletes a reparse point from the file or directory identified by the specified handle. This operation does not delete the file or directory.

To perform this operation, call the DeviceIoControl function with the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to the file or directory
  FSCTL_DELETE_REPARSE_POINT,  // dwIoControlCode, control code of
                           // operation to perform
  (LPVOID) lpInBuffer,     // pointer to REPARSE_DATA_BUFFER structure
  (DWORD) nInBufferSize,   // size, in bytes, of lpInBuffer
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used; must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to an OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the file or directory from which the reparse point is to be deleted. The handle must have write access to the file or directory. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use FSCTL_DELETE_REPARSE_POINT for this operation.
lpInBuffer
Pointer to a REPARSE_DATA_BUFFER structure. The ReparseTag member of this structure must specify the tag of the reparse point to be deleted. The ReparseDataLength member must be zero.
nInBufferSize
Size, in bytes, of the lpInBuffer buffer. This value must be REPARSE_DATA_BUFFER_HEADER_SIZE.
lpOutBuffer
Pointer to the output buffer. Not used; must be NULL.
nOutBufferSize
Size, in bytes, of the output buffer. Not used; must be zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL, lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL, lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If hDevice was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. For extended error information, call GetLastError.

Remarks

For the implications of overlapped I/O on this operation, see the Remarks section of the DeviceIoControl topic.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, CreateFile, DeviceIoControl, FSCTL_GET_REPARSE_POINT, FSCTL_SET_REPARSE_POINT


FSCTL_DISMOUNT_VOLUME

The FSCTL_DISMOUNT_VOLUME operation dismounts a volume. To perform this operation, call the DeviceIoControl function using the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to a file
  FSCTL_DISMOUNT_VOLUME,   // dwIoControlCode, control code of
                           // operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use FSCTL_DISMOUNT_VOLUME for this operation.
lpInBuffer
Pointer to an input buffer. Not used, set to NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to the output buffer. Not used; must be NULL
nOutBufferSize
Size, in bytes, of the output buffer. Not used; must be zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

The hDevice handle passed to DeviceIoControl must be a handle to a volume, opened for direct access. An application can obtain such a handle by calling CreateFile with lpFileName set to a string that looks like this:

\\.\X:

where X is a hard-drive partition letter, floppy disk drive, or CD-ROM drive. The application must also specify the FILE_SHARE_READ and FILE_SHARE_WRITE flags in the dwShareMode parameter of CreateFile.

If the specified volume is locked, the operation fails.

A dismounted volume has the following properties:

  • There are no open files.
  • The operating system does not "know" about the volume.

The operating system tries to mount an unmounted volume as soon as any attempt is made to access it. For example, a call to GetLogicalDrives triggers the operating system to mount any unmounted volumes.

Dismounting a volume is useful whenever a volume needs to disappear for a while. For example, an application that changes a volume's file system from FAT to NTFS might follow these steps:

  1. Open the volume
  2. Lock the volume
  3. Format the volume
  4. Unlock the volume
  5. Dismount the volume
  6. Close the volume handle

A dismounting operation removes the volume from the FAT file system's "awareness." When the operating system mounts the volume, it appears as an NTFS volume.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, CreateFile, DeviceIoControl, ExitThread, GetLogicalDrives


FSCTL_ENABLE_UPGRADE

[This is preliminary documentation and subject to change.]

The FSCTL_ENABLE_UPGRADE operation enables or disables upgrading an NTFS volume to NTFS version 5. To perform this operation, call the DeviceIoControl function with the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  FSCTL_ENABLE_UPGRADE,    // dwIoControlCode, control code of
                           // operation to perform
  lpInBuffer,              // pointer to an unsigned long containing
                           // the input flag
  nInBufferSize,           // size of the input buffer
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,       // pointer to variable to receive
                                   // output byte count
  (LPOVERLAPPED) lpOverlapped      // pointer to OVERLAPPED structure
                                   // for asynchronous operation
);

Parameters

hDevice
Handle to the volume on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use FSCTL_ENABLE_UPGRADE for this operation.
lpInBuffer
Pointer to a ULONG containing the upgrade state flag. The lpInBuffer parameter should be zero to disable an upgrade, or 1 to enable an upgrade. All other bits in the value are reserved and must be set to zero.
nInBufferSize
Size, in bytes, of the input buffer, that is the size of a ULONG.
lpOutBuffer
Pointer to the output buffer. Not used; must be NULL.
nOutBufferSize
Size, in bytes, of the output buffer. Not used; must be zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), the lpBytesReturned parameter is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If the device specified by the hDevice parameter was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If the hDevice device was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

The FSCTL_ENABLE_UPGRADE operation does not actually upgrade to NTFS 5. Rather, it sets or clears a flag that enables the ability to upgrade. Whether FSCTL_ENABLE_UPGRADE sets or resets the flag depends on the value of the ULONG passed in the lpInBuffer parameter. If FSCTL_ENABLE_UPGRADE enables upgrades, the next time Windows NT 5.0 is started the volume will be upgraded.

For the implications of overlapped I/O on the FSCTL_ENABLE_UPGRADE operation, see the Remarks section of DeviceIoControl.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

CreateFile, DeviceIoControl, OVERLAPPED


FSCTL_GET_COMPRESSION

The FSCTL_GET_COMPRESSION operation obtains the current compression state of a file or directory on a volume whose file system supports per-stream compression. To perform this operation, call the DeviceIoControl function using the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to a file
  FSCTL_GET_COMPRESSION,   // dwIoControlCode, control code of
                           // operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  (LPVOID) lpOutBuffer,    // pointer to output buffer
  (DWORD) nOutBufferSize,  // size, in bytes, of lpOutBuffer
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the file or directory on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use FSCTL_GET_COMPRESSION for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to a buffer that receives a USHORT indicating the current compression state of the file or directory.

The following values are defined:
Value | Meaning
COMPRESSION_FORMAT_NONE | The file or directory is not compressed.
COMPRESSION_FORMAT_LZNT1 | The file or directory is compressed, using the LZNT1 compression format.
all other values | Reserved for future use.

nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer. The buffer must be large enough to contain one USHORT value.
lpBytesReturned
Pointer to a DWORD variable that receives the size, in bytes, of output data returned. If the lpOutBuffer buffer is too small, lpBytesReturned receives the required buffer size.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL. If this is an overlapped operation, you can retrieve the number of bytes returned by calling the GetOverlappedResult function. If hDevice is associated with an I/O completion port, you can get the number of bytes returned by calling the GetQueuedCompletionStatus function.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

On this release, LZNT1 is the only compression algorithm implemented. Future releases may have additional compression methods.

COMPRESSION_FORMAT_DEFAULT is not a compression state so it is not included in the table under the lpOutBuffer parameter. This value is only used with the FSCTL_SET_COMPRESSION operation

If the file system of the volume containing the specified file or directory does not support per-file or per-directory compression, the FSCTL_GET_COMPRESSION operation fails.

Windows NT versions 3.51 and later support file compression on volumes formatted with NTFS.

You can set the compression state of a file or directory by using the FSCTL_SET_COMPRESSION DeviceIoControl operation. You can also compress or uncompress a file with that operation.

You can obtain the compression attribute of a file or directory by calling the GetFileAttributes function. The compression attribute indicates whether a file or directory is compressed. The compression state indicates whether a file or directory is compressed, and, if it is, the format of the compressed data.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, FSCTL_SET_COMPRESSION, GetFileAttributes


FSCTL_GET_HFS_INFORMATION

[This is preliminary documentation and subject to change.]

The FSCTL_GET_HFS_INFORMATION operation returns Macintosh Finder information about the file associated with the input handle. To perform this operation, call the DeviceIoControl function using the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hFile,             // handle to file of interest
  FSCTL_GET_HFS_INFORMATION,  // dwIoControlCode, control code of
                              // operation to perform
  NULL,                       // lpInBuffer is not used; must be NULL
  0,                          // nInBufferSize is not used;
                              // must be zero
  (LPVOID) lpOutBuffer,       // pointer to buffer to receive
                              // output data
  (DWORD) nOutBufferSize,     // size of output buffer
  (LPDWORD) lpBytesReturned,  // pointer to variable to receive
                              // output byte count
  (LPOVERLAPPED) lpOverlapped      // pointer to OVERLAPPED structure for
                              // asynchronous operation
);

Parameters

hFile
Handle to the file for which HFS information is sought. To obtain a file handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of file on which the operation is to be performed. Use FSCTL_GET_HFS_INFORMATION for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to the output buffer, an instance of the HFS_INFORMATION_BUFFER structure.
nOutBufferSize
Size, in bytes, of the output buffer, that is the size of an HFS_INFORMATION_BUFFER structure.
lpBytesReturned
Pointer to a DWORD variable that receives the size, in bytes, of output data returned. If the lpOutBuffer buffer is too small, the lpBytesReturned parameter receives the required buffer size.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL. If this is an overlapped operation, you can get the number of bytes returned by calling the GetOverlappedResult function. If hDevice is associated with an I/O completion port, you can retrieve the number of bytes returned by calling the GetQueuedCompletionStatus function.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hFile was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the file was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hFile was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value, and the output buffer pointed to by lpvOutBuffer contains a valid HFS_INFORMATION_BUFFER structure.

If the operation fails, DeviceIoControl returns zero. In this case, the contents of the output buffer pointed to by lpvOutBuffer are meaningless. To get extended error information, call GetLastError.

Remarks

For the implications of overlapped I/O on this operation, see the Remarks section of DeviceIoControl.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

CreateFile, DeviceIoControl, GetOverlappedResult, GetQueuedCompletionStatus, HFS_INFORMATION_BUFFER, OVERLAPPED


FSCTL_GET_REPARSE_POINT

[This is preliminary documentation and subject to change.]

The FSCTL_GET_REPARSE_POINT operation returns the reparse point data associated with the file or directory identified by the specified handle. To perform this operation, call the DeviceIoControl function with the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to the file or directory
  FSCTL_GET_REPARSE_POINT, // dwIoControlCode, control code of
                           // operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  (LPVOID) lpOutBuffer,    // pointer to a REPARSE_DATA_BUFFER
                           // structure
  (DWORD) nOutBufferSize,  // size, in bytes, of lpOutBuffer
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to an OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the file or directory from which to obtain the reparse point data. Call the CreateFile function to obtain a handle.
dwIoControlCode
Specifies the FSCTL_GET_REPARSE_POINT control code.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to a REPARSE_DATA_BUFFER buffer that receives the reparse point data.
nOutBufferSize
Size, in bytes, of the output buffer.
lpBytesReturned
Pointer to a DWORD variable that receives the size, in bytes, of output data returned. If the lpOutBuffer buffer is too small, lpBytesReturned receives the required buffer size.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL. If this is an overlapped operation, you can retrieve the number of bytes returned by calling the GetOverlappedResult function. If hDevice is associated with an I/O completion port, you can get the number of bytes returned by calling the GetQueuedCompletionStatus function.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value, and the output buffer pointed to by lpOutBuffer contains a valid REPARSE_DATA_BUFFER structure, or a portion thereof, depending on the value of nOutBufferSize.

If the operation fails, DeviceIoControl returns zero. The contents of the output buffer pointed to by lpOutBuffer are meaningless. For extended error information, call GetLastError.

Remarks

See the Remarks section of the DeviceIoControl topic for the implications of overlapped I/O on this operation.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, CreateFile, DeviceIoControl, FSCTL_SET_REPARSE_POINT, FSCTL_DELETE_REPARSE_POINT, REPARSE_DATA_BUFFER


FSCTL_LOCK_VOLUME

The FSCTL_LOCK_VOLUME operation locks a volume. A locked volume can be accessed only through handles to the file object (*hDevice) that locks the volume. To perform this operation, call the DeviceIoControl function using the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to a file
  FSCTL_LOCK_VOLUME,       // dwIoControlCode, control code of
                           // operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used; must be zero
  (LPDWORD) lpBytesReturned,   // pointer to receive output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                               // for asynchronous operation
);

Parameters

hDevice
Handle to the volume to be locked. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use FSCTL_LOCK_VOLUME for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to the output buffer. Not used; must be NULL
nOutBufferSize
Size, in bytes, of the output buffer. Not used; must be zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

The hDevice handle passed to DeviceIoControl must be a handle to a volume, opened for direct access. An application can obtain such a handle by calling CreateFile with lpFileName set to a string that looks like this:

\\.\X:

where X is a hard-drive partition letter, floppy disk drive, or CD-ROM drive. The application must also specify the FILE_SHARE_READ and FILE_SHARE_WRITE flags in the dwShareMode parameter of CreateFile.

The FSCTL_LOCK_VOLUME operation fails if there are any open files on the volume. Conversely, success of this operation indicates there are no open files.

The operation is useful for applications that need exclusive access to a volume for a period of time—for example, disk utility programs.

A locked volume remains locked until one of the following occurs:

  • The application invokes the FSCTL_UNLOCK_VOLUME DeviceIoControl operation to unlock the volume.
  • The handle closes, either directly through CloseHandle, or indirectly when a process terminates.

The system flushes all cached data to the volume before locking it. For example, any data held in a lazy-write cache is written to the volume.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, CloseHandle, CreateFile, DeviceIoControl, FSCTL_UNLOCK_VOLUME


FSCTL_QUERY_ALLOCATED_RANGES

[This is preliminary documentation and subject to change.]

The FSCTL_QUERY_ALLOCATED_RANGES operation scans a file looking for ranges that may contain nonzero data. Only compressed or sparse files can have zeroed ranges known to the operating system. For other files, the output buffer will contain only a single entry that contains the starting point and the length requested.

To perform this operation, call the DeviceIoControl function with the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to a file
  FSCTL_QUERY_ALLOCATED_RANGES,    // dwIoControlCode, control code of
                           // operation to perform
  (LPVOID) lpInBuffer,     // pointer to an input buffer
  (DWORD) nInBufferSize,   // size, in bytes, of lpInBuffer
  (LPVOID) lpOutBuffer,    // pointer to an output buffer
  (DWORD) nOutBufferSize,  // size, in bytes, of lpOutBuffer
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to an OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the file on which the operation is to be performed. Call the CreateFile function to obtain a handle. This operation cannot be called with a directory or volume handle.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use FSCTL_QUERY_ALLOCATED_RANGES for this operation.
lpInBuffer
Pointer to a FILE_ALLOCATED_RANGE_BUFFER structure that indicates the portion of the file to search for allocated ranges. The FileOffset member indicates the offset, in bytes, to the first byte of the range to search, and the Length member indicates its size, in bytes.
nInBufferSize
Size, in bytes, of the lpInBuffer buffer.
lpOutBuffer
Pointer to a buffer that receives an array of FILE_ALLOCATED_RANGE_BUFFER structures. Each structure in the array provides information about an allocated range within the file. The FileOffset member of each structure indicates the beginning of a range, and the Length member indicates its size, in bytes.

Ranges returned are always at least partially within the range specified in the lpInBuffer buffer.

nOutBufferSize
Size, in bytes, of the lpOutBuffer buffer.
lpBytesReturned
Pointer to a DWORD variable that receives the size, in bytes, of output data returned. If the lpOutBuffer buffer is too small, lpBytesReturned receives the required buffer size.

If lpOverlapped is NULL, lpBytesReturned cannot be NULL.

If lpOverlapped is not NULL, lpBytesReturned can be NULL. If this is an overlapped operation, you can get the number of bytes returned by calling the GetOverlappedResult function. If hDevice is associated with an I/O completion port, you can get the number of bytes returned by calling the GetQueuedCompletionStatus function.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value, and the output buffer pointed to by lpOutBuffer contains an array of valid FILE_ALLOCATED_RANGE_BUFFER structures.

If the operation fails, DeviceIoControl returns zero. The contents of the output buffer pointed to by lpOutBuffer are meaningless. For extended error information, call GetLastError.

Remarks

See the Remarks section of the DeviceIoControl topic for the implications of overlapped I/O on this operation.

NTFS rounds the input file offset down to a convenient boundary and the length up to a convenient boundary and then begins to walk through the file.

The operating system does not track every piece of zero or nonzero data. Because zero is often a perfectly legal datum, it would be misleading. Instead, the system tracks ranges where disk space is allocated. Where no disk space is allocated, all data are assumed to be zero. Allocated storage can contain zero or nonzero data. So all this operation does is return information about parts of the file where nonzero data may be located. It is up to the application to scan these parts of the file in accordance with the application's data conventions.

Each entry in the output array contains an offset and a length that indicates a range in the file that may contain nonzero data. The actual nonzero data, if any, is somewhere within this range, and the calling program must scan further within the range to locate it and determine if it really is valid data. Multiple instances of valid data may exist within the range.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, FILE_ALLOCATED_RANGE_BUFFER, FSCTL_SET_SPARSE, FSCTL_SET_ZERO_DATA


FSCTL_QUERY_FAT_BPB

[This is preliminary documentation and subject to change.]

The FSCTL_QUERY_FAT_BPB operation returns the first 36 bytes of a FAT16 or FAT12 volume.

This operation is obsolete. Use GetVolumeInformation, GetDriveType, and other related functions to obtain some of the same information in a more structured manner. If you cannot get the necessary information in any other way, use CreateFile to open the volume as a file, and use ReadFile to access the raw hard drive.

To perform this operation, call the DeviceIoControl function with the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  FSCTL_QUERY_FAT_BPB,     // dwIoControlCode, control code of
                           // operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  (LPVOID) lpOutBuffer,    // a pointer to an
                           // FSCTL_QUERY_FAT_BPB_BUFFER
  (DWORD) nOutBufferSize,  // size of the output buffer
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. Call the CreateFile function to obtain a device handle. The handle can only be to a FAT12 or FAT16 volume. The call will fail on a FAT32 volume.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which it is to be performed. Use FSCTL_QUERY_FAT_BPB for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size of the input buffer, in bytes. Not used; must be zero.
lpOutBuffer
Pointer to the output buffer. This will be an FSCTL_QUERY_FAT_BPB_BUFFER structure.
nOutBufferSize
Size of the output buffer, in bytes, which is sizeof(FSCTL_QUERY_FAT_BPB_BUFFER).
lpBytesReturned
Pointer to a DWORD variable that receives the size, in bytes, of output data returned. If the lpOutBuffer buffer is too small, lpBytesReturned receives the required buffer size.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL. If this is an overlapped operation, you can get the number of bytes returned by calling the GetOverlappedResult function. If hDevice is associated with an I/O completion port, you can get the number of bytes returned by calling the GetQueuedCompletionStatus function.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value, and the output buffer pointed to by lpvOutBuffer contains a valid FSCTL_QUERY_FAT_BPB_BUFFER structure.

If the operation fails, DeviceIoControl returns zero. The contents of the output buffer pointed to by lpvOutBuffer are meaningless.

Remarks

For the implications of overlapped I/O on this operation, see the Remarks section of the DeviceIoControl topic.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, CreateFile, FSCTL_QUERY_FAT_BPB_BUFFER, GetVolumeInformation, GetDriveType, ReadFile, GetOverlappedResult, GetQueuedCompletionStatus, Windows 95 Features


FSCTL_SET_COMPRESSION

The FSCTL_SET_COMPRESSION operation sets the compression state of a file or directory on a volume whose file system supports per-file and per-directory compression. You can use this operation to compress or uncompress a file or directory on such a volume. To perform this operation, call the DeviceIoControl function using the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to a file
  FSCTL_SET_COMPRESSION,   // dwIoControlCode, control code of
                           // operation to perform
  (LPVOID) lpInBuffer,     // pointer to buffer with input data
  (DWORD) nInBufferSize,   // size, in bytes, of lpInBuffer
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use FSCTL_SET_COMPRESSION for this operation.
lpInBuffer
Pointer to a buffer containing a USHORT that specifies a new compression state for the file or directory.

The following values are defined:
Value | Meaning
COMPRESSION_FORMAT_NONE | Uncompress the file or directory.
COMPRESSION_FORMAT_DEFAULT | Compress the file or directory, using the default compression format.
COMPRESSION_FORMAT_LZNT1 | Compress the file or directory, using the LZNT1 compression format.
all other values | Reserved for future use.

nInBufferSize
Size, in bytes, of the buffer pointed to by lpInBuffer. The buffer must be large enough to contain one USHORT value.
lpOutBuffer
Pointer to the output buffer. Not used; must be NULL
nOutBufferSize
Size, in bytes, of the output buffer. Not used; must be zero.
lpBytesReturned
Pointer to a DWORD variable that receives the size, in bytes, of output data returned. If the lpOutBuffer buffer is too small, lpBytesReturned receives the required buffer size.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL. If this is an overlapped operation, you can retrieve the number of bytes returned by calling the GetOverlappedResult function. If hDevice is associated with an I/O completion port, you can get the number of bytes returned by calling the GetQueuedCompletionStatus function.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

LZNT1 is the only compression algorithm implemented. As a result, LZNT1 is used as the DEFAULT compression method. Future releases may have additional compression methods which may be used as the DEFAULT.

If the file system of the volume containing the specified file or directory does not support per-file or per-directory compression, the FSCTL_SET_COMPRESSION operation fails.

Windows NT versions 3.51 and later support file compression on volumes formatted with NTFS.

The compression state change of the file or directory occurs synchronously with the call to DeviceIoControl.

You can obtain the compression state of a file or directory by using the FSCTL_GET_COMPRESSION DeviceIoControl operation.

You can obtain the compression attribute of a file or directory by calling the GetFileAttributes function. The compression attribute indicates whether a file or directory is compressed. The compression state indicates whether a file or directory is compressed and, if it is, the format of the compressed data.

Directories are not actually compressed by the FSCTL_SET_COMPRESSION operation. Rather, this operation sets the default state for files created in the directory to be compressed.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, FSCTL_GET_COMPRESSION, GetFileAttributes


FSCTL_SET_REPARSE_POINT

[This is preliminary documentation and subject to change.]

The FSCTL_SET_REPARSE_POINT operation sets a reparse point on a file or directory. To perform this operation, call the DeviceIoControl function with the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to the file or directory
  FSCTL_SET_REPARSE_POINT, // dwIoControlCode, control code of
                           // operation to perform
  (LPVOID) lpInBuffer,     // pointer to REPARSE_DATA_BUFFER
                           // structure
  (DWORD) nInBufferSize,   // size, in bytes, of lpInBuffer
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the file or directory on which to set a reparse point. The handle must have write access to the file or directory. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use FSCTL_SET_REPARSE_POINT for this operation.
lpInBuffer
Pointer to a REPARSE_DATA_BUFFER buffer that contains the reparse point data.
nInBufferSize
Size, in bytes, of the lpInBuffer buffer.
lpOutBuffer
Pointer to the output buffer. Not used; must be NULL
nOutBufferSize
Size, in bytes, of the output buffer. Not used; must be zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. For extended error information, call GetLastError.

Remarks

See the Remarks section of the DeviceIoControl topic for the implications of overlapped I/O on this operation.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, FSCTL_GET_REPARSE_POINT, FSCTL_DELETE_REPARSE_POINT, REPARSE_DATA_BUFFER


FSCTL_SET_SPARSE

[This is preliminary documentation and subject to change.]

The FSCTL_SET_SPARSE operation marks the indicated file as sparse. In a sparse file, large ranges of zeroes may not require disk allocation. Space for nonzero data will be allocated as needed as the file is written. To perform this operation, call the DeviceIoControl function with the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to a file
  FSCTL_SET_SPARSE,        // dwIoControlCode, control code of
                           // operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used; must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the file to be made sparse. Call the CreateFile function to obtain a file handle. The file must be on an NTFS 5.0 file system or later. This operation cannot be called with a directory or volume handle.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use FSCTL_SET_SPARSE for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to the output buffer. Not used; must be NULL
nOutBufferSize
Size, in bytes, of the output buffer. Not used; must be zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

See the Remarks section of the DeviceIoControl topic for the implications of overlapped I/O on this operation.

The FSCTL_SET_SPARSE operation sets the FILE_ATTRIBUTE_SPARSE_FILE attribute of the specified file. The only way to clear this attribute is to overwrite the file, for example, by calling the CreateFile function with the CREATE_ALWAYS flag..

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, FSCTL_QUERY_ALLOCATED_RANGES, FSCTL_SET_ZERO_DATA


FSCTL_SET_ZERO_DATA

[This is preliminary documentation and subject to change.]

The FSCTL_SET_ZERO_DATA operation fills a specified range of a file with zeroes. If the file is sparse or compressed, NTFS may deallocate disk space within the file. This operation sets the range of bytes to zeroes without extending the file size. To perform this operation, call the DeviceIoControl function with the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to a file
  FSCTL_SET_ZERO_DATA,     // dwIoControlCode, control code of
                           // operation to perform
  (LPVOID) lpInBuffer,     // pointer to buffer with input data
  (DWORD) nInBufferSize,   // size, in bytes, of lpInBuffer
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the file on which the operation is to be performed. The file must be on an NTFS 5.0 file system or later. Call the CreateFile function to obtain a file handle. This operation cannot be called with any object other than a file.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use FSCTL_SET_ZERO_DATA for this operation.
lpInBuffer
Pointer to a FILE_ZERO_DATA_INFORMATION structure that specifies the range of the file to set to zeroes. The FileOffset member is the byte offset of the first byte to set to zeroes, and the BeyondFinalZero member is the byte offset of the first byte beyond the last zeroed byte.
nInBufferSize
Size, in bytes, of the input buffer.
lpOutBuffer
Pointer to the output buffer. Not used; must be NULL
nOutBufferSize
Size, in bytes, of the output buffer. Not used; must be zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. For extended error information, call GetLastError.

Remarks

For the implications of overlapped I/O on this operation, see the Remarks section of the DeviceIoControl topic.

If you use the WriteFile function to write zeroes to a sparse file, the file system allocates disk space for the data that you are writing. If you use the FSCTL_SET_ZERO_DATA operation to write zeroes to a sparse file and the zeroed region is large enough, the file system may not allocate disk space.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, FILE_ZERO_DATA_INFORMATION, FSCTL_QUERY_ALLOCATED_RANGES, FSCTL_SET_SPARSE


FSCTL_UNLOCK_VOLUME

The FSCTL_UNLOCK_VOLUME operation unlocks a volume.To perform this operation, call the DeviceIoControl function using the following parameters.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to a file
  FSCTL_UNLOCK_VOLUME,     // dwIoControlCode, control code of
                           // operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
   (LPOVERLAPPED) lpOverlapped // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use FSCTL_UNLOCK_VOLUME for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to the output buffer. Not used; must be NULL
nOutBufferSize
Size, in bytes, of the output buffer. Not used; must be zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

An application can call the FSCTL_LOCK_VOLUME DeviceIoControl operation to lock a volume.

The hDevice handle passed to DeviceIoControl must be a handle to a volume, opened for direct access. An application can obtain such a handle by calling CreateFile with lpFileName set to a string that looks like this:

\\.\X:

where X is a hard-drive partition letter, floppy disk drive, or CD-ROM drive. The application must also specify the FILE_SHARE_READ and FILE_SHARE_WRITE flags in the dwShareMode parameter of CreateFile.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, CreateFile, DeviceIoControl, FSCTL_LOCK_VOLUME


IOCTL_DISK_CHECK_VERIFY

The IOCTL_DISK_CHECK_VERIFY operation has been superseded by the IOCTL_STORAGE_CHECK_VERIFY operation.

See Also

Device Input and Output Overview, Device Input and Output Operations


IOCTL_DISK_EJECT_MEDIA

The IOCTL_DISK_EJECT_MEDIA operation has been superseded by the IOCTL_STORAGE_EJECT_MEDIA operation.

See Also

Device Input and Output Overview, Device Input and Output Operations


IOCTL_DISK_FORMAT_TRACKS

The IOCTL_DISK_FORMAT_TRACKS DeviceIoControl operation formats a specified, contiguous set of tracks on a disk.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_DISK_FORMAT_TRACKS,    // dwIoControlCode, control code of
                           // operation to perform
  (LPVOID) lpInBuffer,     // address of input buffer
  (DWORD) nInBufferSize,   // size, in bytes, of input buffer
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_DISK_FORMAT_TRACKS for this operation.
lpInBuffer
Pointer to a buffer that contains a FORMAT_PARAMETERS data structure.
nInBufferSize
Size, in bytes, of the buffer pointed to by lpInBuffer, which must be large enough to contain a FORMAT_PARAMETERS data structure.
lpOutBuffer
Pointer to the output buffer. Not used; must be NULL
nOutBufferSize
Size, in bytes, of the output buffer. Not used; must be zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

This device I/O control operation is for floppy disk devices only.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, FORMAT_PARAMETERS


IOCTL_DISK_GET_DRIVE_GEOMETRY

The IOCTL_DISK_GET_DRIVE_GEOMETRY DeviceIoControl operation returns information about the physical disk's geometry: type, number of cylinders, tracks per cylinder, sectors per track, and bytes per sector.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_DISK_GET_DRIVE_GEOMETRY, // dwIoControlCode, control code of
                           // operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  (LPVOID) lpOutBuffer,    // pointer to output buffer
  (DWORD) nOutBufferSize,  // size, in bytes, of lpOutBuffer
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_DISK_GET_DRIVE_GEOMETRY for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to a buffer that will receive a DISK_GEOMETRY data structure.
nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer, which must be greater than or equal to the size of a DISK_GEOMETRY data structure.
lpBytesReturned
Pointer to a DWORD variable that receives the size, in bytes, of output data returned. If the lpOutBuffer buffer is too small, lpBytesReturned receives the required buffer size.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL. If this is an overlapped operation, you can retrieve the number of bytes returned by calling the GetOverlappedResult function. If hDevice is associated with an I/O completion port, you can get the number of bytes returned by calling the GetQueuedCompletionStatus function.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

This device I/O control operation is for disk devices.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, DISK_GEOMETRY, IOCTL_DISK_GET_MEDIA_TYPES


IOCTL_DISK_GET_DRIVE_LAYOUT

The IOCTL_DISK_GET_DRIVE_LAYOUT DeviceIoControl operation returns information about the number of partitions on a disk and the features of each partition.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_DISK_GET_DRIVE_LAYOUT, // dwIoControlCode, control code of
                           // operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  (LPVOID) lpOutBuffer,    // pointer to output buffer
  (DWORD) nOutBufferSize,  // size, in bytes, of lpOutBuffer
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_DISK_GET_DRIVE_LAYOUT for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to a buffer that will receive a DRIVE_LAYOUT_INFORMATION structure and a series of PARTITION_INFORMATION structures, one of the latter for each partition on the drive.
nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer, which must be large enough to contain one DRIVE_LAYOUT_INFORMATION data structure and as many PARTITION_INFORMATION data structures as there are partitions on the drive.
lpBytesReturned
Pointer to a DWORD variable that receives the size, in bytes, of output data returned. If the lpOutBuffer buffer is too small, lpBytesReturned receives the required buffer size.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL. If this is an overlapped operation, you can retrieve the number of bytes returned by calling the GetOverlappedResult function. If hDevice is associated with an I/O completion port, you can get the number of bytes returned by calling the GetQueuedCompletionStatus function.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

This device I/O control operation is for disk devices. Floppy disk drivers, however, do not need to handle this operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, DRIVE_LAYOUT_INFORMATION, IOCTL_DISK_SET_DRIVE_LAYOUT, PARTITION_INFORMATION


IOCTL_DISK_GET_MEDIA_TYPES

The IOCTL_DISK_GET_MEDIA_TYPES operation has been superseded by the IOCTL_STORAGE_GET_MEDIA_TYPES operation.

See Also

Device Input and Output Overview, Device Input and Output Operations


IOCTL_DISK_GET_PARTITION_INFO

The IOCTL_DISK_GET_PARTITION_INFO DeviceIoControl operation returns information about the type, size, and nature of a disk partition.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_DISK_GET_PARTITION_INFO,   // dwIoControlCode, control code
                           // of operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  (LPVOID) lpOutBuffer,    // pointer to output buffer
  (DWORD) nOutBufferSize,  // size, in bytes, of lpOutBuffer
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_DISK_GET_PARTITION_INFO for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to a buffer that will receive a PARTITION_INFORMATION data structure.
nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer, which must be large enough to contain a PARTITION_INFORMATION data structure.
lpBytesReturned
Pointer to a DWORD variable that receives the size, in bytes, of output data returned. If the lpOutBuffer buffer is too small, lpBytesReturned receives the required buffer size.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL. If this is an overlapped operation, you can retrieve the number of bytes returned by calling the GetOverlappedResult function. If hDevice is associated with an I/O completion port, you can get the number of bytes returned by calling the GetQueuedCompletionStatus function.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

This device I/O control operation is for disk devices. Floppy disk drivers, however, do not need to handle this operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, IOCTL_DISK_SET_PARTITION_INFO, PARTITION_INFORMATION


IOCTL_DISK_LOAD_MEDIA

The IOCTL_DISK_LOAD_MEDIA operation has been superseded by the IOCTL_STORAGE_LOAD_MEDIA operation.

See Also

Device Input and Output Overview, Device Input and Output Operations


IOCTL_DISK_MEDIA_REMOVAL

The IOCTL_DISK_MEDIA_REMOVAL operation has been superseded by the IOCTL_STORAGE_MEDIA_REMOVAL operation.

See Also

Device Input and Output Overview, Device Input and Output Operations


IOCTL_DISK_PERFORMANCE

The IOCTL_DISK_PERFORMANCE DeviceIoControl operation provides disk performance information.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_DISK_PERFORMANCE,  // dwIoControlCode, control code of
                           // operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  (LPVOID) lpOutBuffer,    // pointer to output buffer
  (DWORD) nOutBufferSize,  // size, in bytes, of lpOutBuffer
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_DISK_PERFORMANCE for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to a buffer that will receive a DISK_PERFORMANCE data structure.
nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer, which must be large enough to contain a DISK_PERFORMANCE data structure.
lpBytesReturned
Pointer to a DWORD variable that receives the size, in bytes, of output data returned. If the lpOutBuffer buffer is too small, lpBytesReturned receives the required buffer size.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL. If this is an overlapped operation, you can retrieve the number of bytes returned by calling the GetOverlappedResult function. If hDevice is associated with an I/O completion port, you can get the number of bytes returned by calling the GetQueuedCompletionStatus function.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

This device I/O control operation is for disk devices.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, DISK_PERFORMANCE


IOCTL_DISK_REASSIGN_BLOCKS

The IOCTL_DISK_REASSIGN_BLOCKS DeviceIoControl operation directs the disk device to map one or more blocks to its spare-block pool.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_DISK_REASSIGN_BLOCKS,  // dwIoControlCode, control code of
                           // operation to perform
  (LPVOID) lpInBuffer,     // address of input buffer
  (DWORD) nInBufferSize,   // size, in bytes, of input buffer
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_DISK_REASSIGN_BLOCKS for this operation.
lpInBuffer
Pointer to a buffer that contains a REASSIGN_BLOCKS data structure specifying the blocks to reassign to its spare block pool.
nInBufferSize
Size, in bytes, of the buffer pointed to by lpInBuffer, which must be large enough to contain the REASSIGN_BLOCKS data structure. Note that this structure is really a header followed by an array of block specifiers; thus, it varies in size according to the number of blocks to be reassigned; each block after the first adds the size of a DWORD to the overall size.
lpOutBuffer
Pointer to an output buffer. Not used with this operation. Set to NULL.
nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer. Not used with this operation. Set to zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

This device I/O control operation is for disk devices.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, REASSIGN_BLOCKS


IOCTL_DISK_SET_DRIVE_LAYOUT

The IOCTL_DISK_SET_DRIVE_LAYOUT DeviceIoControl operation partitions a disk as specified by drive layout and partition information data.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_DISK_SET_DRIVE_LAYOUT, // dwIoControlCode, control code of
                           // operation to perform
  (LPVOID) lpInBuffer,     // address of input buffer
  (DWORD) nInBufferSize,   // size, in bytes, of input buffer
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_DISK_SET_DRIVE_LAYOUT for this operation.
lpInBuffer
Pointer to a buffer that contains drive layout and partition information data. The data exists as a DRIVE_LAYOUT_INFORMATION data structure and a series of PARTITION_INFORMATION data structures, one of the latter for each proposed partition on the drive.
nInBufferSize
Size, in bytes, of the buffer pointed to by lpInBuffer, which must be large enough to contain one DRIVE_LAYOUT_INFORMATION data structure and as many PARTITION_INFORMATION data structures as there are proposed partitions on the drive.
lpOutBuffer
Pointer to an output buffer. Not used with this operation. Set to NULL.
nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer. Not used with this operation. Set to zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

This device I/O control operation is for disk devices. Floppy disk drivers, however, need not handle this operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, DRIVE_LAYOUT_INFORMATION, IOCTL_DISK_GET_DRIVE_LAYOUT, PARTITION_INFORMATION


IOCTL_DISK_SET_PARTITION_INFO

The IOCTL_DISK_SET_PARTITION_INFO DeviceIoControl operation sets the partition type of the specified disk partition.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_DISK_SET_PARTITION_INFO,   // dwIoControlCode, control code of
                           // operation to perform
  (LPVOID) lpInBuffer,     // address of input buffer
  (DWORD) nInBufferSize,   // size, in bytes, of input buffer
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_DISK_SET_PARTITION_INFO for this operation.
lpInBuffer
Pointer to a buffer that contains the partition data to be set. The data exists as a SET_PARTITION_INFORMATION data structure.
nInBufferSize
Size, in bytes, of the buffer pointed to by lpInBuffer, which must be large enough to contain a SET_PARTITION_INFORMATION data structure.
lpOutBuffer
Pointer to an output buffer. Not used with this operation. Set to NULL.
nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer. Not used with this operation. Set to zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

This device I/O control operation is for disk devices. Floppy disk drivers, however, need not handle this operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, IOCTL_DISK_GET_PARTITION_INFO, SET_PARTITION_INFORMATION


IOCTL_DISK_VERIFY

The IOCTL_DISK_VERIFY DeviceIoControl operation performs a logical format of a specified extent on a disk.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_DISK_VERIFY,       // dwIoControlCode, control code of
                           // operation to perform
  (LPVOID) lpInBuffer,     // address of input buffer
  (DWORD) nInBufferSize,   // size, in bytes, of input buffer
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_DISK_VERIFY for this operation.
lpInBuffer
Pointer to a buffer that contains a VERIFY_INFORMATION data structure.
nInBufferSize
Size, in bytes, of the buffer pointed to by lpInBuffer, which must be large enough to contain a VERIFY_INFORMATION data structure.
lpOutBuffer
Pointer to an output buffer. Not used with this operation. Set to NULL.
nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer. Not used with this operation. Set to zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

This device I/O control operation is for disk devices. Floppy disk drivers, however, need not handle this operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, IOCTL_DISK_CHECK_VERIFY, VERIFY_INFORMATION


IOCTL_SERIAL_LSRMST_INSERT

The IOCTL_SERIAL_LSRMST_INSERT DeviceIoControl operation enables or disables the placement of line status and modem status values into the regular data stream that an application acquires through the ReadFile function.

When this line-status and modem-status data placement mode is enabled, status values are preceded in the data stream by an escape character. The user-definable escape character is set by the IOCTL_SERIAL_LSRMST_INSERT operation. Status values consist of 1 to 3 BYTEs. See the Remarks section below for status value details.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_SERIAL_LSRMST_INSERT,  // dwIoControlCode, control code of
                           // operation to perform
  (LPVOID) lpInBuffer,     // address of input buffer
  (DWORD) nInBufferSize,   // size, in bytes, of input buffer
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_SERIAL_LSRMST_INSERT for this operation.
lpInBuffer
Pointer to a buffer that contains a single BYTE.

If the BYTE is a nonzero value, it is the desired line-status and modem-status value escape character. The operation will turn the LSRMST_INSERT line-status and modem-status data placement mode on.

If the BYTE is zero, the operation will turn the LSRMST_INSERT line-status and modem-status data placement mode off.

The escape character can not be the XON or XOFF character.

nInBufferSize
Size, in bytes, of the buffer pointed to by lpInBuffer. For this operation, this value should be 1.
lpOutBuffer
Pointer to an output buffer. Not used with this operation. Set to NULL.
nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer. Not used with this operation. Set to zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

Note that an application that uses this scheme must examine each character in the data stream to determine the presence of modem-status or line-status data.

The following values follow the designated escape character in the data stream if the LSRMST_INSERT mode has been turned on :

Value | Meaning
SERIAL_LSRMST_ESCAPE | Indicates the reception of the escape character itself into the data stream.
SERIAL_LSRMST_LSR_DATA | Indicates that a line status change occurred, and data was available in the receive hardware buffer. Following this BYTE is a BYTE value of the line status register is the BYTE present in the receive hardware buffer when the line status change was processed.
SERIAL_LSRMST_LSR_NODATA | Indicates that a line status change occurred, but no data was available in the receive hardware buffer.
SERIAL_LSRMST_MST | Indicates that a modem status change occurred. Following this BYTE is a BYTE that is the value of the modem status register when the modem status change was processed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, ReadFile


IOCTL_STORAGE_CHECK_VERIFY

The IOCTL_STORAGE_CHECK_VERIFY DeviceIoControl operation determines whether a device's media is accessible; for example, whether the media is in the device.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_STORAGE_CHECK_VERIFY,  // dwIoControlCode, control code of
                           // operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_STORAGE_CHECK_VERIFY for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to an output buffer. Not used with this operation. Set to NULL.
nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer. Not used with this operation. Set to zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds and the device media is accessible, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl


IOCTL_STORAGE_EJECT_MEDIA

The IOCTL_STORAGE_EJECT_MEDIA DeviceIoControl operation causes media to be ejected from a SCSI device.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_STORAGE_EJECT_MEDIA,   // dwIoControlCode, control code of
                           // operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_STORAGE_EJECT_MEDIA for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to an output buffer. Not used with this operation. Set to NULL.
nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer. Not used with this operation. Set to zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

IOCTL_STORAGE_EJECT_MEDIA may or may not be supported on SCSI devices that support removable media.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, IOCTL_DISK_MEDIA_REMOVAL, IOCTL_DISK_LOAD_MEDIA


IOCTL_STORAGE_GET_MEDIA_TYPES

The IOCTL_STORAGE_GET_MEDIA_TYPES DeviceIoControl operation returns information about the types of media a device driver supports.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_STORAGE_GET_MEDIA_TYPES,   // dwIoControlCode, control code
                           // of operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  (LPVOID) lpOutBuffer,    // pointer to output buffer
  (DWORD) nOutBufferSize,  // size, in bytes, of lpOutBuffer
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_STORAGE_GET_MEDIA_TYPES for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to a buffer that will receive an array of DISK_GEOMETRY data structures specifying the media types the device driver supports.
nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer, which must be large enough to contain as many DISK_GEOMETRY structures as there are media that the driver supports.
lpBytesReturned
Pointer to a DWORD variable that receives the size, in bytes, of output data returned. If the lpOutBuffer buffer is too small, lpBytesReturned receives the required buffer size.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL. If this is an overlapped operation, you can retrieve the number of bytes returned by calling the GetOverlappedResult function. If hDevice is associated with an I/O completion port, you can get the number of bytes returned by calling the GetQueuedCompletionStatus function.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns zero. To get extended error information, call GetLastError.

Remarks

This device I/O control operation is for all class drivers, as well as non-small computer system interface (SCSI) hard drives and floppy disk devices.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, DISK_GEOMETRY, IOCTL_DISK_GET_DRIVE_GEOMETRY


IOCTL_STORAGE_LOAD_MEDIA

The IOCTL_STORAGE_LOAD_MEDIA DeviceIoControl operation causes media to be loaded into a device.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_STORAGE_LOAD_MEDIA,    // dwIoControlCode, control code of
                           // operation to perform
  NULL,                    // lpInBuffer is not used; must be NULL
  0,                       // nInBufferSize is not used; must be zero
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_STORAGE_LOAD_MEDIA for this operation.
lpInBuffer
Pointer to the input buffer. Not used; must be NULL.
nInBufferSize
Size, in bytes, of the input buffer. Not used; must be zero.
lpOutBuffer
Pointer to an output buffer. Not used with this operation. Set to NULL.
nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer. Not used with this operation. Set to zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns a nonzero value. To get extended error information, call GetLastError.

Remarks

The IOCTL_STORAGE_LOAD_MEDIA is valid only for devices that support loadable media.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, IOCTL_STORAGE_EJECT_MEDIA, IOCTL_STORAGE_MEDIA_REMOVAL


IOCTL_STORAGE_MEDIA_REMOVAL

The IOCTL_STORAGE_MEDIA_REMOVAL DeviceIoControl operation enables or disables the mechanism that ejects media, for those devices possessing that locking capability.

BOOL DeviceIoControl(
  (HANDLE) hDevice,        // handle to device of interest
  IOCTL_STORAGE_MEDIA_REMOVAL, // dwIoControlCode, control code of
                           // operation to perform
  (LPVOID) lpInBuffer,     // address of input buffer
  (DWORD) nInBufferSize,   // size, in bytes, of input buffer
  NULL,                    // lpOutBuffer is not used; must be NULL
  0,                       // nOutBufferSize is not used;
                           // must be zero
  (LPDWORD) lpBytesReturned,   // pointer to variable to receive
                           // output byte count
  (LPOVERLAPPED) lpOverlapped  // pointer to OVERLAPPED structure
                           // for asynchronous operation
);

Parameters

hDevice
Handle to the object on which the operation is to be performed. To obtain a device handle, call the CreateFile function.
dwIoControlCode
Control code for the operation. This value identifies the specific operation to be performed and the type of device on which the operation is to be performed. Use IOCTL_STORAGE_MEDIA_REMOVAL for this operation.
lpInBuffer
Pointer to a buffer that contains a PREVENT_MEDIA_REMOVAL data structure.

A TRUE value for that structure's PreventMediaRemoval member specifies that media removal is prevented (the device is locked). A FALSE value specifies that media removal is allowed.

nInBufferSize
Size, in bytes, of the buffer pointed to by lpInBuffer, which must be large enough to contain a PREVENT_MEDIA_REMOVAL data structure.
lpOutBuffer
Pointer to an output buffer. Not used with this operation. Set to NULL.
nOutBufferSize
Size, in bytes, of the buffer pointed to by lpOutBuffer. Not used with this operation. Set to zero.
lpBytesReturned
Pointer to a DWORD variable.

If lpOverlapped is NULL (nonoverlapped I/O), lpBytesReturned is used internally and cannot be NULL.

If lpOverlapped is not NULL (overlapped I/O), lpBytesReturned can be NULL.

lpOverlapped
Pointer to an OVERLAPPED structure.

If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, this parameter must point to a valid OVERLAPPED structure. In this case, DeviceIoControl is performed as an overlapped (asynchronous) operation. If the device was opened with the FILE_FLAG_OVERLAPPED flag and lpOverlapped is NULL, the function fails in unpredictable ways.

If hDevice was opened without specifying the FILE_FLAG_OVERLAPPED flag, this parameter is ignored and the DeviceIoControl function does not return until the operation has been completed, or until an error occurs.

Return Values

If the operation succeeds, DeviceIoControl returns a nonzero value.

If the operation fails, DeviceIoControl returns a nonzero value. To get extended error information, call GetLastError.

Remarks

The IOCTL_STORAGE_MEDIA_REMOVAL operation is valid only for devices that support removable media.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Operations, DeviceIoControl, IOCTL_STORAGE_EJECT_MEDIA, IOCTL_STORAGE_LOAD_MEDIA, PREVENT_MEDIA_REMOVAL


Device Input and Output Structures

The following structures are used with device input and output.

DISK_GEOMETRY
DISK_PERFORMANCE
DRIVE_LAYOUT_INFORMATION
FSCTL_QUERY_FAT_BPB_BUFFER
FILE_ALLOCATED_RANGE_BUFFER
FILE_ZERO_DATA_INFORMATION
HFS_INFORMATION_BUFFER
FORMAT_PARAMETERS
PARTITION_INFORMATION
PREVENT_MEDIA_REMOVAL
REASSIGN_BLOCKS
REPARSE_DATA_BUFFER
SET_PARTITION_INFORMATION
VERIFY_INFORMATION


DISK_GEOMETRY

The DISK_GEOMETRY structure describes the geometry of disk devices and media.

typedef struct _DISK_GEOMETRY {
   LARGE_INTEGER  Cylinders;
   MEDIA_TYPE  MediaType;
   DWORD  TracksPerCylinder;
   DWORD  SectorsPerTrack;
   DWORD  BytesPerSector;
} DISK_GEOMETRY ;

Members

Cylinders
The number of cylinders.
MediaType
The type of media. See MEDIA_TYPE.
TracksPerCylinder
The number of tracks per cylinder.
SectorsPerTrack
The number of sectors per track.
BytesPerSector
The number of bytes per sector

Remarks

The DeviceIoControl function receives a DISK_GEOMETRY structure in response to an IOCTL_DISK_GET_DRIVE_GEOMETRY device input and output contol (IOCTL) operation. The DeviceIoControl function receives an array of DISK_GEOMETRY structures in response to an IOCTL_DISK_GET_MEDIA_TYPES device I/O operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Structures, DeviceIoControl, IOCTL_DISK_GET_DRIVE_GEOMETRY, IOCTL_DISK_GET_MEDIA_TYPES, MEDIA_TYPE


DISK_PERFORMANCE

The DISK_PERFORMANCE structure provides disk performance information.

typedef struct _DISK_PERFORMANCE {
        LARGE_INTEGER BytesRead;
        LARGE_INTEGER BytesWritten;
        LARGE_INTEGER ReadTime;
        LARGE_INTEGER WriteTime;
        DWORD ReadCount;
        DWORD WriteCount;
        DWORD QueueDepth;
} DISK_PERFORMANCE ;

Members

BytesRead
Specifies the number of bytes read.
BytesWritten
Specifies the number of bytes written.
ReadTime
Specifies the time it took to complete the read.
WriteTime
Specifies the time it took to complete the write.
ReadCount
Specifies the number of read operations.
WriteCount
Specifies the number of write operations.
QueueDepth
Specifies the depth of the queue.

Remarks

The DeviceIoControl function receives a DISK_PERFORMANCE structure in response to an IOCTL_DISK_PERFORMANCE device I/O operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Structures, DeviceIoControl, IOCTL_DISK_PERFORMANCE


DRIVE_LAYOUT_INFORMATION

The DRIVE_LAYOUT_INFORMATION structure provides information about a drive's partitions.

typedef struct _DRIVE_LAYOUT_INFORMATION {
   DWORD  PartitionCount;
   DWORD  Signature;
   PARTITION_INFORMATION  PartitionEntry[1];
} DRIVE_LAYOUT_INFORMATION;

Members

PartitionCount
The number of partitions on the drive.
Signature
A drive signature value.
PartitionEntry
A variable-sized array of PARTITION_INFORMATION structures, one structure for each partition on the drive.

Remarks

The DeviceIoControl function receives a DRIVE_LAYOUT_INFORMATION structure in response to an IOCTL_DISK_GET_DRIVE_LAYOUT device I/O operation. The DeviceIoControl function uses a DRIVE_LAYOUT_INFORMATION structure as input to an IOCTL_DISK_SET_DRIVE_LAYOUT device I/O operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Structures, DeviceIoControl, IOCTL_DISK_GET_DRIVE_LAYOUT, IOCTL_DISK_SET_DRIVE_LAYOUT, PARTITION_INFORMATION


FSCTL_QUERY_FAT_BPB_BUFFER

[This is preliminary documentation and subject to change.]

The FSCTL_QUERY_FAT_BPB_BUFFER structure describes the first 36 bytes of data on a FAT16 or FAT12 volume. It is used by FSCTL_QUERY_FAT_BPB.

typedef struct _FSCTL_QUERY_FAT_BPB_BUFFER {
    BYTE  First0x24BytesOfBootSector[0x24];
} FSCTL_QUERY_FAT_BPB_BUFFER, *PFSCTL_QUERY_FAT_BPB_BUFFER;

Members

First0x24BytesOfBootSector[0x24]
The first 36 bytes of data from a FAT16 or FAT12 volume.

See Also

Device Input and Output Overview, Device Input and Output Structures, FSCTL_QUERY_FAT_BPB


FILE_ALLOCATED_RANGE_BUFFER

[This is preliminary documentation and subject to change.]

The FILE_ALLOCATED_RANGE_BUFFER structure is used with the FSCTL_QUERY_ALLOCATED_RANGES operation to indicate a range of bytes in a file. On input to the FSCTL_QUERY_ALLOCATED_RANGES operation, the structure indicates the range of the file to search. On output, the operation returns an array of FILE_ALLOCATED_RANGE_BUFFER structures to indicate the allocated ranges within the search range.

typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
    LARGE_INTEGER FileOffset;
    LARGE_INTEGER Length;
} FILE_ALLOCATED_RANGE_BUFFER;

Members

FileOffset
Indicates the file offset, in bytes, of the start of a range of bytes in a file.
Length
Indicates the size, in bytes, of the range.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Structures, FSCTL_QUERY_ALLOCATED_RANGES, Sparse Files


FILE_ZERO_DATA_INFORMATION

[This is preliminary documentation and subject to change.]

The FILE_ZERO_DATA_INFORMATION structure is used with the FSCTL_SET_ZERO_DATA operation to indicate a range of a file to set to zeroes.

typedef struct _FILE_ZERO_DATA_INFORMATION {
    LARGE_INTEGER FileOffset;
    LARGE_INTEGER BeyondFinalZero;
} FILE_ZERO_DATA_INFORMATION;

Members

FileOffset
Indicates the file offset, in bytes, of the start of the range to set to zeroes.
BeyondFinalZero
Indicates the byte offset of the first byte beyond the last zeroed byte.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Structures, FSCTL_SET_ZERO_DATA, Sparse Files


FORMAT_PARAMETERS

The FORMAT_PARAMETERS structure provides information used in formatting a contiguous set of disk tracks.

typedef struct _FORMAT_PARAMETERS{
   MEDIA_TYPE MediaType;
   DWORD StartCylinderNumber;
   DWORD EndCylinderNumber;
   DWORD StartHeadNumber;
   DWORD EndHeadNumber;
} FORMAT_PARAMETERS ;

Members

MediaType
Specifies the media type. See MEDIA_TYPE.
StartCylinderNumber
Specifies the cylinder number at which to begin the format.
EndCylinderNumber
Specifies the cylinder number at which to end the format.
StartHeadNumber
Specifies the beginning head location.
EndHeadNumber
Specifies the ending head location.

Remarks

The DeviceIoControl function uses a FORMAT_PARAMETERS structure as input to an IOCTL_DISK_FORMAT_TRACKS device I/O operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Structures, DeviceIoControl, IOCTL_DISK_FORMAT_TRACKS, MEDIA_TYPE


HFS_INFORMATION_BUFFER

[This is preliminary documentation and subject to change.]

The HFS_INFORMATION_BUFFER structure contains Macintosh Finder information.

typedef struct {
    UCHAR FinderInfo[32];
} HFS_INFORMATION_BUFFER, *PHFS_INFORMATION_BUFFER;

Members

FinderInfo[32]
Thirty-two unsigned characters of Macintosh Finder data.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

FSCTL_GET_HFS_INFORMATION


PARTITION_INFORMATION

The PARTITION_INFORMATION structure provides information about a disk partition.

typedef struct _PARTITION_INFORMATION {
    LARGE_INTEGER StartingOffset;
    LARGE_INTEGER PartitionLength;
    DWORD HiddenSectors;
    DWORD PartitionNumber;
    BYTE  PartitionType;
    BOOLEAN BootIndicator;
    BOOLEAN RecognizedPartition;
    BOOLEAN RewritePartition;
} PARTITION_INFORMATION, *PPARTITION_INFORMATION;

Members

StartingOffset
Specifies the starting offset of the partition.
PartitionLength
Specifies the length of the partition.
HiddenSectors
Specifies the number of hidden sectors in the partition.
PartitionNumber
Specifies the number of the partition (1-based).
PartitionType
Specifies the type of partition. This member can be one of the following values:
Value | Meaning
PARTITION_ENTRY_UNUSED | Entry unused.
PARTITION_FAT_12 | Specifies a partition with 12-bit FAT entries.
PARTITION_XENIX_1 | Specifies a Xenix type 1 partition.
PARTITION_XENIX_2 | Specifies a Xenix type 2 partition.
PARTITION_FAT_16 | Specifies a partition with 16-bit FAT entries.
PARTITION_EXTENDED | Specifies an extended partition entry.
PARTITION_HUGE | Specifies an MS-DOS V4 huge partition.
PARTITION_IFS | Specifies an IFS partition.
PARTITION_PREP | Specifies a PowerPC Reference Platform partition.
PARTITION_UNIX | Specifies a UNIX partition.
VALID_NTFT | Specifies an NTFT partition.
PARTITION_XINT13 | Windows 95 and Windows 98: Specifies a partition that uses extended int13 services.
PARTITION_XINT13_EXTENDED | Windows 95 and Windows 98: Same as PARTITION_EXTENDED, but uses extended int13 services.

BootIndicator
Specifies whether the partition is bootable.
RecognizedPartition
Specifies whether the partition is recognized.
RewritePartition
Specifies whether the partition information has changed. When you change a partition (with IOCTL_DISK_SET_DRIVE_LAYOUT), the system uses this member to determine which partitions have changed and need their information rewritten.

Remarks

The DeviceIoControl function receives a PARTITION_INFORMATION structure in response to an IOCTL_DISK_GET_PARTITION_INFO or IOCTL_DISK_GET_DRIVE_LAYOUT device input and output control (IOCTL) operation. The DeviceIoControl function uses a PARTITION_INFORMATION structure as input to an IOCTL_DISK_SET_DRIVE_LAYOUT device IOCTL operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Structures, DeviceIoControl, IOCTL_DISK_GET_DRIVE_LAYOUT, IOCTL_DISK_GET_PARTITION_INFO, IOCTL_DISK_SET_DRIVE_LAYOUT


PREVENT_MEDIA_REMOVAL

The PREVENT_MEDIA_REMOVAL structure provides removable media locking data.

typedef struct _PREVENT_MEDIA_REMOVAL{
   BOOLEAN PreventMediaRemoval;
} PREVENT_MEDIA_REMOVAL ;

Members

PreventMediaRemoval
Specifies whether the media is to be locked (if TRUE) or not (if FALSE).

Remarks

The DeviceIoControl function uses a PREVENT_MEDIA_REMOVAL structure as input to an IOCTL_DISK_MEDIA_REMOVAL device input and output operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Structures, DeviceIoControl, IOCTL_DISK_MEDIA_REMOVAL


REASSIGN_BLOCKS

The REASSIGN_BLOCKS structure provides disk-block reassignment data. It is a variable-length structure whose last member is an array of block numbers to be reassigned.

typedef struct _REASSIGN_BLOCKS {
    WORD   Reserved;
    WORD   Count;
    DWORD BlockNumber[1];
} REASSIGN_BLOCKS ;

Members

Reserved
This member is reserved. Do not use it. Set it to zero.
Count
Specifies the number of blocks to be reassigned. This is the number of elements that are in the BlockNumber member array.
BlockNumber
An array of Count block numbers, one for each block to be reassigned.

Remarks

The DeviceIoControl function uses a REASSIGN_BLOCKS structure as input to an IOCTL_DISK_REASSIGN_BLOCKS device input and output control operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Structures, DeviceIoControl, IOCTL_DISK_REASSIGN_BLOCKS


REPARSE_DATA_BUFFER

[This is preliminary documentation and subject to change.]

The REPARSE_DATA_BUFFER structure contains information about a reparse point. Each reparse point contains one instance of a REPARSE_DATA_BUFFER.

typedef struct _REPARSE_DATA_BUFFER {
    ULONG  ReparseTag;
    USHORT ReparseDataLength;
    USHORT Reserved;
    UCHAR  DataBuffer[1];
} REPARSE_DATA_BUFFER;

Members

ReparseTag
Identifies the type of reparse point. The ReparseTag member indicates the structure of the user-defined reparse data.

For more information, see Reparse Point Tags.

ReparseDataLength
Size, in bytes, of the reparse data in DataBuffer. This value will vary with different tags.
Reserved
Do not use this member when setting a reparse point.
DataBuffer
User-defined data for the reparse point.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Device Input and Output Overview, Device Input and Output Structures, FSCTL_GET_REPARSE_POINT, Reparse Points


SET_PARTITION_INFORMATION

The SET_PARTITION_INFORMATION structure provides information used to set a disk partition's type.

typedef struct _SET_PARTITION_INFORMATION {
   BYTE PartitionType;
} SET_PARTITION_INFORMATION ;

Members

PartitionType
Specifies the type of partition. This member can be one of the following values:
Value | Meaning
PARTITION_ENTRY_UNUSED | Entry unused.
PARTITION_FAT_12 | Specifies a partition with 12-bit FAT entries.
PARTITION_XENIX_1 | Specifies a Xenix type 1 partition.
PARTITION_XENIX_2 | Specifies a Xenix type 2 partition.
PARTITION_FAT_16 | Specifies a partition with 16-bit FAT entries.
PARTITION_EXTENDED | Specifies an extended partition entry.
PARTITION_HUGE | Specifies an MS-DOS V4 huge partition.
PARTITION_IFS | Specifies an IFS partition.
PARTITION_UNIX | Specifies a UNIX partition.
VALID_NTFT | Specifies an NTFT partition.
PARTITION_XINT13 | Windows 95 and Windows 98: Specifies a partition that uses extended int13 services.
PARTITION_XINT13_EXTENDED | Windows 95 and Windows 98: Same as PARTITION_EXTENDED, but uses extended int13 services.

Remarks

The DeviceIoControl function uses a SET_PARTITION_INFORMATION structure as input to an IOCTL_DISK_SET_PARTITION_INFO device input and output control operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Structures, DeviceIoControl, IOCTL_DISK_GET_PARTITION_INFO, IOCTL_DISK_SET_PARTITION_INFO, PARTITION_INFORMATION


VERIFY_INFORMATION

The VERIFY_INFORMATION structure provides information used to logically format a disk extent.

typedef struct _VERIFY_INFORMATION {
   LARGE_INTEGER  StartingOffset;
   DWORD  Length;
} VERIFY_INFORMATION ;

Members

StartingOffset
Specifies the starting offset of the disk extent.
Length
Length, in bytes, of the disk extent.

Remarks

The DeviceIoControl function uses a VERIFY_INFORMATION structure as input to an IOCTL_DISK_VERIFY device I/O operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Structures, DeviceIoControl, IOCTL_DISK_VERIFY


Device Input and Output Enumeration Types

The following enumeration type is used with device input and output.

MEDIA_TYPE


MEDIA_TYPE

The MEDIA_TYPE enumeration type contains values that specify various forms of device media. The comments explain the enumerators.

typedef enum _MEDIA_TYPE {
    Unknown,                // Format is unknown
    F5_1Pt2_512,            // 5.25", 1.2MB,  512 bytes/sector
    F3_1Pt44_512,           // 3.5",  1.44MB, 512 bytes/sector
    F3_2Pt88_512,           // 3.5",  2.88MB, 512 bytes/sector
    F3_20Pt8_512,           // 3.5",  20.8MB, 512 bytes/sector
    F3_720_512,             // 3.5",  720KB,  512 bytes/sector
    F5_360_512,             // 5.25", 360KB,  512 bytes/sector
    F5_320_512,             // 5.25", 320KB,  512 bytes/sector
    F5_320_1024,            // 5.25", 320KB,  1024 bytes/sector
    F5_180_512,             // 5.25", 180KB,  512 bytes/sector
    F5_160_512,             // 5.25", 160KB,  512 bytes/sector
    RemovableMedia,         // Removable media other than floppy
    FixedMedia              // Fixed hard disk media
} MEDIA_TYPE;

Remarks

The MediaType member of the DISK_GEOMETRY data structure is of type MEDIA_TYPE. The DeviceIoControl function receives a DISK_GEOMETRY structure in response to an IOCTL_DISK_GET_DRIVE_GEOMETRY device I/O operation. The DeviceIoControl function receives an array of DISK_GEOMETRY structures in response to an IOCTL_DISK_GET_MEDIA_TYPES device I/O operation.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winioctl.h.

See Also

Device Input and Output Overview, Device Input and Output Enumeration Types, DeviceIoControl, DISK_GEOMETRY, IOCTL_DISK_GET_DRIVE_GEOMETRY, IOCTL_DISK_GET_MEDIA_TYPES


Power Management

This overview describes the power management support in the Microsoft® Win32® API, and explains how to use it in your applications. It also describes the OnNow initiative and how your applications can take advantage of computers that are "always on" to enhance the user's experience and save power.


About Power Management

To save power and ensure that no data is lost when a computer or device is turned off or placed in a low power state, the system provides power management support. The power management functions and messages retrieve the system power status, notify applications of power management events, and notify the system of each application's power requirements. This overview contains the following topics:

  • OnNow Power Management
  • System Power Status
  • System Power States
  • Power Management Events
  • Power Management Policy
  • System Sleep Criteria
  • System Wake-up Events
  • Message-Waiting Indicators


OnNow Power Management

[This is preliminary documentation and subject to change.]

Computers that comply with OnNow are designed to be instantly accessible to users at the touch of a button. As with appliances, the computer must always be on and ready for use, but appear to be off when not in use. This state of low power consumption is called the sleeping state.

When the computer is in the sleeping state, the computer hardware, the system, and applications running on the computer must be capable of responding immediately to the power switch, communications events, and other actions. If all applications handle power state transitions gracefully, the user will perceive a more elegant and integrated system. Applications that do not handle these transitions can fail when the power is turned off and then on, because of data loss or a dependency on a device that may have been removed.

The following are other benefits of OnNow:

  • Eliminates startup and shutdown delays. The computer need not perform a full system boot when starting or a full system shutdown when turned off. Instead, the computer enters and leaves the sleeping state.
  • Enables automated tasks to run while the computer is "off." The Task Scheduler provides a user interface that enables the user to schedule applications to run, even when the system is in the sleeping state. The Task Scheduler uses waitable timers to ensure that the system is ready when the application is scheduled to run. For more information, see the help file included with the Task Scheduler.
  • Enables per-device power management. Devices that are not in use can save power by entering the sleeping state.
  • Improves power efficiency. Power efficiency is particularly important on portable computers. The life of a battery on a portable computer is significantly reduced by use of the CPU and hard drive. When the computer is running on batteries, the system attempts to put the CPU and hard drive into a low power state whenever they are idle.
  • The Power Management control panel application provides a simple user interface through which the user can specify preferences. The user can create power schemes, set alarms, and specify battery options. The operating system coordinates all power management activities, based on power management policies. For more information, see the help file included with the Power Management control panel application.


System Power Status

The system power status indicates whether the source of power for a computer is a system battery or AC power. For computers that use batteries, the system power status also indicates how much battery life remains and whether the battery is currently charging.

You can retrieve the system power status by using the GetSystemPowerStatus function. This function copies information about the power supply and battery status to a SYSTEM_POWER_STATUS structure. This structure identifies whether the system has a battery, and if it does, whether the battery is being used, and what percentage of the charge remains. The system sends the PBT_APMPOWERSTATUSCHANGE message to all applications when the power status changes. When your application receives this message, it should call GetSystemPowerStatus again to determine what changed.

Applications and installable drivers typically use the system power status to determine whether continued operation is feasible. For example, before an application performs background operations such as compressing or paginating a file, it should call GetSystemPowerStatus to check whether the system is on batteries. As another example, an application that is beginning a lengthy operation should call GetSystemPowerStatus to check the status to determine whether enough battery power exists to complete the operation.

If power is low, an application can request user intervention or request that the system shut itself down. You can suspend system operation by using the SetSystemPowerState function. This generates a power management event that, if approved by all applications and drivers in the system, shuts down the system until the user restores power. Even if a computer uses AC power, an application that determines that the system is idle can request that the system shut itself down to save power.

Applications should also use the GetDevicePowerState function to check whether the hard disk is powered down. Applications that do not perform these checks can cause the hard disk to power up frequently, reducing any power saved by the system through power management. Instead, applications should wait until the user performs an action that causes the hard disk to power up before performing background operations. Applications should also shut down when possible, to save power and reduce noise.


System Power States

[This is preliminary documentation and subject to change.]

To the user, the system appears to be either on or off. There are no other detectable states. However, you should be aware that the system supports these power states. The following table lists the power states from highest to lowest power consumption.

Power State | Description
Working | The system is fully usable; power saving occurs on a per-device basis. Devices that are not in use can save power by entering a lower power state.
Sleeping | Appears to be off. Power consumption is reduced to one of several levels of power consumption, depending on how the system is to be used. The lower the level of power consumption, the more time it takes the system to return to the working state.
Soft Off | Appears to be off. Very low power consumption. The working context can be restored if it is stored on nonvolatile media.
Mechanical Off | No power consumption. The system returns to the working state only after a full reboot.

Applications that assume the system is always in the working state can inadvertently keep it from entering a lower power state. To avoid this, applications should watch for the WM_POWERBROADCAST message. WM_POWERBROADCAST notifies applications of changes in the power state. Console applications should use the RegisterSysMsgHandler function to register a message handler to receive power management messages.

The Sleeping State

There are different levels in the sleeping state. The following table shows the system sleep states and their corresponding advanced configuration and power interface (ACPI) and advanced power management (APM) states.

System Sleep State | ACPI State | APM State
PowerSystemWorking | S0 | Working
PowerSystemSleeping1 | S1 | SUSPEND
PowerSystemSleeping2 | S2 | SUSPEND
PowerSystemSleeping3 | S3 | SUSPEND
PowerSystemHibernate | S4 | SUSPEND

It takes longer to restore a system from a lower power state than from a higher power state because of the extra work the hardware may have to do (stabilize power supply, reinitialize the processor, and so forth). By default, the system will use the lowest sleeping state supported by all enabled wake-up devices, within the specified latency requirements. To set the default sleep state, the user can use the Power Management control panel application. An application can specify its latency requirements using the RequestWakeupLatency function.

After the system has selected the sleeping state the system will enter, it requests permission to enter the sleeping state from all applications, using the PBT_APMQUERYSUSPEND message. If no applications deny the request, the system sends it to the drivers by using the IRP_MJ_POWER and IRP_MN_QUERY_POWER messages. If any drivers deny the request, the system requests the next highest sleeping state, until a sleep state is successfully entered or there are no more available sleep states. The user can configure the system to take one of the following actions if the requested sleep state is higher than the preferred sleep state:

  • Display a dialog box indicating the problem.
  • Ignore the chosen state and use a preferred power state.
  • Ignore the preferred power state and use the chosen state.


Power Management Events

A power management event is a change in either the system power status or the operational mode of a device or the system. Because these events can affect the operation of applications and installable drivers and can lead to loss of data, the system notifies all applications and installable drivers by broadcasting a WM_POWERBROADCAST message for each event.

System Power Status Events

A system power status event occurs when there is a change in the power supply or in the system battery status. For example, the system broadcasts a PBT_APMPOWERSTATUSCHANGE message whenever the user switches from battery to AC power or vice versa. The system also broadcasts this message when remaining battery power slips below the threshold specified by the user.

Operational Mode Events

An operational mode event occurs when there is a change in power consumption, such as the system shutting itself down or the user turning the system off. If applications and drivers do not prepare for changes in operational mode, they can lose data. Therefore, the system broadcasts messages about these changes before they actually occur. For example, if the system determines that it is idle, it broadcasts a PBT_APMSUSPEND message notifying applications and drivers that it is about to suspend operation and shut itself down to save power. The applications and drivers can prepare for this suspension by closing files and saving data that may otherwise be lost when power is shut off.

The system has two ways to shut itself down. It can suspend operation or carry out critical suspension. An application can also shut the system down by using the SetSystemPowerState function to suspend operation.

When system operation is suspended, power to all devices is lost. The WM_POWERBROADCAST message, sent immediately before suspension, allows device drivers to save the state of the device. For many devices (but not all), saving the state means the driver can restore the state when power is eventually restored, allowing the device to continue operation as if power had not been lost.

When the system carries out a critical suspension, the system is shut down immediately because battery power is too low to let the system continue to run. In contrast to suspended operation, the system does not notify applications and drivers before carrying out a critical suspension. This means data may be lost.

When system operation is restored after having been suspended, the system notifies all applications and drivers. It also identifies the manner in which the system was previously shut down so the application or driver can take appropriate steps to restore its data and continue its own operation.

Applications should make every attempt to handle the transition to the sleeping state without any user intervention. When the system requests permission to enter the sleeping state, your application should check to see if it has any open files on removable drives or on the network. If so, the application should autosave and close its files. Applications should deny permission to enter the sleeping state only if an uninterruptible operation is in progress.


Power Management Policy

The system sends a message to all applications and installable drivers whenever a power management event occurs or whenever an application calls the SetSystemPowerState function to suspend operation. The system sends these messages through the WM_POWERBROADCAST message, setting the wParam parameter to the appropriate message. For example, the PBT_APMPOWERSTATUSCHANGE message indicates a system power status change. You must ensure that your application responds to the WM_POWERBROADCAST message to properly stop activity when the system enters the sleeping state and to recover transparently when the system enters the working state. When the system enters the sleeping state, it closes network connections. The user can change the hardware configuration or power supply while the system is in the sleeping state.

The system sends a PBT_APMQUERYSUSPEND message to request permission to suspend system operation. The system expects each application and driver to determine whether the requested event should occur and to return TRUE if it occurs, or return BROADCAST_QUERY_DENY otherwise. Any application or driver can deny the request and prevent the event from occurring.

The system sends a PBT_APMSUSPEND message immediately before suspending operation. This gives applications and drivers one last chance to prepare for the event. In many cases, the system sends these messages without requesting permission to do so. This happens, for example, if an application forces suspension with the SetSystemPowerState function.

The system sends the PBT_APMQUERYSUSPENDFAILED message whenever a requested event is denied. These messages notify applications and drivers to continue operation as usual.

The system sends the PBT_APMRESUMESUSPEND or PBT_APMRESUMECRITICAL message when system operation has been restored.


System Sleep Criteria

[This is preliminary documentation and subject to change.]

As long as the system determines that there is application activity, it will not put the system or any devices into the sleeping state. The system can detect certain activities, such as user input or network communications. However, there are other activities that the system cannot track. For example, a presentation application requires the screen for display. However, it may appear that the application is idle during the presentation, causing the system to turn off the screen. To notify the system that your application is busy, use the SetThreadExecutionState function. This function prevents the system from placing the system or any devices into the sleeping state while the application is running.

Presentation and multimedia applications must call SetThreadExecutionState with ES_DISPLAY_REQUIRED so that the system will know that it should not put the display device into the sleeping state. Event-handling applications, such as utilities for managing incoming faxes, must call SetThreadExecutionState with ES_SYSTEM_REQUIRED, handle the event, then clear the flag so the system can put the system back into the sleeping state. Note that most productivity applications do not need to use SetThreadExecutionState because the system can usually determine activity by user input.

To maintain the time since the last user input, the system uses a display idle timer and a system idle timer. The system compares the idle timers to the time-out values the user sets for the display and system by using the Power Management control panel application. If the display idle timer value is greater than the display time-out value, and no threads have requested the display by calling SetThreadExecutionState with ES_DISPLAY_REQUIRED, the system puts the display into the sleeping state. Similarly, if the system idle timer is greater than the system time-out value, and no applications have requested the system by calling SetThreadExecutionState with ES_SYSTEM_REQUIRED, the system puts the system into the sleeping state.

The system maintains a count of applications that have called SetThreadExecutionState. The system tracks each thread that calls SetThreadExecutionState and adjusts the counter accordingly. If this counter reaches zero and there has not been any user input, the system puts the system into the sleeping state by calling SetSystemPowerState.

When you call the SetSystemPowerState function with fForce set to TRUE, the system generally puts the system into the sleeping state. However, if the next scheduled wake-up time is less than 30 seconds from the current time, SetSystemPowerState leaves the system in the working state and returns FALSE, regardless of the value of fForce.


System Wake_up Events

System Wake-up Events

[This is preliminary documentation and subject to change.]

Your application can restore an On-Now capable computer that is in a sleeping state to the working state by using a scheduled time or a device event. This is known as a wake-up event. Use a waitable timer object to specify the time at which the system should wake. To create the object, use the CreateWaitableTimer function. To set the timer, use the SetWaitableTimer function. The pDueTime parameter specifies when the timer will be signaled. To specify that the system should wake when the timer is signaled, set the fResume parameter to TRUE.

Use the RequestDeviceWakeup function to enable the device's wake-up capability. You can have the system awaken after a modem ring, network request, or other device-based event. Your application should provide an interface for the user to specify the device wake-up, then use RequestDeviceWakeup.

When the system wakes automatically because of an event (other than power switch or user activity), the system automatically sets its idle timer to at least 1 minute. This timer allows applications to call the SetThreadExecutionState function to indicate that they are busy. This enables the system to shut down without affecting the user. The following criteria determine whether a system shutdown is needed:

  • If the system wakes automatically, it shuts down as soon as the last job is completed, as indicated by the process calling SetThreadExecutionState.
  • If the system wakes automatically, but the user provides new input while the event is handled, the system does not shut down when the last job finishes.
  • If the system is on and the user is active, the system does not enter the sleeping state.
  • If the system is on, no applications are busy, and the user is inactive for a long time, the system enters the sleeping state when the timer expires.

When the system wakes automatically, the system sends the PBT_APMRESUMEAUTOMATIC message to all applications. Because the user is not present, most applications should do nothing. Event-handling applications, such as fax servers, should handle their events. If you wish to determine whether the system is in this state, call the IsSystemResumeAutomatic function.

If the system wakes due to user activity after sending PBT_APMRESUMEAUTOMATIC, the system sends the PBT_APMRESUMESUSPEND message and turns on the display. Your application should reopen files that it closed when the system entered the sleeping state, and it should prepare for user input.

If an application called SetSystemPowerState with fForce set to TRUE, no applications will receive the PBT_APMQUERYSUSPEND message when the system enters the sleeping state. If the system is carrying out a critical suspension, no applications will receive the PBT_APMQUERYSUSPEND or PBT_APMSUSPEND message; they will receive only the PBT_APMRESUMECRITICAL message.


Message-Waiting Indicators

[This is preliminary documentation and subject to change.]

The PC97 Designed for Windows logo program requires that new computers have message-waiting indicators on the front of the computer. This enables applications that download e-mail, voice messages, faxes, and other electronic transmissions to indicate to the user that new messages have arrived, even when the system is in the sleeping state. The application calls the SetMessageWaitingIndicator function to update the message-waiting indicator.

The system tracks calls to SetMessageWaitingIndicator on a per-process basis. If a process exits, either normally or abnormally, the system reduces the message-waiting counter by the number of messages specified in the last call the process made to SetMessageWaitingIndicator.


Power Management Reference

The following elements are used with power management.

  • Power Management Functions
  • Power Management Structures
  • Power Management Messages


Power Management Functions

The following functions are used with power management.

CancelDeviceWakeupRequest
GetDevicePowerState
GetSystemPowerStatus
IsSystemResumeAutomatic
RequestDeviceWakeup
RequestWakeupLatency
SetMessageWaitingIndicator
SetSystemPowerState
SetThreadExecutionState


CancelDeviceWakeupRequest

[This is preliminary documentation and subject to change.]

The CancelDeviceWakeupRequest function cancels a device wake-up request issued previously by the RequestDeviceWakeup function.

BOOL CancelDeviceWakeupRequest(
  HANDLE hDevice   // handle to object or device
);

Parameters

hDevice
Handle to an object on the device, such as a file or socket, or a handle to the device itself.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. The function will fail if the device does not support wake-up or if the system is entering the sleeping state.

Remarks

The wake-up functionality may not be turned off immediately. The system will only disable the wake-up feature on the device when all applications that requested wake-up on that device using the RequestDeviceWakeup function have canceled their requests using CancelWakeupRequest.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Power Management Overview, Power Management Functions, RequestDeviceWakeup


GetDevicePowerState

[This is preliminary documentation and subject to change.]

The GetDevicePowerState function retrieves the current power state of the specified device.

BOOL GetDevicePowerState(
  HANDLE hDevice,     // device-context handle
  BOOL pfOn           // pointer to variable receiving power state
);

Parameters

hDevice
Handle to an object on the device, such as a file or socket, or a handle to the device itself.
pfon
Pointer to the variable that receives the power state. This value is TRUE if the device is fully on. Otherwise, it is FALSE.

Return Values

If the function succeeds, it returns a nonzero value. Otherwise, the function returns zero.

Remarks

An application can use GetSystemPowerState to determine whether a disk or other device is spun up. If the device is not spun up, the application should defer accessing it.

This function uses the IOCTL_GET_DEVICE_POWER_STATUS command to obtain the power state.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Power Management Overview, Power Management Functions, GetSystemPowerStatus


GetSystemPowerStatus

[This is preliminary documentation and subject to change.]

The GetSystemPowerStatus function retrieves the power status of the system. The status indicates whether the system is running on AC or DC power, whether the battery is currently charging, and how much battery life remains.

BOOL GetSystemPowerStatus(
  LPSYSTEM_POWER_STATUS lpSystemPowerStatus
);

Parameters

lpSystemPowerStatus
Pointer to a SYSTEM_POWER_STATUS structure that receives status information.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Power Management Overview, Power Management Functions, SYSTEM_POWER_STATUS


IsSystemResumeAutomatic

[This is preliminary documentation and subject to change.]

The IsSystemResumeAutomatic function indicates the current state of the computer.

BOOL IsSystemResumeAutomatic(VOID);

Parameters

This function has no parameters.

Return Values

If the system was restored to the working state automatically and the user is not active, the function returns TRUE. Otherwise, the function returns FALSE.

Remarks

The PBT_APMRESUMEAUTOMATIC message is sent when the system wakes automatically to handle an event. The user is generally not present. If the system detects any user activity after sending the PBT_APMRESUMEAUTOMATIC message, it will send the PBT_APMRESUMESUSPEND message to let applications know they can resume full interaction with the user.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Power Management Overview, Power Management Functions, PBT_APMRESUMEAUTOMATIC, PBT_APMRESUMESUSPEND


RequestDeviceWakeup

[This is preliminary documentation and subject to change.]

The RequestDeviceWakeup function issues a device wake-up request.

BOOL RequestDeviceWakeup(
  HANDLE hDevice      // handle to object or device
);

Parameters

hDevice
Handle to an object on the device, such as a file or socket, or a handle to the device itself.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. The function will fail if the device does not support wake-up, the system is entering the sleeping state, or wake-up could not be enabled.

Remarks

If the device is not marked as a wake-up device, the system will issue the IOCTL_SET_RESUME command to the driver to tell it to enable wake-up. When the system puts the computer in the sleeping state, it makes sure that the device is in a power state that supports signaling wake-up operations.

To cancel the device wake-up request, use the CancelDeviceWakeupRequest function. To specify a latency requirement on the time it takes the system to wake up the computer, use the RequestWakeupLatency function.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Power Management Overview, Power Management Functions, CancelDeviceWakeupRequest, RequestWakeupLatency


RequestWakeupLatency

[This is preliminary documentation and subject to change.]

The RequestWakeupLatency function specifies roughly how quickly the computer should enter the working state.

BOOL RequestWakeupLatency(
  LATENCY_TIME latency      // latency requirement
);

Parameters

latency
Specifies the latency requirement on the time is takes to wake the computer. This parameter can be one of the following values.
Value | Description
LT_LOWEST_LATENCY | PowerSystemSleeping1 state (equivalent to ACPI state S0 and APM state Working).
LT_DONT_CARE | Any latency (default).

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. The function will fail if the device does not support wake-up operations or if the system is entering the sleeping state.

Remarks

The system uses the wake-up latency requirement when choosing a sleeping state. The latency is not guaranteed, because wake-up time is determined by the hardware design of the particular computer.

To cancel a latency request, call RequestWakeupLatency with LT_DONT_CARE.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Power Management Overview, Power Management Functions, CancelDeviceWakeupRequest, RequestDeviceWakeup


SetMessageWaitingIndicator

[This is preliminary documentation and subject to change.]

The SetMessageWaitingIndicator function updates the computer's message waiting indicator. Applications use this feature while the computer is in a low power state to indicate to the user that new e-mail, fax, or voice messages have arrived.

BOOL SetMessageWaitingIndicator(
  HANDLE hIndicator,  // application-defined 32-bit value
  ULONG cmsg          // number of messages waiting
);

Parameters

hIndicator
Handle to the message indicator device. The handle is obtained by calling the CreateFile function on the \\.\MessageIndicator device
cmsg
The current number of messages the application has waiting.

Return Values

If the computer does not have a message waiting indicator, the function returns zero. Otherwise, it returns a nonzero value.

Remarks

The system tracks calls to SetMessageWaitingIndicator on a per-handle basis. It combines the number specified in the cmsg parameter with the current value of the message-waiting indicator and displays the result. If the process exits, either normally or abnormally, the system automatically closes all handles. This reduces the value of the indicator by the amount specified in the application's last call to SetMessageWaitingIndicator.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Power Management Overview, Power Management Functions, CreateFile, GetDevicePowerState


SetSystemPowerState

[This is preliminary documentation and subject to change.]

The SetSystemPowerState function suspends the system by shutting power down. Depending on the ForceFlag parameter, the function either suspends operation immediately or requests permission from all applications and device drivers before doing so.

BOOL SetSystemPowerState(
  BOOL fSuspend,
  BOOL fForce
);

Parameters

fSuspend
Ignored.
fForce
Forced suspension. If TRUE, the function sends a PBT_APMSUSPEND message to each application and driver, then immediately suspends operation. If FALSE, the function sends a PBT_APMQUERYSUSPEND message to each application to request permission to suspend operation.

Return Values

If power has been suspended and subsequently restored, the return value is nonzero.

If the system was not suspended, the return value is zero. To get extended error information, call GetLastError.

Remarks

If any application or driver denies permission to suspend operation, the function sends a PBT_APMQUERYSUSPENDFAILED message to each application and driver. If power is suspended, this function returns only after system operation is resumes and related WM_POWERBROADCAST messages have been sent to all applications and drivers.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Power Management Overview, Power Management Functions, PBT_APMQUERYSUSPEND, PBT_APMQUERYSUSPENDFAILED, PBT_APMSUSPEND, WM_POWERBROADCAST


SetThreadExecutionState

[This is preliminary documentation and subject to change.]

The SetThreadExecutionState function enables applications to inform the system that it is in use, thereby preventing the system from entering the sleeping power state while the application is running.

EXECUTION_STATE SetThreadExecutionState(
  EXECUTION_STATE esFlags  // execution requirements
);

Parameters

esFlags
Specifies the thread's execution requirements. This parameter can be one or more of the following values.
Flag | Description
ES_SYSTEM_REQUIRED | Informs the system that the thread is performing some operation that is not normally detected as activity by the system.
ES_DISPLAY_REQUIRED | Informs the system that the thread is performing some operation that is not normally detected as display activity by the system.
ES_CONTINUOUS | Informs the system that the state being set should remain in effect until the next call that uses ES_CONTINUOUS and one of the other state flags is cleared.

Return Values

If the function succeeds, the return value is the previous thread execution state.

If the function fails, the return value is NULL.

Remarks

Activities that are automatically detected include local keyboard or mouse input, server activity, and changing window focus. Activities that are not automatically detected include disk or CPU activity and video display.

Calling SetThreadExecutionState with ES_SYSTEM_REQUIRED prevents the system from putting the computer in the sleeping state by resetting the system idle timer. Calling SetThreadExecutionState with ES_DISPLAY_REQUIRED prevents the system from turning off the display by resetting the display idle timer. Calling SetThreadExecutionState without ES_CONTINUOUS simply resets the idle timer; to keep the display or system in the working state, the thread must call SetThreadExecutionState periodically.

To run properly on a power-managed computer, applications such as fax servers, answering machines, backup agents, and network management applications must use ES_SYSTEM_REQUIRED | ES_CONTINUOUS when they process events. Multimedia applications, such as video players and presentation applications, must use ES_DISPLAY_REQUIRED when they display video for long periods of time without user input. Applications such as word processors, spreadsheets, browsers, and games do not need to call SetThreadExecutionState.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Power Management Overview, Power Management Functions, SetSystemPowerState, WM_POWERBROADCAST


Power Management Structures

The following structures are used with power management..

SYSTEM_POWER_STATUS


SYSTEM_POWER_STATUS

[This is preliminary documentation and subject to change.]

The SYSTEM_POWER_STATUS structure contains information about the power status of the system.

typedef struct _SYSTEM_POWER_STATUS {
    BYTE ACLineStatus;
    BYTE  BatteryFlag;
    BYTE  BatteryLifePercent;
    BYTE  Reserved1;
    DWORD  BatteryLifeTime;
    DWORD  BatteryFullLifeTime;
} SYSTEM_POWER_STATUS;
typedef struct SYSTEM_POWER_STATUS *LPSYSTEM_POWER_STATUS;

Members

ACLineStatus
AC power status. This parameter can be one of the following values.
Value | Meaning
0 | Offline
1 | Online
255 | Unknown status.

All other values are reserved.

BatteryFlag
Battery charge status. This parameter can be a combination of the following values.
Value | Meaning
1 | High
2 | Low
4 | Critical
8 | Charging
128 | No system battery
255 | Unknown status

All other values are reserved.

BatteryLifePercent
Percentage of full battery charge remaining. This member can be a value in the range 0 to 100, or 255 if status is unknown. All other values are reserved.
Reserved1
Reserved; must be zero.
BatteryLifeTime
Number of seconds of battery life remaining, or 0xFFFFFFFF if remaining seconds are unknown.
BatteryFullLifeTime
Number of seconds of battery life when at full charge, or 0xFFFFFFFF if full battery lifetime is unknown.

Remarks

The system is only capable of estimating BatteryFullTime based on calculations on BatteryLifeTime and BatteryLifePercent. Without smart battery subsystems, this value may not be accurate enough to be useful.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Power Management Overview, Power Management Structures


Power Management Messages

The following messages are used with power management..

PBT_APMBATTERYLOW
PBT_APMOEMEVENT
PBT_APMPOWERSTATUSCHANGE
PBT_APMQUERYSUSPEND
PBT_APMQUERYSUSPENDFAILED
PBT_APMRESUMEAUTOMATIC
PBT_APMRESUMECRITICAL
PBT_APMRESUMESUSPEND
PBT_APMSUSPEND
WM_POWERBROADCAST

Obsolete Messages

WM_POWER

See Also

Power Management Overview, Power Management Structures


PBT_APMBATTERYLOW

[This is preliminary documentation and subject to change.]

The PBT_APMBATTERYLOW message is sent to notify applications that battery power is low. A window receives this message through the WM_POWERBROADCAST message.

PBT_APMBATTERYLOW
dwData = (DWORD) lParam;

Parameters

dwData
Reserved, must be zero.

Return Values

No return value.

Remarks

This message is broadcast when a system's APM BIOS signals an APM battery low notification. Because some APM BIOS implementations do not provide notifications when batteries are low, this message may never be sent on some computers.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in pbt.h.

See Also

Power Management Overview, Power Management Messages, WM_POWERBROADCAST


PBT_APMOEMEVENT

[This is preliminary documentation and subject to change.]

The PBT_APMOEMEVENT message is sent when an APM BIOS signals an APM OEM event. A window receives this message through the WM_POWERBROADCAST message.

PBT_APMOEMEVENT
dwEventCode = (DWORD) lParam;

Parameters

dwEventCode
OEM-defined event code that was signaled by the system's APM BIOS. OEM event codes are in the range 0200h - 02FFh.

Return Values

No return value.

Remarks

Because not all APM BIOS implementations provide OEM event notifications, this message may never be sent on some machines.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in pbt.h.

See Also

Power Management Overview, Power Management Messages, WM_POWERBROADCAST


PBT_APMPOWERSTATUSCHANGE

[This is preliminary documentation and subject to change.]

The PBT_APMPOWERSTATUSCHANGE message is sent when a change in the power status of the computer is detected, such as a switch from battery power to A/C or a drop in remaining battery power below a threshold. A window receives this message through the WM_POWERBROADCAST message.

dwData = (DWORD) lParam;

Parameters

dwData
Reserved; must be 0.

Return Values

No return value.

Remarks

An application should process this message by calling the GetSystemPowerStatus function to retrieve the current power status of the computer. In particular, the application should check the ACLineStatus, BatteryFlag, BatteryLifeTime, and BatteryLifePercent members of the SYSTEM_POWER_STATUS structure for any changes. This message can occur when battery life drops to less than 5 minutes, or when the percentage of battery life drops below 10 percent.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in pbt.h.

See Also

Power Management Overview, Power Management Messages, GetSystemPowerStatus, SYSTEM_POWER_STATUS, WM_POWERBROADCAST


PBT_APMQUERYSUSPEND

[This is preliminary documentation and subject to change.]

The PBT_APMQUERYSUSPEND message is sent to request permission to suspend the computer. An application that grants permission should carry out preparations for the suspension before returning. A window receives this message through the WM_POWERBROADCAST message.

Flags = (DWORD) lParam;

Parameters

Flags
Action flags. If bit 0 is 1, the application can prompt the user for directions on how to prepare for the suspension; otherwise, the application must prepare without user interaction. All other bit values are reserved.

Return Values

Return TRUE to grant the request to suspend. To deny the request, return BROADCAST_QUERY_DENY.

Remarks

An application should process this message by first determining whether permission to suspend can be granted. It must not grant permission if doing so would cause a loss of data. The application can prompt the user for directions on how to prepare for suspension only if bit 0 in the Flags parameter is set.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in pbt.h.

See Also

Power Management Overview, Power Management Messages, WM_POWERBROADCAST


PBT_APMQUERYSUSPENDFAILED

[This is preliminary documentation and subject to change.]

The PBT_APMQUERYSUSPENDFAILED message is sent as a notification that permission to suspend the computer was denied. This message is sent if any application or driver returned BROADCAST_QUERY_DENY to a previous PBT_APMQUERYSUSPEND message. A window receives this message through the WM_POWERBROADCAST message.

dwData = (DWORD) lParam;

Parameters

dwData
Reserved; must be zero.

Return Values

No return value.

Remarks

Applications typically respond to this message by resuming normal operation.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in pbt.h.

See Also

Power Management Overview, Power Management Messages, PBT_APMQUERYSUSPEND, WM_POWERBROADCAST


PBT_APMRESUMEAUTOMATIC

[This is preliminary documentation and subject to change.]

The PBT_APMRESUMEAUTOMATIC message is sent when the computer wakes up automatically to handle an event. An application will not generally respond to this message unless it is handling the event, because the user is not present. A window receives this message through the WM_POWERBROADCAST message.

dwData = (DWORD) lParam;

Parameters

dwData
Reserved; must be 0.

Return Values

No return value.

Remarks

If the system detects any user activity after sending PBT_APMRESUMEAUTOMATIC, it will send a PBT_APMRESUMESUSPEND message to let applications know they can resume full interaction with the user.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in pbt.h.

See Also

Power Management Overview, Power Management Messages, PBT_APMRESUMESUSPEND, WM_POWERBROADCAST


PBT_APMRESUMECRITICAL

[This is preliminary documentation and subject to change.]

The PBT_APMRESUMECRITICAL message is sent as a notification that the system has resumed operation after a critical suspension caused by a failing battery. A driver receives this message through the WM_POWERBROADCAST message.

dwData = (DWORD) lParam;

Parameters

dwData
Reserved; must be 0.

Return Values

No return value.

Remarks

Because a critical suspension occurs without prior notification, resources and data previously available to a driver may not be present when the driver receives this message. The driver should attempt to restore its state to the best of its ability. While in a critical suspension, the system maintains the state of the DRAM and local hard disks, but may not maintain net connections. A driver may need to take action with respect to files that were open on the network before critical suspension.

This message is not sent to applications.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in pbt.h.

See Also

Power Management Overview, Power Management Messages, WM_POWERBROADCAST


PBT_APMRESUMESUSPEND

[This is preliminary documentation and subject to change.]

The PBT_APMRESUMESUSPEND message is sent as a notification that the system has resumed operation after being suspended. A window receives this message through the WM_POWERBROADCAST message.

dwData = (DWORD) lParam;

Parameters

dwData
Reserved; must be 0.

Return Values

No return value.

Remarks

Applications can receive this message at any time without a preceding PBT_APMSUSPEND message.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in pbt.h.

See Also

Power Management Overview, Power Management Messages, PBT_APMSUSPEND, WM_POWERBROADCAST


PBT_APMSUSPEND

[This is preliminary documentation and subject to change.]

The PBT_APMSUSPEND is sent immediately before the computer enters a suspended state. This message is typically sent when all applications and installable drivers have returned TRUE to a previous PBT_APMQUERYSUSPEND message. A window receives this message through the WM_POWERBROADCAST message.

dwData = (DWORD) lParam;

Parameters

dwData
Reserved; must be 0.

Return Values

No return value.

Remarks

An application should process this message by completing all tasks necessary to save data. This message may also be sent, without a prior PBT_APMQUERYSUSPEND message, if an application or device driver uses the SetSystemPowerState function to force suspension.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in pbt.h.

See Also

Power Management Overview, Power Management Messages, PBT_APMQUERYSUSPEND, SetSystemPowerState, WM_POWERBROADCAST


WM_POWER

The WM_POWER message is sent when the system, typically a battery-powered personal computer, is about to enter suspended mode.

The WM_POWER message is obsolete. It is provided to simplify porting of 16-bit Windows-based applications. New Win32-based applications should use the WM_POWERBROADCAST message.

WM_POWER
fwPowerEvt = wParam;    // power-event notification message

Parameters

fwPowerEvt
Value of wParam. Specifies a power-event notification message. This parameter can be one of the following values:
Value | Meaning
PWR_CRITICALRESUME | Indicates that the system is resuming operation after entering suspended mode without first sending a PWR_SUSPENDREQUEST notification message to the application. An application should perform any necessary recovery actions.
PWR_SUSPENDREQUEST | Indicates that the system is about to enter suspended mode.
PWR_SUSPENDRESUME | Indicates that the system is resuming operation after having entered suspended mode normally — that is, the system sent a PWR_SUSPENDREQUEST notification message to the application before the system was suspended. An application should perform any necessary recovery actions.

Return Values

The value an application returns depends on the value of the wParam parameter. If wParam is PWR_SUSPENDREQUEST, the return value is PWR_FAIL to prevent the system from entering the suspended state; otherwise, it is PWR_OK. If wParam is PWR_SUSPENDRESUME or PWR_CRITICALRESUME, the return value is zero.

Remarks

This message is sent only to an application that is running on a system that conforms to the Advanced Power Management (APM) basic input/output system (BIOS) specification. The message is sent by the power-management driver to each window returned by the EnumWindows function.

The suspended mode is the state in which the greatest amount of power savings occurs, but all operational data and parameters are preserved. Random-access memory (RAM) contents are preserved, but many devices are likely to be turned off.

See Also

Power Management Overview, Power Management Messages, EnumWindows, WM_POWERBROADCAST


WM_POWERBROADCAST

The WM_POWERBROADCAST message is sent to an application to notify it of power-management events.

dwPowerEvent = (DWORD) wParam;
dwData = (DWORD) lParam;

Parameters

dwPowerEvent
Event notification message. This parameter can be one of the following values.
Value | Meaning
PBT_APMBATTERYLOW | Battery power is low.
PBT_APMOEMEVENT | OEM-defined event occurred.
PBT_APMPOWERSTATUSCHANGE | Power status has changed.
PBT_APMQUERYSUSPEND | Request for permission to suspend.
PBT_APMQUERYSUSPENDFAILED | Suspension request denied.
PBT_APMRESUMEAUTOMATIC | Operation resuming automatically after event.
PBT_APMRESUMECRITICAL | Operation resuming after critical suspension.
PBT_APMRESUMESUSPEND | Operation resuming after suspension.
PBT_APMSUSPEND | System is suspending operation.

dwData
Function-specific data. For most messages, this parameter is reserved and not used.

However, if wParam is one of the resume notifications (PBT_APMRESUME*), the lParam parameter can specify the PBTF_APMRESUMEFROMFAILURE flag. This flag indicates that a suspend operation failed after the PBT_APMSUSPEND message was sent.

Return Values

Return TRUE to grant a request.

Return BROADCAST_QUERY_DENY to deny a request.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Power Management Overview, Power Management Messages


System Messages

System messages provide the way to uniformly notify all applications and other components in the system of changes that may affect their operation and access to resources. Applications and other components use and process system messages to take advantage of new resources when they become available and to prevent loss of data when existing resources become unavailable.


About System Messages

There are two predefined classes of system messages: device messages and power messages. Device messages notify applications and installable drivers of device change events; power messages notify these of power management events. Applications and other components can also define and use their own system messages to provide for notification of other types of events.

This overview describes system messages, system-message broadcasts, and the specific class of system messages called device messages. For more information about power messages, see Power Management.


System Messages and System-Message Broadcasts

Each system message consists of a message identifier and two 32-bit parameters, wParam and lParam. The message identifier is a unique value that specifies the message purpose. The parameters provide additional information that is message-specific, but the wParam parameter is often a notification value that further specifies the message purpose.

A system-message broadcast is simply the sending of a system message to components in the system. You broadcast a system message by using the BroadcastSystemMessage function and specifying the recipients of the message. Rather than specify individual recipients, you must specify one or more types of recipients. These types are applications, installable drivers, network drivers, and system-level device drivers. BroadcastSystemMessage sends messages to all members of each type you specify.

Most applications do not broadcast system messages. Instead, they process system messages sent by other components. The system typically broadcasts system messages in response to changes that usually take place within system-level device drivers. The device driver or related component generates the system message and broadcasts it to applications and other components to notify them of the change. For example, the subsystem responsible for disk drives generates and broadcasts a system message whenever the device driver for the floppy disk drive detects a change of media such as when the user inserts a disk in the drive.

Applications receive system messages through the window procedure of their top-level windows. System messages are not sent to child windows. The action an application takes in response to a system message depends on the message. Some system messages, called query messages, require the application to respond by returning either TRUE or BROADCAST_QUERY_DENY to indicate whether the system should continue to broadcast the message to other recipients.


Custom System Messages

You can create your own system messages and use them to coordinate activities between applications and other components in the system. This is especially useful if you have created your own installable drivers or system-level device drivers. Your custom system messages can carry information to and from your driver and the applications that use the driver.

You broadcast custom system messages using the BroadcastSystemMessage function. (System-level device drivers use a related, system-level function.) The function sends the messages to the recipients in this order: system-level device drivers, network drivers, installable drivers, and applications. This means that system-level device drivers, if chosen as recipients, always get the first opportunity to respond to a system message. Within a given recipient type, no driver is guaranteed to receive a given message before any other driver. This means that a system message intended for a specific driver must have a globally-unique message identifier so that no other driver unintentionally processes it.

Query messages are a useful way to poll recipients for permission to carry out a given action. You can generate your own query messages by setting the BSF_QUERY value in the dwFlags parameter when calling BroadcastSystemMessage. Each recipient of the query message must return TRUE for the function to send the message to the next recipient. If any recipient returns BROADCAST_QUERY_DENY, the broadcast ends immediately and the function returns 0.

You can create installable drivers that broadcast and process system messages. An installable driver is a dynamic-link library (DLL) that exports a DriverProc function. The driver receives system messages through its DriverProc function and can broadcast messages using BroadcastSystemMessage. Installable drivers are typically used to support multimedia devices, such as sound boards, but can be used for other devices and purposes too.

Network drivers are dynamic-link libraries that provide the underlying support for applications that use the network functions to connect to and browse network resources. System-level device drivers are -system-specific executable components that provide direct access to and management of the hardware devices of the computer. The details regarding how these components process system messages is beyond the scope of this overview.


Device Messages and Device Change Events

Device messages are system messages that notify applications and other components of device change events. These events occur whenever the system detects a change to the system hardware such as when the user docks or undocks a laptop computer, or inserts or removes a device such as a PCMCIA card. Change events can occur while the system is running or when the system resumes operation after temporarily being suspended.

To help ensure that applications and installable drivers do not lose data when devices become unavailable, the system monitors the hardware configuration and sends device message to the applications and installable drivers to notify them of the changes and to give them the opportunity to prepare for the changes before they occur.

For each event, the system broadcasts a WM_DEVICECHANGE message to all applications and installable drivers. In this message, the wParam parameter identifies the event type and the lParam parameter is usually the address of event-specific data.

The event-specific data identifies the device and provides additional detail about the event. The format of this data depends on the device type, but the first few bytes always has the same format as the DEV_BROADCAST_HDR structure. This means you can always check the dbch_devicetype member in the data to determine the device type.

The system sends a DBT_DEVICEARRIVAL message (that is, a WM_DEVICECHANGE message with wParam set to DBT_DEVICEARRIVAL) whenever a device has been inserted and is available for use. Applications typically check the device type and begin using the device immediately if appropriate.

The system sends a DBT_DEVICEQUERYREMOVE message to request permission to remove a device. If an application determines that it needs the device, it can deny this request and cancel the removal by returning BROADCAST_QUERY_DENY. To determine whether it needs the device, an application can display a dialog box to prompt the user for instructions. If the application does not need the device, it must return TRUE. The system immediately sends a DBT_DEVICEQUERYREMOVEFAILED message if any application or driver canceled a previous request to remove a device.

The system sends a DBT_DEVICEREMOVEPENDING message as a last warning before a device is removed. At this point, the application cannot cancel the removal, so if it is using the device it must prepare for its removal to prevent loss of data. This is especially important when a network connection is being removed. The application must determine whether any of its open files or pipes are on that connection. It can do this by comparing the network resource identifier in the event-specific data of the message with the resource identifiers previously obtained for the files and pipes. The system sends a DBT_DEVICEREMOVECOMPLETE message when a device has been removed and is no longer available.

The system sends a DBT_QUERYCHANGECONFIG message to request permission to change the current configuration (dock or undock). Any application can return BROADCAST_QUERY_DENY to deny the request and cancel the change. If an application denies the request, the system sends a DBT_CONFIGCHANGECANCELED message. If the current configuration has changed, due to a dock or undock, the system sends a DBT_CONFIGCHANGED message.

The system sends DBT_DEVICETYPESPECIFIC message whenever a device-specific event occurs.


Using System Messages

  • Processing a request to remove a device


Processing a Request to Remove a Device

An application receives a DBT_DEVICEQUERYREMOVE message when a component in the system has decided to remove a given device. When the application receives this message, it should determine whether it is using the given device and either cancel or prepare for the removal. In the following example, the application processes the message by checking the type of device that is to be removed.

PDEV_BROADCAST_HDR pdbch;
PDEV_BROADCAST_VOLUME pdbcv;

case WM_DEVICECHANGE:
    pdbch = (PDEV_BROADCAST_HDR) lParam;
    switch (pdbch->dbch_devicetype)
    {
        case DBT_DEVTYP_VOLUME:
            pdbcv = (PDEV_BROADCAST_VOLUME) pdbch;
            if (pdbcv->dbcv_flags == DBTF_MEDIA)
                // pdbcv->dbcv_unitmask identifies which logical drive
            return TRUE;
        default:
            return TRUE;
    }


System Messages Reference

The following elements are used with system messages.

  • System Message Functions
  • System Message Messages
  • System Message Structures


System Message Functions

The following function is used with system messages.

BroadcastSystemMessage


System Message Messages

The following are device messages.

DBT_CONFIGCHANGECANCELED
DBT_CONFIGCHANGED
DBT_DEVICEARRIVAL
DBT_DEVICEQUERYREMOVE
DBT_DEVICEQUERYREMOVEFAILED
DBT_DEVICEREMOVECOMPLETE
DBT_DEVICEREMOVEPENDING
DBT_DEVICETYPESPECIFIC
DBT_QUERYCHANGECONFIG
DBT_USERDEFINED
WM_DEVICECHANGE


DBT_CONFIGCHANGECANCELED

The system sends the DBT_CONFIGCHANGECANCELED device message when a request to change the current configuration (dock or undock) has been canceled.

To send the DBT_CONFIGCHANGECANCELED device message, the system sends the WM_DEVICECHANGE message with wParam set to DBT_CONFIGCHANGECANCELED and lParam set to zero.

Parameters

lParam
lParam is zero when the WM_DEVICECHANGE message is sent with wParam set to DBT_CONFIGCHANGECANCELED.

Return Values

Return TRUE.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Messages, DBT_CONFIGCHANGED, DBT_QUERYCHANGECONFIG, WM_DEVICECHANGE


DBT_CONFIGCHANGED

The system sends the DBT_CONFIGCHANGED device message to indicate that the current configuration has changed, due to a dock or undock. An application or driver that stores data in the registry under the HKEY_CURRENT_CONFIG key should update the data.

To send the DBT_CONFIGCHANGED device message, the system sends the WM_DEVICECHANGE message with wParam set to DBT_CONFIGCHANGED and lParam set to zero.

Parameters

lParam
lParam is zero when the WM_DEVICECHANGE message is sent with wParam set to DBT_CONFIGCHANGED.

Return Values

Return TRUE.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Messages, DBT_CONFIGCHANGECANCELED, DBT_QUERYCHANGECONFIG, WM_DEVICECHANGE


DBT_DEVICEARRIVAL

The system sends the DBT_DEVICEARRIVAL device message when a device has been inserted and becomes available.

To send the DBT_DEVICEARRIVAL device message, the system sends the WM_DEVICECHANGE message with wParam set to DBT_DEVICEARRIVAL and lParam set to the address of a DEV_BROADCAST_HDR structure identifying the device inserted.

dwData = (DWORD) lParam;

Parameters

dwData
Address of a DEV_BROADCAST_HDR structure identifying the device inserted.

Return Values

Return TRUE.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Messages, DEV_BROADCAST_HDR, WM_DEVICECHANGE


DBT_DEVICEQUERYREMOVE

The system sends the DBT_DEVICEQUERYREMOVE device message to request permission to remove a device. Any application can deny this request and cancel the removal.

To send the DBT_DEVICEQUERYREMOVE device message, the system sends the WM_DEVICECHANGE message with wParam set to DBT_DEVICEQUERYREMOVE and lParam set to the address of a DEV_BROADCAST_HDR structure identifying the device to remove.

dwData = (DWORD) lParam;

Parameters

dwData
Address of a DEV_BROADCAST_HDR structure identifying the device to remove.

Return Values

Return TRUE to grant permission to remove a device.

Return BROADCAST_QUERY_DENY to deny permission to remove a device.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Messages, DEV_BROADCAST_HDR, WM_DEVICECHANGE


DBT_DEVICEQUERYREMOVEFAILED

The system sends the DBT_DEVICEQUERYREMOVEFAILED device message when a request to remove a device has been canceled.

To send the DBT_DEVICEQUERYREMOVEFAILED device message, the system sends the WM_DEVICECHANGE message with wParam set to DBT_DEVICEQUERYREMOVEFAILED and lParam set to the address of a DEV_BROADCAST_HDR structure identifying the device.

dwData = (DWORD) lParam;

Parameters

dwData
Address of a DEV_BROADCAST_HDR structure identifying the device.

Return Values

Return TRUE.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Messages, DEV_BROADCAST_HDR, WM_DEVICECHANGE


DBT_DEVICEREMOVECOMPLETE

The system sends the DBT_DEVICEREMOVECOMPLETE device message when a device has been removed.

To send the DBT_DEVICEREMOVECOMPLETE device message, the system sends the WM_DEVICECHANGE message with wParam set to DBT_DEVICEREMOVECOMPLETE and lParam set to the address of a DEV_BROADCAST_HDR structure identifying the device removed.

dwData = (DWORD) lParam;

Parameters

dwData
Address of a DEV_BROADCAST_HDR structure identifying the device removed.

Return Values

Return TRUE.

Remarks

The system may send a DBT_DEVICEREMOVECOMPLETE message without sending corresponding DBT_DEVICEQUERYREMOVE and DBT_DEVICEREMOVEPENDING messages. In such cases, the applications and drivers must recover from the loss of the device as best they can.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Messages, DBT_DEVICEQUERYREMOVE, DBT_DEVICEREMOVEPENDING, DEV_BROADCAST_HDR, WM_DEVICECHANGE


DBT_DEVICEREMOVEPENDING

The system sends the DBT_DEVICEREMOVEPENDING device message when the device is about to be removed. This message is the last chance for applications and drivers to prepare for the removal of the device.

To send the DBT_DEVICEREMOVEPENDING device message, the system sends the WM_DEVICECHANGE message with wParam set to DBT_DEVICEREMOVEPENDING and lParam set to the address of a DEV_BROADCAST_HDR structure identifying the device to remove.

dwData = (DWORD) lParam;

Parameters

dwData
Address of a DEV_BROADCAST_HDR structure identifying the device to remove.

Return Values

Return TRUE.

Remarks

This message cannot be denied.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Messages, DEV_BROADCAST_HDR, WM_DEVICECHANGE


DBT_DEVICETYPESPECIFIC

The system sends the DBT_DEVICETYPESPECIFIC device message when a device-specific event occurs.

To send the DBT_DEVICETYPESPECIFIC device message, the system sends the WM_DEVICECHANGE message with wParam set to DBT_DEVICETYPESPECIFIC and lParam set as described in the following.

dwData = (DWORD) lParam;

Parameters

dwData
Address of a DEV_BROADCAST_HDR structure identifying the device. lParam is application-defined. May be zero.

Return Values

Return TRUE.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Messages, DEV_BROADCAST_HDR, WM_DEVICECHANGE


DBT_QUERYCHANGECONFIG

The system sends the DBT_QUERYCHANGECONFIG device message to request permission to change the current configuration (dock or undock). Any application can deny this request and cancel the change.

To send the DBT_QUERYCHANGECONFIG device message, the system sends the WM_DEVICECHANGE message with wParam set to DBT_QUERYCHANGECONFIG and lParam set to zero.

Parameters

lParam
lParam is zero when the WM_DEVICECHANGE message is sent with wParam set to DBT_QUERYCHANGECONFIG.

Return Values

Return TRUE to grant permission to change the configuration.

Return BROADCAST_QUERY_DENY to deny permission to change the configuration.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Messages, DBT_CONFIGCHANGECANCELED, DBT_CONFIGCHANGED, WM_DEVICECHANGE


DBT_USERDEFINED

The DBT_USERDEFINED device message identifies a user-defined system message.

To send the DBT_USERDEFINED device message, send the WM_DEVICECHANGE message with wParam set to DBT_USERDEFINED and lParam set as described following.

pDbu = (struct _DEV_BROADCAST_USERDEFINED *)lParam;

Parameters

pDbu
Pointer to a _DEV_BROADCAST_USERDEFINED structure which describes the user-defined broadcast in progress. The dbud_szName member contains the name of the user-defined message, followed by arbitrary user-defined data.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Messages, _DEV_BROADCAST_USERDEFINED, WM_DEVICECHANGE


WM_DEVICECHANGE

The WM_DEVICECHANGE device message notifies an application or device driver of a change to the hardware configuration of a device or the computer.

Event = (UINT) wParam;
dwData = (DWORD) lParam;

Parameters

Event
Event type. This parameter can be one of the following values:
Value | Meaning
DBT_CONFIGCHANGECANCELED | A request to change the current configuration (dock or undock) has been canceled.
DBT_CONFIGCHANGED | The current configuration has changed, due to a dock or undock.
DBT_DEVICEARRIVAL | A device has been inserted and is now available.
DBT_DEVICEQUERYREMOVE | Permission is requested to remove a device. Any application can deny this request and cancel the removal.
DBT_DEVICEQUERYREMOVEFAILED | A request to remove a device has been canceled.
DBT_DEVICEREMOVECOMPLETE | A device has been removed.
DBT_DEVICEREMOVEPENDING | A device is about to be removed. Cannot be denied.
DBT_DEVICETYPESPECIFIC | A device-specific event has occurred.
DBT_QUERYCHANGECONFIG | Permission is requested to change the current configuration (dock or undock).
DBT_USERDEFINED | The meaning of this message is user-defined.

dwData
Address of a structure that contains event-specific data. Its meaning depends on the given event.

Return Values

Return TRUE to grant a requested action.

Return BROADCAST_QUERY_DENY to deny a requested action.

Remarks

For devices that offer software-controllable features, such as ejection and locking, the system typically sends a DBT_DEVICEREMOVEPENDING message to let applications and device drivers end their use of the device gracefully.

If the system forcibly removes a device, it may not send a DBT_DEVICEQUERYREMOVE message before doing so.

DBT_CONFIGCHANGECANCELED, DBT_CONFIGCHANGED, DBT_DEVICEARRIVAL, DBT_DEVICEQUERYREMOVE, DBT_DEVICEQUERYREMOVEFAILED, DBT_DEVICEREMOVECOMPLETE, DBT_DEVICEREMOVEPENDING, DBT_DEVICETYPESPECIFIC, DBT_QUERYCHANGECONFIG, DBT_USERDEFINED

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

System Messages Overview, System Message Messages


System Message Structures

The following structures are used with device messages.

_DEV_BROADCAST_USERDEFINED
DEV_BROADCAST_HDR
DEV_BROADCAST_OEM
DEV_BROADCAST_PORT
DEV_BROADCAST_VOLUME

See Also

System Messages Overview, System Message Messages


_DEV_BROADCAST_USERDEFINED

The _DEV_BROADCAST_USERDEFINED structure contains the user-defined message and optional data associated with the DBT_USERDEFINED device message.

struct _DEV_BROADCAST_USERDEFINED {
    struct _DEV_BROADCAST_HDR dbud_dbh;
    char  dbud_szName[1];           // ASCIIZ name
//    BYTE  dbud_rgbUserDefined[];  // Optional user-defined contents
};

Members

dbud_dbh
Information about the device affected by a WM_DEVICECHANGE message as specified by the DEV_BROADCAST_HDR structure. Because the _DEV_BROADCAST_USERDEFINED structure is variable length, dbud_dbh.dbch_size must be the size in bytes of the entire structure, including the variable length part.
dbud_szName
A case-sensitive, null-terminated string that names the message. The name must consist of the vendor name, a backslash, followed by arbitrary user-defined null-terminated text. For example:
"WidgetWare\QueryScannerShutdown"

or

"WidgetWare\Video Q39S\AdapterReady"
dbud_rgbUserDefined
Optional user-defined information.

Because this structure contains variable length fields, use this structure tag as a template for creating a pointer to a user-defined structure. Note that the structure must not contain pointers. For example:

#define NAME_LENGTH 32
#define USER_LENGTH 50

typedef struct tagWIDGET_WARE_DEV_BROADCAST_USERDEFINED
{
    struct _DEV_BROADCAST_HDR DBHeader;
    char  szName[NAME_LENGTH]
    BYTE  UserDefined[USER_LENGTH];
} WIDGET_WARE_DEV_BROADCAST_USERDEFINED;

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Structures, DBT_USERDEFINED, DEV_BROADCAST_HDR, WM_DEVICECHANGE


DEV_BROADCAST_HDR

The DEV_BROADCAST_HDR structure contains information about the device affected by a WM_DEVICECHANGE message.

typedef struct _DEV_BROADCAST_HDR {
    ULONG dbch_size;
    ULONG dbch_devicetype;
    ULONG dbch_reserved;
} DEV_BROADCAST_HDR;
typedef DEV_BROADCAST_HDR *PDEV_BROADCAST_HDR;

Members

dbch_size
Size of this structure, in bytes.
dbch_devicetype
Type of device. Can be one of these values:
Value | Meaning
DBT_DEVTYP_OEM | OEM- or IHV-defined device type.
DBT_DEVTYP_VOLUME | Logical volume.
DBT_DEVTYP_PORT | Port device (serial or parallel).

dbch_reserved
Reserved; do not use.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Structures, WM_DEVICECHANGE


DEV_BROADCAST_OEM

The DEV_BROADCAST_OEM structure contains information about a OEM-defined device type.

typedef struct _DEV_BROADCAST_OEM {
    ULONG dbco_size;
    ULONG dbco_devicetype;
    ULONG dbco_reserved;
    ULONG dbco_identifier;
    ULONG dbco_suppfunc;
} DEV_BROADCAST_OEM;
typedef DEV_BROADCAST_OEM *PDEV_BROADCAST_OEM;

Members

dbco_size
Size of this structure, in bytes.
dbco_devicetype
DBT_DEVTYPE_OEM.
dbco_reserved
Reserved; do not use.
dbco_identifier
Globally unique identifier (GUID) for the device. Use the uuidgen utility to create this identifier.
dbco_suppfunc
OEM-specific function value. Possible values depend on the device.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Structures


DEV_BROADCAST_PORT

The DEV_BROADCAST_PORT structure contains information about a modem, serial, or parallel port.

typedef struct _DEV_BROADCAST_PORT {
    ULONG dbcp_size;
    ULONG dbcp_devicetype;
    ULONG dbcp_reserved;
    char dbcp_name[1];
} DEV_BROADCAST_PORT;
typedef DEV_BROADCAST_PORT *PDEV_BROADCAST_PORT;

Members

dbcp_size
Size of this structure, in bytes.
dbcp_devicetype
DBT_DEVTYP_VOLUME.
dbcp_reserved
Reserved; do not use.
dbcp_name
Null-terminated string specifying the friendly name of the port or the device connected to the port. Friendly names are intended to help the user quickly and accurately identify the device—for example, "COM1", "Hayes 2400 Smartmodem", and "LPT1" are considered friendly names.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Structures


DEV_BROADCAST_VOLUME

The DEV_BROADCAST_VOLUME structure contains information about a logical volume.

typedef struct _DEV_BROADCAST_VOLUME {
    ULONG dbcv_size;
    ULONG dbcv_devicetype;
    ULONG dbcv_reserved;
    ULONG dbcv_unitmask;
    USHORT dbcv_flags;
} DEV_BROADCAST_VOLUME;
typedef DEV_BROADCAST_VOLUME *PDEV_BROADCAST_VOLUME;

Members

dbcv_size
Size of this structure, in bytes.
dbcv_devicetype
DBT_DEVTYP_VOLUME.
dbcv_reserved
Reserved; do not use.
dbcv_unitmask
Logical unit mask identifying one or more logical units. Each bit in the mask corresponds to one logical drive. Bit 0 represents drive A, bit 1 drive B, and so on.
dbcv_flags
Flags indicating whether drive or media.
Value | Meaning
DBTF_MEDIA | Change affects media in drive. If not set, change affects physical device or drive.
DBTF_NET | Indicated logical volume is a network volume.

Remarks

Although the dbcv_unitmask member may specify more than one volume in any given message, this does not guarantee that only message is generated for a given event. Multiple system components may independently generate messages for logical volumes at the same time.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dbt.h.

See Also

System Messages Overview, System Message Structures


End-User-Defined Characters

End-user-defined characters (EUDC) are customized characters that users install for viewing and printing documents.

This overview discusses the TrueType fonts that support end-user-defined characters and describes the functions used to access and manage these characters in Win32-based applications.


About End-User-Defined Characters

End-user-defined characters give users a way to form names and other words using characters that are not available in standard screen and printer fonts.

End-user-defined characters are available only in Asian-language versions of the system.


Character Sets and Fonts

An end-user-defined character is always associated with a double-byte character set (DBCS) and a TrueType font. Applications identify the specified character by using the character's assigned DBCS character value, and the system uses this value to locate shape and style information in a corresponding TrueType font. The shape and style information specifies how the character is drawn on the screen or printed page.

The DBCS character values that can be assigned depend on the specified character set. Each set has at least one range of reserved values for use as end-user-defined characters. The system or applications explicitly define these ranges by setting appropriate values under the EUDCCodeRange key in the registry. In the registry, each character set is identified by a unique code-page number.

To create an end-user-defined character, the user chooses a character value that is within the specified range and adds the shape and style information to the TrueType font in the entry that corresponds to that character value. Users create the shape and style information using an EUDC editor or by purchasing end-user-defined font packages from font vendors. Any DBCS TrueType font can contain end-user-defined characters. The font is called a "separate" EUDC font if it contains only end-user-defined characters. The font is an "integrated" EUDC font if it contains standard characters as well as end-user-defined characters.

Separate EUDC fonts are said to be either "typeface-aware" or "typeface-unaware." A typeface-unaware font is designed to be a general purpose font that can be used with fonts of different typeface styles and of different implementations, such as GDI raster, WIFE, device, and TrueType fonts. A typeface-aware font is designed for use with a specific TrueType font.

The system default EUDC font is a typeface-unaware font that the system automatically associates with all DBCS fonts except those TrueType fonts that have explicitly associated typeface-aware fonts. Applications set the system default EUDC font by setting the value of the SystemDefaultEUDCFont name under the EUDC key in the registry. Similarly, applications can associate typeface-aware fonts with corresponding TrueType fonts by specifying a typeface name and associated font file under the EUDC key. Separate EUDC fonts cannot be associated with integrated EUDC fonts.

The system "hides" the system default EUDC and typeface-aware fonts. This means applications cannot enumerate or otherwise examine these fonts using GDI functions. Applications, such as EUDC editors and Control Panel, must use the registry entries to add, modify, and delete EUDC fonts.

End-user-defined characters can also be used in Unicode-enabled applications. The reserved ranges for each character set are mapped to corresponding values in the Unicode private use area (values 0xE000 and higher). There are mappings for both Japanese and Chinese character sets. For a list of these mappings, see Japanese EUDC Ranges and Chinese EUDC Ranges.


Writing, Mapping, and Sorting Characters

Applications write end-user-defined characters to the screen or printer the same way as writing other characters, by using output functions such as TextOut and ExtTextOut. These functions automatically retrieve character information from EUDC fonts if EUDC is enabled. When writing end-user-defined characters, the action of the text output function depends on the currently selected font. If the selected font is an integrated EUDC font, the function retrieves character information from that font. If the selected font is a DBCS TrueType font that has an associated typeface-aware EUDC font, the function retrieves information from the specified typeface-aware font. If the selected font does not have an associated typeface-aware font, the function retrieves information from the system default EUDC font. If the character is not in the system default EUDC font or there is no system default EUDC font, the function writes the default character defined by the selected font.

Applications can map end-user-defined characters to and from Unicode by using the MultiByteToWideChar and WideCharToMultiByte functions. The MultiByteToWideChar function maps an end-user-defined character to a character position in the Unicode private use area. The WideCharToMultiByte function maps a character in the private use area to its multibyte character counterpart, if such a mapping exists. The code page specified in this function must contain an EUDC code range for the mapping to occur. If it does not, the function returns the default character for any characters in the Unicode private use area.

Both MultiByteToWideChar and WideCharToMultiByte preserve the "round trip" mapping of end-user-defined characters from a code page to Unicode and back to the original code page. But these functions do not necessarily preserve mapping to other code pages. For example, if a character from code page 932 is mapped to Unicode, then mapped from Unicode to another code page with an EUDC range, it is likely that the original character will be mapped to a different end-user-defined character in the destination code page. Similarly, mapping a Unicode string to a code page that has an EUDC range may have unintended results. If the Unicode string contains a private-use code point, that code point may be mapped to an end-user-defined character whether or not the code point actually represents such a character.

Applications can compare strings that contain end-user-defined characters by using the CompareStringA function. The function maps the characters to the Unicode end user zone before comparing character values. Applications can create a sort key for the string by using the LCMapStringA function and the LCMAP_SORTKEY value. This function maps characters to Unicode first. All characters in the private use area are sorted after all other Unicode characters. Within the area, characters are sorted in numerical order. If an application attempts to retrieve CTYPE ifnormation for an end-user-defined character by using the GetStringTypeA function, the function returns NULL for each character.


End-User-Defined Character Reference

This following elements are used with end-user-defined characters.

  • Registry entries
  • End-user-defined character constants


Registry Entries

The following topics describe the registry entries for use with end-user-defined characters.

  • EUDCCodeRange
  • EUDC


EUDCCodeRange

The EUDCCodeRange registry entry contains entries that define end-user-defined characters (EUDC) code ranges for the various code pages (character sets).

EUDCCodeRange
    CodePage=FromTo[,FromTo]

The EUDCCodeRange key has the following location:

HKEY_LOCAL_MACHINE\
     System\CurrentControlSet\Control\NLS\CodePage\EUDCCodeRange

The key contains one or more values specifying the range of character values within a code page that are available for end-user-defined characters. Under this key, a value name is one of these code-page values:

Value | Meaning
932 | Japan
936 | Simplified Chinese
949 | Unified Hangeul Code (Hangeul TongHabHyung Code)
950 | Traditional Chinese
1361 | Johab

The value associated with each name is a string consisting of one or more pairs of 4-digit hexadecimal numbers, with the numbers in each pair separated by a hyphen (-) and each pair separated from any preceding pair by a comma (,). The following example illustrates this format:

HKEY_LOCAL_MACHINE\
    System\CurrentControlSet\Control\NLS\CodePage\EUDCCodeRange
923=F040-F9FC
950=FA40-FEFE, 8E40-A0FE, 8140-8DFE, C6A1-C8FE
CodePage

A user-defined value name that identifies the code page. It must be the letters "CP" followed by 5 decimal digits specifying the code page.

FromTo
A string value consisting of a pair of 4-digit hexadecimal values separated by a hyphen (-). Multiple FromTo values may be specified, but each must be separated from the previous by a comma (,).

The following examples show possible EUDC ranges for code pages 923 and 950:

CP00923=F040-F9FC
CP00950=FA40-FEFE,8E40-A0FE,8140-8DFE,C6A1-C8FE


EUDC

The EUDC key contains one or more subkeys with each subkey containing values defining the fonts associated with end-user-defined characters for a given code page.

EUDC
    SystemDefaultEUDCFont=TrueTypeEUDCFontFileName
    TrueTypeFontTypeface=TrueTypeEUDCFontFileName

The EUDC registry key has the following location in the registry:

HKEY_CURRENT_USER\EUDC

Under the EUDC, a subkey name can be one of these code-page numbers:

Value | Meaning
932 | Japan
936 | Simplified Chinese
949 | Unified Hangeul Code (Hangeul TongHabHyung Code)
950 | Traditional Chinese
1361 | Johab

One value under the subkey has the name SystemDefaultEUDCFont. Other values, if any, have names that identify a typeface. The values associated with these names are strings specifying the name of TrueType font file containing the given font. The following example shows the EUDC key for code page 932:

HKEY_CURRENT_USER\EUDC\932
SystemDefaultEUDCFont=EUDC.TTF
MS Mincho=MINEUDC.TTF
MS Gothic=GTEUDC.TTF
SystemDefaultEUDCFont
Predefined value name used to set the system default font. The corresponding value must be a string that identifies a typeface-unaware EUDC font. There is no system default EUDC font unless this entry is explicitly specified.
TrueTypeFontTypeface
A user-defined value name that identifies the typeface name associated with a TrueType font. The corresponding value must be a string that identifies a typeface-aware EUDC font.
TrueTypeEUDCFontFileName
A string value consisting of the filename of a "separate" EUDC font file.

The following example sets the system default EUDC font to be EUDC.TTF and associates the typeface-aware fonts, MINEUDC.TTF and GOTEUDC.TTF, with the typeface names "MS Mincho" and "MS Gothic":

SystemDefaultEUDCFont=EUDC.TTF
MS Mincho=MINEUDC.TTF
MS Gothic=GOTEUDC.TTF


End-User-Defined Character Constants

The following constants are used with end-user-defined characters in the following Far Eastern languages.

  • Japanese EUDC Ranges
  • Chinese EUDC Ranges
  • Korean EUDC Ranges


Japanese EUDC Ranges

The following table shows the mapping between the Japanese Microsoft Standard Character Set (ShiftJIS) and Unicode.

Shift JIS | Unicode
F040 | U+E000
F041 | U+E001
F042 | U+E002
: | :
F9FA | U+E755
F9FB | U+E756
F9FC | U+E757


Chinese EUDC Ranges

The following table shows the mapping between the Chinese character sets (BIG-5 and GB 2312-80) and Unicode.

BIG-5 | Unicode
FA40 - FEFE | U+E000 - U+E310
8E40 - A0FE | U+E311 - U+EEB7
8140 - 8DFE | U+EEB8 - U+F6B0
C6A1 - C8FE | U+F6B1 - U+F8FF

GB 2312-80 | Unicode
F8A1 - FEFE | U+E000 - U+E29F
AAA1 - AFFE | U+E2A0 - U+E4DF


Korean EUDC Ranges

The following table shows the mapping from Korean EUDC characters (Unified Hangeul Code) and Unicode.

Unified Hangeul | Unicode
C9A1 - C9FE | U+E000 - U+E05D
FEA1 - FEFE | U+E05E - U+E0BB


Input Method Editor

The input method editor (IME) helps minimize the effort needed by users to enter text containing characters from Unicode and the double-byte character set (DBCS).

This overview describes the IME and explains how to use the input method manager functions to create and manage IME windows.


About Input Method Editor

The input method editor relieves users of the need to remember all possible character values. Instead, the IME monitors the user's keystrokes, anticipates the characters the user may want, and presents a list of candidate characters from which to choose.

By default, the IME provides an IME window through which users enter keystrokes and view and select candidates. Win32-based applications can use the input method manager (IMM) functions and messages to create and manage their own IME windows, providing a custom interface while using the conversion capabilities of the IME.


Status, Composition, and Candidates Windows

The status, composition, and candidates windows form the user interface for the IME. The status window indicates that the IME is open and provides the user the means to set the conversion modes. The composition window appears when the user enters text and, depending on the conversion mode, either displays the text as entered or displays converted text. The candidates window appears in conjunction with the composition window. It contains a list of "candidates" (alternative characters) for the selected character or characters in the composition window. The user can scroll through the candidates list and select the desired character(s), then return to the composition window. The user can compose the desired text in this way until the composition string is finalized and the window is closed. The IME sends the composed characters to the application in the form of WM_IME_CHAR or WM_IME_COMPOSITION/GCS_RESULT messages. If the application does not process these messages, the DefWindowProc function translates them into one or more WM_CHAR messages.

By default, the system automatically creates and manages status, composition, and candidates windows for all windows that require text input. For many applications, this default processing is sufficient. These applications rely entirely on the system for IME support and are said to be IME-unaware because they are unaware of the many tasks the system carries out to manage the IME windows.

An IME-aware application, on the other hand, participates in the creation and management of IME windows. Such applications control the operation, position, and appearance of the default windows by sending messages to and by intercepting and processing messages intended for these windows. In some cases, applications create their own IME windows and provide complete processing for their custom status, composition and candidates windows.


IME Window Class

The "IME" window class is a predefined system global class that defines the appearance and behavior of the standard IME windows. The class is similar to common control classes in that you create a window of this class by using the CreateWindowEx function. Like static controls, an IME window does not respond to user input by itself. Instead, it notifies the IME of user input actions and processes control messages sent to it by the IME or applications to carry out a response to the user action.

IME-aware applications sometimes create their own IME windows using the IME class. This allows the application to take advantage of the default processing of the IME window while having control of the positioning of the window.


IME Messages

The system sends IME window messages to the window procedure of the application when certain event occur that affect the IME windows. For example, the system sends the WM_IME_SETCONTEXT message to the application when a window is activated. IME-unaware application pass these messages to the DefWindowProc function which sends them to the corresponding default IME window. IME-aware applications either process these messages or forward them the their own IME windows.

You can direct an IME window to carry out an action, such as change the position of composition window, by using the WM_IME_CONTROL message. The IME notifies the application about changes to the composition string by using the WM_IME_COMPOSITION message and about general changes to the status of the IME windows by sending the WM_IME_NOTIFY message.


Input Context

An input context is an internal structure, maintained by the IME, that contains information about the status of the IME and is used by IME windows. By default, the system creates and assigns an input context to each thread. Within the thread, this default input context is a shared resource and is associated with each newly created window.

To retrieve or set information in the IME, an application must first retrieve a handle to the input context associated with a given window. You retrieve the handle by using the ImmGetContext function. You can use the retrieved handle in subsequent calls to the input method manager functions to retrieve and set IME values, such as the composition window style, the composition style, and the status window position. Once you have finished using the context, you must release it using the ImmReleaseContext function.

Because the default input context is a shared resource, any changes you make to it apply to all windows in the thread. However, you can override this default behavior by creating and associating your own input context to one or more window of the thread. The changes you make to your own input context apply only to the windows with which it is associated.

You can create an input context by using the ImmCreateContext function. You assign the context to a window by using the ImmAssociateContext function. This function returns the handle of the previously associated input context. If you have not associated an input context with the window before, the returned handle is for the default input context. You should save this handle and later reassociate with the window if you no longer want to use your own input context.

Once an input context is associated with a window, the system automatically selects that context when the window is activated and receives the input focus. The style and other information in the input context affects subsequent keyboard input for that window, determining whether and how the IME operates.

You must destroy any input context you create before terminating your application. You destroy an input context by using the ImmDestroyContext function. Before destroying it, you must remove the input context from any association it has with windows in the thread by using the ImmAssociateContext function.


Composition String

The composition string is the current text in the composition window. This is the text that the IME converts to final characters. Each composition string consists of one or more clauses, where a clause is the smallest combination of characters that the IME can convert to a final character. You can get and set the composition string and get and set the composition string by using the ImmGetCompositionString and ImmSetCompositionString functions.

As the user enters text in the composition window, the IME tracks the status of the composition string. This status includes attribute information, clause information, typing information, and cursor position. You can retrieve the composition status by using the ImmGetCompositionString function.

In the attribute information array, all characters of one clause must have the same attribute. The attribute information is an array of 8-bit values that specifies the status of characters in the composition string. There is one value for each byte in the string, including one byte each for the lead and second bytes of any double-byte characters in the string. For each value in the array, bits 0 through 3 can be one combination of these values:

ATTR_INPUT
 | Character being entered by the user. It is yet to be converted by the IME.
ATTR_INPUT_ERROR
 | Character is the error character and cannot be converted by the IME.
ATTR_TARGET_CONVERTED
 | Character converted by the IME. The user has selected this character and the IME has converted it.
ATTR_CONVERTED
 | A converted character. The IME has already converted this character.
ATTR_TARGET_NOTCONVERTED
 | Character being converted. The user has selected this character but the IME has not yet converted it.
ATTR_FIXEDCONVERTED
 | Characters that will not be converted. The IME will not convert these characters anymore.

All other values are reserved. In Japanese, any unconverted character having the ATTR_INPUT attribute is a Hiragana, Katakana, or alphanumeric character. In Korean, this character is a Hangeul character that is not converted by IME yet. In Traditional and Simplified Chinese, each IME may limit its character in some range.

You can retrieve the composition status by using the ImmGetCompositionString function.

The clause information is an array of 32-bit values that specify the positions of the clauses in the composition string. There is one value for each clause and a final value that specifies the length of the full string. Each value in the array specifies the offset, in bytes, from the beginning of the string to the clause. The first value is always 0 because the first clause always starts at the beginning of the string. For example, if a string has two clauses, the clause information has three values: the first value is 0, the second value is the offset of the second clause, and the third value is the length of the string.

The typing information a null-terminated character string representing the characters entered at the keyboard.

The cursor position is a value indicating the position of the cursor relative to the characters in the composition string. The value is the offset, in bytes, from the beginning of the string. If this value is 0, the cursor is immediately before the first character in the string. If the value is equal to the length of the string, the cursor is immediately after the last character. If -1, the cursor is not present.

You can set the composition string or elements of the composition status by using the ImmSetCompositionString function. To ensure that the composition window updates it appearance based on these changes, the function allows for generating a notification message to be sent to the window. Applications that set a combination of composition status elements typically set the fNotify parameter to FALSE for all but the last call to this function so that only one notification message is generated for the composition window.

Finally, the edit control supports two messages for changing the IME's handling of composition strings. See EM_GETIMESTATUS and EM_SETIMESTATUS for more information. For more information on the edit control, see Edit Controls.


Candidate Lists

A candidate list is a CANDIDATELIST structure consisting of an array of strings that specify the characters or character strings that the user may choose from. You can retrieve the candidate lists by using the ImmGetCandidateListCount and ImmGetCandidateList functions.


Hot Keys

Hot keys give the user a way to quickly change the input mode of the IME or to switch to another IME. Although applications cannot add hot keys to the system, they can initiate the same action as a hot key by using the ImmSimulateHotKey function.


Using Input Method Editor

  • Processing the WM_IME_COMPOSITION message


Processing the WM_IME_COMPOSITION Message

Applications that process the WM_IME_COMPOSITION message test the bits in lParam parameter and call the ImmGetCompositionString function to retrieve the indicated string or data. The following example checks for the result string, allocates sufficient memory for the string, and retrieves the result string from the IME:

HIMC hIMC;
HWND hWnd;
DWORD dwSize;
HGLOBAL hstr;
LPSTR lpstr;

case WM_IME_COMPOSITION:
    if (lParam & GCS_RESULTSTR)
    {
        hIMC = ImmGetContext(hWnd);

        If (!hIMC)
            MyError(ERROR_NULLCONTEXT);

        // Get the size of the result string.
        dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);

        // increase buffer size for NULL terminator,
        //   maybe it is in UNICODE
        dwSize += sizeof(WCHAR);

        hstr = GlobalAlloc(GHND,dwSize);
        if (hstr == NULL)
             MyError(ERROR_GLOBALALLOC);

        lpstr = GlobalLock(hstr);
        if (lpstr == NULL)
             MyError(ERROR_GLOBALLOCK);

        // Get the result strings that is generated by IME into lpstr.
        ImmGetCompositionString(hIMC, GCS_RESULTSTR, lpstr, dwSize);
        ImmReleaseContext(hWnd, hIMC);

        // add this string into text buffer of application

        GlobalUnlock(hstr);
        GlobalFree(hstr);
    }


The Input Method Editor and Unicode

There are two issues involved with Unicode handling and the IME. One is the existence of Unicode versions of IME routines, and the other is getting the IME to return Unicode characters (rather than DBCS) in the WM_CHAR and WM_IME_CHAR messages.

All routines which handle strings have a Unicode equivalent in the IME, even under Windows 98. The IME is different from other Unicode function implementations in Windows, however, in that the Unicode versions return the size of a buffer in bytes rather than 16-bit Unicode characters.

You can use the RegisterClassW function under Windows NT (and only under Windows NT; under Windows 9x this function is stubbed out) to cause the WM_CHAR and WM_IME_CHAR messages to return Unicode characters in the wParam parameter rather than DBCS characters.

Using Recoversion with the Input Method Editor

In Windows 98 and Windows NT 5.0, the IME implements a new feature called reconversion. Normally the IME determines the lists of candidates based only on what is typed. Reconversion allows the IME to determine candidates (or only one candidate) based on the sentence it is in (its context). There are three types of reconversion: simple, normal, and enhanced.

Reconversion is useful when a user notices a composition error in the document. In this case the user can select the error, choose recoversion from a menu, and the IME will use the context to determine the best replacement.


Input Method Editor Reference

This following elements are used with the input method editor.

  • Input Method Editor Functions
  • Input Method Editor Messages
  • Input Method Editor Structures
  • Input Method Editor Constants


Input Method Editor Functions

This section describes the input method editor functions.

EnumRegisterWordProc
ImmAssociateContext
ImmAssociateContextEx
ImmConfigureIME
ImmCreateContext
ImmDestroyContext
ImmDisableIME
ImmEnumRegisterWord
ImmEscape
ImmGetCandidateList
ImmGetCandidateListCount
ImmGetCandidateWindow
ImmGetCompositionFont
ImmGetCompositionString
ImmGetCompositionWindow
ImmGetContext
ImmGetConversionList
ImmGetConversionStatus
ImmGetDefaultIMEWnd
ImmGetDescription
ImmGetGuideLine
ImmGetIMEFileName
ImmGetImeMenuItems
ImmGetOpenStatus
ImmGetProperty
ImmGetRegisterWordStyle
ImmGetStatusWindowPos
ImmGetVirtualKey
ImmInstallIME
ImmIsIME
ImmIsUIMessage
ImmNotifyIME
ImmRegisterWord
ImmReleaseContext
ImmSetCandidateWindow
ImmSetCompositionFont
ImmSetCompositionString
ImmSetCompositionWindow
ImmSetConversionStatus
ImmSetOpenStatus
ImmSetStatusWindowPos
ImmSimulateHotKey
ImmUnregisterWord


EnumRegisterWordProc

The EnumRegisterWordProc function is an application-defined callback function used with the ImmEnumRegisterWord function. It is used to process data of register strings. The REGISTERWORDENUMPROC type defines a pointer to this callback function. EnumRegisterWordProc is a placeholder for the application-defined function name.

UINT CALLBACK EnumRegisterWordProc(
  LPCTSTR lpReading,
  DWORD dwStyle,
  LPCTSTR lpszString,
  LPVOID lpData
);

Parameters

lpszReading
Pointer to a null-terminated string specifying the matched reading string.
dwStyle
Style of register string.
lpszString
Pointer to a null-terminated string specifying the matched register string.
lpData
Application-supplied data.

Return Values

Returns a nonzero value to continue enumeration; zero to stop enumeration.

Remarks

An application must register this function by passing its address to the ImmEnumRegisterWord function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: User-defined.

See Also

Input Method Editor Overview, Input Method Editor Functions, ImmEnumRegisterWord


ImmAssociateContext

The ImmAssociateContext function associates the specified input context with the specified window. If hIMC is NULL, the function removes any association the window may have with an input context. By default, the system associates the default input context with each window as it is created.

HIMC ImmAssociateContext(
  HWND hWnd,
  HIMC hIMC
);

Parameters

hWnd
Handle to the window to be associated with the input context.
hIMC
Handle to the input context.

Return Values

Returns the handle to the input context previously associated with the window.

Remarks

If an application associates an input context with a window, the application must remove that association before destroying the input context. One way to do this is to save and reassociate the handle to the default input context with the window.

Windows CE: If the hIMC parameter is NULL, the ImmAssociateContext function removes any association the window may have with an input context. By default, the system associates the default input context with each window as it is created.

An application can specify only the default input context or NULL.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmAssociateContextEx

[This is preliminary documentation and subject to change.]

The ImmAssociateContextEx function changes the association between the input method context and the specified window or its children.

BOOL ImmAssociateContextEx(
  HWND hWnd,    // handle to window
  HINC hIMC,    // handle to input method context
  DWORD dwFlags // flag
);

Parameters

hWnd
Handle to the window to be associated with the input context.
hIMC
Handle to the input method context.
dwFlags
Type of association between the window and the input method context. This parameter can be the following values:
Value | Meaning
IACE_CHILDREN | Associate the input method context to the child windows of hWnd only.
IACE_DEFAULT | Restore the window's default input method context.
IACE_IGNORENOCONTEXT | Do not associate the input method context with windows that are not associated with any input method context.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

Remarks

If the application calls this function with IACE_CHILDREN, the system associates the specified input method context with child windows of hWnd. It associates the input method context only with child windows of the thread that created hWnd. Any child window that is created after this function has been called will not be affected. Instead, the default input method context will be associated with it.

If the application calls this function with IACE_DEFAULT, the system restores the window's default input method context. In this case, the hIMC parameter is ignored.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmConfigureIME

The ImmConfigureIME function displays the configuration dialog box for the IME.

BOOL ImmConfigureIME(
  HKL hKL,
  HWND hWnd,
  DWORD dwMode,
  LPVOID lpdata
);

Parameters

hKL
Handle to the keyboard layout.
hWnd
Handle to the parent window for the dialog box.
dwMode
Type of dialog box to display. This parameter can be one of the following values:
Value | Meaning
IME_CONFIG_GENERAL | Displays general purpose configuration dialog box.
IME_CONFIG_REGISTERWORD | Displays register word dialog box.
IME_CONFIG_SELECTDICTIONARY | Displays dictionary selection dialog box.

lpData
Pointer to supplemental data. If dwMode is IME_CONFIG_REGISTERWORD, this parameter must be the address of a REGISTERWORD structure.

If dwMode is not IME_CONFIG_REGISTERWORD, this parameter is ignored.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

Remarks

The ImmConfigureIME function is called by the Control Panel.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmCreateContext

The ImmCreateContext function creates a new input context, allocating memory for the context and initializing it. An application calls this function to prepare its own input context.

HIMC ImmCreateContext(void);

Return Values

If the function succeeds, the return value is the handle to the new input context.

If the function fails, the return value is NULL.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmDestroyContext

The ImmDestroyContext function releases the input context and frees any memory associated with it.

BOOL ImmDestroyContext(
  HIMC hIMC
);

Parameters

hIMC
Handle to the input context to free.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

Remarks

Any application that creates an input context by using the ImmCreateContext function must call this function to free the context before it terminates.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions, ImmCreateContext


ImmDisableIME

[This is preliminary documentation and subject to change.]

The ImmDisableIME function disables the input method editor (IME) for a thread or all threads in a process.

BOOL ImmDisableIME(
  DWORD idThread   // thread to disable IME
);

Parameters

idThread
The thread for which the IME will be disabled. If idThread is zero, the IME for the current thread is disabled. If idThread is –1, the IME is disabled for all threads in the current process.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

Remarks

The application must call this function before the first top-level window in the thread receives the WM_CREATE message. This means the application must call this function in one of the following places:

  • Any time before calling CreateWindow to create the first top-level window
  • In the first top-level window's WM_NCCREATE handler

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmEnumRegisterWord

The ImmEnumRegisterWord function enumerates the register strings having the specified reading string, style, and register string.

UINT ImmEnumRegisterWord(
  HKL hKL,
  REGISTERWORDENUMPROC lpfnEnumProc,
  LPCTSTR lpszReading,
  DWORD dwStyle,
  LPCTSTR lpszRegister,
  LPVOID lpData
);

Parameters

hKL
Handle to the keyboard layout.
lpfnEnumProc
Pointer to the callback function. For more information, see EnumRegisterWordProc.
lpszReading
Pointer to the reading string to be enumerated. If NULL, this function enumerates all available reading strings that match with the specified dwStyle and lpszRegister.
dwStyle
Style to be enumerate. If zero, this function enumerates all available styles that match with the specified lpszReading and lpszRegister.
lpszRegister
Pointer to the register string to enumerate. If NULL, this function enumerates all register strings that match with the specified lpszReading and dwStyle.
lpData
Application-supplied data. The function passes this parameter to the callback function.

Return Values

Returns the last value return by the callback function. Its meaning is defined by the application. The function returns zero if it cannot enumerate the register strings.

Remarks

If dwStyle is zero and both lpszReading and lpszRegister are NULL, the ImmEnumRegisterWord function enumerates all register strings in the IME dictionary.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions, EnumRegisterWordProc


ImmEscape

The ImmEscape function carries out IME-specific subfunctions and is used mainly for country-specific functions.

LRESULT ImmEscape(
  HKL hKL,
  HIMC hIMC,
  UINT uEscape,
  LPVOID lpData
);

Parameters

hKL
Handle to the keyboard layout.
hIMC
Handle to the input context.
uEscape
Index of the subfunction. For more information about the escape, see the "IME Escapes" table in Input Method Editor Constants.
lpData
Subfunction-specific data.

Return Values

Returns zero on error; otherwise, returns an escape-specific value.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmGetCandidateList

The ImmGetCandidateList function retrieves a specified candidate list, copying the list to the specified buffer.

DWORD ImmGetCandidateList(
  HIMC hIMC,
  DWORD deIndex,
  LPCANDIDATELIST lpCandList,
  DWORD dwBufLen
);

Parameters

hIMC
Handle to the input context.
deIndex
Zero-based index of the candidate list.
lpCandList
Pointer to the CANDIDATELIST structure that receives the candidate list.
dwBufLen
Size of the buffer, in bytes. If zero, the function returns the size in bytes required to receive the complete candidate list.

Return Values

If the function succeeds, the return value is the number of bytes copied to the specified buffer.

If the function fails, the return value is zero.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions, CANDIDATELIST


ImmGetCandidateListCount

The ImmGetCandidateListCount function retrieves the size, in bytes, of the candidate lists.

DWORD ImeGetCandidateListCount(
  HIMC hIMC,
  LPDWORD lpdwListCount
);

Parameters

hIMC
Handle to the input context.
lpdwListCount
Pointer to the 32-bit variable that receives the size of the candidate lists.

Return Values

Returns the number of bytes required to receive all candidate lists.

Remarks

Applications typically call this function in response to a IMN_OPENCANDIDATE or IMN_CHANGECANDIDATE message.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions, IMN_CHANGECANDIDATE, IMN_OPENCANDIDATE


ImmGetCandidateWindow

The ImmGetCandidateWindow function gets information about the candidate list window.

BOOL ImmGetCandidateWindow(
  HIMC hIMC,
  DWORD dwBufLen,
  LPCANDIDATEFORM lpCandidate
);

Parameters

hIMC
Handle to the input context.
dwBufLen
Size, in bytes, of the buffer that receives the information.
lpCandidate
Pointer to the CANDIDATEFORM structure that receives information about the candidate window.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions, CANDIDATEFORM


ImmGetCompositionFont

The ImmGetCompositionFont function retrieves information about the logical font currently used to display characters in the composition window.

BOOL ImmGetCompositionFont(
  HIMC hIMC,
  LPLOGFONT lplf
);

Parameters

hIMC
Handle to the input context.
lplf
Pointer to a LOGFONT structure that receives the font information.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions, LOGFONT


ImmGetCompositionString

The ImmGetCompositionString function retrieves information about the composition string.

LONG ImmGetCompositionString(
  HIMC hIMC,
  DWORD dwIndex,
  LPVOID lpBuf,
  DWORD dwBufLen
);

Parameters

hIMC
Handle to the input context.
dwIndex
Index of the information to retrieve. This parameter can be one of the values specified in the "IME Composition String Values" table in Input Method Editor Constants. For each value except GCS_CURSORPOS and GCS_DELTASTART, the function copies the requested information to the specified buffer. The function returns the cursor and delta position values in the low 16-bits of the return value.
lpBuf
Pointer to the buffer that receives the requested information.
dwBufLen
Size of the buffer, in bytes. If zero, the ImmGetCompositionString function returns the buffer size needed for the complete information.

Return Values

Returns the number of bytes copied to the destination buffer or, if dwBufLen is zero, the buffer size, in bytes, needed to receive all of the requested information. On an error, the function returns one of the following negative error values:

Value | Meaning
IMM_ERROR_NODATA | Composition data is not ready in the input context.
IMM_ERROR_GENERAL | General error detected by IME.

Remarks

An application calls this function in response to the WM_IME_COMPOSITION or WM_IME_STARTCOMPOSITION message. The IMM removes the information when an application calls the ImmReleaseContext function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions, ImmReleaseContext, WM_IME_COMPOSITION


ImmGetCompositionWindow

The ImmGetCompositionWindow function gets information about the composition window.

BOOL ImmGetCompositionWindow(
  HIMC hIMC,
  LPCOMPOSITIONFORM lpCompForm
);

Parameters

hIMC
Handle to the input context.
lpCompForm
Pointer to the COMPOSITIONFORM structure that receives information about the composition window.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions, COMPOSITIONFORM


ImmGetContext

The ImmGetContext function retrieves the input context associated with the specified window.

HIMC ImmGetContext(
  HWND hWnd
);

Parameters

hWnd
Handle to the window to retrieve the input context for.

Return Values

Returns the handle to the input context.

Remarks

An application should routinely use this function to retrieve the current input context before attempting to access information in the context.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmGetConversionList

The ImmGetConversionList function retrieves the list of characters or words from one character or word.

UINT ImmGetConversionList(
  HKL hKL,
  HIMC hIMC,
  LPCTSTR lpSrc,
  LPCANDIDATELIST lpDst,
  DWORD dwBufLen,
  UINT uFlag
);

Parameters

hKL
Handle to the keyboard layout.
hIMC
Handle to the input context.
lpSrc
Pointer to a null-terminated character string.
lpDst
Pointer to the CANDIDATELIST structure that receives the conversion result.
dwBufLen
Size of the destination buffer, in bytes. If zero, the function returns the buffer size needed for the complete conversion result.
uFlag
Action flag. This parameter can be one of the following values:
Value | Meaning
GCL_CONVERSION | Source string is the reading string. The function copies the result string to the destination buffer.
GCL_REVERSECONVERSION | Source string is the result string. The function copies the reading string to the destination buffer.
GCL_REVERSE_LENGTH | Source string is the result string. The function returns the size in bytes of the reading string that would be created if GCL_REVERSECONVERSION were specified.

Return Values

Returns the number of bytes copied to the specified buffer or, if dwBufLen is zero, the buffer size needed to receive the list.

Remarks

Windows CE: The hKL parameter must be NULL.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions, CANDIDATELIST


ImmGetConversionStatus

The ImmGetConversionStatus function gets the current conversion status.

BOOL ImmGetConversionStatus(
  HIMC hIMC,
  LPDWORD lpfdwConversion,
  LPDWORD lpfdwSentence
);

Parameters

hIMC
Handle to the input context for which to retrieve information.
lpfdwConversion
Pointer to a 32-bit variable that receives a combination of conversion mode values. For more information, see the "IME Conversion Mode Values" table in Input Method Editor Constants.
lpfdwSentence
Pointer to a 32-bit variable that receives a sentence mode value. For more information, see the "IME Sentence Mode Values" table in Input Method Editor Constants.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

Remarks

Conversion and sentence mode values are set only if the IME supports those modes.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmGetDefaultIMEWnd

The ImmGetDefaultIMEWnd function gets the default window handle to the IME class.

HWND ImmGetDefaultIMEWnd(
  HWND hWnd
);

Parameters

hWnd
Handle to the window for the application.

Return Values

If the function succeeds, the return value is the default window handle to the IME class.

If the function fails, the return value is NULL.

Remarks

The system creates a default IME window for every thread. The IME window is created based on the IME class. The application can send WM_IME_CONTROL to this window.

Windows CE: The system creates only one default IME window. Windows CE does not support the IME class.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions, WM_IME_CONTROL


ImmGetDescription

The ImmGetDescription function copies the description of the IME to the specified buffer.

UINT ImmGetDescription(
  HKL hKL,
  LPTSTR lpszDescription,
  UINT uBufLen
);

Parameters

hKL
Handle to the keyboard layout.
lpszDescription
Pointer to the buffer that receives the null-terminated string describing the IME.
uBufLen
Size of the buffer, in characters. If zero, the function returns the buffer size needed for the complete description, not including terminating null character.

Windows NT: The size of the buffer is in Unicode characters (each character is two bytes).

Return Values

Returns the number of characters copied to the buffer or, if uBufLen is zero, the buffer size in characters needed to receive the description. Neither value includes the terminating null character.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmGetGuideLine

The ImmGetGuideLine function gets information about errors. Applications use the information to notify users.

DWORD ImmGetGuideLine(
  HIMC hIMC,
  DWORD dwIndex,
  LPTSTR lpBuf,
  DWORD dwBufLen
);

Parameters

hIMC
Handle to the input context.
dwIndex
Type of guideline information to retrieve. This parameter can be one of the following values.
Value | Meaning
GGL_LEVEL | Returns the error level.
GGL_INDEX | Returns the error index.
GGL_STRING | Retrieves the error message string.
GGL_PRIVATE | Returns information about reverse conversion.

lpBuf
Pointer to the buffer that receives the error message string. This parameter can be NULL if dwIndex is not GGL_STRING or GGL_PRIVATE if dwBufLen is zero.
dwBufLen
Size, in bytes, of the buffer pointed to by lpBuf. If zero, the function returns the buffer size needed to receive the error message string, not including the terminating null character.

Return Values

The return value is an error level, an error index, or the size of an error message string, depending on the value of the dwIndex parameter. If dwIndex is GGL_LEVEL, the return value is one of the following:

Value | Meaning
GL_LEVEL_ERROR | Error. The IME may not be able to continue.
GL_LEVEL_FATAL | Fatal error. The IME cannot continue, and data may be lost.
GL_LEVEL_INFORMATION | No error, but information is available for the user.
GL_LEVEL_NOGUIDELINE | No error. Remove previous error message if still visible.
GL_LEVEL_WARNING | Unexpected input or other result. The user should be warned, but the IME can continue.

If dwIndex is GGL_INDEX, the return value is one of the following:

Value | Meaning
GL_ID_CANNOTSAVE | The dictionary or the statistics data cannot be saved.
GL_ID_NOCONVERT | The IME cannot convert any more.
GL_ID_NODICTIONARY | The IME cannot find the dictionary, or the dictionary has an unexpected format.
GL_ID_NOMODULE | The IME can not find the module that IME needs.
GL_ID_READINGCONFLICT | For example, some vowels cannot put together.
GL_ID_TOOMANYSTROKE | There are too many strokes for one character or one clause.
GL_ID_TYPINGERROR | Typing error. The IME can not handle this typing.
GL_ID_UNKNOWN | Unknown error. The application should refer to the error message string.
GL_ID_INPUTREADING | IME accepts reading character input.
GL_ID_INPUTRADICAL | IME accepts radical character input.
GL_ID_INPUTCODE | IME accepts character code input.
GL_ID_CHOOSECANDIDATE | IME accepts candidate string selection.
GL_ID_REVERSECONVERSION | Information about reverse conversion is available.

If dwIndex is GGL_STRING, the return value is the number of bytes of the string copied to the buffer, or if dwBufLen is zero, the return value is the buffer size needed to receive the string.

If dwIndex is GGL_PRIVATE, the return value is the number of bytes of information copied to the buffer. If dwIndex is GGL_PRIVATE and dwBufLen is zero, the return value is the buffer size needed to receive the information.

Remarks

Applications typically call this function after receiving an IMN_GUIDELINE message.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmGetIMEFileName

The ImmGetIMEFileName function gets the filename of the IME associated with the specified keyboard layout.

BOOL ImmGetIMEFileName(
  HKL hKL,
  LPTSTR lpszFileName,
  UINT uBufLen
);

Parameters

hKL
Handle to the keyboard layout.
lpszFileName
Pointer to the buffer that receives the filename.
uBufLen
Size in bytes of the buffer. If zero, the function returns the buffer size in bytes needed to receive the filename, not including the termintaing null character.

Return Values

The return value is the number of bytes in the filename copied to the buffer, or if uBufLen is zero, the return value is the buffer size needed for the filename. In either case, the terminating null character is not included.

Remarks

In the registry, the system stores the filename as the IME name value in HKEY_LOCAL_MACHINE root under the \System\CurrentControlSet\control\keyboard layouts\hKL key.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmGetImeMenuItems

[This is preliminary documentation and subject to change.]

The ImmGetImeMenuItems function retrieves the menu items that are registered in the IME menu.

DWORD WINAPI ImmGetImeMenuItems(
   HIMC                hIMC,
   DWORD               dwFlags,
   DWORD               dwType,
   LPIMEMENUITEMINFO   lpImeParentMenu,
   LPIMEMENUITEMINFO   lpImeMenu,
   DWORD               dwSize
);

Parameters

hIMC
Handle to the input context.
dwFlags
Menu information flags. The following value is defined:
Value | Meaning
IGIMIF_RIGHTMENU | If set, the function returns the menu items for the context menu (obtained by a right mouse click).

dwType
Type of menu returned by this function. This parameter can be a combination of the following values.
Value | Meaning
IGIMII_CMODE | Returns the menu items that control the conversion mode.
IGIMII_SMODE | Returns the menu items that control sentence mode.
IGIMII_CONFIGURE | Returns the menu items that are related to configuration.
IGIMII_TOOLS | Returns the menu items that are related to tools.
IGIMII_HELP | Returns the menu items that control help.
IGIMII_OTHER | Returns the menu items that control other IME functions.
IGIMII_INPUTTOOLS | Returns the menu items that control input tools.

lpImeParentMenu
Pointer to the parent menu. It points to a IMEMENUITEMINFO structure with the fType member set to MFT_SUBMENU in order to return information about the submenu items of this parent menu. If this parameter is NULL, however, the function returns only top-level menu items.
lpImeMenu
Pointer to a buffer to receive the contents of the menu items. The buffer is an array of IMEMENUINFO structures. If this parameter is NULL, the function returns the number of registered menu items.
dwSize
The size of the buffer to receive the IMEMENUITEMINFO structure.

Return Values

The return value is the number of menu items that were copied into lpImeMenu. If lpImeMenu is NULL, the function returns the number of registered menu items.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions, IMEMENUITEMINFO


ImmGetOpenStatus

The ImmGetOpenStatus function checks whether the IME is open or closed.

BOOL WINAPI ImmGetOpenStatus(
  HIMC hIMC
);

Parameters

hIMC
Handle to the input context.

Return Values

The return value is a nonzero value if the IME is open, and zero otherwise.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmGetProperty

The ImmGetProperty function gets the property and capabilities of the IME associated with the specified keyboard layout.

BOOL ImmGetProperty(
  HKL hKL,
  DWORD fdwIndex
);

Parameters

hKL
Handle to the keyboard layout.
fdwIndex
Type of property information to retrieve. This parameter can be one of the following values:
Value | Meaning
IGP_PROPERTY | Property information.
IGP_CONVERSION | Conversion capabilities.
IGP_SENTENCE | Sentence mode capabilities.
IGP_UI | User interface capabilities.
IGP_SETCOMPSTR | Composition string capabilities.
IGP_SELECT | Selection inheritance capabilities.
IGP_GETIMEVERSION | Retrieves the system version number for which the specified IME was created.

Return Values

Returns the property or capability value, depending on the value of the dwIndex parameter. If dwIndex is IGP_PROPERTY, returns a combination of the following values:

Value | Meaning
IME_PROP_AT_CARET | If set, conversion window is at the caret position. If clear, the window is near caret position.
IME_PROP_SPECIAL_UI | If set, IME has a nonstandard user interface. The application should not draw in the IME window.
IME_PROP_CANDLIST_START_FROM_1 | If set, strings in the candidate list are numbered starting at 1. If clear, strings start at 0.
IME_PROP_UNICODE | If set, strings for the input context have Unicode characters. If clear, strings have single and double-byte characters.
IME_PROP_COMPLETE_ON_UNSELECT | If set, the IME will complete the composition string when the IME is deactivated. If clear, the IME will cancel the composition string when the IME is deactivated (such as from a keyboard layout change).

If dwIndex is IGP_UI, the return value is a combination of the following values:

Value | Meaning
UI_CAP_2700 | Supports text escapement values of 0 or 2700.
UI_CAP_ROT90 | Supports text escapement values of 0, 900, 1800, or 2700.
UI_CAP_ROTANY | Supports any text escapement value.

If dwIndex is IGP_SETCOMPSTR, the return value is a combination of the following values:

Value | Meaning
SCS_CAP_COMPSTR | Can create the composition string by using the SCS_SETSTR value of the ImmSetCompositionString function.
SCS_CAP_MAKEREAD | Can create the reading string from corresponding composition string when using the SCS_SETSTR value of the ImmSetCompositionString function.

If dwIndex is IGP_SELECT, the return value is a combination of the following values:

Value | Meaning
SELECT_CAP_CONVMODE | Inherits conversion mode when a new IME is selected.
SELECT_CAP_SENTENCE | Inherits sentence mode when a new IME is selected.

If dwIndex is IGP_GETIMEVERSION, the return value is one of the following values:

Value | Meaning
IMEVER_0310 | The IME was created for Windows 3.1
IMEVER_0400 | The IME was created for Windows 95.

Remarks

Windows CE: The hKL parameter must be NULL.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmGetRegisterWordStyle

The ImmGetRegisterWordStyle function gets a list of the styles support by the IME associated with the specified keyboard layout.

UINT ImmGetRegisterWordStyle(
  HKL hKL,
  UINT nItem,
  LPSTYLEBUF lpStyleBuf
);

Parameters

hKL
Handle to the keyboard layout.
nItem
Maximum number of styles that the buffer can hold.
lpStyleBuf
Pointer to the STYLEBUF structure that receives the style information.

Return Values

The return value is the number of layout handles copied to the buffer, or if nItems is zero, the return value is the buffer size in array elements needed to receive all available style information.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions, STYLEBUF


ImmGetStatusWindowPos

The ImmGetStatusWindowPos function gets the position of the status window.

BOOL ImmGetStatusWindowPos(
  HIMC hIMC,
  LPPOINT lpptPos
);

Parameters

hIMC
Handle to the input context.
lpptPos
Pointer to the POINT structure that receives the position coordinates. These are screen coordinates, relative to the upper-left corner of the screen.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions, POINT


ImmGetVirtualKey

The ImmGetVirtualKey function recovers the original virtual-key value associated with a key input message that has already been processed by the IME.

UINT ImmGetVirtualKey(
  HWND hWnd
);

Parameters

hWnd
Handle to the window that receives the key message.

Return Values

The return value is the original virtual-key value.

Remarks

Although the IME sets the virtual-key value to VK_PROCESSKEY after processing a key input message, an application can recover the original virtual-key value with the ImmGetVirtualKey function. This function can be used only for key input messages containing the VK_PROCESSKEY value.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmInstallIME

The ImmInstallIME function installs an IME into the system.

HKL ImmInstallIME(
  LPCTSTR lpszIMEFileName,
  LPCTSTR lpszLayoutText
);

Parameters

lpszIMEFileName
Pointer to a null-terminated string that specifies the full path of the IME.
lpszLayoutText
Pointer to a null-terminated string that specifies the name of the IME. This name also specifies the layout text of the IME.

Return Values

The return value is the handle to the keyboard layout for the IME.

Remarks

This function is intended to be used by IME setup programs only.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmIsIME

The ImmIsIME function checks whether the specified handle identifies an IME.

BOOL ImmIsIME(
  HKL hKL
);

Parameters

hKL
Handle to the keyboard layout to check.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmIsUIMessage

The ImmIsUIMessage function checks for messages intended for the IME window and sends those messages to the specified window.

BOOL ImmIsUIMessage(
  HWND hWndIME,
  UINT msg,
  WPARAM wParam,
  LPARAM lParam
);

Parameters

hWndIME
Handle to a window belonging to the IME window class.
msg
Message to check.
wParam
32-bit message-specific parameter.
lParam
32-bit message-specific parameter.

Return Values

If the message is processed by the IME window, the return value is a nonzero value.

If the message is not processed by the IME window, the return value is zero.

Remarks

An application typically uses this function to display any composition string or candidate list specified by IME. If hWndIME is NULL, the function checks whether the message is a user interface message.

Windows CE: The hWndIME parameter is a handle to a default IME window.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmNotifyIME

The ImmNotifyIME function notifies the IME about changes to the status of the input context.

BOOL ImmNotifyIME(
  HIMC hIMC,
  DWORD dwAction,
  DWORD dwIndex,
  DWORD dwValue
);

Parameters

hIMC
Handle to the input context.
dwAction
Notification code. This parameter can be one of the following values:
Value | Meaning
NI_CHANGECANDIDATELIST | An application changed the current selected candidate; dwIndex is an index of a candidate list to be selected and dwValue is not used.
NI_CLOSECANDIDATE | An application directs the IME to close a candidate list; dwIndex is the index of the list to close; dwValue is not used. The IME sends a IMN_CLOSECANDIDATE message to the application if it closes the list.
NI_COMPOSITIONSTR | An application directs the IME to carry out an action on the composition string; dwValue is not used and dwIndex can be CPS_CANCEL, CPS_COMPLETE, CPS_CONVERT, or CPS_REVERT.
NI_IMEMENUSELECTED | An application directs the IME to allow the application to handle the specified menu; dwIndex is the ID of the menu and dwValue is an application-defined value for that menu item.
NI_OPENCANDIDATE | An application directs the IME to open a candidate list; dwIndex is the index of the list to open; dwValue is not used. The IME sends a IMN_OPENCANDIDATE message to the application if it opens the list.
NI_SELECTCANDIDATESTR | An application selected one of candidates; dwIndex is an index of a candidate list to be selected and dwValue is an index of a candidate string in the selected candidate list.
NI_SETCANDIDATE_PAGESIZE | The dwIndex parameter specifies the candidate list to be changed and must have a value in the range 0 to 31.
NI_SETCANDIDATE_PAGESTART | The dwIndex parameter specifies the candidate list to be changed and must have a value in the range 0 to 31.

dwIndex
Index of a candidate list or, if dwAction is NI_COMPOSITIONSTR, one of the following values:
Value | Meaning
CPS_CANCEL | Clear the composition string and set the status to no composition string.
CPS_COMPLETE | Set the composition string as the result string.
CPS_CONVERT | Convert the composition string.
CPS_REVERT | Cancel the current composition string and revert to the unconverted string.

dwValue
Index of a candidate string or not used, depending on the value of the dwAction parameter.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmRegisterWord

The ImmRegisterWord function registers a string into the dictionary of the IME associated with the specified keyboard layout.

BOOL ImmRegisterWord(
  HKL hKL,
  LPCTSR lpszReading,
  DWORD dwStyle,
  LPCTSTR lpszRegister
);

Parameters

hKL
Handle to the keyboard layout.
lpszReading
Pointer to a null-terminated string specifying the reading string associated with the string to register.
dwStyle
Style of the register string. This parameter can be IME_REGWORD_STYLE_EUDC to indicate the string is in the EUDC range, or any value in the reserved range IME_REGWORD_STYLE_USER_FIRST to IME_REGWORD_STYLE_USER_LAST to indicate a private style maintained by the specified IME.
lpszRegister
Pointer to a null-terminated string specifying the string to register.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmReleaseContext

The ImmReleaseContext function releases the input context and unlocks the memory associated in the context. An application must call this function for each call to the ImmGetContext function.

BOOL ImmReleaseContext(
  HWND hWnd,
  HIMC hIMC
);

Parameters

hWnd
Handle to the window for which the input context was previously retrieved.
hIMC
Handle to the input context.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions, ImmGetContext


ImmSetCandidateWindow

The ImmSetCandidateWindow function sets information about the candidate list window.

BOOL ImmSetCandidateWindow(
  HIMC hIMC,
  LPCANDIDATEFORM lpCandidate
);

Parameters

hIMC
Handle to the input context.
lpCandidate
Pointer to the CANDIDATEFORM structure that contains information about the candidate window.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

Remarks

ImmSetCandidateWindow causes an IMN_SETCANDIDATEPOS message to be sent to the application.

Windows CE: For Japanese version 1.0 and later, the ImmSetCandidateWindow function allows an index range of 0 to 4 for the dwIndex member of the CANDIDATEFORM structure.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions, CANDIDATEFORM


ImmSetCompositionFont

The ImmSetCompositionFont function sets the logical font to be used to display characters in the composition window.

BOOL ImmSetCompositionFont(
  HIMC hIMC,
  LPLOGFONT lplf
);

Parameters

hIMC
Handle to the input context.
lplf
Pointer to the LOGFONT structure containing the font information to set.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

Remarks

Even if an application never uses the composition window, it must set the appropriate font to ensure that characters are displayed properly. This is especially true for vertical writing.

This function causes a IMN_SETCOMPOSITIONFONT message to be sent to the application.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions, IMN_SETCOMPOSITIONFONT, LOGFONT


ImmSetCompositionString

The ImmSetCompositionString function sets the characters, attributes, and clauses of the composition and reading strings.

BOOL ImmSetCompositionString(
  HIMC hIMC,
  DWORD dwIndex,
  LPCVOID lpComp,
  DWORD dwCompLen,
  LPCVOID lpRead,
  DWORD dwReadLen
);

Parameters

hIMC
Handle to the input context.
dwIndex
Type of information to set. This parameter can be one of one of the following values:
Value | Meaning
SCS_SETSTR | Sets the composition string, the reading string, or both. At least one of the lpComp and lpRead parameters must point to a valid string. If either string is too long, the IME truncates it.
SCS_CHANGEATTR | Sets attributes for the composition string, the reading string, or both. At least one of the lpComp and lpRead parameters must point to a valid attribute array.
SCS_CHANGECLAUSE | Sets the clause information for the composition string, the reading string, or both. At least one of the lpComp and lpRead parameters must point to a valid clause information array.

lpComp
Pointer to the buffer containing the information to set for the composition string. The information is as specified by the dwIndex value.
dwCompLen
Size in bytes of the information buffer for the composition string.
lpRead
Pointer to the buffer containing the information to set for the reading string. The information is as specified by the dwIndex value.
dwReadLen
Size, in bytes, of the information buffer for the reading string.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

Remarks

When changing attributes, all characters in a clause must have the same attribute. Converted characters must be either ATTR_CONVERTED or ATTR_TARGET_CONVERTED; unconverted characters either ATTR_INPUT or ATTR_TARGET_NOTCONVERTED.

When changing clause information, only the target clause can be changed and only one boundary of the clause can be changed at a time. The target clause has the ATTR_TARGET_CONVERTED or ATTR_TARGET_NOTCONVERTED attribute.

When the IME completes the changes, it sends a WM_IME_COMPOSITION message to the application notifying it of the changes.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions, WM_IME_COMPOSITION


ImmSetCompositionWindow

The ImmSetCompositionWindow function sets the position of the composition window.

BOOL ImmSetCompositionWindow(
  HIMC hIMC,
  LPCOMPOSITIONFORM lpCompForm
);

Parameters

hIMC
Handle to the input context.
lpCompForm
Pointer to the COMPOSITIONFORM structure that contains the new position and other related information about the composition window.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

Remarks

The ImmSetCompositionWindow function causes a IMN_SETSCOMPOSITIONWINDOW message to be sent to the application.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions, COMPOSITIONFORM


ImmSetConversionStatus

The ImmSetConversionStatus function sets the current conversion status.

BOOL ImmSetConversionStatus(
  HIMC hIMC,
  DWORD fdwConversion,
  DWORD fdwSentence
);

Parameters

hIMC
Handle to the input context.
fdwConvStatus
Conversion mode values. For more information, see the "IME Conversion Mode Values" table in Input Method Editor Constants.
fdwSentence
Sentence mode values. For more information, see the "IME Sentence Mode Values" table in Input Method Editor Constants.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

Remarks

This function sends a IMN_SETCONVERSIONSTATUS message to the application.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmSetOpenStatus

The ImmSetOpenStatus function opens or closes the IME.

BOOL ImmSetOpenStatus(
  HIMC hIMC,
  BOOL fOpen
);

Parameters

hIMC
Handle to the input context.
fOpen
Open flag. If TRUE, the IME is opened; otherwise, it is closed.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

Remarks

This function causes a IMN_SETOPENSTATUS message to be sent to the application.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions, IMN_SETOPENSTATUS


ImmSetStatusWindowPos

The ImmSetStatusWindowPos function sets the position of the status window.

BOOL ImmSetStatusWindowPos(
  HIMC hIMC,
  LPPOINT lpptPos
);

Parameters

hIMC
Handle to the input context.
lpptPos
Pointer to the POINT structure that receives the new position of the status window.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

Remarks

The ImmSetStatusWindowPos function causes a IMN_SETSTATUSWINDOWPOS message to be sent to the application.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions, IMN_SETSTATUSWINDOWPOS, POINT


ImmSimulateHotKey

The ImmSimulateHotKey function simulates the specified IME hot key, causing the same response as if the user had pressed the hot key in the specified window.

BOOL ImmSimulateHotKey(
  HWND hWnd,
  DWORD dwHotKeyID
);

Parameters

hWnd
Handle to the window.
dwHotKeyID
Identifier of the IME hot key. This parameter can be one of the values specified in the "IME Hot Key Identifiers" table in Input Method Editor Constants.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

Remarks

Windows CE: Windows CE supports the following value for the dwHotKeyID parameter:

IME_JHOTKEY_CLOSE_OPEN
(Japanese) Alternately opens and closes the IME.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later (FE).
Header: Declared in imm.h.
Import Library: Use imm32.lib.

See Also

Input Method Editor Overview, Input Method Editor Functions


ImmUnregisterWord

The ImmUnregisterWord function removes a register string from the dictionary of the IME associated with the specified keyboard layout.

BOOL ImmUnregisterWord(
  HKL hKL,
  LPCTSTR lpszReading,
  DWORD dwStyle,
  LPCTSTR lpszUnregister
);

Parameters

hKL
Handle to the keyboard layout.
lpszReading
Pointer to a null-terminated string specifying the reading string associated with the string to remove.
dwStyle
Style of the register string. This parameter can be IME_REGWORD_STYLE_EUDC to indicate the string is in the EUDC range, or any value in the reserved range IME_REGWORD_STYLE_USER_FIRST to IME_REGWORD_STYLE_USER_LAST to indicate a private style maintained by the specified IME.
lpszUnregister
Pointer to a null-terminated string specifying the register string to remove.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Import Library: Use imm32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Input Method Editor Overview, Input Method Editor Functions


Input Method Editor Messages

This section describes the input method editor messages.

IMC_CLOSESTATUSWINDOW
IMC_GETCANDIDATEPOS
IMC_GETCOMPOSITIONFONT
IMC_GETCOMPOSITIONWINDOW
IMC_GETCONVERSIONMODE
IMC_GETOPENSTATUS
IMC_GETSENTENCEMODE
IMC_GETSTATUSWINDOWPOS
IMC_OPENSTATUSWINDOW
IMC_SETCANDIDATEPOS
IMC_SETCOMPOSITIONFONT
IMC_SETCOMPOSITIONWINDOW
IMC_SETCONVERSIONMODE
IMC_SETOPENSTATUS
IMC_SETSENTENCEMODE
IMC_SETSTATUSWINDOWPOS
IMN_CHANGECANDIDATE
IMN_CLOSECANDIDATE
IMN_CLOSESTATUSWINDOW
IMN_GUIDELINE
IMN_OPENCANDIDATE
IMN_OPENSTATUSWINDOW
IMN_SETCANDIDATEPOS
IMN_SETCOMPOSITIONFONT
IMN_SETCOMPOSITIONWINDOW
IMN_SETCONVERSIONMODE
IMN_SETOPENSTATUS
IMN_SETSENTENCEMODE
IMN_SETSTATUSWINDOWPOS
IMR_CANDIDATEFORM
IMR_COMPOSITIONFONT
IMR_COMPOSITIONFORM
IMR_CONFIRMRECONVERTSTRING
IMR_RECONVERTSTRING
WM_IME_CHAR
WM_IME_COMPOSITION
WM_IME_COMPOSITIONFULL
WM_IME_CONTROL
WM_IME_ENDCOMPOSITION
WM_IME_KEYDOWN
WM_IME_KEYUP
WM_IME_NOTIFY
WM_IME_REQUEST
WM_IME_SELECT
WM_IME_SETCONTEXT
WM_IME_STARTCOMPOSITION

See Also

Input Method Editor Overview, Input Method Editor Functions


IMC_CLOSESTATUSWINDOW

An application sends the IMC_CLOSESTATUSWINDOW message to the IME window to hide the status window.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_CLOSESTATUSWINDOW;
lParam = (LPARAM) 0;

Return Values

Returns zero if successful, nonzero otherwise.

Remarks

When the status window of IME is already hidden, this message does nothing. Although an application may send this message to the IME window, the application does not receive the corresponding IMN_CLOSESTATUSWINDOW message.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages


IMC_GETCANDIDATEPOS

An application sends the IMC_GETCANDIDATEPOS message to an IME window to get the position of the candidate window. Because the IME may adjust the position of a candidate window, an application uses this message to get the actual position to decide whether to reposition the window.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_GETCANDIDATEPOS;
lParam = (LPARAM) &CandForm;

Parameters

lParam
Pointer to the CANDIDATEFORM structure that receives the position of the candidate window.

Return Values

Returns zero if successful, nonzero otherwise.

Remarks

The returned position is in window coordinates relative to the window having the current input focus.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, CANDIDATEFORM


IMC_GETCOMPOSITIONFONT

An application sends the IMC_GETCOMPOSITIONFONT message to an IME window to retrieve the logical font used for displaying intermediate characters in the composition window.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_GETCOMPOSITIONFONT;
lParam = (LPARAM) &LogFont;

Parameters

lParam
Pointer to the LOGFONT structure that receives information about the logical font.

Return Values

Returns zero if successful, nonzero otherwise.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, LOGFONT


IMC_GETCOMPOSITIONWINDOW

An application sends the IMC_GETCOMPOSITIONWINDOW message to an IME window to get the position of the composition window. Because the IME may adjust the position of a composition window, an application uses this message to get the actual position to decide whether to reposition the window.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_GETCOMPOSITIONWINDOW;
lParam = (LPARAM) &CompForm;

Parameters

lParam
Pointer to the COMPOSITIONFORM structure that receives the position of the composition window.

Return Values

Returns zero if successful, nonzero otherwise.

Remarks

The returned position is in window coordinates relative to the window having the current input focus.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, COMPOSITIONFORM


IMC_GETCONVERSIONMODE

An application sends the IMC_GETCONVERSIONMODE message to an IME window to obtain the current conversion mode. The window retrieves the current conversion mode from the current input context.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_GETCONVERSIONMODE;
lParam = 0;

Return Values

Returns a combination of the values specified in the "IME Conversion Modes" table in Input Method Editor Constants.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.

See Also

Input Method Editor Overview, Input Method Editor Messages


IMC_GETOPENSTATUS

An application sends the IMC_GETOPENSTATUS message to an IME window to determine whether the IME is open.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_GETOPENSTATUS;
lParam = 0;

Return Values

Returns nonzero if the current IME is open, zero otherwise.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.

See Also

Input Method Editor Overview, Input Method Editor Messages


IMC_GETSENTENCEMODE

An application sends the IMC_GETSENTENCEMODE message to an IME window to obtain current sentence mode.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_GETSENTENCEMODE;
lParam = 0;

Return Values

Returns a combination of the values specified in the "IME Sentence Modes" table in Input Method Editor Constants.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.

See Also

Input Method Editor Overview, Input Method Editor Messages


IMC_GETSTATUSWINDOWPOS

An application sends the IMC_GETSTATUSWINDOWPOS message to an IME window to get the position of the status window.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_GETSTATUSWINDOWPOS;
lParam = 0;

Return Values

Returns a POINTS structure that contains the x- and y-coordinates of the status window position.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, POINTS


IMC_OPENSTATUSWINDOW

An application sends the IMC_OPENSTATUSWINDOW message to the IME window to show the status window. This message is ignored if the system is not in the show IME status mode. The user can set or clear the show IME status mode from the task bar.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_OPENSTATUSWINDOW;
lParam = (LPARAM) 0;

Return Values

Returns zero if successful, nonzero otherwise.

Remarks

If the status window is already shown, this message does nothing. Although the application may send this message to the IME window, the application does not receive the corresponding IMN_OPENSTATUSWINDOW message.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages


IMC_SETCANDIDATEPOS

An application sends the IMC_SETCANDIDATEPOS message to an IME window to set the position of the candidate window. This message is intended for applications that display composition characters on their own but use the IME window to display candidates.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_SETCANDIDATEPOS;
lParam = (LPARAM) &CandForm;

Parameters

lParam
Pointer to the CANDIDATEFORM structure that contains the x- and y-coordinates for the candidate window. The application should set the dwIndex member in the structure.

Return Values

Return zero if successful, nonzero otherwise.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, CANDIDATEFORM


IMC_SETCOMPOSITIONFONT

An application sends the IMC_SETCOMPOSITIONFONT message to an IME window to specify the logical font to use for displaying intermediate characters in the composition window.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_SETCOMPOSITIONFONT;
lParam = (LPARAM) &LogFont;

Parameters

lParam
Pointer to the LOGFONT structure that contains information about the logical font.

Return Values

Returns zero if successful, nonzero otherwise.

Remarks

When processing this message, the IME window changes the current selected font in the input context.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, LOGFONT


IMC_SETCOMPOSITIONWINDOW

An application sends the IMC_SETCOMPOSITIONWINDOW message to an IME window to set the style of the composition window. The message set this style in the current input context and the style is subsequently applied to each IME window that receives that input context.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_SETCOMPOSITIONWINDOW;
lParam = (LPARAM) &CompForm;

Parameters

lParam
Pointer to the COMPOSITIONFORM structure that contains the style information.

Return Values

Returns zero if successful, nonzero otherwise.

Remarks

By default, the IME window has the CFS_POINT style. This means the IME window uses the current caret position and window client area when it opens composition window.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, COMPOSITIONFORM


IMC_SETCONVERSIONMODE

An application sends the IMC_SETCONVERSIONMODE message to an IME window to set current conversion mode.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_SETCONVERSIONMODE;
lParam = (LPARAM) cMode;

Parameters

lParam
Conversion mode. This parameter can be one of the values specified in the "IME Conversion Modes" table in Input Method Editor Constants.

Return Values

Returns zero if successful, nonzero otherwise.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.

See Also

Input Method Editor Overview, Input Method Editor Messages


IMC_SETOPENSTATUS

An application sends the IMC_SETOPENSTATUS message to an IME window to open or close the current IME.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_SETOPENSTATUS;
lParam = (LPARAM) bOpen;

Parameters

lParam
Open status. If TRUE, the IME is opened, closed otherwise.

Return Values

Returns zero if successful, nonzero otherwise.

Remarks

When processing this message, the IME window changes the current input context.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.

See Also

Input Method Editor Overview, Input Method Editor Messages


IMC_SETSENTENCEMODE

An application sends the IMC_SETSENTENCEMODE message to an IME window to set the current sentence mode.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_SETSENTENCEMODE;
lParam = 0;

Parameters

lParam
Sentence mode. This parameter can be one of the values specified in the "IME Sentence Modes" table in Input Method Editor Constants.

Return Values

Returns zero if successful, nonzero otherwise.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.

See Also

Input Method Editor Overview, Input Method Editor Messages


IMC_SETSTATUSWINDOWPOS

An application sends the IMC_SETSTATUSWINDOWPOS message to an IME window to set the position of the status window.

msg = (UINT) WM_IME_CONTROL;
wParam = (WPARAM) IMC_SETSTATUSWINDOWPOS;
lParam = (LPARAM) &pts;

Parameters

lParam
Pointer to a POINTS structure that contains the x- and y-coordinates of the position of the status window.

Return Values

Returns zero if successful, nonzero otherwise.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, POINTS


IMN_CHANGECANDIDATE

The IMN_CHANGECANDIDATE message is sent to the application when an IME is about to change the content of the candidate window. An application should process this notification message if it displays candidates itself. The application receives this notification message through the WM_IME_NOTIFY message.

fCandidates = (DWORD) lParam;

Parameters

fCandidates
Candidate lists flag. Each bit corresponds to a candidate list: bit 0 to the first list, bit 1 to the second, and so on. If a specified bit is 1, the corresponding candidate window is about to be changed.

Return Values

No return value.

Remarks

The IME window changes the appearance of the candidate window when it processes this message. An application can get information about the system window with the ImmGetCandidateListCount and ImmGetCandidateList functions.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, ImmGetCandidateList, ImmGetCandidateListCount, WM_IME_NOTIFY


IMN_CLOSECANDIDATE

The IMN_CLOSECANDIDATE message is sent to the application when an IME is about to close the candidate window. An application should process this message if it displays candidates itself. The application receives this notification message through the WM_IME_NOTIFY message.

fCandidate = (DWORD) lParam;

Parameters

fCandidates
Candidate lists flag. Each bit corresponds to a candidate list: bit 0 to the first list, bit 1 to the second, and so on. If a specified bit is 1, the corresponding candidate window is about to be closed.

Return Values

No return value.

Remarks

By default, the IME window destroys a candidate window when it processes this message.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, WM_IME_NOTIFY


IMN_CLOSESTATUSWINDOW

The IMN_CLOSESTATUSWINDOW message is sent to the application when an IME is about to close the status window. An application should process this notification message if it displays the status window for the IME. The application receives this notification message through the WM_IME_NOTIFY message.

Return Values

No return value.

Remarks

The IME window closes the status window when it processes this message.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, WM_IME_NOTIFY


IMN_GUIDELINE

The IMN_GUIDELINE message is sent when an IME is about to show an error message or other information. An application processes this message by calling the ImmGetGuideLine function to retrieve the error message or information from the IME. The application receives this notification message through the WM_IME_NOTIFY message.

Return Values

No return value.

Remarks

The IME window displays the error message or information string in an information window.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, ImmGetGuideLine, WM_IME_NOTIFY


IMN_OPENCANDIDATE

The IMN_OPENCANDIDATE message is sent to the application when an IME is about to open the candidate window. An application should process this message if it displays candidates itself. The application can retrieve a list of candidates to display by using the ImmGetCandidateList function. The application receives this notification message through the WM_IME_NOTIFY message.

fCandidate = (DWORD) lParam;

Parameters

fCandidates
Candidate lists flag. Each bit corresponds to a candidate list: bit 0 to the first list, bit 1 to the second, and so on. If a specified bit is 1, the corresponding candidate window is about to be opened.

Return Values

No return value.

Remarks

By default, the IME window creates a candidate window when it processes this message.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, ImmGetCandidateList, WM_IME_NOTIFY


IMN_OPENSTATUSWINDOW

The IMN_OPENSTATUSWINDOW message is sent when an IME is about to create the status window. An application processes this message to display the status window for the IME by itself. The application receives this notification message through the WM_IME_NOTIFY message.

Return Values

No return value.

Remarks

The IME window creates a status window when it processes this message and sets the strings to display in the window into the input context. Applications can get information about the status window by using the ImmGetConversionStatus function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, ImmGetConversionStatus, WM_IME_NOTIFY


IMN_SETCANDIDATEPOS

The IMN_SETCANDIDATEPOS message is sent when the IME is about to move the candidate window. An application should process this message if it displays the candidate window itself. The application receives this notification message through the WM_IME_NOTIFY message.

fCandidates = (DWORD) lParam;

Parameters

fCandidates
Candidate lists flag. Each bit corresponds to a candidate list: bit 0 to the first list, bit 1 to the second, and so on. If a specified bit is 1, the corresponding candidate window is about to be moved.

Return Values

No return value.

Remarks

The IME window moves the candidate window when it processes this message.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, WM_IME_NOTIFY


IMN_SETCOMPOSITIONFONT

The IMN_SETCOMPOSITIONFONT message is sent when the font of the input context is updated. The application receives this notification message through the WM_IME_NOTIFY message.

Return Values

No return value.

Remarks

The application can get information about the font by using the ImmGetCompositionFont function. The IME window subsequently uses the font to draw the composition string.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, ImmGetCompositionFont, WM_IME_NOTIFY


IMN_SETCOMPOSITIONWINDOW

The IMN_SETCOMPOSITIONWINDOW message is sent when the style or position of the composition window is updated. The application receives this notification message through the WM_IME_NOTIFY message.

Return Values

No return value.

Remarks

The application can get information about the composition form by using the IMC_GETCOMPOSITIONWINDOW message.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, IMC_GETCOMPOSITIONWINDOW, WM_IME_NOTIFY


IMN_SETCONVERSIONMODE

The IMN_SETCONVERSIONMODE message is sent when the conversion mode of the input context is updated. The application receives this notification message through the WM_IME_NOTIFY message.

Return Values

No return value.

Remarks

The application can get information about the conversion mode by using the ImmGetConversionStatus function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, ImmGetConversionStatus, WM_IME_NOTIFY


IMN_SETOPENSTATUS

The IMN_SETOPENSTATUS message is sent when the open status of the input context is updated. The application receives this notification message through the WM_IME_NOTIFY message.

Return Values

No return value.

Remarks

The application can get information about the open status by using the ImmGetOpenStatus function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, ImmGetOpenStatus, WM_IME_NOTIFY


IMN_SETSENTENCEMODE

The IMN_SETSENTENCEMODE message is sent when the sentence mode of the input context is updated. The application receives this notification message through the WM_IME_NOTIFY message.

Return Values

No return value.

Remarks

The application can get information about the sentence mode by using the ImmGetConversionStatus function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, ImmGetConversionStatus, WM_IME_NOTIFY


IMN_SETSTATUSWINDOWPOS

The IMN_SETSTATUSWINDOWPOS message is sent when the status window position in the input context is updated. The application receives this notification message through the WM_IME_NOTIFY message.

Return Values

No return value.

Remarks

The application can get information about the status window position by using the IMC_GETSTATUSWINDOWPOS message.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, IMC_GETSTATUSWINDOWPOS, WM_IME_NOTIFY


IMR_CANDIDATEFORM

When a selected IME needs information about the candidate window, the IMR_CANDIDATEFORM message is sent to the application through the WM_IME_REQUEST message.

lParam = (LPARAM) lpCANDIDATEFORM;

Parameters

lpCANDIDATEFORM
Pointer to a buffer containing a CANDIDATEFORM structure. Its dwIndex member contains the index to the candidate window referenced.

Return Values

Returns a nonzero value if the application filled in the CANDIDATEFORM structure in lParam. Otherwise, returns zero.

Remarks

This notification may be sent by the IME to a window that cleared the ISC_SHOWUICANDIDATEWINDOW flag in the WM_SETCONTEXT message handler.

See Also

Input Method Editor Overview, Input Method Editor Messages, WM_IME_REQUEST


IMR_COMPOSITIONFONT

When a selected IME needs information about the font used by the composition window, the IMR_COMPOSITIONFONT message is sent to the application through the WM_IME_REQUEST message.

lParam= (LPARAM) lpLOGFONT;

Parameters

lpLOGFONT
Pointer to a buffer containing a LOGFONT structure. The application fills in the values for the current composition window.

Return Values

Returns a nonzero value if the application filled in the LOGFONT structure specified by lParam. Otherwise, returns zero.

Remarks

This notification may be sent by the IME to a window that cleared the ISC_SHOWUICOMPOSITIONWINDOW flag in the WM_SETCONTEXT message handler.

See Also

Input Method Editor Overview, Input Method Editor Messages, WM_IME_REQUEST


IMR_COMPOSITIONFORM

When a selected IME needs information about the composition window, the IMR_COMPOSITIONFORM message is sent to the application through the WM_IME_REQUEST message.

lParam =-(LPARAM) lpCOMPOSITIONFORM;

Parameters

lpCOMPOSITIONFORM
Pointer to a buffer containing a COMPOSITIONFORM structure.

Return Values

Returns a nonzero value if the application filled in the COMPOSITIONFORM structure in lParam. Otherwise, returns zero.

Remarks

This notification may be sent by the IME to a window that cleared the ISC_SHOWUICOMPOSITIONWINDOW flag in the WM_SETCONTEXT message handler.

See Also

Input Method Editor Overview, Input Method Editor Messages, WM_IME_REQUEST


IMR_CONFIRMRECONVERTSTRING

When the IME needs to change the RECONVERTSTRING structure (previously filled in by the application upon receiving the IMR_RECONVERTSTRING message), the application receives the IMR_CONFIRMRECONVERTSTRING message through the WM_IME_REQUEST message.

lParam = (LPARAM) lpRECONVERTSTRING;

Parameters

lpRECONVERTSTRING
Pointer to a buffer containing the reconversion string.

Return Values

Returns a nonzero value if the application accepts the changed RECONVERTSTRING structure. Otherwise, returns zero and the IME will use the original RECONVERTSTRING.

Remarks

After the application has handled IMR_RECONVERTSTRING, the IME may or may not adjust the RECONVERTSTRING structure that is specified by the application. The IME sends WM_IME_REQUEST with IMR_CONFIRMRECONVERTSTRING to confirm the changes to the RECONVERTSTRING. If the application returns true for IMR_CONFIRMRECONVERTSTRING, the IME will generate a new composition string based on the RECONVERSTRING structure in the IMR_CONFIRMRECONVERTSTRING message. If the application returns false for IMR_CONFIRMRECONVERTSTRING, the IME will generate a new composition string based on the original RECONVERTSTRING structure that was specified by the application in the IMR_RECONVERTSTRING message.

See Also

Input Method Editor Overview, Input Method Editor Messages, IMR_RECONVERTSTRING, RECONVERTSTRING, WM_IME_REQUEST


IMR_RECONVERTSTRING

When a selected IME needs a string for re-conversion, this message is sent to the application through the WM_IME_REQUEST message.

lParam = (LPARAM) lpRECONVERTSTRING;

Parameters

lpRECONVERTSTRING
Pointer to a buffer containing the RECONVERTSTRING structure and strings.

Return Values

Returns the required size of the RECONVERTSTRING if the application filled the RECONVERTSTRING structure in lParam. Otherwise, returns zero. However, if lParam is NULL, the application must return the required size of the RECONVERTSTRING.

See Also

Input Method Editor Overview, Input Method Editor Messages, RECONVERTSTRING, WM_IME_REQUEST


WM_IME_CHAR

The WM_IME_CHAR message is sent to an application when the IME gets a character of the conversion result. Unlike the WM_CHAR message, this message can include double-byte as well as single-byte character values.

// for double-byte characters:
chCharCode1 = (char) wParam & 0xff;
chCharCode2 = (char) wParam >> 8;
// for Unicode:
chCharCode1 = (WORD) wParam;
lKeyData = lParam;

Parameters

chCharCode1 and chCharCode2
(For double-byte character sets) Single- or double-byte character value. For a double-byte character, chCharCode1 contains the lead byte.
chCharCode1
(For Unicode) Unicode character value.
lKeyData
Repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown following:
Bit | Meaning
0 - 15 | Repeat count: Since the first byte and second byte is continuous, this is always 1.
16 - 23 | Scan Code: Scan code for a complete FE character.
24 - 28 | Not used.
29 | Context code.
31 | Conversion state.

Remarks

If the WM_IME_CHAR message includes a double-byte character and the application passes this message to DefWindowProc, the IME converts this message into two WM_CHAR messages, each containing one byte of the double-byte character.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, DefWindowProc, WM_CHAR


WM_IME_COMPOSITION

The WM_IME_COMPOSITION message is sent to an application when the IME changes composition status as a result of a key stroke. An application should process this message if it displays composition characters itself. Otherwise, it should send the message to the IME window.

chDBCS = (WORD) wParam;
fFlags = (BOOL) lParam;

Parameters

chDBCS
DBCS character representing the latest change to the composition string.
fFlags
Change flag, indicating how the composition string or character changed. This parameter can be one or more of the following values:
GCS_COMPSTR | GCS_SETCURSORPOS
GCS_COMPATTR | GCS_RESULTSTR
GCS_COMPCLAUSE | GCS_RESULTCLAUSE
GCS_COMPREADSTR | GCS_RESULTREADSTR
GCS_COMPREADATTR | GCS_RESULTREADCLAUSE
GCS_COMPREADCLAUSE | GCR_ERRORSTR
GCS_TYPINGINFO | GCR_INFOSTR

Return Values

No return value.

Remarks

For more information about these values, see the "IME Composition String Values" table in Input Method Editor Constants.

The fFlags parameter can also be a combination of the following values:

Value | Meaning
CS_INSERTCHAR | Specifies that the given composition character should be inserted at the current insertion point. An application should display the composition character if it processes this message.
CS_NOMOVECARET | Specifies that the application must not move the caret position as a result of processing the message. For example, if an IME specifies a combination of CS_INSERTCHAR and CS_NOMOVECARET, the application should insert the given character at the current caret position but should not move caret to the next position. A subsequent WM_IME_COMPOSITION message with GCS_RESULTSTR will replace this character.

If the application has created an IME window, it should pass this message to that window. The DefWindowProc function processes this message by passing it to the default IME window.The IME window processes this message by updating its appearance based on the change flag given. An application can call ImmGetCompositionString to retrieve the new composition status.

If none of the GCS_ values are set, the message indicates that the current composition has been canceled and applications that draw the composition string should delete the string.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, DefWindowProc, ImmGetCompositionString


WM_IME_COMPOSITIONFULL

The WM_IME_COMPOSITIONFULL message is sent to an application when the IME window finds no space to extend the area for the composition window. The application should use the IMC_SETCOMPOSITIONWINDOW message to specify how to display the window.

Return Values

No return value.

Remarks

The wParam and lParam parameters are not used. The IME window, not the IME, sends this notification message by using the SendMessage message.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, IMC_SETCOMPOSITIONWINDOW, SendMessage


WM_IME_CONTROL

The WM_IME_CONTROL message directs the IME window to carry out the requested command. An application uses this message to control the IME window created by the application.

wParam = (WPARAM) (DWORD) dwCommand;
lParam = (LPARAM) (DWORD) dwData;

Parameters

dwCommand
Command value. This parameter can be one of the following values:
IMC_GETCANDIDATEPOS IMC_OPENSTATUSWINDOW
IMC_GETCOMPOSITIONFONT IMC_SETCANDIDATEPOS
IMC_GETCOMPOSITIONWINDOW IMC_SETCOMPOSITIONFONT
IMC_GETCONVERSIONMODE IMC_SETCOMPOSITIONWINDOW
IMC_GETOPENSTATUS IMC_SETCONVERSIONMODE
IMC_GETSENTENCEMODE IMC_SETOPENSTATUS
IMC_GETSTATUSWINDOWPOS IMC_SETSENTENCEMODE
IMC_CLOSESTATUSWINDOW IMC_SETSTATUSWINDOWPOS

For more information about these commands, see the individual descriptions.

dwData
Command-specific value.

Return Values

Returns a command-specific value.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, IMC_CLOSESTATUSWINDOW, IMC_GETCANDIDATEPOS, IMC_GETCOMPOSITIONFONT, IMC_GETCOMPOSITIONWINDOW, IMC_GETCONVERSIONMODE, IMC_GETOPENSTATUS, IMC_GETSENTENCEMODE, IMC_GETSTATUSWINDOWPOS, IMC_OPENSTATUSWINDOW, IMC_SETCANDIDATEPOS, IMC_SETCOMPOSITIONFONT, IMC_SETCOMPOSITIONWINDOW, IMC_SETCONVERSIONMODE, IMC_SETOPENSTATUS, IMC_SETSENTENCEMODE, IMC_SETSTATUSWINDOWPOS


WM_IME_ENDCOMPOSITION

The WM_IME_ENDCOMPOSITION message is sent to an application when the IME ends composition. An application should process this message if it displays composition characters itself.

Return Values

No return value.

Remarks

The wParam and lParam parameters are not used.

If an application has created an IME window, it should pass this message to that window. The DefWindowProc function processes this message by passing it to default IME window.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, DefWindowProc


WM_IME_KEYDOWN

The WM_IME_KEYDOWN message is sent to an application by the IME to notify the application of a key press. The parameters and return value for this message are identical to the WM_KEYDOWN message. An application can process this message or pass it to the DefWindowProc function to generate a matching WM_KEYDOWN message. This message is usually generated by the IME to keep message order.

nVirtKey = (int) wParam;    // virtual-key code
lKeyData = lParam;          // key data

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, DefWindowProc


WM_IME_KEYUP

The WM_IME_KEYUP message is sent to an application by the IME to notify the application of a key release. The parameters and return value for this message are identical to the WM_KEYUP message. An application can process this message or pass it to the DefWindowProc function to generate a matching WM_KEYUP message. This message is usually generated by the IME to keep message order.

nVirtKey = (int) wParam;    // virtual-key code
lKeyData = lParam;          // key data

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, DefWindowProc


WM_IME_NOTIFY

The WM_IME_NOTIFY message is sent to an application to notify it of changes to the IME window. An application processes this message if it is responsible for managing the IME window.

dwCommand = (DWORD) wParam;
dwData = (DWORD) lParam;

Parameters

dwCommand
Command value. This parameter may be one of the following values:
IMN_CHANGECANDIDATE IMN_SETCANDIDATEPOS
IMN_CLOSECANDIDATE IMN_SETCOMPOSITIONFONT
IMN_CLOSESTATUSWINDOW IMN_SETCOMPOSITIONWINDOW
IMN_GUIDELINE IMN_SETCONVERSIONMODE
IMN_OPENCANDIDATE IMN_SETOPENSTATUS
IMN_OPENSTATUSWINDOW IMN_SETSENTENCEMODE
IMN_PRIVATE IMN_SETSTATUSWINDOWPOS

For more information about these commands, see the corresponding descriptions.

dwData
Command-specific value.

Return Values

Returns a command-specific value.

IMN_CHANGECANDIDATE, IMN_OPENCANDIDATE, IMN_OPENSTATUSWINDOW, IMN_SETCANDIDATEPOS, IMN_SETCOMPOSITIONFONT, IMN_SETCOMPOSITIONWINDOW, IMN_SETCONVERSIONMODE, IMN_SETOPENSTATUS, IMN_SETSENTENCEMODE, IMN_SETSTATUSWINDOWPOS

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages


WM_IME_REQUEST

The WM_IME_REQUEST message requests information about the state of the IME.

dwRequest = (WPARAM) (DWORD)wParam;
dwDate = (LPARAM) (DWORD) lParam;

Parameters

dwRequst
Request value. This parameter can be one of the following values.
IMR_CANDIDATEFORM IMR_COMPOSITIONFONT
IMR_COMPOSITIONFORM IMR_CONFIRMRECONVERTSTRING
IMR_RECONVERTSTRING

See each value for more information.

dwData
Request-specific data. See the description for each request value for more information.

Return Values

Returns a request-specific value. See the description for each request value for more information.

See Also

Input Method Editor Overview, Input Method Editor Messages, Input Method Editor Messages


WM_IME_SELECT

The WM_IME_SELECT message is sent to an application when the system is about to change the current IME. An application that has created an IME window should pass this message to that window so that it can retrieve the keyboard layout handle for the newly selected IME.

fSeleft = (BOOL) wParam;
hKL = (HANDLE) lParam;

Parameters

fSelect
Selection flag. If TRUE, the specified IME is selected; if FALSE, the specified IME is no longer selected.
hKL
Handle to the keyboard layout associated with the IME.

Return Values

No return value.

Remarks

The DefWindowProc function processes this message by passing the information to the default IME window.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, DefWindowProc


WM_IME_SETCONTEXT

The WM_IME_SETCONTEXT message is sent to an application when a window of the application is activated. If the application has created an IME window, it should call the ImmIsUIMessage function. Otherwise, it should pass this message to the DefWindowProc function.

fSet = (BOOL) wParam;
iShow = (DWORD) lParam;

Parameters

fSet
Active flag. If TRUE, the input context is active. If FALSE, the context is inactive.
iShow
Show flags. This parameter can be a combination of the following values.
Value | Description
ISC_SHOWUICOMPOSITIONWINDOW | Shows the composition window by UI window.
ISC_SHOWUIGUIDWINDOW | Shows the guide window by UI window
ISC_SHOWUISOFTKBD | Shows the soft keyboard by UI window
ISC_SHOWUICANDIDATEWINDOW | Shows the candidate window of Index 0 by UI window.
ISC_SHOWUICANDIDATEWINDOW << 1 | Shows the candidate window of Index 1 by UI window.
ISC_SHOWUICANDIDATEWINDOW << 2 | Shows the candidate window of Index 2 by UI window.
ISC_SHOWUICANDIDATEWINDOW << 3 | Shows the candidate window of Index 3 by UI window.

If the application draws the composition window, the default IME window does not need to show its composition window. In this case, the application must clear the ISC_SHOWUICOMPOSITIONWINDOW value from the lParam parameter before passing the message to the DefWindowProc or ImmIsUIMessage functions.

Return Values

Returns the value returned by DefWindowProc or ImmIsUIMessage.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, DefWindowProc, ImmIsUIMessage


WM_IME_STARTCOMPOSITION

The WM_IME_STARTCOMPOSITION message is sent immediately before the IME generates composition string as a result of a key stroke. The message is a notification to an IME window to open its composition window. An application should process this message if it displays composition characters itself.

Return Values

No return value.

Remarks

The wParam and lParam parameters are not used.

If an application has created an IME window, it should pass the WM_IME_STARTCOMPOSITION message to that window. The DefWindowProc function processes this message by passing it to the default IME window.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Messages, DefWindowProc


Input Method Editor Structures

This section describes the structures used with input method editor functions and messages.

CANDIDATEFORM
CANDIDATELIST
COMPOSITIONFORM
IMEMENUITEMINFO
RECONVERTSTRING
REGISTERWORD
STYLEBUF


CANDIDATEFORM

The CANDIDATEFORM structure contains position information for the candidate window.

typedef _tagCANDIDATEFORM {
    DWORD  dwIndex;
    DWORD  dwStyle;
    POINT  ptCurrentPos;
    RECT   rcArea;
} CANDIDATEFORM;

Members

dwIndex
Candidate list identifier. Can be 0 for the first list, 1 for the second, and so on. The maximum index is 31.
dwStyle
Position style. This member can be one of the following values:
CFS_CANDIDATEPOS | Display the upper-left corner of the candidate list window at the position given by ptCurrentPos. The coordinates are relative to the upper-left corner of the window containing the list window, and are subject to adjustment by the system.
CFS_EXCLUDE | Exclude the candidate window from the area given by rcArea. The ptCurrentPos member specifies the coordinates of the current point of interest, typically the caret position.

ptCurrentPos
Coordinates of the upper-left corner of the candidate window or the caret position, depending on the value of dwStyle.
rcArea
Coordinates of the upper-left and lower-right corners of the exclusion area.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Structures


CANDIDATELIST

The CANDIDATELIST structure contains information about a candidate list.

typedef struct _tagCANDIDATELIST {
    DWORD  dwSize;
    DWORD  dwStyle;
    DWORD  dwCount;
    DWORD  dwSelection;
    DWORD  dwPageStart;
    DWORD  dwPageSize;
    DWORD  dwOffset[];
} CANDIDATELIST;

Members

dwSize
Size, in bytes, of the structure, the offset array, and all candidate strings.
dwStyle
Candidate style values. This member can be one or more of the following values:
Value | Meaning
IME_CAND_UNKNOWN | Candidates are in a style other than listed here.
IME_CAND_READ | Candidates are in same reading.
IME_CAND_CODE | Candidates are in a code range.
IME_CAND_MEANING | Candidates are in same meaning.
IME_CAND_RADICAL | Candidates use same radical character.
IME_CAND_STROKES | Candidates are in same number of strokes.

For the IME_CAND_CODE style, the candidate list has a special structure depending on the value of the dwCount member. If dwCount is 1, the dwOffset member contains a single DBCS character rather than an offset, and no candidate string is provided. If the dwCount member is greater than 1, the dwOffset member contains valid offsets, and the candidate strings are text representations of individual DBCS character values in hexadecimal notation.

dwCount
Number of candidate strings.
dwSelection
Index of the selected candidate string.
dwPageStart
Index of the first candidate string in the candidate window. This varies as the user presses the PAGE UP and PAGE DOWN keys.
dwPageSize
Number of candidate strings to be shown in one page in the candidate window. The user can move to the next page by pressing IME-defined keys, such as the page up or page down key. If this number is zero, an application can define a proper value by itself.
dwOffset
Offset to the start of the first candidate string, relative to the start of this structure. The offsets for subsequent strings immediately follow this member, forming an array of 32-bit offsets.

Remarks

The candidate strings immediately follow the last offset in the dwOffset array.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Structures


COMPOSITIONFORM

The COMPOSITIONFORM structure contains position information for a composition window.

typedef _tagCOMPOSITIONFORM {
    DWORD  dwStyle;
    POINT  ptCurrentPos;
    RECT   rcArea;
} COMPOSITIONFORM;

Members

dwStyle
Position style. This member can be one of the following values:
Value | Meaning
CFS_DEFAULT | Move the composition window to the default position. The IME window can display the composition window outside the client area, such as in a floating window.
CFS_FORCE_POSITION | Display the upper-left corner of the composition window at exactly the position given by ptCurrentPos. The coordinates are relative to the upper-left corner of the window containing the composition window and are not subject to adjustment by the IME.
CFS_POINT | Display the upper-left corner of the composition window at the position given by ptCurrentPos. The coordinates are relative to the upper-left corner of the window containing the composition window and are subject to adjustment by the IME.
CFS_RECT | Display the composition window at the position given by rcArea. The coordinates are relative to the upper-left of the window containing the composition window.

ptCurrentPos
Coordinates of the upper-left corner of the composition window.
rcArea
Coordinates of the upper-left and lower-right corners of the composition window.

Remarks

Some IME windows adjust the composition window position specified by the system or the application. The CFS_FORCE_POSITION directs the IME window to skip this adjustment.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Structures


IMEMENUITEMINFO

[This is preliminary documentation and subject to change.]

The IMEMENUITEMINFO structure contains information about IME menu items.

typedef struct tagIMEMENUITEMINFO {
    UINT        cbSize;
    UINT        fType;
    UINT        fState;
    UINT        wID;
    HBITMAP     hbmpChecked;
    HBITMAP     hbmpUnchecked;
    DWORD       dwItemData;
    WCHAR       szString[IMEMENUITEM_STRING_SIZE];
    HBITMAP     hbmpItem;
} IMEMENUITEMINFO, *PIMEMENUITEMINFO, NEAR *NPIMEMENUITEMINFO, FAR *LPIMEMENUITEMINFO

Members

cbSize
Size of the structure in bytes.
fType
Menu item type. This member can be one of the following values.
Value | Meaning
IMFT_RADIOCCHECK | Displays checked menu items using a radio-button mark instead of a check mark if the hbmpChecked member is NULL.
IMFT_SEPARATOR | Specifies that the menu item is a separator. A menu item separator appears as a horizontal dividing line. The hbmpItem and szString members are ignored in this case.
IMFT_SUBMENU | Specifies that the menu item is a submenu.

fState
Menu item state. This member can have one or more of the following values.
Value | Meaning
IMFS_CHECKED | The menu item is checked. For more information, see the description of the hbmpChecked member.
IMFS_DEFAULT | The menu item is the default. A menu can contain only one default menu item, which is displayed in bold.
IMFS_DISABLED | The menu item is disabled but not shaded. It can still be selected.
IMFS_ENABLED | The menu item is enabled. This is the default state.
IMFS_GRAYED | The menu item is disabled and shaded so it cannot be selected.
IMFS_HILITE | The menu item is highlighted.
IMFS_UNCHECKED | The menu item is unchecked. For more information about unchecked menu items, see the description of the hbmpUnchecked member.
IMFS_UNHILITE | The menu item is not highlighted. This is the default state.

wID
Application-defined 16-bit value that identifies the menu item.
hbmpChecked
Handle to the bitmap to display next to the item if it is checked. If this member is NULL, a default bitmap is used. If the IMFT_RADIOCHECK type value is specified, the default bitmap is a bullet. Otherwise, it is a check mark.
hbmpUnchecked
Handle to the bitmap to display next to the item if it is not checked. If this member is NULL, no bitmap is used.
dwItemData
Application-defined value associated with the menu item.
szString
Content of the menu item. This is a null-terminated string.
hbmpItem
Handle to a bitmap to display.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in imm.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Input Method Editor Overview, Input Method Editor Structures, ImmGetImeMenuItems


RECONVERTSTRING

[This is preliminary documentation and subject to change.]

The RECONVERTSTRING structure defines the strings for IME reconversion. It is the first item in a memory block that contains the strings for reconversion.

typedef struct tagRECONVERTSTRING {
    DWORD dwSize;
    DWORD dwVersion;
    DWORD dwStrLen;
    DWORD dwStrOffset;
    DWORD dwCompStrLen;
    DWORD dwCompStrOffset;
    DWORD dwTargetStrLen;
    DWORD dwTargetStrOffset;
} RECONVERTSTRING, *PRECONVERTSTRING, NEAR *NPRECONVERTSTRING, FAR *LPRECONVERTSTRING;

Members

dwSize
Specifies the size of this structure and the memory block it heads.
dwVersion
Specifies the version number. Must be zero.
dwStrLen
Specifies the length of the string that contains the composition string.
dwStrOffset
Specifies the offset from the start position of this structure.
dwCompStrLen
Specifies the length of the string that will be the composition string.
dwCompStrOffset
Specifies the offset of the string that will be the composition string.
dwTargetStrLen
Specifies the length of the string that is related to the target clause in the composition string.
dwTargetStrOffset
Specifies the offset of the target string.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98.
Windows CE: Unsupported.
Header: Declared in imm.h.

See Also

Input Method Editor Overview, Input Method Editor Structures, IMR_CONFIRMRECONVERTSTRING, IMR_RECONVERTSTRING


REGISTERWORD

The REGISTERWORD structure contains reading information or a word to register. You can pass this structure to the ImmConfigureIME function to have the information or word appear as an initial value in the configuration dialog box of the input method editor.

typedef struct tagREGISTERWORD {
    LPTSTR  lpReading;
    LPTSTR  lpWord;
} REGISTERWORD;

Members

lpReading
Pointer to the reading information for the word to register. If the reading information is not needed, it can be NULL.
lpWord
Pointer to the word to register. If a word is not needed, it can be NULL.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Input Method Editor Overview, Input Method Editor Structures, ImmConfigureIME


STYLEBUF

The STYLEBUF structure contains the identifier and name of a style.

typedef struct _tagSTYLEBUF {
    DWORD  dwStyle;
    CHAR  szDescription[32];
} STYLEBUF;

Members

dwStyle
Style of the register string. Can be IME_REGWORD_STYLE_EUDC to indicate a string in the EUDC range.
szDescription
Description of the style.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in imm.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Input Method Editor Overview, Input Method Editor Structures


Input Method Editor Constants

The following constants are used by the input method editor functions and messages.

  • IME Conversion Mode Values
  • IME Composition String Values
  • IME Hot Key Identifiers
  • IME Sentence Mode Values
  • IME Escapes


IME Conversion Mode Values

Bit | Meaning
IME_CMODE_CHARCODE | Set to 1 if character code input mode; 0 if not.
IME_CMODE_EUDC | Set to 1 if EUDC conversion mode; 0 if not.
IME_CMODE_FIXED | Set to 1 if fixed conversion mode; 0 if not.
IME_CMODE_FULLSHAPE | Set to 1 if full shape mode; 0 if half shape mode.
IME_CMODE_HANJACONVERT | Set to 1 if HANJA convert mode; 0 if not.
IME_CMODE_KATAKANA | Set to 1 if KATAKANA mode; 0 if HIRAGANA mode.
IME_CMODE_NATIVE | Set to 1 if NATIVE mode; 0 if ALPHANUMERIC mode.
IME_CMODE_NOCONVERSION | Set to 1 to prevent processing of conversions by IME; 0 if not.
IME_CMODE_ROMAN | Set to 1 if ROMAN input mode; 0 if not.
IME_CMODE_SOFTKBD | Set to 1 if Soft Keyboard mode; 0 if not.

All other bits are reserved.


IME Composition String Values

Value | Description
GCR_ERRORSTR | Retrieves or updates the error string.
GCR_INFORMATIONSTR | Retrieves or updates the information string.
GCS_COMPATTR | Retrieves or updates the attribute of the composition string.
GCS_COMPCLAUSE | Retrieves or updates clause information of the composition string.
GCS_COMPREADATTR | Retrieves or updates the attributes of the reading string of the current composition.
GCS_COMPREADCLAUSE | Retrieves or updates the clause information of the reading string of the composition string.
GCS_COMPREADSTR | Retrieves or updates the reading string of the current composition.
GCS_COMPSTR | Retrieves or updates the current composition string.
GCS_CURSORPOS | Retrieves or updates the cursor position in composition string.
GCS_DELTASTART | Retrieves or updates the starting position of any changes in composition string.
GCS_RESULTCLAUSE | Retrieves or updates clause information of the result string.
GCS_RESULTREADCLAUSE | Retrieves or updates clause information of the reading string.
GCS_RESULTREADSTR | Retrieves or updates the reading string.
GCS_RESULTSTR | Retrieves or updates the string of the composition result.
GCS_TYPINGINFO | Retrieves or updates the typing information of reading string. In contrast to reading information, this shows raw key strokes that the end user types.


IME Hot Key Identifiers

IME_CHOTKEY_IME_NONIME_TOGGLE | (Simplified Chinese) Toggles between IME and non-IME operation.
IME_CHOTKEY_SHAPE_TOGGLE | (Simplified Chinese) Toggles the shape conversion mode of IME.
IME_CHOTKEY_SYMBOL_TOGGLE | (Simplified Chinese) Toggles the symbol conversion mode of IME. Symbol mode indicates that the user can input Chinese punctuation and symbols by mapping to the punctuation and symbols on the keyboard.
IME_ITHOTKEY_RECONVERTSTRING | (Traditional Chinese) Triggers re-conversion.
IME_JHOTKEY_CLOSE_OPEN | (Japanese) Alternately opens and closes the IME.
IME_KHOTKEY_ENGLISH | (Korean) Switches to English.
IME_KHOTKEY_SHAPE_TOGGLE | (Korean) Toggles the shape conversion mode of IME.
IME_KHOTKEY_HANJACONVERT | (Korean) Switches to Hanja converision.
IME_THOTKEY_IME_NONIME_TOGGLE | (Traditional Chinese) Toggles between IME and non-IME operation.
IME_THOTKEY_SHAPE_TOGGLE | (Traditional Chinese) Toggles the shape conversion mode of IME.
IME_THOTKEY_SYMBOL_TOGGLE | (Traditional Chinese) Toggles the symbol conversion mode of IME.


IME Sentence Mode Values

Constant | Definition
IME_SMODE_AUTOMATIC | The IME carries out conversion processing in automatic mode.
IME_SMODE_NONE | No information for sentence.
IME_SMODE_PHRASEPREDICT | The IME uses phrase information to predict the next character.
IME_SMODE_PLURALCLAUSE | The IME uses plural clause information to carry out conversion processing.
IME_SMODE_SINGLECONVERT | The IME carries out conversion processing in single character mode.
IME_SMODE_CONVERSATION | The IME uses conversation mode. This is useful for chat applications.

Bits 16 through 31 are reserved for IME use.


IME Escapes

Escape | Description
IME_ESC_GET_EUDC_DICTIONARY | Retrieves the path of the EUDC dictionary file. On input, the lpData parameter must be the pointer to the buffer to receive the path. This buffer must be no less than 80 characters in length. On return, the buffer contains the null-terminated string specifying the full path. For use by the Chinese EUDC editor; do not use in other applications.
IME_ESC_HANJA_MODE | Converts from Hangeul to Hanja. On input, lpData must be the pointer to the buffer that contains the Hangeul character to convert; on output, it receives the converted Hanja as a null-terminated string. For use by the Korean editor; do not use in other applications.
IME_ESC_IME_NAME | Retrieves the name of the IME. On input, the lpData parameter must be the pointer to the buffer to receive the name. This buffer must be no less than 64 characters in length. On return, the buffer contains the null-terminated string specifying the IME name. For use by the Chinese EUDC editor; do not use in other applications.
IME_ESC_MAX_KEY | Returns the maximum number of key stokes for an EUDC character. For use by the Chinese EUDC editor; do not use in other applications.
IME_ESC_QUERY_SUPPORT | Checks for implementation. Returns zero if the escape is not implemented.
IME_ESC_SEQUENCE_TO_INTERNAL | Returns the character code that matches the given sequence code. On input, the lpData parameter is the pointer to a 32-bit variable that contains the sequence code. For use by the Chinese EUDC editor; do not use in other applications. Normally, the Chinese IME will encode its reading character codes into sequence 1 to n.
IME_ESC_SET_EUDC_DICTIONARY | Sets the EUDC dictionary file. On input, the lpData parameter is the pointer to a null-terminated string specifying the full path. For use by the Chinese EUDC editor; do not use in other applications.
IME_ESC_GETHELPFILENAME | Returns the name of the IME's help file. On return the lpData parameter is the full path of the IME's help file. The path should be less than 80 * sizeof(TCHAR).

The system reserves the escapes in the range IME_ESC_RESERVED_FIRST to IME_ESC_RESERVED_LAST for its own use.

The system reserves the escapes in the range IME_ESC_PRIVATE_FIRST to IME_ESC_PRIVATE_LAST for private use by IMEs.


National Language Support

National language support functions help Win32®-based applications support the differing language- and location-specific needs of users around the world.

This overview describes the national language support functions and explains how to use them in your Win32-based applications.


About National Language Support

The national language support functions let applications set the locale for the user, identifying the language in which the user carries out work, and retrieve strings, representing times, dates and other information, that are correctly formatted for the given language and location of the world.

National language support also includes support for keyboard layouts and language-specific fonts. For more information about these topics, see Keyboard Input and Fonts and Text.


Locales

A locale is a collection of language-related, user preference information represented as a list of values. Each system has at least one installed locale and usually has many locales from which the user may choose.

The system assigns a locale to each thread. Initially, the system assigns the system default locale to the thread. This default locale is set by the user when the system is installed or through the Regional Settings applet of the Control Panel. If a thread is run in a process belonging to a user, the system assigns the user default locale to the thread. An application can override either default by using the SetThreadLocale function to explicitly set the locale for a thread.

Each locale has a unique locale identifier (LCID), a 32-bit value that consists of a language identifier and a sort identifier. The LCID is constructed using the MAKELCID macro. The following illustration shows the format of the bits in an LCID.

+-------------+---------+-------------------------+
|   Reserved  | Sort ID |      Language ID        |
+-------------+---------+-------------------------+
31         20 19     16 15                      0   bit

There are predefined locale identifiers: LOCALE_SYSTEM_DEFAULT, which identifies the system default locale, LOCALE_USER_DEFAULT, which identifies the locale of the current user, and LOCALE_NEUTRAL, which identifies the default language-neutral locale. An application can retrieve the current locale identifiers by using the GetSystemDefaultLCID and GetUserDefaultLCID functions.

A language identifier is a standard international numeric abbreviation for a country or geographical region. Each language has a unique language identifier (LANGID), a 16-bit value that consists of a primary language identifier and a secondary language identifier. The LANGID is constructed using the MAKELANGID macro. The following illustration shows the format of the bits in a LANGID.

+-------------------------+-------------------------+
|  Secondary Language ID  |   Primary Language ID   |
+-------------------------+-------------------------+
15                    10  9                         0   bit

There are predefined language identifiers: LANG_SYSTEM_DEFAULT, which identifies the system default language, and LANG_USER_DEFAULT, which identifies the language of the current user. An application can retrieve the current language identifiers by using the GetSystemDefaultLangID and GetUserDefaultLangID functions.

An application can retrieve specific information about any available language or locale. This can be important for handling language- and locale-specific strings. An application can retrieve information about a locale by using the GetLocaleInfo function. Each element of locale information has a unique LCTYPE value that identifies a specific information type. Applications use these values to retrieve the information they need.

All LCTYPE values are mutually-exclusive, so only one type of information can be retrieved at a time. An exception is the LOCALE_NOUSEROVERRIDE which can be used to bypasses user overrides and retrieve the system default values for the requested locale.

Locale information is always stored and manipulated as a null-terminated string. No binary data is allowed; any numeric values must be specified as text. Each type of information has a particular format. Also, several of types are linked together, such that changing one changes the value of the other as well.

Although a given locale identifier may be supported, it is not available for use by an application unless it is also installed.


Time and Date

You can retrieve strings for any given time or date in a format that is appropriate for the current locale by using the GetTimeFormat and GetDateFormat functions.

For GetTimeFormat, the time values in the SYSTEMTIME structure pointed to by lpTime must be valid. The function checks each of the time values to determine that it is within the appropriate range of values. If any of the time values are outside the correct range, the function fails, and sets the last-error to ERROR_INVALID_PARAMETER.

The function ignores the date portions of the SYSTEMTIME structure pointed to by lpTime: wYear, wMonth, wDayOfWeek, and wDay.

If a time marker exists and the TIME_NOTIMEMARKER flag is not set, the function localizes the time marker based on the specified locale identifier. Examples of time markers are "AM" and "PM" for US English, "de." and "du." for Mexican Spanish.

If TIME_NOMINUTESORSECONDS or TIME_NOSECONDS is specified, the function removes the separator(s) preceding the minutes and/or seconds element(s).

If TIME_NOTIMEMARKER is specified, the function removes the separator(s) preceding and following the time marker.

If TIME_FORCE24HOURFORMAT is specified, the function displays any existing time marker, unless the TIME_NOTIMEMARKER flag is also set.

The function does not include milliseconds as part of the formatted time string.

To use the LOCALE_NOUSEROVERRIDE flag, lpFormat must be NULL.

No errors are returned for a bad format string. The function simply forms the best time string that it can. If more than two hour, minute, second, or time marker format pictures are passed in, then the function defaults to two. For example, the only time marker pictures that are valid are L"t" and L"tt" (the 'L' indicates a Unicode (16-bit characters) string). If L"ttt" is passed in, the function assumes L"tt".

For GetDateFormat, the date values in the SYSTEMTIME structure pointed to by lpDate must be valid. The function checks each of the date values: year, month, day, and day of week. If the day of the week is incorrect, the function uses the correct value, and returns no error. If any of the other date values are outside the correct range, the function fails, and sets the last-error to ERROR_INVALID_PARAMETER.

The day name, abbreviated day name, month name, and abbreviated month name are all localized based on the given locale identifier. The function ignores the time portions of the SYSTEMTIME structure pointed to by lpDate: wHour, wMinute, wSecond, and wMilliseconds.

The flag DATE_USE_ALT_CALENDAR will always use the format defined as the default format for that alternate calendar, rather than using any user overrides. The user overrides will only be used in the event that there is no default format for the alternate calendar specified.

The DATE_SHORTDATE and DATE_LONGDATE flag options are mutually exclusive. If neither one is specified and lpFormat is NULL, then DATE_SHORTDATE is the default.

If the lpFormat parameter is not NULL, the dwFlags parameter must be zero. None of the flags make sense when the format string is specified.

No errors are returned for a bad format string. The function simply forms the best date string that it can. For example, the only year pictures that are valid are L"yyyy" and L"yy" (the 'L' indicates a Unicode (16-bit characters) string). If L"y" is passed in, the function assumes L"yy". If L"yyy" is passed in, the function assumes L"yyyy". If more than 4 date (L"dddd") or 4 month (L"MMMM") pictures are passed in, then the function defaults to L"dddd" or L"MMMM".

Any text that should remain in its exact form in the date string should be enclosed within single quotes in the date format picture. The single quote may also be used as an escape character to allow the single quote itself to be displayed in the date string. However, the escape sequence must be enclosed within two single quotes. For example, to display the date as "May '93", the format string would be: L"MMMM ''''yy " The first and last single quotes are the enclosing quotes. The second and third single quotes are the escape sequence to allow the single quote to be displayed before the century.


Date and Calendar

Most locales use the standard Gregorian calendar and a set number of date formats. These "default choices" for date formats are available for display by using the EnumDateFormats function. There are other locales which require special considerations when creating a complete list of format choices. Some of these require text strings to be inserted within the date format string, others require a completely different method of computation of the values. These special requirements are addressed by the addition of new LCTYPE and CALTYPE values.

Each locale identifier has a default calendar type associated with it. A locale identifier can also have an alternate calendar type, which can be set using the LOCALE_IOPTIONALCALENDAR type for this locale.


Localization and the Shell Font

Windows NT is available in localized editions of many different languages, but the U.S. English edition can also be used to run applications written in other languages. This is true even when the base character sets are different, such as when applications are written in the Central and Eastern European languages, or in Greek. These applications require a user interface (UI) with dialog boxes, icons, and applets that provide information in the application's language, which may be different than the language being used in the current Windows NT UI.

To enable the U.S. English Windows NT user interface, as well as characters outside the Windows character set for the US and Western Europe (code page 1252), to display correctly within applications and in system edit controls, Windows NT uses intelligent font switching based on the currently selected locale. This allows currently shipping localized applications to run on the U.S. English version of Windows NT without modifying the application in any way.

An example of the problem being addressed here is that the U.S. English Windows NT shell font is MS Sans Serif but the shell font for Greek Windows 3.1 is MS Sans Serif Greek. These character sets cannot be directly mapped to each other so simply replacing the MS Sans Serif font with the MS Sans Serif Greek font when the locale is set to Greek does not allow existing applications with this kind of difference to run adequately or to display Greek characters in system menus, dialogs and edit controls. To resolve this problem at run time, Microsoft has defined a new font face name, MS Shell Dlg. It is mapped by an entry in the registry to the appropriate shell font for the currently active locale.


MS Shell Dlg

MS Shell Dlg is a mapping mechanism that enables U.S. English Windows NT to support non-code page 1252 locales. It is not a font but only a face name for a nonexistent font. It can be specified in either the Windows NT Setup file during the installation process or when customizing a local system by double-clicking on the Control Panel's International icon. When you double-click on the icon, select the appropriate Country and Language in the International dialog box, and then reboot the system, the appropriate change occurs in the following registry key:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\Current Version\FontSubstitutes

An added benefit of this new means of font mapping in the registry is that you can change the font for the entire shell by simply changing one .inf file entry. For example, localization for Asia is much easier because you can change the .inf file entry, instead of changing every instance of MS Sans Serif in every .rc and .dlg file, and the change is complete without rebuilding any binaries.

Win32-based applications can also take advantage of this feature. It is very helpful when your application contains multiple language resources that cross character-set boundaries. It is also useful when you have an English application in which supporting multiple languages and character sets is important.

Windows 95: You cannot switch Windows character sets, so the role of MS Shell Dlg is more limited. It does, however, facilitate localization in that Windows 95 is equipped with a static entry to replace the standard system font. For example, the system font, MS San Serif, is easily replaced with MS San Serif Greek or another language. This also ensures compatibility with the applets provided with Windows NT.


When MS Shell Dlg Should Not Be Used

MS Shell Dlg is not intended for use when you are working with a static, non-English UI application that you want to run when the user has chosen a locale with a different Windows base character set. This is because the application's UI language may not be supported with the font that is substituted for MS Shell Dlg. For example, if you are using a German localized version of Windows NT and want to install a non-Unicode, Greek application, you can use the Control Panel's Regional Settings applet to change the locale to Greek. This will reset MS Shell Dlg to be a Greek font but this font does not contain all of the glyphs necessary to display German. Therefore, any non-ASCII characters in your German UI will not be displayed properly. To support this scenario, you would have to set MS Shell Dlg to a font that contains both the Western European and the Greek glyphs.


National Language Support Reference

The following elements are used with national language support.

  • National Language Support Functions
  • National Language Support Macros
  • National Language Support Constants


National Language Support Functions

The following functions are used with national language support.

ConvertDefaultLocale
EnumCalendarInfo
EnumCalendarInfoEx
EnumCalendarInfoProc
EnumCalendarInfoProcEx
EnumCodePagesProc
EnumDateFormats
EnumDateFormatsProc
EnumLocalesProc
EnumSystemCodePages
EnumSystemLocales
EnumTimeFormats
EnumTimeFormatsProc
GetACP
GetCPInfo
GetCPInfoEx
GetCurrencyFormat
GetDateFormat
GetLocaleInfo
GetNumberFormat
GetOEMCP
GetSystemDefaultLangID
GetSystemDefaultLCID
GetThreadLocale
GetTimeFormat
GetUserDefaultLangID
GetUserDefaultLCID
IsValidCodePage
IsValidLocale
LCMapString
SetLocaleInfo
SetThreadLocale


ConvertDefaultLocale

The ConvertDefaultLocale function converts a default locale value to an actual locale identifier.

LCID ConvertDefaultLocale(
  LCID Locale   // default locale value to be converted
);

Parameters

Locale
A default locale value that the function converts to a locale identifier (LCID). The following list shows the default locale values:
Value | Description
LOCALE_SYSTEM_DEFAULT | The system's default locale.
LOCALE_USER_DEFAULT | The current user's default locale.
LOCALE_NEUTRAL | The language-neutral default locale.
Any sublanguage-neutral locale | A locale identifier constructed by calling MAKELCID with a primary language identifier, such as LANG_ENGLISH, and the SUBLANG_NEUTRAL secondary language identifier.

Return Values

If the function succeeds, the return value is the appropriate LCID.

If the function fails, the return value is the Locale parameter. The function fails when Locale is not one of the default locale values listed above.

Remarks

A call to ConvertDefaultLocale(LOCALE_SYSTEM_DEFAULT) is equivalent to a call to GetSystemDefaultLCID. A call to ConvertDefaultLocale(LOCALE_USER_DEFAULT) is equivalent to a call to GetUserDefaultLCID.

For more information, see Locales and Language Identifiers.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

National Language Support Overview, National Language Support Functions, GetSystemDefaultLCID, GetUserDefaultLCID


EnumCalendarInfo

The EnumCalendarInfo function enumerates calendar information for a specified locale. The CalType parameter specifies the type of calendar information to enumerate. The function returns the specified calendar information for all applicable calendars for the locale, or for a single requested calendar, depending on the value of the Calendar parameter.

The EnumCalendarInfo function enumerates the calendar information by calling an application-defined callback function. It passes the callback function a pointer to a string buffer containing the requested calendar information. This continues until either the last applicable calendar is found or the callback function returns FALSE.

BOOL EnumCalendarInfo(
  CALINFO_ENUMPROC lpCalInfoEnumProc, // pointer to enumeration callback function
  LCID Locale,                        // locale of interest
  CALID Calendar,                     // calendar whose information is of interest
  CALTYPE CalType                     // type of calendar information of interest
);

Parameters

lpCalInfoEnumProc
Points to an application-defined callback function. For more information, see the EnumCalendarInfoProc callback function.
Locale
Specifies the locale to retrieve calendar information for. This parameter can be a locale identifier created by the MAKELCID macro, or one of the following predefined values:
LOCALE_SYSTEM_DEFAULT | Default system locale.
LOCALE_USER_DEFAULT | Default user locale.
LOCALE_NEUTRAL | Default language-neutral locale.

Calendar
Specifies the calendar for which information is requested. The following values are defined:
Value | Meaning
ENUM_ALL_CALENDARS | Enumerate all applicable calendars for the locale specified by Locale.
CAL_GREGORIAN | Gregorian (localized)
CAL_GREGORIAN_US | Gregorian (English strings always)
CAL_JAPAN | Japanese Emperor Era
CAL_TAIWAN | Taiwan Region Era
CAL_KOREA | Korean Tangun Era
CAL_HIJRI | Hijri (Arabic Lunar)
CAL_THAI | Thai
CAL_HEBREW | Hebrew
CAL_GREGORIAN_ME_FRENCH | Gregorian Middle East French
CAL_GREGORIAN_ARABIC | Gregorian Arabic
CAL_GREGORIAN_XLIT_ENGLISH | Gregorian transliterated English
CAL_GREGORIAN_XLIT_FRENCH | Gregorian transliterated French

CalType
Indicates the type of calendar information to be returned. See the listing of constant values in Calendar Type Information. Note that only one CALTYPE value can be specified per call of this function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_BADDB
ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

National Language Support Overview, National Language Support Functions, EnumCalendarInfoProc, EnumDateFormats


EnumCalendarInfoEx

The EnumCalendarInfoEx function enumerates calendar information for a specified locale. The CalType parameter specifies the type of calendar information to enumerate. The function returns the specified calendar information for all applicable calendars for the locale, or for a single requested calendar, depending on the value of the Calendar parameter.

The EnumCalendarInfoEx function enumerates the calendar information by calling an application-defined callback function. It passes the callback function a pointer to a string buffer containing the requested calendar information and a Calendar ID (CALID). This continues until either the last applicable calendar is found or the callback function returns FALSE.

BOOL EnumCalendarInfo(
  CALINFO_ENUMPROCEX lpCalInfoEnumProcEx,
                   // pointer to enumeration callback function
  LCID Locale,     // locale of interest
  CALID Calendar,  // calendar whose information is of interest
  CALTYPE CalType  // type of calendar information of interest
);

Parameters

lpCalInfoEnumProcEx
Points to an application-defined callback function. For more information, see the EnumCalendarInfoProcEx callback function.
Locale
Specifies the locale for which to retrieve calendar information. This parameter can be a locale identifier created by the MAKELCID macro, or one of the following predefined values:
LOCALE_SYSTEM_DEFAULT | Default system locale.
LOCALE_USER_DEFAULT | Default user locale.
LOCALE_NEUTRAL | Default language-neutral locale.

Calendar
Specifies the calendar for which information is requested. The following values are defined:
Value | Meaning
ENUM_ALL_CALENDARS | Enumerate all applicable calendars for the locale specified by Locale.
CAL_GREGORIAN | Gregorian (localized)
CAL_GREGORIAN_US | Gregorian (English strings always)
CAL_JAPAN | Japanese Emperor Era
CAL_TAIWAN | Taiwan Region Era
CAL_KOREA | Korean Tangun Era
CAL_HIJRI | Hijri (Arabic Lunar)
CAL_THAI | Thai
CAL_HEBREW | Hebrew
CAL_GREGORIAN_ME_FRENCH | Gregorian Middle East French
CAL_GREGORIAN_ARABIC | Gregorian Arabic
CAL_GREGORIAN_XLIT_ENGLISH | Gregorian transliterated English
CAL_GREGORIAN_XLIT_FRENCH | Gregorian transliterated French

CalType
Indicates the type of calendar information to be returned. See the listing of constant values in Calendar Type Information. Note that only one CALTYPE value can be specified per call of this function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_BADDB
ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

National Language Support Overview, National Language Support Functions, EnumCalendarInfoProc, EnumDateFormats


EnumCalendarInfoProc

The EnumCalendarInfoProc function is an application-defined callback function used with the EnumCalendarInfo function. It receives a pointer to a string buffer containing a calendar information string. The CALINFO_ENUMPROC type defines a pointer to this callback function. EnumCalendarInfoProc is a placeholder for the application-defined function name.

BOOL CALLBACK EnumCalendarInfoProc(
  LPTSTR lpCalendarInfoString   // pointer to calendar information string
);

Parameters

lpCalendarInfoString
Pointer to a string buffer containing a null-terminated calendar information string. This string is formatted according to the CALTYPE value passed to EnumCalendarInfo. Note that lpCalendarInfoString should be an LPWSTR for the Unicode (W) version of EnumCalendarInfo, and an LPSTR for the ANSI (A) version of EnumCalendarInfo.

Return Values

To continue enumeration, the callback function should return TRUE.

To stop enumeration, the callback function should return FALSE.

Remarks

An EnumCalendarInfoProc function can carry out any desired task.

An application registers an EnumCalendarInfoProc function by passing its address to the EnumCalendarInfo function.

Windows CE: Windows CE does not support the ANSI version of this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 98 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: User-defined.

See Also

National Language Support Overview, National Language Support Functions, EnumCalendarInfo


EnumCalendarInfoProcEx

The EnumCalendarInfoProcEx function is an application-defined callback function used with the EnumCalendarInfoEx function. It receives a pointer to a string buffer containing a calendar information string and a Calendar ID (CALID). The CALINFO_ENUMPROCEX type defines a pointer to this callback function. EnumCalendarInfoProcEx is a placeholder for the application-defined function name.

BOOL CALLBACK EnumCalendarInfoProc(
  LPTSTR lpCalendarInfoString   // pointer to calendar information string
  CALID Calendar                // ID of the calendar of interest.
);

Parameters

lpCalendarInfoString
Pointer to a string buffer containing a null-terminated calendar information string. This string is formatted according to the CALTYPE value passed to EnumCalendarInfoEx. Note that lpCalendarInfoString should be an LPWSTR for the Unicode (W) version of EnumCalendarInfoEx, and an LPSTR for the ANSI (A) version of EnumCalendarInfoEx.
Calendar
Calendar ID associated with the associated calendar information retrieved.

Return Values

To continue enumeration, the callback function should return TRUE.

To stop enumeration, the callback function should return FALSE.

Remarks

An EnumCalendarInfoProcEx function can carry out any desired task.

An application registers an EnumCalendarInfoProcEx function by passing its address to the EnumCalendarInfoEx function.

See Also

National Language Support Overview, National Language Support Functions, EnumCalendarInfo


EnumCodePagesProc

The EnumCodePagesProc function is an application-defined callback function used with the EnumSystemCodePages function. It receives a pointer to a string buffer containing a code page identifier. The CODEPAGE_ENUMPROC type defines a pointer to this callback function. EnumCodePagesProc is a placeholder for the application-defined function name.

BOOL CALLBACK EnumCodePagesProc(
  LPTSTR lpCodePageString   // pointer to code page identifier string
);

Parameters

lpCodePageString
Pointer to a string buffer containing a null-terminated code page identifier string.

Return Values

To continue enumeration, the callback function should return TRUE.

To stop enumeration, the callback function should return FALSE.

Remarks

An EnumCodePagesProc function can carry out any desired task.

An application registers an EnumCodePagesProc function by passing its address to the EnumSystemCodePages function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winnls.h.
Import Library: User-defined.

See Also

National Language Support Overview, National Language Support Functions, EnumSystemCodePages


EnumDateFormats

The EnumDateFormats function enumerates the long or short date formats that are available for a specified locale, including date formats for any alternate calendars. The value of the dwFlags parameter determines whether the long or short date formats are enumerated. The function enumerates the date formats by passing date format string pointers, one at a time, to the specified application-defined callback function. This continues until the last date format is found or the callback function returns FALSE.

BOOL EnumDateFormats(
  DATEFMT_ENUMPROC lpDateFmtEnumProc, // pointer to enumeration callback function
  LCID Locale,                        // locale whose date formats are of interest
  DWORD dwFlags                       // date formats to enumerate
);

Parameters

lpDateFmtEnumProc
Points to an application-defined callback function. The EnumDateFormats function enumerates date formats by making repeated calls to this callback function. For more information, see the EnumDateFormatsProc callback function.
Locale
Specifies the locale to retrieve date format information for. This parameter can be a locale identifier created by the MAKELCID macro, or one of the following predefined values:
LOCALE_SYSTEM_DEFAULT | Default system locale.
LOCALE_USER_DEFAULT | Default user locale.
LOCALE_NEUTRAL | Default language-neutral locale.

dwFlags
Specifies the date formats that are of interest. Use one of the following values:
Value | Meaning
DATE_SHORTDATE | Return short date formats.
DATE_LONGDATE | Return long date formats.
DATE_YEARMONTH | Return year/month formats.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INVALID_PARAMETER
ERROR_BADDB
ERROR_INVALID FLAGS

Remarks

The DATE_SHORTDATE and DATE_LONGDATE flags are mutually exclusive. Use one or the other, but not both.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

National Language Support Overview, National Language Support Functions, EnumDateFormatsProc, EnumCalendarInfo, EnumTimeFormats


EnumDateFormatsProc

The EnumDateFormatsProc function is an application-defined callback function used with the EnumDateFormats function. It receives a pointer to a string buffer containing a date format string. The DATEFMT_ENUMPROC type defines a pointer to this callback function. EnumDateFormatsProc is a placeholder for the application-defined function name.

BOOL CALLBACK EnumDateFormatsProc(
  LPTSTR lpDateFormatString   // pointer to date format string
);

Parameters

lpDateFormatString
Pointer to a string buffer containing a null-terminated date format string. This string is a long or short date format, depending on the value of the dwFlags parameter passed to EnumDateFormats. Note that lpDateFormatString should be an LPWSTR for the Unicode (W) version of EnumDateFormats, and an LPSTR for the ANSI (A) version of EnumDateFormats.

Return Values

To continue enumeration, the callback function should return TRUE.

To stop enumeration, the callback function should return FALSE.

Remarks

An EnumDateFormatsProc function can carry out any desired task.

An application registers an EnumDateFormatsProc function by passing its address to the EnumDateFormats function.

Windows CE: Windows CE does not support the ANSI version of this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 98 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: User-defined.

See Also

National Language Support Overview, National Language Support Functions, EnumDateFormats


EnumLocalesProc

The EnumLocalesProc function is an application-defined callback function used with the EnumSystemLocales function. It receives a pointer to a string buffer containing a locale identifier. The LOCALE_ENUMPROC type defines a pointer to this callback function. EnumLocalesProc is a placeholder for the application-defined function name.

BOOL CALLBACK EnumLocalesProc(
  LPTSTR lpLocaleString   // pointer to locale identifier string
);

Parameters

lpLocaleString
Pointer to a string buffer containing a null-terminated locale identifier string. Note that lpLocaleString should be an LPWSTR for the Unicode (W) version of EnumLocalesProc, and an LPSTR for the ANSI (A) version of EnumLocalesProc.

Return Values

To continue enumeration, the callback function should return TRUE.

To stop enumeration, the callback function should return FALSE.

Remarks

An application registers an EnumLocalesProc function by passing its address to the EnumSystemLocales function.

Windows CE: Windows CE does not support the ANSI version of this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 98 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: User-defined.

See Also

National Language Support Overview, National Language Support Functions, EnumSystemLocales


EnumSystemCodePages

The EnumSystemCodePages function enumerates the code pages that are either installed on or supported by a system. The dwFlags parameter determines whether the function enumerates installed or supported code pages. The function enumerates the code pages by passing code page identifiers, one at a time, to the specified application-defined callback function. This continues until all of the installed or supported code page identifiers have been passed to the callback function, or the callback function returns FALSE.

BOOL EnumSystemCodePages(
  CODEPAGE_ENUMPROC lpCodePageEnumProc,  // pointer to callback function
  DWORD dwFlags                          // indicates the code pages to enumerate
);

Parameters

lpCodePageEnumProc
Points to an application-defined callback function. The EnumSystemCodePages function enumerates code pages by making repeated calls to this callback function. For more information, see the EnumCodePagesProc callback function.
dwFlags
Specifies the code pages to enumerate. This parameter can be one of the following values:
Value | Meaning
CP_INSTALLED | Enumerate only installed code pages.
CP_SUPPORTED | Enumerate all supported code pages.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INVALID_PARAMETER
ERROR_BADDB
ERROR_INVALID FLAGS

Remarks

The CP_INSTALLED and CP_SUPPORTED flags are mutually exclusive.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

National Language Support Overview, National Language Support Functions, EnumCodePagesProc


EnumSystemLocales

The EnumSystemLocales function enumerates the locales that are either installed on or supported by a system. The dwFlags parameter determines whether the function enumerates installed or supported system locales. The function enumerates locales by passing locale identifiers, one at a time, to the specified application-defined callback function. This continues until all of the installed or supported locale identifiers have been passed to the callback function or the callback function returns FALSE.

BOOL EnumSystemLocales(
  LOCALE_ENUMPROC lpLocaleEnumProc,
                  // pointer to enumeration callback function
  DWORD dwFlags   // indicates which locales to enumerate
);

Parameters

lpLocaleEnumProc
Points to an application-defined callback function. The EnumSystemLocales function enumerates locales by making repeated calls to this callback function. For more information, see the EnumLocalesProc callback function.
dwFlags
Specifies the locale identifiers to enumerate. This parameter can be one of the following values:
Value | Meaning
LCID_INSTALLED | Enumerate only installed locale identifiers.
LCID_SUPPORTED | Enumerate all supported locale identifiers.
LCID_ALTERNATE_SORTS | Enumerate only the alternate sorts. If this flag is used by itself, then only the alternate sort locale IDs will be returned. If this flag is used with either LCID_INSTALLED or LCID_SUPPORTED, then the installed or supported locales will be returned as well as the alternate sort locale IDs.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INVALID_PARAMETER
ERROR_BADDB
ERROR_INVALID FLAGS

Remarks

The LCID_INSTALLED and LCID_SUPPORTED flags are mutually exclusive.

Windows CE: Windows CE does not support the LCID_ALTERNATE_SORTS flag.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

National Language Support Overview, National Language Support Functions, EnumLocalesProc


EnumTimeFormats

The EnumTimeFormats function enumerates the time formats that are available for a specified locale. The function enumerates the time formats by passing a pointer to a string buffer containing a time format to an application-defined callback function. It continues to do so until the last time format is found or the callback function returns FALSE.

BOOL EnumTimeFormats(
  TIMEFMT_ENUMPROC lpTimeFmtEnumProc, // pointer to callback function
  LCID Locale,                        // locale whose time formats are of interest
  DWORD dwFlags                       // currently unused
);

Parameters

lpTimeFmtEnumProc
Points to an application-defined callback function. See the EnumTimeFormatsProc callback function for further details.
Locale
Specifies the locale to retrieve time format information for. This parameter can be a locale identifier created by the MAKELCID macro, or one of the following predefined values:
LOCALE_SYSTEM_DEFAULT | Default system locale.
LOCALE_USER_DEFAULT | Default user locale.
LOCALE_NEUTRAL | Default language-neutral locale.

dwFlags
Currently unused. Must be zero.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INVALID_PARAMETER
ERROR_BADDB
ERROR_INVALID FLAGS

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

National Language Support Overview, National Language Support Functions, EnumTimeFormatsProc, EnumCalendarInfo, EnumDateFormats


EnumTimeFormatsProc

The EnumTimeFormatsProc function is an application-defined callback function used with the EnumTimeFormats function. The TIMEFMT_ENUMPROC type defines a pointer to this callback function. EnumTimeFormatsProc is a placeholder for the application-defined function name.

BOOL CALLBACK EnumTimeFormatsProc(
  LPTSTR lpTimeFormatString   // pointer to time format string
);

Parameters

lpTimeFormatString
Pointer to a string buffer containing a null-terminated time format string. Note that lpTimeFormatString should be an LPWSTR for the Unicode (W) version of EnumTimeFormatsProc, and an LPSTR for the ANSI (A) version of EnumTimeFormatsProc.

Return Values

To continue enumeration, the callback function should return TRUE.

To stop enumeration, the callback function should return FALSE.

Remarks

An application registers an EnumTimeFormatsProc function by passing its address to the EnumTimeFormats function.

Windows CE: Windows CE does not support the ANSI version of this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 98 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: User-defined.

See Also

National Language Support Overview, National Language Support Functions, EnumTimeFormats


GetACP

The GetACP function retrieves the current ANSI code-page identifier for the system.

UINT GetACP(VOID)

Parameters

This function has no parameters.

Return Values

The return value is the current ANSI code-page identifier for the system, or a default identifier if no code page is current.

Remarks

Following are the ANSI code-page identifiers:

Identifier | Meaning
874 | Thai
932 | Japan
936 | Chinese (PRC, Singapore)
949 | Korean
950 | Chinese (Taiwan Region; Hong Kong SAR, PRC)
1200 | Unicode (BMP of ISO 10646)
1250 | Windows 3.1 Eastern European
1251 | Windows 3.1 Cyrillic
1252 | Windows 3.1 Latin 1 (US, Western Europe)
1253 | Windows 3.1 Greek
1254 | Windows 3.1 Turkish
1255 | Hebrew
1256 | Arabic
1257 | Baltic

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

National Language Support Overview, National Language Support Functions, GetCPInfo, GetOEMCP


GetCPInfo

The GetCPInfo function retrieves information about any valid installed or available code page.

BOOL GetCPInfo(
  UINT CodePage,      // code page identifier
  LPCPINFO lpCPInfo   // address of structure for information
);

Parameters

CodePage
Specifies the code page about which information is to be retrieved. You can specify the code page identifier for any installed or available code page, or you can specify one of the following predefined values:
Value | Meaning
CP_ACP | Use the system default ANSI code page
CP_MACCP | Use the system default Macintosh code page
CP_OEMCP | Use the system default OEM code page

lpCPInfo
Points to a CPINFO structure that receives information about the code page.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError .

Remarks

If the specified code page is not installed or not available, GetCPInfo sets the last-error value to ERROR_INVALID_PARAMETER.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

National Language Support Overview, National Language Support Functions, GetACP, GetOEMCP, CPINFO


GetCPInfoEx

[This is preliminary documentation and subject to change.]

The GetCPInfoEx function retrieves information about any valid installed or available code page.

BOOL GetCPInfoEx (
  UINT CodePage,         // code-page identifier
  DWORD dwFlags,         // flags (must be 0)
  LPCPINFOEX lpCPInfoEx  // address of structure for information
);

Parameters

CodePage
Specifies the code page about which information is to be retrieved. You can specify the code-page identifier for any installed or available code page, or you can specify one of the following predefined values.
Value | Meaning
CP_ACP | Use the system default ANSI code page.
CP_MACCP | Use the system default Macintosh code page.
CP_OEMCP | Use the system default OEM code page.

dwFlags
Reserved. Must be 0.
lpCPInfoEx
Pointer to a CPINFOEX structure that receives information about the code page.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the specified code page is not installed or not available, the GetCPInfoEx function sets the last-error value to ERROR_INVALID_PARAMETER.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

National Language Support Overview, National Language Support Functions, GetACP, GetOEMCP, CPINFOEX


GetCurrencyFormat

The GetCurrencyFormat function formats a number string as a currency string for a specified locale.

int GetCurrencyFormat(
  LCID Locale,                  // locale for which string is to be formatted
  DWORD dwFlags,                // bit flag that controls the function's operation
  LPCTSTR lpValue,              // pointer to input number string
  CONST CURRENCYFMT *lpFormat,  // pointer to a formatting information structure
  LPTSTR lpCurrencyStr,         // pointer to output buffer
  int cchCurrency               // size of output buffer
);

Parameters

Locale
Specifies the locale for which the currency string is to be formatted. If lpFormat is NULL, the function formats the string according to the currency format for this locale. If lpFormat is not NULL, the function uses the locale only for formatting information not specified in the CURRENCYFMT structure (for example, the locale's string value for the negative sign).

This parameter can be a locale identifier created by the MAKELCID macro, or one of the following predefined values:
LOCALE_SYSTEM_DEFAULT | Default system locale.
LOCALE_USER_DEFAULT | Default user locale.
LOCALE_NEUTRAL | Default language-neutral locale.

dwFlags
A bit flag that controls the operation of the function. If lpFormat is non-NULL, this parameter must be zero.

If lpFormat is NULL, you can specify the LOCALE_NOUSEROVERRIDE flag to format the string using the system default currency format for the specified locale; or you can specify zero to format the string using any user overrides to the locale's default currency format.

lpValue
Points to a null-terminated string containing the number string to format.

This string can contain only the following characters:

  • Characters '0' through '9'
  • One decimal point (dot) if the number is a floating-point value
  • A minus sign in the first character position if the number is a negative value

All other characters are invalid. The function returns an error if the string pointed to by lpValue deviates from these rules.

lpFormat
Pointer to a CURRENCYFMT structure that contains currency formatting information. All members in the structure pointed to by lpFormat must contain appropriate values.

If lpFormat is NULL, the function uses the currency format of the specified locale.

lpCurrencyStr
Points to a buffer to receive the formatted currency string.
cchCurrency
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the lpCurrencyStr buffer. If cchCurrency is zero, the function returns the number of bytes or characters required to hold the formatted currency string, and the buffer pointed to by lpCurrencyStr is not used.

Return Values

If the function succeeds, the return value is the number of bytes (ANSI version) or characters (Unicode version) written to the buffer pointed to by lpCurrencyStr, or if the cchCurrency parameter is zero, the number of bytes or characters required to hold the formatted currency string. The count includes the terminating null.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INSUFFICIENT_BUFFER
ERROR_INVALID FLAGS
ERROR_INVALID_PARAMETER

Remarks

Windows CE: The Locale parameter is ignored and the system locale is always used. The Locale parameter should be set to LOCALE_SYSTEM_DEFAULT to ensure compatibility with future versions of Windows CE.

No flags are supported for the dwFlags parameter.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

National Language Support Overview, National Language Support Functions, GetNumberFormat, CURRENCYFMT


GetDateFormat

The GetDateFormat function formats a date as a date string for a specified locale. The function formats either a specified date or the local system date.

int GetDateFormat(
  LCID Locale,               // locale for which date is to be formatted
  DWORD dwFlags,             // flags specifying function options
  CONST SYSTEMTIME *lpDate,  // date to be formatted
  LPCTSTR lpFormat,          // date format string
  LPTSTR lpDateStr,          // buffer for storing formatted string
  int cchDate                // size of buffer
);

Parameters

Locale
Specifies the locale for which the date string is to be formatted. If lpFormat is NULL, the function formats the string according to the date format for this locale. If lpFormat is not NULL, the function uses the locale only for information not specified in the format picture string (for example, the locale's day and month names).

This parameter can be a locale identifier created by the MAKELCID macro, or one of the following predefined values:
LOCALE_SYSTEM_DEFAULT | Default system locale.
LOCALE_USER_DEFAULT | Default user locale.
LOCALE_NEUTRAL | Default language-neutral locale.

dwFlags
A set of bit flags that specify various function options. If lpFormat is non-NULL, this parameter must be zero.

If lpFormat is NULL, you can specify a combination of the following flags:
Flag | Meaning
LOCALE_NOUSEROVERRIDE | If set, the function formats the string using the system default date format for the specified locale. If not set, the function formats the string using any user overrides to the locale's default date format.
DATE_SHORTDATE | Use the short date format. This is the default. Cannot be used with DATE_LONGDATE or DATE_YEARMONTH.
DATE_LONGDATE | Use the long date format. Cannot be used with DATE_SHORTDATE or DATE_YEARMONTH.
DATE_YEARMONTH | Use the year/month format. Cannot be used with DATE_SHORTDATE or DATE_LONGDATE.
DATE_USE_ALT_CALENDAR | Use the alternate calendar, if one exists, to format the date string. If this flag is set, the function uses the default format for that alternate calendar, rather than using any user overrides. The user overrides will be used only in the event that there is no default format for the specified alternate calendar.
DATE_LTRREADING | Adds marks for left-to-right reading order layout. Cannot be used with DATE_RTLREADING.
DATE_RTLREADING | Adds marks for right-to left reading order layout. Cannot be used with DATE_LTRREADING

lpDate
Pointer to a SYSTEMTIME structure that contains the date information to be formatted. If this pointer is NULL, the function uses the current local system date.
lpFormat
Pointer to a format picture string to use to form the date string. If lpFormat is NULL, the function uses the date format of the specified locale.

Use the following elements to construct a format picture string. If you use spaces to separate the elements in the format string, these spaces will appear in the same location in the output string. The letters must be in uppercase or lowercase as shown in the table (for example, "MM" not "mm"). Characters in the format string that are enclosed in single quotation marks will appear in the same location and unchanged in the output string.
Picture | Meaning
d | Day of month as digits with no leading zero for single-digit days.
dd | Day of month as digits with leading zero for single-digit days.
ddd | Day of week as a three-letter abbreviation. The function uses the LOCALE_SABBREVDAYNAME value associated with the specified locale.
dddd | Day of week as its full name. The function uses the LOCALE_SDAYNAME value associated with the specified locale.
M | Month as digits with no leading zero for single-digit months.
MM | Month as digits with leading zero for single-digit months.
MMM | Month as a three-letter abbreviation. The function uses the LOCALE_SABBREVMONTHNAME value associated with the specified locale.
MMMM | Month as its full name. The function uses the LOCALE_SMONTHNAME value associated with the specified locale.
y | Year as last two digits, but with no leading zero for years less than 10.
yy | Year as last two digits, but with leading zero for years less than 10.
yyyy | Year represented by full four digits.
gg | Period/era string. The function uses the CAL_SERASTRING value associated with the specified locale. This element is ignored if the date to be formatted does not have an associated era or period string.

For example, to get the date string

"Wed, Aug 31 94"

use the following picture string:

"ddd',' MMM dd yy"

lpDateStr
Pointer to a buffer that receives the formatted date string.
cchDate
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the lpDateStr buffer. If cchDate is zero, the function returns the number of bytes or characters required to hold the formatted date string, and the buffer pointed to by lpDateStr is not used.

Return Values

If the function succeeds, the return value is the number of bytes (ANSI version) or characters (Unicode version) written to the lpDateStr buffer, or if the cchDate parameter is zero, the number of bytes or characters required to hold the formatted date string. The count includes the terminating null.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INSUFFICIENT_BUFFER
ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER

Remarks

The day name, abbreviated day name, month name, and abbreviated month name are all localized based on the given locale identifier.

The date values in the SYSTEMTIME structure pointed to by lpDate must be valid. The function checks each of the date values: year, month, day, and day of week. If the day of the week is incorrect, the function uses the correct value, and returns no error. If any of the other date values are outside the correct range, the function fails, and sets the last-error to ERROR_INVALID_PARAMETER.

The function ignores the time portions of the SYSTEMTIME structure pointed to by lpDate: wHour, wMinute, wSecond, and wMilliseconds.

The DATE_SHORTDATE and DATE_LONGDATE flag options are mutually exclusive. If neither one is specified and lpFormat is NULL, then DATE_SHORTDATE is the default.

No errors are returned for a bad format string. The function simply forms the best date string that it can. For example, the only year pictures that are valid are L"yyyy" and L"yy" (the 'L' indicates a Unicode (16-bit characters) string). If L"y" is passed in, the function assumes L"yy". If L"yyy" is passed in, the function assumes L"yyyy". If more than 4 date (L"dddd") or 4 month (L"MMMM") pictures are passed in, then the function defaults to L"dddd" or L"MMMM".

Any text that should remain in its exact form in the date string should be enclosed within single quotation marks in the date format picture. The single quotation mark may also be used as an escape character to allow the single quotation mark itself to be displayed in the date string. However, the escape sequence must be enclosed within two single quotation marks. For example, to display the date as "May '93", the format string would be: L"MMMM ''''yy" The first and last single quotation marks are the enclosing quotation marks. The second and third single quotation marks are the escape sequence to allow the single quotation mark to be displayed before the century.

Windows CE: The Locale parameter is ignored and the system locale is always used. The Locale parameter should be set to LOCALE_SYSTEM_DEFAULT to ensure compatibility with future versions of Windows CE.

Windows CE does not support the following flags for the dwFlags parameter:

LOCALE_NOUSEROVERRIDE

DATE_USE_ALT_CALENDAR

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

National Language Support Overview, National Language Support Functions, GetTimeFormat, SYSTEMTIME


GetLocaleInfo

The GetLocaleInfo function retrieves information about a locale.

int GetLocaleInfo(
  LCID Locale,      // locale identifier
  LCTYPE LCType,    // type of information
  LPTSTR lpLCData,  // address of buffer for information
  int cchData       // size of buffer
);

Parameters

Locale
Specifies the locale to retrieve information for. This parameter can be a locale identifier created by the MAKELCID macro, or one of the following predefined values:
LOCALE_SYSTEM_DEFAULT | Default system locale.
LOCALE_USER_DEFAULT | Default user locale.
LOCALE_NEUTRAL | Default language-neutral locale.

LCType
Specifies one of the LCTYPE constants to indicate the type of information to be retrieved.

All LCTYPE values are mutually exclusive, with the exception of LOCALE_NOUSEROVERRIDE. An application may use the binary-OR operator to combine LOCALE_NOUSEROVERRIDE with any other LCTYPE value. If passed such an LCType value, the function bypasses user overrides, and returns the system default value for the requested LCID.

lpLCData
Points to a buffer to receive the requested data.
cchData
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the lpLCData buffer. If cchData is zero, the function returns the number of bytes or characters required to hold the information, and the buffer pointed to by lpLCData is not used.

Return Values

If the function succeeds, the return value is the number of bytes (ANSI version) or characters (Unicode version) written to the destination buffer, or if the cchData parameter is zero, the number of bytes or characters required to hold the locale information.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INSUFFICIENT_BUFFER
ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER

Remarks

The GetLocaleInfo function always retrieves information in text format. If the information is a numeric value, the function converts the number to text using decimal notation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

National Language Support Overview, National Language Support Functions, GetStringTypeA, GetStringTypeEx, GetStringTypeW, GetSystemDefaultLCID, GetUserDefaultLCID, LCTYPE Constants, SetLocaleInfo, MAKELCID


GetNumberFormat

The GetNumberFormat function formats a number string as a number string customized for a specified locale.

int GetNumberFormat(
  LCID Locale,                // locale for which string is to be formatted
  DWORD dwFlags,              // bit flag that controls the function's operation
  LPCTSTR lpValue,            // pointer to input number string
  CONST NUMBERFMT *lpFormat,  // pointer to a formatting information structure
  LPTSTR lpNumberStr,         // pointer to output buffer
  int cchNumber               // size of output buffer
);

Parameters

Locale
Specifies the locale for which the number string is to be formatted. If lpFormat is NULL, the function formats the string according to the number format for this locale. If lpFormat is not NULL, the function uses the locale only for formatting information not specified in the NUMBERFMT structure (for example, the locale's string value for the negative sign).

This parameter can be a locale identifier created by the MAKELCID macro, or one of the following predefined values:
LOCALE_SYSTEM_DEFAULT | Default system locale.
LOCALE_USER_DEFAULT | Default user locale.
LOCALE_NEUTRAL | Default language-neutral locale.

dwFlags
Contains a bit flag that controls the operation of the function. If lpFormat is non-NULL, this parameter must be zero.

If lpFormat is NULL, you can specify the LOCALE_NOUSEROVERRIDE flag to format the string using the system default number format for the specified locale; or you can specify zero to format the string using any user overrides to the locale's default number format

lpValue
Points to a null-terminated string containing the number string to format.

This string can only contain the following characters:

  • Characters '0' through '9'
  • One decimal point (dot) if the number is a floating-point value
  • A minus sign in the first character position if the number is a negative value

All other characters are invalid. The function returns an error if the string pointed to by lpValue deviates from these rules.

lpFormat
Pointer to a NUMBERFMT structure that contains number formatting information. All members in the structure pointed to by lpFormat must contain appropriate values.

If lpFormat is NULL, the function uses the number format of the specified locale.

lpNumberStr
Points to a buffer to receive the formatted number string.
cchNumber
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the lpNumberStr buffer. If cchNumber is zero, the function returns the number of bytes or characters required to hold the formatted number string, and the buffer pointed to by lpNumberStr is not used.

Return Values

If the function succeeds, the return value is the number of bytes (ANSI version) or characters (Unicode version) written to the buffer pointed to by lpNumberStr, or if the cchNumber parameter is zero, the number of bytes or characters required to hold the formatted number string. The count includes the terminating null.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INSUFFICIENT_BUFFER
ERROR_INVALID FLAGS
ERROR_INVALID_PARAMETER

Remarks

Windows CE: The Locale parameter is ignored and the default system locale is always used. The Locale parameter should be set to LOCALE_SYSTEM_DEFAULT to ensure compatibility with future versions of Windows CE.

No flags are supported for the dwFlags parameter, it should be set to zero.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

National Language Support Overview, National Language Support Functions, GetCurrencyFormat, NUMBERFMT


GetOEMCP

The GetOEMCP function retrieves the current OEM code-page identifier for the system. (OEM stands for original equipment manufacturer.)

UINT GetOEMCP(VOID)

Parameters

This function has no parameters.

Return Values

The return value is the current OEM code-page identifier for the system or a default identifier if no code page is current.

Remarks

Following are the OEM code-page identifiers:

Identifier | Meaning
437 | MS-DOS United States
708 | Arabic (ASMO 708)
709 | Arabic (ASMO 449+, BCON V4)
710 | Arabic (Transparent Arabic)
720 | Arabic (Transparent ASMO)
737 | Greek (formerly 437G)
775 | Baltic
850 | MS-DOS Multilingual (Latin I)
852 | MS-DOS Slavic (Latin II)
855 | IBM Cyrillic (primarily Russian)
857 | IBM Turkish
860 | MS-DOS Portuguese
861 | MS-DOS Icelandic
862 | Hebrew
863 | MS-DOS Canadian-French
864 | Arabic
865 | MS-DOS Nordic
866 | MS-DOS Russian (former USSR)
869 | IBM Modern Greek
874 | Thai
932 | Japan
936 | Chinese (PRC, Singapore)
949 | Korean
950 | Chinese (Taiwan Region; Hong Kong SAR, PRC)
1361 | Korean (Johab)

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

National Language Support Overview, National Language Support Functions, GetACP


GetSystemDefaultLangID

The GetSystemDefaultLangID function retrieves the system default language identifier.

LANGID GetSystemDefaultLangID(VOID)

Parameters

This function has no parameters.

Return Values

The return value is the system default language identifier.

Remarks

For more information about language identifiers, see Language Identifiers and Locale Information.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

National Language Support Overview, National Language Support Functions, GetUserDefaultLangID, MAKELANGID


GetSystemDefaultLCID

The GetSystemDefaultLCID function retrieves the system default locale identifier.

LCID GetSystemDefaultLCID(VOID)

Parameters

This function has no parameters.

Return Values

The return value is the system default locale identifier.

Remarks

For more information about locale identifiers, see Locales.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

National Language Support Overview, National Language Support Functions, GetLocaleInfo, GetUserDefaultLCID, MAKELCID


GetThreadLocale

The GetThreadLocale function returns the calling thread's current locale.

LCID GetThreadLocale(VOID)

Parameters

This function has no parameters.

Return Values

The function returns the calling thread's locale identifier.

Remarks

When a thread is created, it is given the system default thread locale. The system reads the system default thread locale from the registry when the system boots. This system default can be modified for future process and thread creation using Control Panel's International application.

For more information about locale identifiers, see Locales.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

National Language Support Overview, National Language Support Functions, SetThreadLocale, GetSystemDefaultLCID, GetUserDefaultLCID


GetTimeFormat

The GetTimeFormat function formats a time as a time string for a specified locale. The function formats either a specified time or the local system time.

int GetTimeFormat(
  LCID Locale,       // locale for which time is to be formatted
  DWORD dwFlags,             // flags specifying function options
  CONST SYSTEMTIME *lpTime,  // time to be formatted
  LPCTSTR lpFormat,          // time format string
  LPTSTR lpTimeStr,          // buffer for storing formatted string
  int cchTime                // size, in bytes or characters, of the buffer
);

Parameters

Locale
Specifies the locale for which the time string is to be formatted. If lpFormat is NULL, the function formats the string according to the time format for this locale. If lpFormat is not NULL, the function uses the locale only for information not specified in the format picture string (for example, the locale's time markers).

This parameter can be a locale identifier created by the MAKELCID macro, or one of the following predefined values:
LOCALE_SYSTEM_DEFAULT | Default system locale.
LOCALE_USER_DEFAULT | Default user locale.
LOCALE_NEUTRAL | Default language-neutral locale.

dwFlags
A set of bit flags that specify various function options. You can specify a combination of the following flags:
Flag | Meaning
LOCALE_NOUSEROVERRIDE | If set, the function formats the string using the system default time format for the specified locale. If not set, the function formats the string using any user overrides to the locale's default time format. This flag cannot be set if lpFormat is non-NULL.
TIME_NOMINUTESORSECONDS | Do not use minutes or seconds.
TIME_NOSECONDS | Do not use seconds.
TIME_NOTIMEMARKER | Do not use a time marker.
TIME_FORCE24HOURFORMAT | Always use a 24-hour time format.

lpTime
Pointer to a SYSTEMTIME structure that contains the time information to be formatted. If this pointer is NULL, the function uses the current local system time.
lpFormat
Pointer to a format picture to use to form the time string. If lpFormat is NULL, the function uses the time format of the specified locale.

Use the following elements to construct a format picture string. If you use spaces to separate the elements in the format string, these spaces will appear in the same location in the output string. The letters must be in uppercase or lowercase as shown (for example, "ss", not "SS"). Characters in the format string that are enclosed in single quotation marks will appear in the same location and unchanged in the output string.
Picture | Meaning
h | Hours with no leading zero for single-digit hours; 12-hour clock
hh | Hours with leading zero for single-digit hours; 12-hour clock
H | Hours with no leading zero for single-digit hours; 24-hour clock
HH | Hours with leading zero for single-digit hours; 24-hour clock
m | Minutes with no leading zero for single-digit minutes
mm | Minutes with leading zero for single-digit minutes
s | Seconds with no leading zero for single-digit seconds
ss | Seconds with leading zero for single-digit seconds
t | One character time marker string, such as A or P
tt | Multicharacter time marker string, such as AM or PM

For example, to get the time string

"11:29:40 PM"

use the following picture string:

"hh':'mm':'ss tt"

lpTimeStr
Pointer to a buffer that receives the formatted time string.
cchTime
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the lpTimeStr buffer. If cchTime is zero, the function returns the number of bytes or characters required to hold the formatted time string, and the buffer pointed to by lpTimeStr is not used.

Return Values

If the function succeeds, the return value is the number of bytes (ANSI version) or characters (Unicode version) written to the buffer pointed to by lpTimeStr. If the cchTime parameter is zero, the return value is the number of bytes or characters required to hold the formatted time string. The count includes the terminating null.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INSUFFICIENT_BUFFER
ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER

Remarks

If a time marker exists and the TIME_NOTIMEMARKER flag is not set, the function localizes the time marker based on the specified locale identifier. Examples of time markers are "AM" and "PM" for US English.

The time values in the SYSTEMTIME structure pointed to by lpTime must be valid. The function checks each of the time values to determine that it is within the appropriate range of values. If any of the time values are outside the correct range, the function fails, and sets the last-error to ERROR_INVALID_PARAMETER.

The function ignores the date portions of the SYSTEMTIME structure pointed to by lpTime: wYear, wMonth, wDayOfWeek, and wDay.

If TIME_NOMINUTESORSECONDS or TIME_NOSECONDS is specified, the function removes the separator(s) preceding the minutes and/or seconds element(s).

If TIME_NOTIMEMARKER is specified, the function removes the separator(s) preceding and following the time marker.

If TIME_FORCE24HOURFORMAT is specified, the function displays any existing time marker, unless the TIME_NOTIMEMARKER flag is also set.

The function does not include milliseconds as part of the formatted time string.

To use the LOCALE_NOUSEROVERRIDE flag, lpFormat must be NULL.

No errors are returned for a bad format string. The function simply forms the best time string that it can. If more than two hour, minute, second, or time marker format pictures are passed in, then the function defaults to two. For example, the only time marker pictures that are valid are L"t" and L"tt" (the 'L' indicates a Unicode (16-bit characters) string). If L"ttt" is passed in, the function assumes L"tt".

Windows CE: The Locale parameter is ignored and the default system locale is always used. The Locale parameter should be set to LOCALE_SYSTEM_DEFAULT to ensure compatibility with future versions of Windows CE.

Windows CE does not support the LOCALE_NOUSEOVERRIDE flag for the dwFlags parameter.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

National Language Support Overview, National Language Support Functions, GetDateFormat, SYSTEMTIME


GetUserDefaultLangID

The GetUserDefaultLangID function retrieves the user-default language identifier.

LANGID GetUserDefaultLangID(VOID)

Parameters

This function has no parameters.

Return Values

The return value is the user -default language identifier.

Remarks

For more information about language identifiers, see Language Identifiers and Locale Information.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

National Language Support Overview, National Language Support Functions, GetSystemDefaultLangID, MAKELANGID


GetUserDefaultLCID

The GetUserDefaultLCID function retrieves the user-default locale identifier.

LCID GetUserDefaultLCID(VOID)

Parameters

This function has no parameters.

Return Values

The return value is the user-default locale identifier.

Remarks

For more information about locale identifiers, see Locales.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

National Language Support Overview, National Language Support Functions, GetLocaleInfo, GetSystemDefaultLCID, MAKELCID


IsValidCodePage

The IsValidCodePage determines whether a specified code page is valid.

BOOL IsValidCodePage(
  UINT CodePage   // specifies the code page to check
);

Parameters

CodePage
Specifies the code page to check. Each code page is identified by a unique number.

Return Values

If the code page is valid, the return value is nonzero.

If the code page is not valid, the return value is zero. To get extended error information, call GetLastError.

Remarks

A code page is considered valid only if it is installed in the system.

Following are the code-page identifiers:

Identifier | Meaning
037 | EBCDIC
437 | MS-DOS United States
500 | EBCDIC "500V1"
708 | Arabic (ASMO 708)
709 | Arabic (ASMO 449+, BCON V4)
710 | Arabic (Transparent Arabic)
720 | Arabic (Transparent ASMO)
737 | Greek (formerly 437G)
775 | Baltic
850 | MS-DOS Multilingual (Latin I)
852 | MS-DOS Slavic (Latin II)
855 | IBM Cyrillic (primarily Russian)
857 | IBM Turkish
860 | MS-DOS Portuguese
861 | MS-DOS Icelandic
862 | Hebrew
863 | MS-DOS Canadian-French
864 | Arabic
865 | MS-DOS Nordic
866 | MS-DOS Russian
869 | IBM Modern Greek
874 | Thai
875 | EBCDIC
932 | Japan
936 | Chinese (PRC, Singapore)
949 | Korean
950 | Chinese (Taiwan Region; Hong Kong SAR, PRC)
1026 | EBCDIC
1200 | Unicode (BMP of ISO 10646)
1250 | Windows 3.1 Eastern European
1251 | Windows 3.1 Cyrillic
1252 | Windows 3.1 US (ANSI)
1253 | Windows 3.1 Greek
1254 | Windows 3.1 Turkish
1255 | Hebrew
1256 | Arabic
1257 | Baltic
1361 | Korean (Johab)
10000 | Macintosh Roman
10001 | Macintosh Japanese
10006 | Macintosh Greek I
10007 | Macintosh Cyrillic
10029 | Macintosh Latin 2
10079 | Macintosh Icelandic
10081 | Macintosh Turkish

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

National Language Support Overview, National Language Support Functions, GetACP, GetCPInfo, GetOEMCP


IsValidLocale

The IsValidLocale function applies a validity test to a locale identifier. The dwFlags parameter determines the nature of the validity test. Currently, the function tests whether a locale identifier is installed or supported on the calling system.

BOOL IsValidLocale(
  LCID Locale,    // locale identifier to validate
  DWORD dwFlags   // specifies validity test
);

Parameters

Locale
Specifies the locale identifier to be validated. You can use the MAKELCID macro to create a locale identifier.
dwFlags
Specifies the validity test to apply to the locale identifier. This parameter can be one of the following values:
Value | Meaning
LCID_INSTALLED | Test whether the locale identifier is both supported and installed.
LCID_SUPPORTED | Test whether the locale identifier is supported.

Return Values

If the locale identifier passes the specified validity test, the return value is nonzero.

If the locale identifier does not pass the specified validity test, the return value is zero.

Remarks

If the LCID_INSTALLED flag is specified and this function returns a nonzero value, the locale identifier is both supported and installed on the system.

If the LCID_SUPPORTED flag is specified and this function returns zero, the locale identifier is supported in the release, but not necessarily installed on the system.

For more information, see Locales.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

National Language Support Overview, National Language Support Functions, GetLocaleInfo


LCMapString

The LCMapString function maps one character string to another, performing a specified locale-dependent transformation. The function can also be used to generate a sort key for the input string.

int LCMapString(
  LCID Locale,       // locale identifier
  DWORD dwMapFlags,  // mapping transformation type
  LPCTSTR lpSrcStr,  // address of source string
  int cchSrc,        // number of characters in source string
  LPTSTR lpDestStr,  // address of destination buffer
  int cchDest        // size of destination buffer
);

Parameters

Locale
Specifies a locale identifier. The locale provides a context for the string mapping or sort key generation. An application can use the MAKELCID macro to create a locale identifier.
dwMapFlags
A set of flags that indicate the type of transformation to be used during string mapping or sort key generation. An application can specify more than one of these options on a single transformation, although some combinations are invalid. The following mapping options are defined; restrictions are noted following the table:
Option | Meaning
LCMAP_BYTEREV | Windows NT: Use byte reversal. For example, if you pass in 0x3450 0x4822 the result is 0x5034 0x2248.
LCMAP_FULLWIDTH | Wide characters (where applicable).
LCMAP_HALFWIDTH | Narrow characters (where applicable).
LCMAP_HIRAGANA | Hiragana.
LCMAP_KATAKANA | Katakana.
LCMAP_LINGUISTIC_CASING | Use linguistic rules for casing, rather than file system rules (the default). Valid with LCMAP_LOWERCASE or LCMAP_UPPERCASE only.
LCMAP_LOWERCASE | Use lowercase.
LCMAP_SIMPLIFIED_CHINESE | Map simplified Chinese characters to traditional Chinese characters.
LCMAP_SORTKEY | Produce a normalized wide-character sort key.
LCMAP_TRADITIONAL_CHINESE | Map traditional Chinese characters to simplified Chinese characters.
LCMAP_UPPERCASE | Use uppercase.
NORM_IGNORECASE | Ignore case.
NORM_IGNOREKANATYPE | Do not differentiate between Hiragana and Katakana characters. Corresponding Hiragana and Katakana will compare as equal.
NORM_IGNORENONSPACE | Ignore nonspacing. This flag also removes Japanese accent characters.
NORM_IGNORESYMBOLS | Ignore symbols.
NORM_IGNOREWIDTH | Do not differentiate between a single-byte character and the same character as a double-byte character.
SORT_STRINGSORT | Treat punctuation the same as symbols.

If the LCMAP_SORTKEY flag is not specified, the LCMapString function performs string mapping. In this case the following restrictions apply:

  • LCMAP_LOWERCASE and LCMAP_UPPERCASE are mutually exclusive.
  • LCMAP_HIRAGANA and LCMAP_KATAKANA are mutually exclusive.
  • LCMAP_HALFWIDTH and LCMAP_FULLWIDTH are mutually exclusive.
  • SORT_STRINGSORT, NORM_IGNOREKANATYPE, NORM_IGNOREWIDTH, and NORM_IGNORECASE are not valid.
  • LCMAP_TRADITIONAL_CHINESE and LCMAP_SIMPLIFIED_CHINESE are mutually exclusive.
  • LCMAP_LOWERCASE and LCMAP_UPPERCASE are not valid in combination with any of the following flags: LCMAP_HIRAGANA, LCMAP_KATAKANA, LCMAP_HALFWIDTH, and LCMAP_FULLWIDTH.

When the LCMAP_SORTKEY flag is specified, the LCMapString function generates a sort key. In this case the following restriction applies:

  • LCMAP_SORTKEY is mutually exclusive with all other LCMAP_* flags, with the sole exception of LCMAP_BYTEREV.
lpSrcStr
Pointer to a source string that the function maps or uses for sort key generation.
cchSrc
Specifies the number of bytes (ANSI version) or characters (Unicode version) in the string pointed to by the lpSrcStr parameter.

This count can include the NULL terminator, or not include it. If the NULL terminator is included in the character count, it does not greatly affect the mapping behavior. That is because NULL is considered to be unsortable, and always maps to itself.

A cchSrc value of –1 specifies that the string pointed to by lpSrcStr is null-terminated. If this is the case, and LCMapString is being used in its string-mapping mode, the function calculates the string's length itself, and null-terminates the mapped string stored into *lpDestStr.

lpDestStr
Pointer to a buffer into which the function stores the mapped string or sort key.

If LCMAP_SORTKEY is specified, LCMapString stores a sort key into the buffer. The sort key is stored as an array of byte values in the following format:

[all Unicode sort weights] 0x01 [all Diacritic weights] 0x01 [all Case weights] 0x01 [all Special weights] 0x00

Note that the sort key is null-terminated. This is true regardless of the value of cchSrc. Also note that, even if some of the sort weights are absent from the sort key, due to the presence of one or more ignore flags in dwMapFlags, the 0x01 separators and the 0x00 terminator are still present.

cchDest
Specifies the size in bytes (ANSI version) or characters (Unicode version) of the buffer pointed to by lpDestStr.

If the function is being used for string mapping, the size is a character count. If space for a NULL terminator is included in cchSrc, then cchDest must also include space for a NULL terminator.

If the function is being used to generate a sort key, the size is a byte count. This byte count must include space for the sort key 0x00 terminator.

If cchDest is zero, the function's return value is the number of characters, or bytes if LCMAP_SORTKEY is specified, required to hold the mapped string or sort key. In this case, the buffer pointed to by lpDestStr is not used.

Return Values

If the function succeeds, and the value of cchDest is nonzero, the return value is the number of characters, or bytes if LCMAP_SORTKEY is specified, written to the buffer. This count includes room for a NULL terminator.

If the function succeeds, and the value of cchDest is zero, the return value is the size of the buffer in characters, or bytes if LCMAP_SORTKEY is specified, required to receive the translated string or sort key. This size includes room for a NULL terminator.

If the function fails, the return value is 0. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INSUFFICIENT_BUFFER
ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER

Remarks

The mapped string is null terminated if the source string is null terminated.

The A version of this function maps strings to and from Unicode based on the specified LCID's default ANSI code page.

If the LCMAP_HIRAGANA flag is specified to map Katakana characters to Hiragana characters, and LCMAP_FULLWIDTH is not specified, the function only maps full-width characters to Hiragana. In this case, any half-width Katakana characters are placed as-is in the output string, with no mapping to Hiragana. An application must specify LCMAP_FULLWIDTH if it wants half-width Katakana characters mapped to Hiragana.

The lpSrcStr and lpDestStr pointers must not be the same. If they are the same, the function fails, and GetLastError returns ERROR_INVALID_PARAMETER.

Even if the wide-character Unicode version of this function is called, the output string is only in WCHAR or CHAR format if the string mapping mode of LCMapString is used. If the sort key generation mode is used, specified by LCMAP_SORTKEY, the output is an array of byte values. An application can compare sort keys by using a byte-by-byte comparison.

An application can call the function with the NORM_IGNORENONSPACE and NORM_IGNORESYMBOLS flags set, and all other options flags cleared, in order to simply strip characters from the input string. If this is done with an input string that is not null-terminated, it is possible for LCMapString to return an empty string and not return an error.

The LCMapString function ignores the Arabic Kashida. If an application calls the function to create a sort key for a string containing an Arabic Kashida, there will be no sort key value for the Kashida.

The function treats the hyphen and apostrophe a bit differently than other punctuation symbols, so that words like coop and co-op stay together in a list. All punctuation symbols other than the hyphen and apostrophe sort before the alphanumeric characters. An application can change this behavior by setting the SORT_STRINGSORT flag. See CompareString for a more detailed discussion of this issue.

When LCMapString is used to generate a sort key, by setting the LC_MAPSORTKEY flag, the sort key stored into *lpDestStr may contain an odd number of bytes. The LCMAP_BYTEREV option only reverses an even number of bytes. If both options are chosen, the last (odd-positioned) byte in the sort key is not reversed. If the terminating 0x00 byte is an odd-positioned byte, then it remains the last byte in the sort key. If the terminating 0x00 byte is an even-positioned byte, it exchanges positions with the byte that precedes it.

Windows CE: The following dwMapFlags values are not supported:

LCMAP_LINGUISTIC_CASING

LCMAP_SIMPLIFIED_CHINESE

LCMAP_TRADITIONAL_CHINESE

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

National Language Support Overview, National Language Support Functions, CompareString, FoldString, MAKELCID


SetLocaleInfo

The SetLocaleInfo function sets an item of locale information. It does so by making an entry in the process portion of the locale table. This setting only affects the user override portion of the locale settings; it does not set the system defaults.

Only certain types of locale information, or LCTYPE values, can be set by this function. See the following Remarks section for a list of valid LCTYPE values.

The locale information is always passed in as a null-terminated Unicode string in the Unicode (W) version of the function, and as a null-terminated ANSI string in the ANSI (A) version. No integers are allowed by this function; any numeric values must be specified as Unicode or ANSI text. Each LCTYPE has a particular format, as noted in Locale Identifiers.

BOOL SetLocaleInfo(
  LCID Locale,       // locale identifier
  LCTYPE LCType,     // type of information to set
  LPCTSTR lpLCData   // pointer to information to set
);

Parameters

Locale
Specifies the locale whose information the function will set. The locale provides a context for the string mapping or sort key generation. An application can use the MAKELCID macro to create a locale identifier.
LCType
Specifies the type of locale information to be set by the function. Note that only one LCTYPE may be specified per call. Not all LCTYPE values are valid; see the list of valid LCTYPE values in the following Remarks section.
lpLCData
Points to a null-terminated string containing the locale information the function will set. This should be an LPWSTR for the Unicode (W) version of the function, and an LPSTR for the ANSI (A) version. The information must be in the specified LCTYPE's particular format.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INVALID_ACCESS
ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER

Remarks

The following LCTYPE values are valid for this function:

LOCALE_ICALENDARTYPE | LOCALE_SDATE
LOCALE_ICURRDIGITS | LOCALE_SDECIMAL
LOCALE_ICURRENCY | LOCALE_SGROUPING
LOCALE_IDIGITS | LOCALE_SLIST
LOCALE_IFIRSTDAYOFWEEK | LOCALE_SLONGDATE
LOCALE_IFIRSTWEEKOFYEAR | LOCALE_SMONDECIMALSEP
LOCALE_ILZERO | LOCALE_SMONGROUPING
LOCALE_IMEASURE | LOCALE_SMONTHOUSANDSEP
LOCALE_INEGCURR | LOCALE_SNEGATIVESIGN
LOCALE_INEGNUMBER | LOCALE_SPOSITIVESIGN
LOCALE_IPAPERSIZE | LOCALE_SSHORTDATE
LOCALE_ITIME | LOCALE_STHOUSAND
LOCALE_S1159 | LOCALE_STIME
LOCALE_S2359 | LOCALE_STIMEFORMAT
LOCALE_SCURRENCY | LOCALE_SYEARMONTH

Windows CE: Windows CE supports an additional LCTYPE value, LOCALE_SYEARMONTH. Windows CE does not support the LOCALE_IPAPERSIZE value.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

National Language Support Overview, National Language Support Functions, GetLocaleInfo


SetThreadLocale

The SetThreadLocale function sets the calling thread's current locale.

BOOL SetThreadLocale (
  LCID Locale   // locale identifier
);

Parameters

Locale
Specifies the new locale for the calling thread. This parameter can be a locale identifier created by the MAKELCID macro, or one of the following predefined values:
LOCALE_SYSTEM_DEFAULT | Default system locale.
LOCALE_USER_DEFAULT | Default user locale.
LOCALE_NEUTRAL | Default language-neutral locale.

For more information, see Locales.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

When a thread is created, it is given the system default thread locale. The system reads the system default thread locale from the registry when the system boots. This system default can be modified for future process and thread creation using Control Panel's International application.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

National Language Support Overview, National Language Support Functions, GetThreadLocale, GetSystemDefaultLCID, GetUserDefaultLCID


National Language Support Structures

The following structures are used with national language support.

CPINFO
CPINFOEX
CURRENCYFMT
NUMBERFMT


CPINFO

The CPINFO structure contains information about a code page.

struct _cpinfo {
    UINT MaxCharSize;
    BYTE DefaultChar[MAX_DEFAULTCHAR];
    BYTE LeadByte[MAX_LEADBYTES];
} CPINFO;

Members

MaxCharSize
Specifies the maximum length, in bytes, of a character in this code page.
DefaultChar
Specifies the default character used in translations into this code page. This character is used by the WideCharToMultiByte function if an explicit default character is not given.
LeadByte
Specifies a fixed-length array of lead-byte ranges, where the number of lead-byte ranges is variable. If there are no lead bytes in this code page, then every element of the array is NULL. If there are lead bytes in this code page, a starting value and ending value is given for each range. Ranges are inclusive. The maximum number of lead-byte ranges for any code page is 5. The array uses two bytes to describe each range, with a double-byte null terminator after the last range.

Remarks

Lead bytes are unique to double-byte character sets (DBCS). A lead byte is the first byte of a 2-byte character in a DBCS. Lead bytes occupy a specific range of byte values.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winnls.h.

See Also

National Language Support Overview, National Language Support Structures, GetCPInfo, WideCharToMultiByte


CPINFOEX

[This is preliminary documentation and subject to change.]

The CPINFOEX structure contains information about a code page. It is used by the GetCPInfoEx function.

typedef struct _cpinfoex {
    UINT    MaxCharSize;
    BYTE    DefaultChar[MAX_DEFAULTCHAR];
    BYTE    LeadByte[MAX_LEADBYTES];
    WCHAR   UnicodeDefaultChar;
    UINT    CodePage;
    TCHAR   CodePageName[MAX_PATH];
} CPINFOEX *LPCPINFOEX;

Members

MaxCharSize
Specifies the maximum length, in bytes, of a character in the code page.
DefaultChar
Specifies the default character used when translating character strings into this code page. This character is used by the WideCharToMultiByte function if an explicit default character is not given.
LeadByte
Specifies a fixed-length array of lead-byte ranges, where the number of lead-byte ranges is variable. If there are no lead bytes in this code page, every element of the array is NULL. If there are lead bytes in this code page, the array contains a starting and ending value for each range. Ranges are inclusive. The maximum number of lead-byte ranges for any code page is 5. The array uses 2 bytes to describe each range, with a double-byte null terminator after the last range.
UnicodeDefaultChar
Specifies the Unicode default character used in translations from this code page. This character is used by the MultiByteToWideChar function.
CodePage
Specifies the code page value.
CodePageName
Specifies the full, localized name of the code page.

Remarks

Lead bytes are unique to double-byte character sets (DBCS). A lead byte is the first byte of a 2-byte character in a DBCS. Lead bytes occupy a specific range of byte values.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winnls.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

National Language Support Overview, National Language Support Structures, GetCPInfoEx, MultiByteToWideChar, WideCharToMultiByte


CURRENCYFMT

The CURRENCYFMT structure contains information that defines the format of a currency string. The GetCurrencyFormat function uses this information to customize a currency string for a specified locale.

typedef struct _currencyfmt {
    UINT      NumDigits;
    UINT      LeadingZero;
    UINT      Grouping;
    LPTSTR    lpDecimalSep;
    LPTSTR    lpThousandSep;
    UINT      NegativeOrder;
    UINT      PositiveOrder;
    LPTSTR    lpCurrencySymbol;
} CURRENCYFMT;

Members

NumDigits
Specifies the number of fractional digits. This is equivalent to the locale information specified by the LCTYPE constant value LOCALE_IDIGITS.
LeadingZero
Specifies whether to use leading zeroes in decimal fields. This is equivalent to the locale information specified by the LCTYPE constant value LOCALE_ILZERO.
Grouping
Specifies the size of each group of digits to the left of the decimal. Values in the range 0 – 9 are valid.
lpDecimalSep
Points to a null-terminated decimal separator string.
lpThousandSep
Points to a null-terminated thousand separator string.
NegativeOrder
Specifies the negative currency mode. This is equivalent to the locale information specified by the LCTYPE constant value LOCALE_INEGCURR.
PositiveOrder
Specifies the positive currency mode. This is equivalent to the locale information specified by the LCTYPE constant value LOCALE_ICURRENCY.
lpCurrencySymbol
Points to a null-terminated currency symbol string.

Remarks

For more information about the LCTYPE constants, see LCTYPE Constants.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

National Language Support Overview, National Language Support Structures, GetCurrencyFormat


NUMBERFMT

The NUMBERFMT structure contains information that defines the format of a number string. The GetNumberFormat function uses this information to customize a number string for a specified locale.

typedef struct _numberfmt {
    UINT      NumDigits;
    UINT      LeadingZero;
    UINT      Grouping;
    LPTSTR    lpDecimalSep;
    LPTSTR    lpThousandSep;
    UINT      NegativeOrder;
} NUMBERFMT;

Members

NumDigits
Specifies the number of fractional digits. This is equivalent to the locale information specified by the LCTYPE constant value LOCALE_IDIGITS.
LeadingZero
Specifies whether to use leading zeroes in decimal fields. This is equivalent to the locale information specified by the LCTYPE constant value LOCALE_ILZERO.
Grouping
Specifies the size of each group of digits to the left of the decimal. Values in the range 0 – 9 are valid.
lpDecimalSep
Points to a null-terminated decimal separator string.
lpThousandSep
Points to a null-terminated thousand separator string.
NegativeOrder
Specifies the negative number mode. This is equivalent to the locale information specified by the LCTYPE constant value LOCALE_INEGNUMBER.

Remarks

For more information about the LCTYPE constants, see LCTYPE Constants.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

National Language Support Overview, National Language Support Structures, GetNumberFormat


National Language Support Macros

The following macros are used with national language support.

LANGIDFROMLCID
MAKELANGID
MAKELCID
PRIMARYLANGID
SORTIDFROMLCID
SUBLANGID


LANGIDFROMLCID

The LANGIDFROMLCID macro retrieves a language identifier from a locale identifier.

WORD LANGIDFROMLCID(
  LCID lcid  // locale identifier
);

Parameters

lcid
Specifies the locale identifier. This parameter may have been created by using the MAKELCID macro.

Return Values

The return value is a language identifier.

Remarks

The LANGIDFROMLCID macro is defined as follows:

#define LANGIDFROMLCID(lcid)   ((WORD) (lcid))

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

National Language Support Overview, National Language Support Macros, MAKELANGID, MAKELCID, PRIMARYLANGID, SUBLANGID


MAKELANGID

The MAKELANGID macro creates a language identifier from a primary language identifier and a secondary language identifier.

WORD MAKELANGID(
  USHORT usPrimaryLanguage,  // primary language identifier
  USHORT usSubLanguage       // sublanguage identifier
);

Parameters

usPrimaryLanguage
Specifies the primary language identifier. This parameter can be one of the following predefined values:
LANG_AFRIKAANS | LANG_KONKANI
LANG_ALBANIAN | LANG_KOREAN
LANG_ARABIC | LANG_LATVIAN
LANG_ARMENIAN | LANG_LITHUANIAN
LANG_ASSAMESE | LANG_MACEDONIAN
LANG_AZERI | LANG_MALAY
LANG_BASQUE | LANG_MALAYALAM
LANG_BELARUSIAN | LANG_MANIPURI
LANG_BENGALI | LANG_MARATHI
LANG_BULGARIAN | LANG_NEPALI
LANG_CATALAN | LANG_NEUTRAL
LANG_CHINESE | LANG_NORWEGIAN
LANG_CROATIAN | LANG_ORIYA
LANG_CZECH | LANG_POLISH
LANG_DANISH | LANG_PORTUGUESE
LANG_DUTCH | LANG_PUNJABI
LANG_ENGLISH | LANG_ROMANIAN
LANG_ESTONIAN | LANG_RUSSIAN
LANG_FAEROESE | LANG_SANSKRIT
LANG_FARSI | LANG_SERBIAN
LANG_FINNISH | LANG_SINDHI
LANG_FRENCH | LANG_SLOVAK
LANG_GEORGIAN | LANG_SLOVENIAN
LANG_GERMAN | LANG_SPANISH
LANG_GREEK | LANG_SWAHILI
LANG_GUJARATI | LANG_SWEDISH
LANG_HEBREW | LANG_TAMIL
LANG_HINDI | LANG_TATAR
LANG_HUNGARIAN | LANG_TELUGU
LANG_ICELANDIC | LANG_THAI
LANG_INDONESIAN | LANG_TURKISH
LANG_ITALIAN | LANG_UKRANIAN
LANG_JAPANESE | LANG_URDU
LANG_KANNADA | LANG_UZBEK
LANG_KASHMIRI | LANG_VIETNAMESE
LANG_KAZAK

For a user-defined language, usPrimaryLanguage can be a value in the range 0x0200 to 0x03FF. All other values are reserved for system use.

usSubLanguage
Specifies the secondary language identifier. This parameter can be one of the following values:
SUBLANG_ARABIC_SAUDI_ARABIA | SUBLANG_GERMAN_AUSTRIAN
SUBLANG_ARABIC_IRAQ | SUBLANG_GERMAN_LUXEMBOURG
SUBLANG_ARABIC_EGYPT | SUBLANG_GERMAN_LIECHTENSTEIN
SUBLANG_ARABIC_LIBYA | SUBLANG_ITALIAN
SUBLANG_ARABIC_ALGERIA | SUBLANG_ITALIAN_SWISS
SUBLANG_ARABIC_MOROCCO | SUBLANG_KASHMIRI_INDIA
SUBLANG_ARABIC_TUNISIA | SUBLANG_KOREAN
SUBLANG_ARABIC_OMAN | SUBLANG_LITHUANIAN
SUBLANG_ARABIC_YEMEN | SUBLANG_LITHUANIAN_CLASSIC
SUBLANG_ARABIC_SYRIA | SUBLANG_MALAY_BRUNEI_DARUSSALAM
SUBLANG_ARABIC_JORDAN | SUBLANG_MALAY_MALAYSIA
SUBLANG_ARABIC_LEBANON | SUBLANG_NEPALI_INDIA
SUBLANG_ARABIC_KUWAIT | SUBLANG_NEUTRAL
SUBLANG_ARABIC_UAE | SUBLANG_NORWEGIAN_BOKMAL
SUBLANG_ARABIC_BAHRAIN | SUBLANG_NORWEGIAN_NYNORSK
SUBLANG_ARABIC_QATAR | SUBLANG_PORTUGUESE
SUBLANG_AZERI_CYRILLIC | SUBLANG_PORTUGUESE_BRAZILIAN
SUBLANG_AZERI_LATIN | SUBLANG_SERBIAN_LATIN
SUBLANG_CHINESE_TRADITIONAL | SUBLANG_SERBIAN_CYRILLIC
SUBLANG_CHINESE_SIMPLIFIED | SUBLANG_SPANISH
SUBLANG_CHINESE_HONGKONG | SUBLANG_SPANISH_MEXICAN
SUBLANG_CHINESE_SINGAPORE | SUBLANG_SPANISH_MODERN
SUBLANG_CHINESE_MACAU | SUBLANG_SPANISH_GUATEMALA
SUBLANG_DEFAULT | SUBLANG_SPANISH_COSTA_RICA
SUBLANG_DUTCH | SUBLANG_SPANISH_PANAMA
SUBLANG_DUTCH_BELGIAN | SUBLANG_SPANISH_DOMINICAN_REPUBLIC
SUBLANG_ENGLISH_US | SUBLANG_SPANISH_VENEZUELA
SUBLANG_ENGLISH_UK | SUBLANG_SPANISH_COLOMBIA
SUBLANG_ENGLISH_AUS | SUBLANG_SPANISH_PERU
SUBLANG_ENGLISH_CAN | SUBLANG_SPANISH_ARGENTINA
SUBLANG_ENGLISH_NZ | SUBLANG_SPANISH_ECUADOR
SUBLANG_ENGLISH_EIRE | SUBLANG_SPANISH_CHILE
SUBLANG_ENGLISH_SOUTH_AFRICA | SUBLANG_SPANISH_URUGUAY
SUBLANG_ENGLISH_JAMAICA | SUBLANG_SPANISH_PARAGUAY
SUBLANG_ENGLISH_CARIBBEAN | SUBLANG_SPANISH_BOLIVIA
SUBLANG_ENGLISH_BELIZE | SUBLANG_SPANISH_EL_SALVADOR
SUBLANG_ENGLISH_TRINIDAD | SUBLANG_SPANISH_HONDURAS
SUBLANG_ENGLISH_PHILIPPINES | SUBLANG_SPANISH_NICARAGUA
SUBLANG_ENGLISH_ZIMBABWE | SUBLANG_SPANISH_PUERTO_RICO
SUBLANG_FRENCH | SUBLANG_SWEDISH
SUBLANG_FRENCH_BELGIAN | SUBLANG_SWEDISH_FINLAND
SUBLANG_FRENCH_CANADIAN | SUBLANG_SYS_DEFAULT
SUBLANG_FRENCH_SWISS | SUBLANG_URDU_INDIA
SUBLANG_FRENCH_LUXEMBOURG | SUBLANG_URDU_PAKISTAN
SUBLANG_FRENCH_MONACO | SUBLANG_UZBEK_CYRILLIC
SUBLANG_GERMAN | SUBLANG_UZBEK_LATIN
SUBLANG_GERMAN_SWISS

For a user-defined secondary language, usSubLanguage can be a value in the range 0x20 to 0x3F. All other values are reserved for system use.

Return Values

The return value is a language identifier.

Remarks

The following three combinations of usPrimaryLanguage and usSubLanguage have special meaning:

Primary language ID | Secondary language ID | Meaning
LANG_NEUTRAL | SUBLANG_NEUTRAL | Language neutral
LANG_NEUTRAL | SUBLANG_DEFAULT | User default language
LANG_NEUTRAL | SUBLANG_SYS_DEFAULT | System default language

The MAKELANGID macro is defined as follows:

#define MAKELANGID(p, s) ((((WORD) (s)) << 10) | (WORD) (p))

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnt.h.

See Also

National Language Support Overview, National Language Support Macros, EnumSystemLocales, LANGIDFROMLCID, MAKELCID, PRIMARYLANGID, SUBLANGID


MAKELCID

The MAKELCID macro creates a locale identifier from a language identifier.

DWORD MAKELCID(
  WORD wLanguageID,  // language identifier
  WORD wSortID       // sorting identifier
);

Parameters

wLanguageID
Specifies the language identifier. This parameter is a combination of a primary language identifier and a secondary language identifier and is usually created by using the MAKELANGID macro.
wSortID
Specifies the sort identifier. The following sort identifiers are defined:
Value | Meaning
SORT_DEFAULT | Specifies the default sort.
SORT_JAPANESE_XJIS | Specifies Japanese XJIS order.
SORT_JAPANESE_UNICODE | Specifies Japanese Unicode order.
SORT_CHINESE_BIG5 | Specifies Chinese BIG5 order.
SORT_CHINESE_UNICODE | Specifies Chinese Unicode order.
SORT_KOREAN_KSC | Specifies Korean KSC order.
SORT_KOREAN_UNICODE | Specifies Korean Unicode order.

Return Values

The return value is a locale identifier.

Remarks

The MAKELCID macro is defined as follows:

#define MAKELCID(lgid, srtid)  \
    ((DWORD)((((DWORD)((WORD  )(srtid))) << 16) |  \
            ((DWORD)((WORD  )(lgid)))))

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnt.h.

See Also

National Language Support Overview, National Language Support Macros, LANGIDFROMLCID, MAKELANGID, SORTIDFROMLCID


PRIMARYLANGID

The PRIMARYLANGID macro extracts a primary language identifier from a language identifier.

WORD PRIMARYLANGID(
  WORD lgid  // language identifier
);

Parameters

lgid
Specifies the language identifier. This value is a combination of a primary language identifier and a secondary language identifier and is usually created by using the MAKELANGID macro.

Return Values

The return value is a primary language identifier. The following primary language identifiers are defined:

LANG_AFRIKAANS | LANG_KONKANI
LANG_ALBANIAN | LANG_KOREAN
LANG_ARABIC | LANG_LATVIAN
LANG_ARMENIAN | LANG_LITHUANIAN
LANG_ASSAMESE | LANG_MACEDONIAN
LANG_AZERI | LANG_MALAY
LANG_BASQUE | LANG_MALAYALAM
LANG_BELARUSIAN | LANG_MANIPURI
LANG_BENGALI | LANG_MARATHI
LANG_BULGARIAN | LANG_NEPALI
LANG_CATALAN | LANG_NEUTRAL
LANG_CHINESE | LANG_NORWEGIAN
LANG_CROATIAN | LANG_ORIYA
LANG_CZECH | LANG_POLISH
LANG_DANISH | LANG_PORTUGUESE
LANG_DUTCH | LANG_PUNJABI
LANG_ENGLISH | LANG_ROMANIAN
LANG_ESTONIAN | LANG_RUSSIAN
LANG_FAEROESE | LANG_SANSKRIT
LANG_FARSI | LANG_SERBIAN
LANG_FINNISH | LANG_SINDHI
LANG_FRENCH | LANG_SLOVAK
LANG_GEORGIAN | LANG_SLOVENIAN
LANG_GERMAN | LANG_SPANISH
LANG_GREEK | LANG_SWAHILI
LANG_GUJARATI | LANG_SWEDISH
LANG_HEBREW | LANG_TAMIL
LANG_HINDI | LANG_TATAR
LANG_HUNGARIAN | LANG_TELUGU
LANG_ICELANDIC | LANG_THAI
LANG_INDONESIAN | LANG_TURKISH
LANG_ITALIAN | LANG_UKRANIAN
LANG_JAPANESE | LANG_URDU
LANG_KANNADA | LANG_UZBEK
LANG_KASHMIRI | LANG_VIETNAMESE
LANG_KAZAK |

Remarks

The PRIMARYLANGID macro is defined as follows:

#define PRIMARYLANGID(lgid)    ((WORD  )(lgid) & 0x3ff)

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnt.h.

See Also

National Language Support Overview, National Language Support Macros, EnumSystemLocales, LANGIDFROMLCID, MAKELANGID, SUBLANGID


SORTIDFROMLCID

The SORTIDFROMLCID macro retrieves a sort identifier from a locale identifier.

WORD SORTIDFROMLCID(
  LCID lcid  // locale identifier
);

Parameters

lcid
Specifies the locale identifier. This parameter may have been created by using the MAKELCID macro.

Return Values

The return value is a sort identifier. The following sort identifiers are defined:

Value | Meaning
SORT_DEFAULT | Specifies the default sort.
SORT_JAPANESE_XJIS | Specifies Japanese XJIS order.
SORT_JAPANESE_UNICODE | Specifies Japanese Unicode order.
SORT_CHINESE_BIG5 | Specifies Chinese BIG5 order.
SORT_CHINESE_UNICODE | Specifies Chinese Unicode order.
SORT_KOREAN_KSC | Specifies Korean KSC order.
SORT_KOREAN_UNICODE | Specifies Korean Unicode order.

Remarks

The SORTIDFROMLCID macro is defined as follows:

#define SORTIDFROMLCID(lcid) \
          ((WORD  )((((DWORD)(lcid)) & NLS_VALID_LOCALE_MASK) >> 16))

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

National Language Support Overview, National Language Support Macros, MAKELANGID, MAKELCID, PRIMARYLANGID, SUBLANGID


SUBLANGID

The SUBLANGID macro extracts a sublanguage identifier from a language identifier.

WORD SUBLANGID(
  WORD lgid  // language identifier
);

Parameters

lgid
Specifies the language identifier. This value is a combination of a primary language identifier and a secondary language identifier and is usually created by using the MAKELANGID macro.

Return Values

The return value is a secondary language identifier. The following secondary language identifiers are defined:

SUBLANG_ARABIC_SAUDI_ARABIA | SUBLANG_GERMAN_AUSTRIAN
SUBLANG_ARABIC_IRAQ | SUBLANG_GERMAN_LUXEMBOURG
SUBLANG_ARABIC_EGYPT | SUBLANG_GERMAN_LIECHTENSTEIN
SUBLANG_ARABIC_LIBYA | SUBLANG_ITALIAN
SUBLANG_ARABIC_ALGERIA | SUBLANG_ITALIAN_SWISS
SUBLANG_ARABIC_MOROCCO | SUBLANG_KASHMIRI_INDIA
SUBLANG_ARABIC_TUNISIA | SUBLANG_KOREAN
SUBLANG_ARABIC_OMAN | SUBLANG_LITHUANIAN
SUBLANG_ARABIC_YEMEN | SUBLANG_LITHUANIAN_CLASSIC
SUBLANG_ARABIC_SYRIA | SUBLANG_MALAY_BRUNEI_DARUSSALAM
SUBLANG_ARABIC_JORDAN | SUBLANG_MALAY_MALAYSIA
SUBLANG_ARABIC_LEBANON | SUBLANG_NEPALI_INDIA
SUBLANG_ARABIC_KUWAIT | SUBLANG_NEUTRAL
SUBLANG_ARABIC_UAE | SUBLANG_NORWEGIAN_BOKMAL
SUBLANG_ARABIC_BAHRAIN | SUBLANG_NORWEGIAN_NYNORSK
SUBLANG_ARABIC_QATAR | SUBLANG_PORTUGUESE
SUBLANG_AZERI_CYRILLIC | SUBLANG_PORTUGUESE_BRAZILIAN
SUBLANG_AZERI_LATIN | SUBLANG_SERBIAN_LATIN
SUBLANG_CHINESE_TRADITIONAL | SUBLANG_SERBIAN_CYRILLIC
SUBLANG_CHINESE_SIMPLIFIED | SUBLANG_SPANISH
SUBLANG_CHINESE_HONGKONG | SUBLANG_SPANISH_MEXICAN
SUBLANG_CHINESE_SINGAPORE | SUBLANG_SPANISH_MODERN
SUBLANG_CHINESE_MACAU | SUBLANG_SPANISH_GUATEMALA
SUBLANG_DEFAULT | SUBLANG_SPANISH_COSTA_RICA
SUBLANG_DUTCH | SUBLANG_SPANISH_PANAMA
SUBLANG_DUTCH_BELGIAN | SUBLANG_SPANISH_DOMINICAN_REPUBLIC
SUBLANG_ENGLISH_US | SUBLANG_SPANISH_VENEZUELA
SUBLANG_ENGLISH_UK | SUBLANG_SPANISH_COLOMBIA
SUBLANG_ENGLISH_AUS | SUBLANG_SPANISH_PERU
SUBLANG_ENGLISH_CAN | SUBLANG_SPANISH_ARGENTINA
SUBLANG_ENGLISH_NZ | SUBLANG_SPANISH_ECUADOR
SUBLANG_ENGLISH_EIRE | SUBLANG_SPANISH_CHILE
SUBLANG_ENGLISH_SOUTH_AFRICA | SUBLANG_SPANISH_URUGUAY
SUBLANG_ENGLISH_JAMAICA | SUBLANG_SPANISH_PARAGUAY
SUBLANG_ENGLISH_CARIBBEAN | SUBLANG_SPANISH_BOLIVIA
SUBLANG_ENGLISH_BELIZE | SUBLANG_SPANISH_EL_SALVADOR
SUBLANG_ENGLISH_TRINIDAD | SUBLANG_SPANISH_HONDURAS
SUBLANG_ENGLISH_PHILIPPINES | SUBLANG_SPANISH_NICARAGUA
SUBLANG_ENGLISH_ZIMBABWE | SUBLANG_SPANISH_PUERTO_RICO
SUBLANG_FRENCH | SUBLANG_SWEDISH
SUBLANG_FRENCH_BELGIAN | SUBLANG_SWEDISH_FINLAND
SUBLANG_FRENCH_CANADIAN | SUBLANG_SYS_DEFAULT
SUBLANG_FRENCH_SWISS | SUBLANG_URDU_INDIA
SUBLANG_FRENCH_LUXEMBOURG | SUBLANG_URDU_PAKISTAN
SUBLANG_FRENCH_MONACO | SUBLANG_UZBEK_CYRILLIC
SUBLANG_GERMAN | SUBLANG_UZBEK_LATIN
SUBLANG_GERMAN_SWISS |

Remarks

The SUBLANGID macro is defined as follows:

#define SUBLANGID(lgid)        ((WORD  )(lgid) >> 10)

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnt.h.

See Also

National Language Support Overview, National Language Support Macros, EnumSystemLocales, LANGIDFROMLCID, MAKELANGID, PRIMARYLANGID


National Language Support Constants

The following sections describes the constants used with the national language support functions.

  • Locale Information
  • Day, Month, Year, and Era Format Pictures
  • Hour, Minute, and Second Format Pictures
  • Primary Language Identifiers
  • Secondary Language Identifiers
  • Language Identifiers
  • Calendar Type Information
  • Language Code and Scripts


Locale Information

The following are locale constants.

LOCALE_FONTSIGNATURE
Windows NT 4.0 or later: A bit pattern used to determine the relationship between character coverage needed to support the locale and font contents.
LOCALE_ICALENDARTYPE
Current calendar type. This type can be one of these values:
1 | Gregorian (as in United States)
2 | Gregorian (English strings always)
3 | Era: Year of the Emperor (Japan)
4 | Era: Year of Taiwan Region
5 | Tangun Era (Korea)
6 | Hijri (Arabic lunar)
7 | Thai
8 | Hebrew (Lunar)
9 | Gregorian Middle East French calendar
10 | Gregorian Arabic calendar
11 | Gregorian Transliterated English calendar
12 | Gregorian Transliterated French calendar

LOCALE_ICENTURY
Specifier for full 4-digit century. The maximum number of characters allowed for this string is two. The specifier can be one of the following values:
0 | Abbreviated 2-digit century
1 | Full 4-digit century

LOCALE_ICOUNTRY
Country code, based on international phone codes, also referred to as IBM country codes. The maximum number of characters allowed for this string is six.
LOCALE_ICURRDIGITS
Number of fractional digits for the local monetary format. The maximum number of characters allowed for this string is three.
LOCALE_ICURRENCY
Positive currency mode. The maximum number of characters allowed for this string is two. The mode can be one of the following values:
0 | Prefix, no separation
1 | Suffix, no separation
2 | Prefix, 1-character separation
3 | Suffix, 1-character separation

LOCALE_IDATE
Short date format-ordering specifier. The maximum number of characters allowed for this string is two. The specifier can be one of the following values:
0 | Month-Day-Year
1 | Day-Month-Year
2 | Year-Month-Day

LOCALE_IDAYLZERO
Specifier for leading zeros in day fields. The maximum number of characters allowed for this string is two. The specifier can be one of the following values:
0 | No leading zeros for days
1 | Leading zeros for days

LOCALE_IDEFAULTANSICODEPAGE
American National Standards Institute (ANSI) code page associated with this locale. The maximum number of characters allowed for this string is six.
LOCALE_IDEFAULTCODEPAGE
Original equipment manufacturer (OEM) code page associated with the country. The maximum number of characters allowed for this string is six.
LOCALE_IDEFAULTCOUNTRY
Country code for the principal country in this locale. This is provided so that partially specified locales can be completed with default values. The maximum number of characters allowed for this string is six.
LOCALE_IDEFAULTEBCDICCODEPAGE
Windows NT 5.0 or later: Default EBCDIC code page associated with the locale. The maximum number of characters allowed for this string is six.
LOCALE_IDEFAULTLANGUAGE
Language identifier for the principal language spoken in this locale. This is provided so partially specified locales can be completed with default values. The maximum number of characters allowed for this string is five.
LOCALE_IDEFAULTMACCODEPAGE
Default Macintosh code page associated with the locale.
LOCALE_IDEFAULTOEMCODEPAGE
Original equipment manufacturer (OEM) code page associated with the locale. The maximum number of characters allowed for this string is six.
LOCALE_IDIGITS
Number of fractional digits. The maximum number of characters allowed for this string is three.
LOCALE_IDIGITSUBSTITUTION
Windows NT 5.0 or later: Determines the shape of the digits. The specifier can be one of these values:
0 | Context—the national shape depends on the previous text in the same output.
1 | None/Arabic—gives full Unicode compatibility.
2 | Native—national shapes determined by LOCALE_SNATIVEDIGITS.

LOCALE_IFIRSTDAYOFWEEK
Specifier for the first day in a week. The specifier can be one of these values:
0 | LOCALE_SDAYNAME1
1 | LOCALE_SDAYNAME2
2 | LOCALE_SDAYNAME3
3 | LOCALE_SDAYNAME4
4 | LOCALE_SDAYNAME5
5 | LOCALE_SDAYNAME6
6 | LOCALE_SDAYNAME7

LOCALE_IFIRSTWEEKOFYEAR
Specifier for the first week of the year. The specifier can be one of these values:
0 | Week containing 1/1 is the first week of that year.
1 | First full week following 1/1 is the first week of that year.
2 | First week containing at least four days is the first week of that year.

LOCALE_IINTLCURRDIGITS
Number of fractional digits for the international monetary format. The maximum number of characters allowed for this string is three.
LOCALE_ILANGUAGE
Language identifier indicating the language. The maximum number of characters allowed for this string is five.
LOCALE_ILDATE
Long date format-ordering specifier. The maximum number of characters allowed for this string is two. The specifier can be one of the following values:
0 | Month-Day-Year
1 | Day-Month-Year
2 | Year-Month-Day

LOCALE_ILZERO
Specifier for leading zeros in decimal fields. The maximum number of characters allowed for this string is two. The specifier can be one of the following values:
0 | No leading zeros
1 | Leading zeros

LOCALE_IMEASURE
System of measurement. This value is zero if the metric system (Systéme International d'Unités, or S.I.) is used, and 1 if the U.S. system is used. The maximum number of characters allowed for this string is two.
LOCALE_IMONLZERO
Specifier for leading zeros in month fields. The maximum number of characters allowed for this string is two. The specifier can be one of the following values:
0 | No leading zeros for months
1 | Leading zeros for months

LOCALE_INEGCURR
Negative currency mode. The maximum number of characters allowed for this string is three. The mode can be one of the following values:
0 | ($1.1)
1 | –$1.1
2 | $–1.1
3 | $1.1–
4 | (1.1$)
5 | –1.1$
6 | 1.1–$
7 | 1.1$–
8 | –1.1 $ (space before $)
9 | –$ 1.1 (space after $)
10 | 1.1 $– (space before $)
11 | $ 1.1– (space after $)
12 | $ –1.1 (space after $)
13 | 1.1– $ (space before $)
14 | ($ 1.1) (space after $)
15 | (1.1 $) (space before $)

LOCALE_INEGNUMBER
Negative number mode. The mode can be one of these values:
0 | (1.1)
1 | -1.1
2 | - 1.1
3 | 1.1-
4 | 1.1 -

LOCALE_INEGSEPBYSPACE
Separation of monetary symbol in a negative monetary value. This value is 1 if the monetary symbol is separated by a space from the negative amount, zero if it is not. The maximum number of characters allowed for this string is two.
LOCALE_INEGSIGNPOSN
Formatting index for negative values. This index uses the same values as LOCALE_IPOSSIGNPOSN. The maximum number of characters allowed for this string is two.
LOCALE_INEGSYMPRECEDES
Position of monetary symbol in a negative monetary value. This value is 1 if the monetary symbol precedes the negative amount, zero if it follows it. The maximum number of characters allowed for this string is two.
LOCALE_IOPTIONALCALENDAR
Additional calendar types. This can be a zero-separated list of one or more of these calendars type values:
0 | No additional types valid
1 | Gregorian (as in United States)
2 | Gregorian (English strings always)
3 | Era: Year of the Emperor (Japan)
4 | Era: Year of Taiwan Region
5 | Tangun Era (Korea)
6 | Hijri (Arabic lunar)
7 | Thai
8 | Hebrew (Lunar)
9 | Gregorian Middle East French calendar
10 | Gregorian Arabic calendar
11 | Gregorian Transliterated English calendar
12 | Gregorian Transliterated French calendar

LOCALE_IPAPERSIZE
Windows NT 5.0 or later: Default paper size associated with the locale. The specifier can be one of the following values:
0 | US Letter
1 | A4
2 | Legal

LOCALE_IPOSSEPBYSPACE
Separation of monetary symbol in a positive monetary value. This value is 1 if the monetary symbol is separated by a space from a positive amount, zero if it is not. The maximum number of characters allowed for this string is two.
LOCALE_IPOSSIGNPOSN
Formatting index for positive values. The maximum number of characters allowed for this string is two. The index can be one of the following values:
0 | Parentheses surround the amount and the monetary symbol.
1 | The sign string precedes the amount and the monetary symbol.
2 | The sign string succeeds the amount and the monetary symbol.
3 | The sign string immediately precedes the monetary symbol.
4 | The sign string immediately succeeds the monetary symbol.

LOCALE_IPOSSYMPRECEDES
Position of monetary symbol in a positive monetary value. This value is 1 if the monetary symbol precedes the positive amount, zero if it follows it. The maximum number of characters allowed for this string is two.
LOCALE_ITIME
Time format specifier. The maximum number of characters allowed for this string is two. The specifier can be one of the following values:
0 | AM / PM 12-hour format
1 | 24-hour format

LOCALE_ITIMEMARKPOSN
Specifier indicating whether the time marker string (AM or PM) preceeds or follows the time string. The registry value is iTimePrefix for compatibility with previous Asian versions of Windows. The specifier can take one of the following values:
0 | Use as suffix.
1 | Use as prefix.

LOCALE_ITIMEMARKERUSE
Specifier indicating whether the time marker should be used for 12-hour, 24-hour, or both types of clock settings. The specifier can take one of the following values:
0 | Use with 12-hour clock.
1 | Use with 24-hour clock.
2 | Use with both 12-hour and 24-hour clocks.
3 | Never use.

LOCALE_ITLZERO
Specifier for leading zeros in time fields. The maximum number of characters allowed for this string is two. The specifier can be one of the following values:
0 | No leading zeros for hours
1 | Leading zeros for hours

LOCALE_NOUSEROVERRIDE
Can be combined with other LOCALE values to bypass any user override and return the system default value for the given locale information.
LOCALE_RETURN_NUMBER
Windows NT 4.0 or later: This value may be ORed with any specifier beginning with LOCALE_I to return the value as a number instead of as a string. The buffer to receive the value must be at least the length of a DWORD.
LOCALE_S1159
String for the AM designator.
LOCALE_S2359
String for the PM designator.
LOCALE_SABBREVCTRYNAME
Abbreviated name of the country from the ISO Standard 3166.
LOCALE_SABBREVDAYNAME1
Native abbreviated name for Monday.
LOCALE_SABBREVDAYNAME2
Native abbreviated name for Tuesday.
LOCALE_SABBREVDAYNAME3
Native abbreviated name for Wednesday.
LOCALE_SABBREVDAYNAME4
Native abbreviated name for Thursday.
LOCALE_SABBREVDAYNAME5
Native abbreviated name for Friday.
LOCALE_SABBREVDAYNAME6
Native abbreviated name for Saturday.
LOCALE_SABBREVDAYNAME7
Native abbreviated name for Sunday.
LOCALE_SABBREVLANGNAME
Abbreviated name of the language, created by taking the two-letter language abbreviation from the ISO Standard 639 and adding a third letter, as appropriate, to indicate the sublanguage.
LOCALE_SABBREVMONTHNAME1
Native abbreviated name for January.
LOCALE_SABBREVMONTHNAME2
Native abbreviated name for February.
LOCALE_SABBREVMONTHNAME3
Native abbreviated name for March.
LOCALE_SABBREVMONTHNAME4
Native abbreviated name for April.
LOCALE_SABBREVMONTHNAME5
Native abbreviated name for May.
LOCALE_SABBREVMONTHNAME6
Native abbreviated name for June.
LOCALE_SABBREVMONTHNAME7
Native abbreviated name for July.
LOCALE_SABBREVMONTHNAME8
Native abbreviated name for August.
LOCALE_SABBREVMONTHNAME9
Native abbreviated name for September.
LOCALE_SABBREVMONTHNAME10
Native abbreviated name for October.
LOCALE_SABBREVMONTHNAME11
Native abbreviated name for November.
LOCALE_SABBREVMONTHNAME12
Native abbreviated name for December.
LOCALE_SABBREVMONTHNAME13
Native abbreviated name for 13th month, if it exists.
LOCALE_SCOUNTRY
Full localized name of the country.
LOCALE_SCURRENCY
String used as the local monetary symbol.
LOCALE_SDATE
Character(s) for the date separator.
LOCALE_SDAYNAME1
Native long name for Monday.
LOCALE_SDAYNAME2
Native long name for Tuesday.
LOCALE_SDAYNAME3
Native long name for Wednesday.
LOCALE_SDAYNAME4
Native long name for Thursday.
LOCALE_SDAYNAME5
Native long name for Friday.
LOCALE_SDAYNAME6
Native long name for Saturday.
LOCALE_SDAYNAME7
Native long name for Sunday.
LOCALE_SDECIMAL
Character(s) used as the decimal separator.
LOCALE_SENGCOUNTRY
Full English name of the country. This is always restricted to characters that can be mapped into the ASCII 127-character subset.
LOCALE_SENGCURRNAME
Windows NT 5.0 or later: The full English name of the currency associated with the locale.
LOCALE_SENGLANGUAGE
Full English name of the language from the International Organization for Standardization (ISO) Standard 639. This is always restricted to characters that can be mapped into the ASCII 127-character subset.
LOCALE_SGROUPING
Sizes for each group of digits to the left of the decimal. An explicit size is needed for each group, and sizes are separated by semicolons. If the last value is zero, the preceding value is repeated. For example, to group thousands, specify 3;0.
LOCALE_SINTLSYMBOL
Three characters of the international monetary symbol specified in ISO 4217, "Codes for the Representation of Currencies and Funds," followed by the character separating this string from the amount.
LOCALE_SISO3166CTRYNAME
Windows NT 4.0 or later: The ISO 3166 code for the country name.
LOCALE_SISO639LANGNAME
Windows NT 4.0 or later: The abbreviated name of the language based on the ISO Standard 639 values.
LOCALE_SLANGUAGE
Full localized name of the language.
LOCALE_SLIST
Character(s) used to separate list items. For example, a comma is used in many locales.
LOCALE_SLONGDATE
Long date formatting string for this locale. The string can consist of a combination of day, month, and year format pictures defined in the Day, Month, Year, and Era Format Pictures table in National Language Support Constants and any string of characters enclosed in single quotes. Characters in single quotes remain as given.
LOCALE_SMONDECIMALSEP
Character(s) used as the monetary decimal separator.
LOCALE_SMONGROUPING
Sizes for each group of monetary digits to the left of the decimal. An explicit size is needed for each group, and sizes are separated by semicolons. If the last value is zero, the preceding value is repeated. For example, to group thousands, specify 3;0.
LOCALE_SMONTHNAME1
Native long name for January.
LOCALE_SMONTHNAME2
Native long name for February.
LOCALE_SMONTHNAME3
Native long name for March.
LOCALE_SMONTHNAME4
Native long name for April.
LOCALE_SMONTHNAME5
Native long name for May.
LOCALE_SMONTHNAME6
Native long name for June.
LOCALE_SMONTHNAME7
Native long name for July.
LOCALE_SMONTHNAME8
Native long name for August.
LOCALE_SMONTHNAME9
Native long name for September.
LOCALE_SMONTHNAME10
Native long name for October.
LOCALE_SMONTHNAME11
Native long name for November.
LOCALE_SMONTHNAME12
Native long name for December.
LOCALE_SMONTHNAME13
Native name for 13th month, if it exists.
LOCALE_SMONTHOUSANDSEP
Character(s) used as the monetary separator between groups of digits to the left of the decimal.
LOCALE_SNATIVECTRYNAME
Native name of the country.
LOCALE_SNATIVECURRNAME
Windows NT 5.0 or later: The native name of the currency associated with the locale.
LOCALE_SNATIVEDIGITS
Native equivalents to ASCII zero through 9.
LOCALE_SNATIVELANGNAME
Native name of the language.
LOCALE_SNEGATIVESIGN
String value for the negative sign.
LOCALE_SPOSITIVESIGN
String value for the positive sign.
LOCALE_SSHORTDATE
Short date formatting string for this locale. The string can consist of a combination of day, month, and year format pictures defined in Day, Month, Year, and Era Format Pictures table in National Language Support Constants.
LOCALE_SSORTNAME
Windows NT 5.0 or later: The full localized name of the sort for the given locale identifier.
LOCALE_STHOUSAND
Character(s) used to separate groups of digits to the left of the decimal.
LOCALE_STIME
Character(s) for the time separator.
LOCALE_STIMEFORMAT
Time formatting strings for this locale. The string can consist of a combination of the hour, minute, and second format pictures defined in the Hour, Minute, and Second Format Pictures table in National Language Support Constants.
LOCALE_SYEARMONTH
Windows NT 5.0 or later: The Year/Month formatting string for the locale. This string shows the proper format for a date string that contains only the year and the month.
LOCALE_USE_CP_ACP
This may be ORed with any other LCTYPE in the GetLocaleInfoA call to ensure that the code page used to do the translation of the other LCTYPE from Unicode to ANSI is based on the system ANSI code page, rather than the default ANSI code page for the LCID specified in the GetlocalInfoA call.

Many of the locale types previously listed are closely related, such that changing one affects the value of the others. The following table shows the relationships between these types:

Constant | Affects
LOCALE_ICURRENCY | LOCALE_IPOSSEPBYSPACE, LOCALE_IPOSSYMPRECEDES
LOCALE_INEGCURR | LOCALE_INEGSEPBYSPACE, LOCALE_INEGSYMPRECEDES, LOCALE_INEGSIGNPOSN, LOCALE_IPOSSIGNPOSN
LOCALE_SSHORTDATE | LOCALE_SDATE, LOCALE_IDATE
LOCALE_SLONGDATE | LOCALE_ILDATE
LOCALE_STIMEFORMAT | LOCALE_STIME, LOCALE_ITIME, LOCALE_ITLZERO


Day, Month, Year, and Era Format Pictures

The format picture for a date string consists of a combination of null-terminated strings.

Day |
d | Day of the month as digits without leading zeros for single digit days.
dd | Day of the month as digits with leading zeros for single digit days
ddd | Day of the week as a 3-letter abbreviation as given by a LOCALE_SABBREVDAYNAME value.
dddd | Day of the week as given by a LOCALE_SDAYNAME value.
Month |
M | Month as digits without leading zeros for single digit months.
MM | Month as digits with leading zeros for single digit months
MMM | Month as a three letter abbreviation as given by a LOCALE_SABBREVMONTHNAME value.
MMMM | Month as given by a LOCALE_SMONTHNAME value.
Year |
y | Year represented only be the last digit.
yy | Year represented only be the last two digits.
yyyy | Year represented by the full 4 digits.
Period/Era |
gg | Period/era string as given by the CAL_SERASTRING value. The gg format picture in a date string is ignored if there is no associated era string.


Hour, Minute, and Second Format Pictures

The format picture for a time string consists of a combination of one string from each of these format types:

Hours |
h | Hours without leading zeros for single digit hours (12 hour clock)
hh | Hours with leading zeros for single digit hours (12 hour clock)
H | Hours without leading zeros for single digit hours (24 hour clock)
HH | Hours with leading zeros for single digit hours (24 hour clock)
Minutes |
m | Minutes without leading zeros for single digit minutes
mm | Minutes with leading zeros for single digit minutes
Seconds |
s | Seconds without leading zeros for single digit seconds
ss | Seconds with leading zeros for single digit seconds
Time Marker |
t | One character time marker string
tt | Multi-character time marker string


Primary Language Identifiers

The following are the primary language identifiers. They can be combined with secondary language identifiers to form language identifiers.

Identifier | Prefined Symbol | Language
0x00 | LANG_NEUTRAL | Neutral
0x01 | LANG_ARABIC | Arabic
0x02 | LANG_BULGARIAN | Bulgarian
0x03 | LANG_CATALAN | Catalan
0x04 | LANG_CHINESE | Chinese
0x05 | LANG_CZECH | Czech
0x06 | LANG_DANISH | Danish
0x07 | LANG_GERMAN | German
0x08 | LANG_GREEK | Greek
0x09 | LANG_ENGLISH | English
0x0a | LANG_SPANISH | Spanish
0x0b | LANG_FINNISH | Finnish
0x0c | LANG_FRENCH | French
0x0d | LANG_HEBREW | Hebrew
0x0e | LANG_HUNGARIAN | Hungarian
0x0f | LANG_ICELANDIC | Icelandic
0x10 | LANG_ITALIAN | Italian
0x11 | LANG_JAPANESE | Japanese
0x12 | LANG_KOREAN | Korean
0x13 | LANG_DUTCH | Dutch
0x14 | LANG_NORWEGIAN | Norwegian
0x15 | LANG_POLISH | Polish
0x16 | LANG_PORTUGUESE | Portuguese
0x18 | LANG_ROMANIAN | Romanian
0x19 | LANG_RUSSIAN | Russian
0x1a | LANG_CROATIAN | Croatian
0x1a | LANG_SERBIAN | Serbian
0x1b | LANG_SLOVAK | Slovak
0x1c | LANG_ALBANIAN | Albanian
0x1d | LANG_SWEDISH | Swedish
0x1e | LANG_THAI | Thai
0x1f | LANG_TURKISH | Turkish
0x20 | LANG_URDU | Urdu
0x21 | LANG_INDONESIAN | Indonesian
0x22 | LANG_UKRANIAN | Ukrainian
0x23 | LANG_BELARUSIAN | Belarusian
0x24 | LANG_SLOVENIAN | Slovenian
0x25 | LANG_ESTONIAN | Estonian
0x26 | LANG_LATVIAN | Latvian
0x27 | LANG_LITHUANIAN | Lithuanian
0x29 | LANG_FARSI | Farsi
0x2a | LANG_VIETNAMESE | Vietnamese
0x2b | LANG_ARMENIAN | Armenian
0x2c | LANG_AZERI | Azeri
0x2d | LANG_BASQUE | Basque
0x2f | LANG_MACEDONIAN | Macedonian
0x36 | LANG_AFRIKAANS | Afrikaans
0x37 | LANG_GEORGIAN | Georgian
0x38 | LANG_FAEROESE | Faeroese
0x39 | LANG_HINDI | Hindi
0x3e | LANG_MALAY | Malay
0x3f | LANG_KAZAK | Kazak
0x41 | LANG_SWAHILI | Swahili
0x43 | LANG_UZBEK | Uzbek
0x44 | LANG_TATAR | Tatar
0x45 | LANG_BENGALI | Bengali
0x46 | LANG_PUNJABI | Punjabi
0x47 | LANG_GUJARATI | Gujarati
0x48 | LANG_ORIYA | Oriya
0x49 | LANG_TAMIL | Tamil
0x4a | LANG_TELUGU | Telugu
0x4b | LANG_KANNADA | Kannada
0x4c | LANG_MALAYALAM | Malayalam
0x4d | LANG_ASSAMESE | Assamese
0x4e | LANG_MARATHI | Marathi
0x4f | LANG_SANSKRIT | Sanskrit
0x57 | LANG_KONKANI | Konkani
0x58 | LANG_MANIPURI | Manipuri
0x59 | LANG_SINDHI | Sindhi
0x60 | LANG_KASHMIRI | Kashmiri
0x61 | LANG_NEPALI | Nepali


Secondary Language Identifiers

The following are secondary language identifiers. They can be combined with primary language identifiers to form language identifiers.

Identifier | Predefined Symbol | Language
0x00 | SUBLANG_NEUTRAL | Neutral
0x01 | SUBLANG_DEFAULT | Default
0x02 | SUBLANG_SYS_DEFAULT | System Default
0x01 | SUBLANG_ARABIC_SAUDI_ARABIA | Arabic (Saudi Arabia)
0x02 | SUBLANG_ARABIC_IRAQ | Arabic (Iraq)
0x03 | SUBLANG_ARABIC_EGYPT | Arabic (Egypt)
0x04 | SUBLANG_ARABIC_LIBYA | Arabic (Libya)
0x05 | SUBLANG_ARABIC_ALGERIA | Arabic (Algeria)
0x06 | SUBLANG_ARABIC_MOROCCO | Arabic (Morocco)
0x07 | SUBLANG_ARABIC_TUNISIA | Arabic (Tunisia)
0x08 | SUBLANG_ARABIC_OMAN | Arabic (Oman)
0x09 | SUBLANG_ARABIC_YEMEN | Arabic (Yemen)
0x10 | SUBLANG_ARABIC_SYRIA | Arabic (Syria)
0x11 | SUBLANG_ARABIC_JORDAN | Arabic (Jordan)
0x12 | SUBLANG_ARABIC_LEBANON | Arabic (Lebanon)
0x13 | SUBLANG_ARABIC_KUWAIT | Arabic (Kuwait)
0x14 | SUBLANG_ARABIC_UAE | Arabic (U.A.E.)
0x15 | SUBLANG_ARABIC_BAHRAIN | Arabic (Bahrain)
0x16 | SUBLANG_ARABIC_QATAR | Arabic (Qatar)
0x01 | SUBLANG_AZERI_CYRILLIC | Azeri (Latin)
0x02 | SUBLANG_AZERI_LATIN | Azeri (Cyrillic)
0x01 | SUBLANG_CHINESE_TRADITIONAL | Chinese (Traditional)
0x02 | SUBLANG_CHINESE_SIMPLIFIED | Chinese (Simplified)
0x03 | SUBLANG_CHINESE_HONGKONG | Chinese (Hong Kong SAR, PRC)
0x04 | SUBLANG_CHINESE_SINGAPORE | Chinese (Singapore)
0x05 | SUBLANG_CHINESE_MACAU | Chinese (Macau)
0x01 | SUBLANG_DUTCH | Dutch
0x02 | SUBLANG_DUTCH_BELGIAN | Dutch (Belgian)
0x01 | SUBLANG_ENGLISH_US | English (US)
0x02 | SUBLANG_ENGLISH_UK | English (UK)
0x03 | SUBLANG_ENGLISH_AUS | English (Australian)
0x04 | SUBLANG_ENGLISH_CAN | English (Canadian)
0x05 | SUBLANG_ENGLISH_NZ | English (New Zealand)
0x06 | SUBLANG_ENGLISH_EIRE | English (Ireland)
0x07 | SUBLANG_ENGLISH_SOUTH_AFRICA | English (South Africa)
0x08 | SUBLANG_ENGLISH_JAMAICA | English (Jamaica)
0x09 | SUBLANG_ENGLISH_CARIBBEAN | English (Caribbean)
0x0a | SUBLANG_ENGLISH_BELIZE | English (Belize)
0x0b | SUBLANG_ENGLISH_TRINIDAD | English (Trinidad)
0x0c | SUBLANG_ENGLISH_PHILIPPINES | English (Zimbabwe)
0x0d | SUBLANG_ENGLISH_ZIMBABWE | English (Philippines)
0x01 | SUBLANG_FRENCH | French
0x02 | SUBLANG_FRENCH_BELGIAN | French (Belgian)
0x03 | SUBLANG_FRENCH_CANADIAN | French (Canadian)
0x04 | SUBLANG_FRENCH_SWISS | French (Swiss)
0x05 | SUBLANG_FRENCH_LUXEMBOURG | French (Luxembourg)
0x06 | SUBLANG_FRENCH_MONACO | French (Monaco)
0x01 | SUBLANG_GERMAN | German
0x02 | SUBLANG_GERMAN_SWISS | German (Swiss)
0x03 | SUBLANG_GERMAN_AUSTRIAN | German (Austrian)
0x04 | SUBLANG_GERMAN_LUXEMBOURG | German (Luxembourg)
0x05 | SUBLANG_GERMAN_LIECHTENSTEIN | German (Liechtenstein)
0x01 | SUBLANG_ITALIAN | Italian
0x02 | SUBLANG_ITALIAN_SWISS | Italian (Swiss)
0x02 | SUBLANG_KASHMIRI_INDIA | Kashmiri (India)
0x01 | SUBLANG_KOREAN | Korean
0x01 | SUBLANG_LITHUANIAN | Lithuanian
0x02 | SUBLANG_LITHUANIAN_CLASSIC | Lithuanian (Classic)
0x01 | SUBLANG_MALAY_MALAYSIA | Malay (Malaysia)
0x02 | SUBLANG_MALAY_BRUNEI_DARUSSALAM | Malay (Brunei Darassalam)
0x02 | SUBLANG_NEPALI_INDIA | Nepali (India)
0x01 | SUBLANG_NORWEGIAN_BOKMAL | Norwegian (Bokmal)
0x02 | SUBLANG_NORWEGIAN_NYNORSK | Norwegian (Nynorsk)
0x01 | SUBLANG_PORTUGUESE | Portuguese (Brazilian)
0x02 | SUBLANG_PORTUGUESE_BRAZILIAN | Portuguese
0x02 | SUBLANG_SERBIAN_LATIN | Serbian (Latin)
0x03 | SUBLANG_SERBIAN_CYRILLIC | Serbian (Cyrillic)
0x01 | SUBLANG_SPANISH | Spanish (Castilian)
0x02 | SUBLANG_SPANISH_MEXICAN | Spanish (Mexican)
0x03 | SUBLANG_SPANISH_MODERN | Spanish (Modern)
0x04 | SUBLANG_SPANISH_GUATEMALA | Spanish (Guatemala)
0x05 | SUBLANG_SPANISH_COSTA_RICA | Spanish (Costa Rica)
0x06 | SUBLANG_SPANISH_PANAMA | Spanish (Panama)
0x07 | SUBLANG_SPANISH_DOMINICAN_REPUBLIC | Spanish (Dominican Republic)
0x08 | SUBLANG_SPANISH_VENEZUELA | Spanish (Venezuela)
0x09 | SUBLANG_SPANISH_COLOMBIA | Spanish (Colombia)
0x0a | SUBLANG_SPANISH_PERU | Spanish (Peru)
0x0b | SUBLANG_SPANISH_ARGENTINA | Spanish (Argentina)
0x0c | SUBLANG_SPANISH_ECUADOR | Spanish (Ecuador)
0x0d | SUBLANG_SPANISH_CHILE | Spanish (Chile)
0x0e | SUBLANG_SPANISH_URUGUAY | Spanish (Uruguay)
0x0f | SUBLANG_SPANISH_PARAGUAY | Spanish (Paraguay)
0x10 | SUBLANG_SPANISH_BOLIVIA | Spanish (Bolivia)
0x11 | SUBLANG_SPANISH_EL_SALVADOR | Spanish (El Salvador)
0x12 | SUBLANG_SPANISH_HONDURAS | Spanish (Honduras)
0x13 | SUBLANG_SPANISH_NICARAGUA | Spanish (Nicaragua)
0x14 | SUBLANG_SPANISH_PUERTO_RICO | Spanish (Puerto Rico)
0x01 | SUBLANG_SWEDISH | Swedish
0x02 | SUBLANG_SWEDISH_FINLAND | Swedish (Finland)
0x01 | SUBLANG_URDU_PAKISTAN | Urdu (Pakistan)
0x02 | SUBLANG_URDU_INDIA | Urdu (India)
0x01 | SUBLANG_UZBEK_LATIN | Uzbek (Latin)
0x02 | SUBLANG_UZBEK_CYRILLIC | Uzbek (Cyrillic)


Language Identifiers

The following are language identifiers. They are composed of a primary language identifier and a secondary language identifier.

The following identifiers were composed using the MAKELANGID macro.

Identifier | Language
0x0000 | Language Neutral
0x0400 | Process Default Language
0x0401 | Arabic (Saudi Arabia)
0x0801 | Arabic (Iraq)
0x0c01 | Arabic (Egypt)
0x1001 | Arabic (Libya)
0x1401 | Arabic (Algeria)
0x1801 | Arabic (Morocco)
0x1c01 | Arabic (Tunisia)
0x2001 | Arabic (Oman)
0x2401 | Arabic (Yemen)
0x2801 | Arabic (Syria)
0x2c01 | Arabic (Jordan)
0x3001 | Arabic (Lebanon)
0x3401 | Arabic (Kuwait)
0x3801 | Arabic (U.A.E.)
0x3c01 | Arabic (Bahrain)
0x4001 | Arabic (Qatar)
0x0402 | Bulgarian
0x0403 | Catalan
0x0404 | Chinese (Taiwan Region)
0x0804 | Chinese (PRC)
0x0c04 | Chinese (Hong Kong SAR, PRC)
0x1004 | Chinese (Singapore)
0x0405 | Czech
0x0406 | Danish
0x0407 | German (Standard)
0x0807 | German (Swiss)
0x0c07 | German (Austrian)
0x1007 | German (Luxembourg)
0x1407 | German (Liechtenstein)
0x0408 | Greek
0x0409 | English (United States)
0x0809 | English (United Kingdom)
0x0c09 | English (Australian)
0x1009 | English (Canadian)
0x1409 | English (New Zealand)
0x1809 | English (Ireland)
0x1c09 | English (South Africa)
0x2009 | English (Jamaica)
0x2409 | English (Caribbean)
0x2809 | English (Belize)
0x2c09 | English (Trinidad)
0x040a | Spanish (Traditional Sort)
0x080a | Spanish (Mexican)
0x0c0a | Spanish (Modern Sort)
0x100a | Spanish (Guatemala)
0x140a | Spanish (Costa Rica)
0x180a | Spanish (Panama)
0x1c0a | Spanish (Dominican Republic)
0x200a | Spanish (Venezuela)
0x240a | Spanish (Colombia)
0x280a | Spanish (Peru)
0x2c0a | Spanish (Argentina)
0x300a | Spanish (Ecuador)
0x340a | Spanish (Chile)
0x380a | Spanish (Uruguay)
0x3c0a | Spanish (Paraguay)
0x400a | Spanish (Bolivia)
0x440a | Spanish (El Salvador)
0x480a | Spanish (Honduras)
0x4c0a | Spanish (Nicaragua)
0x500a | Spanish (Puerto Rico)
0x040b | Finnish
0x040c | French (Standard)
0x080c | French (Belgian)
0x0c0c | French (Canadian)
0x100c | French (Swiss)
0x140c | French (Luxembourg)
0x040d | Hebrew
0x040e | Hungarian
0x040f | Icelandic
0x0410 | Italian (Standard)
0x0810 | Italian (Swiss)
0x0411 | Japanese
0x0412 | Korean
0x0812 | Korean (Johab)
0x0413 | Dutch (Standard)
0x0813 | Dutch (Belgian)
0x0414 | Norwegian (Bokmal)
0x0814 | Norwegian (Nynorsk)
0x0415 | Polish
0x0416 | Portuguese (Brazilian)
0x0816 | Portuguese (Standard)
0x0418 | Romanian
0x0419 | Russian
0x041a | Croatian
0x081a | Serbian (Latin)
0x0c1a | Serbian (Cyrillic)
0x041b | Slovak
0x041c | Albanian
0x041d | Swedish
0x081d | Swedish (Finland)
0x041e | Thai
0x041f | Turkish
0x0421 | Indonesian
0x0422 | Ukrainian
0x0423 | Belarusian
0x0424 | Slovenian
0x0425 | Estonian
0x0426 | Latvian
0x0427 | Lithuanian
0x0429 | Farsi
0x042a | Vietnamese
0x042d | Basque
0x0436 | Afrikaans
0x0438 | Faeroese


Calendar Type Information

The following are calendar types.

Type | Description
CAL_ICALINTVALUE | An integer value indicating the calendar type of the alternate calendar.
CAL_IYEAROFFSETRANGE | One or more null-terminated strings that specify the year offsets for each of the era ranges. The last string has an extra terminating null character.
CAL_SABBREVDAYNAME1 | Abbreviated native name of the first day of the week.
CAL_SABBREVDAYNAME2 | Abbreviated native name of the second day of the week.
CAL_SABBREVDAYNAME3 | Abbreviated native name of the third day of the week.
CAL_SABBREVDAYNAME4 | Abbreviated native name of the fourth day of the week.
CAL_SABBREVDAYNAME5 | Abbreviated native name of the fifth day of the week.
CAL_SABBREVDAYNAME6 | Abbreviated native name of the sixth day of the week.
CAL_SABBREVDAYNAME7 | Abbreviated native name of the seventh day of the week.
CAL_SABBREVMONTHNAME1 | Abbreviated native name of the first month of the year.
CAL_SABBREVMONTHNAME2 | Abbreviated native name of the second month of the year.
CAL_SABBREVMONTHNAME3 | Abbreviated native name of the third month of the year.
CAL_SABBREVMONTHNAME4 | Abbreviated native name of the fourth month of the year.
CAL_SABBREVMONTHNAME5 | Abbreviated native name of the fifth month of the year.
CAL_SABBREVMONTHNAME6 | Abbreviated native name of the sixth month of the year.
CAL_SABBREVMONTHNAME7 | Abbreviated native name of the seventh month of the year.
CAL_SABBREVMONTHNAME8 | Abbreviated native name of the eighth month of the year.
CAL_SABBREVMONTHNAME9 | Abbreviated native name of the ninth month of the year.
CAL_SABBREVMONTHNAME10 | Abbreviated native name of the tenth month of the year.
CAL_SABBREVMONTHNAME11 | Abbreviated native name of the eleventh month of the year.
CAL_SABBREVMONTHNAME12 | Abbreviated native name of the twelfth month of the year.
CAL_SABBREVMONTHNAME13 | Abbreviated native name of the thirteenth month of the year, if it exists.
CAL_SCALNAME | The native name of the alternate calendar.
CAL_SDAYNAME1 | Native name of the first day of the week.
CAL_SDAYNAME2 | Native name of the second day of the week.
CAL_SDAYNAME3 | Native name of the third day of the week.
CAL_SDAYNAME4 | Native name of the fourth day of the week.
CAL_SDAYNAME5 | Native name of the fifth day of the week.
CAL_SDAYNAME6 | Native name of the sixth day of the week.
CAL_SDAYNAME7 | Native name of the seventh day of the week.
CAL_SERASTRING | One or more null-terminated strings that specify each of the Unicode codepoints specifying the era associated with the given CAL_IYEAROFFSETRANGE. The last string has an extra terminating null character. See example below.
CAL_SLONGDATE | Long date formats for this calendar type.
CAL_SMONTHNAME1 | Native name of the first month of the year.
CAL_SMONTHNAME2 | Native name of the second month of the year.
CAL_SMONTHNAME3 | Native name of the fifth month of the year.
CAL_SMONTHNAME4 | Native name of the fourth month of the year.
CAL_SMONTHNAME5 | Native name of the fifth month of the year.
CAL_SMONTHNAME6 | Native name of the sixth month of the year.
CAL_SMONTHNAME7 | Native name of the seventh month of the year.
CAL_SMONTHNAME8 | Native name of the eighth month of the year.
CAL_SMONTHNAME9 | Native name of the ninth month of the year.
CAL_SMONTHNAME10 | Native name of the tenth month of the year.
CAL_SMONTHNAME11 | Native name of the eleventh month of the year.
CAL_SMONTHNAME12 | Native name of the twelfth month of the year.
CAL_SMONTHNAME13 | Native name of the thirteenth month of the year, if it exists.
CAL_SSHORTDATE | Short date formats for this calendar type.
CAL_SYEARMONTH | Windows NT 5.0 or later: Enumerates the year/month formats for the specified calendars.

If the native name for the day of the week or for a month is an empty string, that name is identical to the name given in the corresponding locale information and therefore is not duplicated here.

The CAL_IYEAROFFSETRANGE and CAL_SERASTRING values vary in format depending on the type of optional calendar. The following example shows the values for these types (for each supported alternate calendar type) along with the formula for how to use the CAL_IYEAROFFSETRANGE value to compute the correct year given the Gregorian current year value Y:

CAL_ICALINTVALUE = "1"
CAL_IYEAROFFSETRANGE = ""
CAL_SERASTRING = ""

CAL_ICALINTVALUE = "2"
CAL_IYEAROFFSETRANGE = ""
CAL_SERASTRING = ""

CAL_ICALINTVALUE = "3"
CAL_IYEAROFFSETRANGE = "1989\01926\01912\01868\0"
CAL_SERASTRING = "Ux337B\0Ux337C\0Ux337D\0Ux337E\0"
if (Y>=1989) { Y = (Y-1989)+1; }
if (Y>=1926 && Y<1989) { Y = (Y-1926)+1; }
if (Y>=1912 && Y<1926) { Y = (Y-1912)+1; }
if (Y>=1868 && Y<1912) { Y = (Y-1868)+1; }
if (Y<1868) { Y = Y; }

CAL_ICALINTVALUE = "4"
CAL_IYEAROFFSETRANGE = "1912\0"
CAL_SERASTRING = "Ux4E2D\0Ux83EF\0Ux6C11\0Ux570B\0"
if (Y>=1912) { Y = (Y-1912)+1; }
if (Y<1912) { Y = Y; }

CAL_ICALINTVALUE = "5"
CAL_IYEAROFFSETRANGE = "2333\0"
CAL_SERASTRING = ""
Y = Y+2333;


Language Code and Scripts

The following table shows language codes and scripts.

Language | Code | Script
Greek | ELL | Other
Russian | RUS | Cyrillic
Turkish | TRK | Latin 2
Polish | PLK | Latin 2
Czech | CSY | Latin 2
Slovak | SKY | Latin 2
Hungarian | HUN | Latin 2
Danish | DAN | Latin 1
Dutch (Standard) | NLD | Latin 1
Belgian (Flemish) | NLB | Latin 1
English (American) | ENU | Latin 1
English (British) | ENG | Latin 1
English (Australian) | ENA | Latin 1
English (Canadian) | ENC | Latin 1
English (New Zealand) | ENZ | Latin 1
English (Ireland) | ENI | Latin 1
Finnish | FIN | Latin 1
French (Standard) | FRA | Latin 1
French (Belgian) | FRB | Latin 1
French (Canadian) | FRC | Latin 1
French (Swiss) | FRS | Latin 1
German (Standard) | DEU | Latin 1
German (Swiss) | DES | Latin 1
German (Austrian) | DEA | Latin 1
Icelandic | ISL | Latin 1
Italian (Standard) | ITA | Latin 1
Italian (Swiss) | ITS | Latin 1
Norwegian (Bokmal) | NOR | Latin 1
Norwegian (Nynorsk) | NON | Latin 1
Portuguese (Brazilian) | PTB | Latin 1
Portuguese (Standard) | PTG | Latin 1
Swedish | SVE | Latin 1
Spanish (Standard/Traditional) | ESP | Latin 1
Spanish (Mexican) | ESM | Latin 1
Spanish (Modern) | ESN | Latin 1


Unicode and Character Sets

The Microsoft® Win32® API provides support for the many different written languages of the international marketplace through Unicode and traditional character sets. Unicode is a worldwide character-encoding standard that uses 16-bit character values to represent all the characters used in modern computing, including technical symbols and special characters used in publishing. Traditional character sets are previous character-encoding standards, such as the Windows ANSI character set, that use 8-bit character values or combinations of 8-bit values to represent the characters used in a specific language or geographical region.

This overview describes the character set functions and explains how to use them in your Win32-based applications.


About Unicode and Character Sets

Because the world's character-based data has been developed using both Unicode and traditional characters sets, the Microsoft® Win32® API provides character set functions that help Win32-based applications convert the character-based data from its original character set to Unicode or another traditional character set. Because not all operating systems support Unicode, these character set functions also help Win32-based applications create character-based data that may be transferred to and used on any operating system.

For details about Unicode beyond the scope of this overview, see The Unicode™ Standard: Worldwide Character Encoding, Version 2.0, Addison-Wesley Publishing Company: 1991–1992, ISBN 0-201-48345-9.

This section provides detailed reference information for the character set functions, structures, and messages. The information is separated into the following functional groups.


Character Sets

A character set is a mapping of characters to their identifying numeric values. Most of the character sets commonly used in computers are single-byte character sets in which each character is identified by a value one byte wide. The large number of characters in Asian languages led to the development of multibyte character sets, in particular the double-byte character set (DBCS). Microsoft® Windows NT® incorporates a new global standard for character encoding: Unicode.

For more information, see the following topics:

  • Single-byte Character Sets
  • Double-byte Character Sets
  • Unicode


Single-byte Character Sets

A single-byte character set is a mapping of 256 individual characters to their identifying numeric values. The character codes 0x20 through 0x7E represent standardized displayable characters, but the characters represented by the remaining codes vary among character sets. The ASCII character set covers the range 0x00 through 0x7F.

The ANSI character set is used in window manager and graphics device interface (GDI), but the MS-DOS file allocation table (FAT) file system uses a character set called the original equipment manufacturer (OEM) character set. Variations on the character sets, called code pages, include different special characters, typically customized for a language or group of languages. The OEM code page generally used in the United States is code page 437.

Win32-based applications can use Unicode to avoid the inconsistencies of varied code pages and as an aid in developing easily localized applications.

An application can use the GetACP function to retrieve the ANSI code-page identifier for the system or use the GetOEMCP function to retrieve the OEM code-page identifier.

The OemToChar and OemToCharBuff functions allow an application to convert a character or string from the OEM code page to either the ANSI code page or Unicode. To convert in the other direction, you can use either the CharToOem or CharToOemBuff function. In addition, an application can use the MultiByteToWideChar and WideCharToMultiByte functions to map single-byte character set (SBCS) strings to Unicode and Unicode strings to SBCS strings.

The GetCPInfo function fills a CPINFO structure with information that includes the size, in bytes, of the largest character in the code page and the default character used when a character code is entered that has no corresponding entry in the code page.


Double-byte Character Sets

The double-byte character set (DBCS) is called an expanded 8-bit character set because its smallest unit is a byte. It can be thought of as the ANSI character set for some Asian versions of Microsoft® Windows NT®, Windows® 95, and Windows® 98 (particularly the Japanese versions). Win32 functions for the Japanese versions of Windows NT, Windows 95, and Windows 98 accept DBCS strings for the ANSI versions of the functions. However, unlike the handling of Unicode, DBCS character handling requires detailed changes in the character-processing algorithms throughout an application's source code.

An application can use the IsDBCSLeadByte function to determine whether a given character is the first byte in a 2-byte character; this helps identify double-byte character sets. In addition, an application can use the MultiByteToWideChar and WideCharToMultiByte functions to map DBCS strings to Unicode and Unicode strings to DBCS strings.


Unicode

Unicode is a worldwide character-encoding standard. Windows NT uses it exclusively at the system level for character and string manipulation. Unicode simplifies localization of software and improves multilingual text processing. By implementing it in your applications, you can enable the application with universal data exchange capabilities for global marketing, using a single binary file for every possible character code.

Unicode defines semantics for each character, standardizes script behavior, provides a standard algorithm for bidirectional text, and defines cross-mappings to other standards. Among the scripts supported by Unicode are Latin, Greek, Han, Hiragana, and Katakana. Supported languages include, but are not limited to, German, French, English, Greek, Chinese, and Japanese.

Unicode can represent all the world's characters in modern computer use, including technical symbols and special characters used in publishing. Because each Unicode character is 16 bits wide, it is possible to have separate values for up to 65,536 characters. Unicode-enabled functions are often referred to as "wide-character" functions.

Win32 functions support applications that use either Unicode or the regular ANSI character set. Mixed use in the same application is also possible. Adding Unicode support to an application is easy, and you can even maintain a single set of sources from which to compile an application that supports either Unicode or the Windows ANSI character set.

Win32 functions support Unicode by assigning its strings a specific data type and providing a separate set of entry points and messages to support this new data type. A series of macros and naming conventions make transparent migration to Unicode, or even compiling both non-Unicode and Unicode versions of an application from the same set of sources, a straightforward matter.

Implementing Unicode as a separate data type also enables the compiler's type checking to ensure that only Unicode parameters are used with functions expecting Unicode strings.


Unicode in the Win32 API

Win32 API elements that use characters are generally implemented in one of three formats:

  • A generic version that can be compiled for either ANSI or Unicode
  • An ANSI version
  • A Unicode version

The following topics discuss Unicode data types and how they are used in functions and messages; the use of resources, filenames, and command-line arguments; and methods of translating between different types of strings.

  • Win32 Data Types
  • Win32 Function Prototypes
  • Message Translation
  • String Functions
  • Standard C Functions
  • Character Sets Used in Filenames
  • Translation Between String Types
  • Command-line Arguments


Win32 Data Types

Most string operations for Unicode can be written by using the same logic used for handling the Windows ANSI character set, except that the basic unit of operation is a 16-bit character instead of an 8-bit byte. The Platform SDK header files provide a number of type definitions that make it easy to create sources that can be compiled for Unicode or for the ANSI character set.

The following example shows the method used in the Platform SDK header files to define three sets of data types: a set of generic type definitions that can compile for either ANSI or Unicode, and two sets of specific type definitions. The first set of specific type definitions is for use with the existing Windows (ANSI) character set, and the other is for use with Unicode (or wide) characters.

// Generic types

#ifdef UNICODE
    typedef wchar_t TCHAR;
#else
    typedef unsigned char TCHAR;
#endif

typedef TCHAR * LPTSTR, *LPTCH;

// 8-bit character specific

typedef unsigned char CHAR;
typedef CHAR *LPSTR, *LPCH;

// Unicode specific (wide characters)

typedef unsigned wchar_t WCHAR;
typedef WCHAR *LPWSTR, *LPWCH;

The letter T in a type definition designates a generic type that can be compiled for either ANSI or Unicode. The letter W in a type definition designates a wide-character (Unicode) type. For the actual implementation of this method, see the WINNT.H header file.

An application using generic data types can be compiled for Unicode simply by defining UNICODE before the include statements for the header files, OR DURING COMPILATION. To compile the code for ANSI, omit the UNICODE definition. It is best to use the generic data types, but the specific types exist for applications that require mixed types.


Win32 Function Prototypes

Win32 function prototypes are provided in generic, ANSI, and Unicode versions, as shown following. The generic function prototype is provided in the documentation. For example, the following is the generic prototype for the SetWindowText function.

Generic Prototype:

BOOL SetWindowText(
  HWND hwnd,
  LPCTSTR lpText
);

The header file provides the generic function name implemented as a macro.

#ifdef UNICODE
#define SetWindowText SetWindowTextW
#else
#define SetWindowText SetWindowTextA
#endif // !UNICODE

The preprocessor expands the macro into either the ANSI or Unicode function names, depending on whether UNICODE is defined. The letter A (ANSI) or W (wide) is added at the end of the generic function name, as appropriate. The header file then provides ANSI and Unicode function prototypes, as shown in the following examples.

ANSI Prototype:

BOOL
WINAPI
SetWindowTextA(
    HWND hwnd,
    LPCSTR lpText );

Unicode Prototype:

BOOL
WINAPI
SetWindowTextW(
    HWND hwnd,
    LPCWSTR lpText );

Note that the generic function prototype uses the generic LPCTSTR for the text parameter, but the ANSI prototype uses LPCSTR and the Unicode prototype uses LPCWSTR.

You can call the generic function in your application, then define UNICODE when you compile the code to use the Unicode function. To default to the ANSI function, do not define UNICODE. You can mix function calls by using the explicit function names ending with A and W.

This approach applies to all functions with text arguments. Always use a generic function prototype with the generic string and character types. All function names that end with an uppercase W take wide-character arguments. Some functions exist only in wide-character versions and can be used only with the appropriate data types.

The QuickInfo section in the documentation for each function provides information on the function versions implemented by the system. The QuickInfo section indicates whether a function has both a Unicode and an ANSI version, or whether the function accepts only Unicode strings.

Note Whenever a function has a length parameter for a character string, the length should be documented as a count of TCHAR values in the string. However, functions that require or return pointers to untyped memory blocks, such as the GlobalAlloc function, are exceptions.


Message Translation

Although applications generally use the same window class, messages between windows of different classes are transparently translated by the system.

Even though a window function is implemented to receive messages in Unicode or ANSI format, the window procedure can still send messages or call functions of either type.

The following messages have text arguments and are subject to automatic text translation. (For information about automatic translation, see Subclassing and Automatic Message Translation.)

CB_ADDSTRING WM_ASKCBFORMATNAME
CB_DIR WM_CHAR
CB_FINDSTRING WM_CHARTOITEM
CB_GETLBTEXT WM_CREATE
CB_INSERTSTRING WM_DEADCHAR
CB_SELECTSTRING WM_DEVMODECHANGE
WM_GETTEXT
EM_GETLINE WM_MDICREATE
EM_REPLACESEL WM_MENUCHAR
EM_SETPASSWORDCHAR WM_NCCREATE
WM_SETTEXT
LB_ADDFILE WM_SYSCHAR
LB_ADDSTRING WM_SYSDEADCHAR
LB_DIR WM_WININICHANGE
LB_FINDSTRING
LB_GETTEXT
LB_INSERTSTRING
LB_SELECTSTRING


String Functions

All of the string functions listed in this section exist in ANSI and Unicode implementations to support ANSI and Unicode arguments. There are, however, subtle differences among some of them.

The following string functions do not require special comment; their ANSI and Unicode implementations work identically.

CharNext
CharPrev
lstrcat
lstrcpy
lstrlen

The value returned by the lstrlen function is always the number of characters, regardless of whether the ANSI or Unicode form is used.

The following string functions are sensitive to the locale of the current thread (as derived from the locale the user selects in Control Panel). The lstrcmp and lstrcmpi functions do not perform byte comparisons like their ANSI C namesakes; they compare strings according to the rules of the selected locale.

CharLower
CharLowerBuff
CharUpper
CharUpperBuff
lstrcmp
lstrcmpi

The following functions convert between the OEM character set and either ANSI or Unicode, depending on which version is used.

CharToOem
CharToOemBuff
OemToChar
OemToCharBuff

The print function wsprintf supports Unicode by providing the following new and changed data types in its format specifications. These format specifications affect the way the wsprintf function interprets the corresponding passed-in parameter.

Format specification | ANSI version | Unicode version
c | CHAR | WCHAR
C | WCHAR | CHAR
hc, hC | CHAR | CHAR
hs, hS | LPSTR | LPSTR
lc, lC | WCHAR | WCHAR
ls, lS | LPWSTR | LPWSTR
s | LPSTR | LPWSTR
S | LPWSTR | LPSTR

The data type for the output text always depends on the version of the function. Where the data type of the passed-in parameter and of the output text do not agree, wsprintf will perform a conversion from Unicode to ANSI, or vice versa, as required.

For the Unicode version of wsprintf, the format string is Unicode, as is the output text.


Standard C Functions

The standard C run-time libraries contain wide-character versions of the ANSI string functions that begin with the letters str. The wide-character versions of the functions start with the letters wcs (or sometimes _wcs). The Unicode data type is compatible with the wide-character data type wchar_t in ANSI C; this allows access to the wide-character string functions.

Generic functions exist for all standard C string functions. They start with the letters _tcs and are listed in the TCHAR.H header file. These functions use the generic data types TCHAR and TCHAR*

An application must add the following lines to its program in order to use the generic functions and compile for Unicode:

#define _UNICODE

     #include <tchar.h>
     #include <wchar.h>

Note that both the TCHAR.H and WCHAR.H are required, and that the leading underscore on the _UNICODE variable is also required.

The wcstombs and mbstowcs functions can convert from the character set supported by the standard C library to Unicode and back, with some limitations. For more information about translating strings to and from Unicode, see Translation Between String Types.

The printf function defined in TCHAR.H supports the same format specifications as wsprintf; for details, see String Functions. Similarly, TCHAR.H contains a wprintf function, in which the format string itself is a Unicode string.


Character Sets Used in Filenames

Window manager and GDI use the ANSI character set; the MS-DOS FAT file system uses the OEM character set. Applications that create MS-DOS files sometimes have to use the CharToOem and OemToChar functions to translate between these character sets. However, NTFS is capable of storing filenames in Unicode; no translation is necessary with NTFS.

With Unicode implementations of the file-system functions, it is not necessary to perform translations to and from ANSI and OEM character sets. Instead, you can use a single source file to compile non-Unicode versions of an application by providing macros for functions that are not invoked when compiling for Unicode, such as CharToOem and OemToChar.

The special filename characters in MS-DOS are unchanged in Unicode filenames:

"\," "/," ".," "?," "*."

These special characters are in the ASCII range of characters (0x00 through 0x7F) and their Unicode equivalents are simply the same values in a 2-byte form: 0x0000 through 0x007F.


Translation Between String Types

The following Win32 functions translate character strings from one string type to another.

Function | Description
FoldString | Translates one character string to another.
LCMapString | Maps a character string by locale.
ToUnicode | Translates a virtual-key code into a Unicode character.
MultiByteToWideChar | Maps a multibyte string into a wide-character string.
WideCharToMultiByte | Maps a wide-character string into a multibyte string.

The WideCharToMultiByte and MultiByteToWideChar functions are particularly useful for applications that support several string types. ANSI C also defines the conversion functions wcstombs and mbstowcs, but they can only convert to and from the character set supported by the standard C library.


Command-line Arguments

An application can use the GetCommandLine function to retrieve Unicode command-line arguments by calling it as a Unicode function.


Using Strings and Unicode

  • Using generic data types
  • Registering window classes
  • Subclassing and automatic message translation
  • Using special characters in Unicode
  • Using functions that have no Unicode equivalents


Using Generic Data Types

If you use generic data types in your code, it can be compiled for Unicode simply by defining UNICODE before the include statements for the header files. To compile the code for ANSI, omit the UNICODE definition.

To convert code that processes strings so it can be compiled for either ANSI or Unicode, follow these steps.

  1. Change all character and string types used for text to TCHAR, LPTSTR, or LPTCH.
  2. Be sure that pointers to nontext data buffers or binary byte arrays are coded with the LPBYTE type and not mistakenly with the LPTSTR or LPTCH type. Declare pointers of indeterminate type explicitly as void pointers by using LPVOID, as appropriate.
  3. Make pointer arithmetic type-independent. Using units of TCHAR size yields variables that are two bytes if UNICODE is defined, and one byte if UNICODE is not defined. Using pointer arithmetic always returns the number of elements pointed to by the pointer, whether the elements are one or two bytes in size. The following expression always returns the number of elements, regardless of whether UNICODE is defined:
    cCount = lpEnd - lpStart;

    The following expression determines the number of bytes used:

    cByteCount = (lpEnd - lpStart) * sizeof(TCHAR);

    There is no need to change a statement like the following one, because the pointer increment points to the next character element.

    chNext = *++lpText;
  4. Replace literal strings and manifest character constants with macros. Change expressions like the following one.
    while(*lpFileName++ != '\\')
    {
    // ...
    }

    Use the TEXT macro as follows in this expression.

    while(*lpFileName++ != TEXT('\\'))
    {
    // ...
    }

    The TEXT macro causes strings to be evaluated as L"string" when UNICODE is defined, and to "string" otherwise. For easier management, move literal strings into resources, especially if they contain characters outside the ASCII range (that is, 0x00 through 0x7F).

  5. Call only the Unicode versions of the standard C library string functions, as listed in Standard C Functions ›.
  6. Change any code that relies on 255 as the largest value for a character.

When you compile code that you have changed as outlined above, the compiler creates the same binary file as it did before you made the changes. When you define UNICODE during compilation, however, it is compiled as a Unicode application.


Registering Window Classes

A window class is supported by a window procedure. You can register a window class by using either the RegisterClassA or RegisterClassW function. If you register the window class by using RegisterClassA, the application tells the system that the windows of the created class expect messages with text or character parameters to use the ANSI character set; if you register it by using RegisterClassW, the application requests that the system pass text parameters of messages as Unicode. The IsWindowUnicode function enables applications to query the nature of each window.

The following example shows how to register an ANSI window class and a Unicode window class and how to write the window procedures for both cases. For the purposes of this example, all functions and structures are shown with the specific A or W data types. Using the techniques explained in Using Generic Data Types, you could alternatively write this example by using generic data types, so that it could be compiled as either ANSI or Unicode, depending on whether UNICODE is defined.

// Register an ANSI window class.

WNDCLASSA AnsiWndCls;

AnsiWndCls.style         = CS_DBLCLKS | CS_PARENTDC;
AnsiWndCls.lpfnWndProc   = (WNDPROC)AnsiWndProc;
AnsiWndCls.cbClsExtra    = 0;
AnsiWndCls.cbWndExtra    = 0;
AnsiWndCls.hInstance     = hmodUser;
AnsiWndCls.hIcon         = NULL;
AnsiWndCls.hCursor       = LoadCursor(NULL, (LPTSTR)IDC_IBEAM);
AnsiWndCls.hbrBackground = NULL;
AnsiWndCls.lpszMenuName  = NULL;
AnsiWndCls.lpszClassName = "TestAnsi";

RegisterClassA(&AnsiWndCls);

// Register a Unicode window class.

WNDCLASSW UnicodeWndCls;

UnicodeWndCls.style         = CS_DBLCLKS | CS_PARENTDC;
UnicodeWndCls.lpfnWndProc   = (WNDPROC)UniWndProc;
UnicodeWndCls.cbClsExtra    = 0;
UnicodeWndCls.cbWndExtra    = 0;
UnicodeWndCls.hInstance     = hmodUser;
UnicodeWndCls.hIcon         = NULL;
UnicodeWndCls.hCursor       = LoadCursor(NULL,(LPTSTR)IDC_IBEAM);
UnicodeWndCls.hbrBackground = NULL;
UnicodeWndCls.lpszMenuName  = NULL;
UnicodeWndCls.lpszClassName = L"TestUnicode";

RegisterClassW(&UnicodeWndCls);

The following example shows the difference between handling the WM_CHAR message in an ANSI window procedure and a Unicode window procedure.

// ANSI Window Procedure

LONG AnsiWndProc(HWND hwnd, UINT message,
                 WPARAM wParam, LPARAM lParam)
{

    // Dispatch the messages that can be received.

    switch (message)
    {
        case WM_CHAR:

            // wParam - the value of the key
            // lParam - (not used in this example)

            if (lstrcmpA("Q", (LPCSTR) wParam))
            {
                // ...
            }
            else
            {
                // ...
            }
            break;
        // Process other messages.
    }
}

// Unicode Window Procedure

LONG UniWndProc(HWND hwnd, UINT message,
    WPARAM wParam, LPARAM lParam)
{

    // Dispatch the messages that can be received.

    switch (message)
    {
        case WM_CHAR:

            // wParam - the value of the key
            // lParam - (not used in this example)

            if (lstrcmpW(L"Q", (LPCWSTR) wParam))
            {
                // ...
            }
            else
            {
                // ...
            }
            break;
        // Process other messages.
    }
}

All text in messages received by AnsiWndProc will be composed of ANSI characters, and all text in messages received by UniWndProc will be composed of Unicode characters.


Subclassing and Automatic Message Translation

Subclassing is a technique that allows an application to intercept and process messages sent or posted to a particular window before the window has a chance to process them. The system automatically translates messages into ANSI or Unicode form, depending on the form of the function that subclassed the window procedure.

The following call to the SetWindowLongA function subclasses the current window procedure associated with the window identified by the hwnd parameter. The new window procedure, NewWndProc, will receive messages with text in ANSI format.

OldWndProc = (WNDPROC) SetWindowLongA(hwnd,
    GWL_WNDPROC, (LONG)NewWndProc);

When NewWndProc has finished processing a message, it uses the CallWindowProc function as follows to pass the message to OldWndProc.

CallWindowProc(OldWndProc, hwnd, uMessage, wParam, lParam);

If OldWndProc was created with a class style of UNICODE, messages will be translated from the ANSI form received by NewWndProc into Unicode.

Similarly, a call to the SetWindowLongW function would subclass the current window procedure with a window procedure that expects Unicode text messages. Message translation, if necessary, is performed during the processing of the CallWindowProc function.

For more information about subclassing, see Window Procedures.


Using Special Characters in Unicode

There are a few special characters and characters with unusual meanings in Unicode text strings. To avoid unexpected problems with these characters, use the rules provided in the following topics.

  • Null-terminated strings
  • Byte-order mark
  • Escape sequences and control characters
  • Line and paragraph separators
  • ASCII control codes 0x000D and 0x000A
  • Nonspacing characters and diacritics


Null-terminated Strings

Always cast zero to TCHAR when using null-terminated strings. The code 0x0000 is the Unicode string terminator for null-terminated strings. A single null byte is not sufficient for this code, because many Unicode characters contain null bytes as either the high or the low byte. An example is the letter A, for which the character code is 0x0041.


Byte-order Mark

Always prefix a Unicode plain text file with a byte-order mark. Because Unicode plain text is a sequence of 16-bit codes, it is sensitive to the byte ordering used when the text was written.

A byte-order mark is not a control character that selects the byte order of the text; it simply informs an application receiving the file that the file is byte ordered.

Ideally, all Unicode text would follow only one set of byte-ordering rules. This is not possible, however, because microprocessors differ in the position of the least significant byte: Intel® and MIPS® processors have the least significant byte first; Motorola processors (and byte-reversed Unicode files) have it last. With only a single set of byte-ordering rules, users of one type of microprocessor would be forced to swap the byte order every time a plain text file is read from or written to, even if the file is never transferred to another system based on a different microprocessor.

The preferred place to specify byte order is in a file header, but text files do not have headers. Therefore, Unicode has defined a character (0xFEFF) and a noncharacter (0xFFFE) as byte-order marks. They are mirror byte-images of each other.

Since the sequence 0xFEFF is exceedingly rare at the outset of regular non-Unicode text files, it can serve as an implicit marker or signature to identify the file as a Unicode file. Applications written to read both Unicode and non-Unicode text files should use the presence of this sequence as a near-certain indicator that the file is a Unicode file. (Compare this technique to using the MS-DOS EOF marker to terminate text files.)

When an application finds 0xFEFF at the beginning of a text file, it typically processes the file as though it were a Unicode file, although it may also perform further heuristic checks to verify that this is true. Such a check could be as simple as a test of whether the variation in the low-order bytes is much higher than the variation in the high-order bytes. For example, if ASCII text is converted to Unicode text, every second byte is zero. Also, checking both for the linefeed and carriage-return characters (0x000A and 0x000D) and for even or odd file size can provide a strong indicator of the nature of the file.

When an application finds 0xFFFE at the beginning of a text file, it interprets it to mean the file is a byte-reversed Unicode file. The application can either swap the order of the bytes or alert the user that an error has occurred.

The Unicode byte-order mark character is not found in any code page, so it disappears if data is converted to ANSI. Unlike other Unicode characters, it is not replaced by a default character when it is converted. If a byte-order mark is found in the middle of a file, it is not interpreted as a Unicode character and has no effect on text output.

The Unicode value 0xFFFF is illegal in plain text files and cannot be passed between Win32 functions. The value 0xFFFF is reserved for an application's private use.


Escape Sequences and Control Characters

Translate escape sequences character by character into Unicode. When an ASCII plain text file is converted to Unicode, there is a chance that it will subsequently be converted back to ASCII. Converting escape sequences into Unicode on a character-by-character basis, rather than as a single 2-byte characters makes it possible to perform the reverse conversion without recognizing and parsing the escape sequences as such. For example, esc+a should become 0x001B (esc), 0x0041 (A), rather than 0x411B.

The first 32 sixteen-bit characters in Unicode are intended for the 32 control characters. This approach supports the existing use of control characters for formatting purposes — that is, Unicode applications can treat these control characters in exactly the same way as they treat their ASCII equivalents.


Line and Paragraph Separators

Use the line-separator character (0x2028) and the paragraph-separator character (0x2029) to divide plain text. A new line is begun after each line separator. A new paragraph is begun after each paragraph separator.

Because these are separator codes, it is not necessary to start the first line or paragraph in the file with them, or to end the last line or paragraph with them. (Doing so would indicate that there is an empty line or paragraph in that location.)

The line separator can be used to indicate an unconditional end of line. However, line separators do not correspond to the carriage-return and linefeed characters, or to the carriage-return–linefeed character combination; they must be processed separately from carriage return and linefeed characters.

The paragraph separator can be inserted between paragraphs of text. This allows plain text files to be created that can be formatted with different line widths on different systems. The receiving system can ignore any line breaks and break paragraphs only at the paragraph separators.


ASCII Control Codes 0x000D and 0x000A

The Unicode standard does not prescribe a specific meaning for the control codes 0x000D (carriage return) and 0x000A (linefeed). There is no requirement that these codes be used in combination, and if used individually, either code may represent either itself only or both codes together. It is entirely up to the application to determine what these codes represent. (Applications have always had to interpret these control codes in ASCII; the Unicode policy is not a change in their use.)


Nonspacing Characters and Diacritics

When breaking lines or otherwise separating text, be sure to keep nonspacing characters with their base characters. Many scripts contain characters that visually combine with other characters on output — for example, the diacritical marks (or "floating accents"). In Unicode, nonspacing characters follow their base character.


Using Functions That Have No Unicode Equivalents

Win32 functions that have not been exported in a Unicode version have typically been replaced by more powerful or extended functions that do support Unicode. If you are porting code that calls the OpenFile function, for example, you can support Unicode by using the CreateFile function instead.

If a function has no Unicode equivalent, you can map characters to and from 8-bit character sets before and after the function call. For example, the number-formatting functions atoi and itoa use only the digits 0 through 9. Normally, mapping Unicode to 8-bit characters could cause loss of data, but you can avoid this by making your code type independent and conditionalizing the expressions. For example, the following statements are type dependent and should be changed to support Unicode.

char str[4];

    num = atoi(str);

These statements could be rewritten as follows to make them type independent.

TCHAR tstr[4];

    CHAR strTmp[SIZE];

    #ifdef UNICODE

    wcstombs(strTmp, (const wchar_t *) tstr, sizeof(strTmp));

    num = atoi(strTmp);

    #else

    num = atoi(tstr);

    #endif

In this example, the wcstombs function is the standard C function that translates Unicode to ASCII. The example relies on the fact that the digits 0 through 9 can always be translated from Unicode to ASCII, even if some of the surrounding text cannot. The atoi function stops at any character that is not a digit. You can use the LCMapString function if you need to process text that includes the native digits provided for some of the scripts in Unicode.


Unicode and Character Set Reference

The following elements are used with character sets.

  • Unicode and Character Set Functions
  • Unicode and Character Set Structures
  • Unicode and Character Set Macros
  • Unicode and Character Set Constants


Unicode and Character Set Functions

The following functions are used with character set.

GetTextCharset
GetTextCharsetInfo
IsDBCSLeadByte
IsDBCSLeadByteEx
IsTextUnicode
MultiByteToWideChar
TranslateCharsetInfo
WideCharToMultiByte


GetTextCharset

The GetTextCharset function obtains a character-set identifier for the font that is currently selected into a specified device context.

The function call GetTextCharset(hdc) is equivalent to the function call GetTextCharsetInfo(hdc, NULL, 0).

UINT GetTextCharsetInfo(
  HDC hdc,  // handle to device context
);

Parameters

hdc
Handle to a device context. The function obtains a character-set identifier for the font that is selected into this device context.

Return Values

If the function succeeds, the return value identifies the character set of the font that is currently selected into the specified device context. The following character-set identifiers are defined:

ANSI_CHARSET
BALTIC_CHARSET
CHINESEBIG5_CHARSET
DEFAULT_CHARSET
EASTEUROPE_CHARSET
GB2312_CHARSET
GREEK_CHARSET
HANGUL_CHARSET
MAC_CHARSET
OEM_CHARSET
RUSSIAN_CHARSET
SHIFTJIS_CHARSET
SYMBOL_CHARSET
TURKISH_CHARSET

Korean Windows:
JOHAB_CHARSET
Middle-Eastern Windows:
HEBREW_CHARSET
ARABIC_CHARSET
Thai Windows:
THAI_CHARSET

If the function fails, the return value is DEFAULT_CHARSET.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wingdi.h.
Import Library: Use gdi32.lib.

See Also

Unicode and Character Sets Overview, Unicode and Character Set Functions, GetTextCharsetInfo


GetTextCharsetInfo

The GetTextCharsetInfo function obtains information about the character set of the font that is currently selected into a specified device context.

UINT GetTextCharsetInfo(
  HDC hdc,                // handle to device context
  LPFONTSIGNATURE lpSig,  // pointer to structure to receive data
  DWORD dwFlags           // reserved; must be zero
);

Parameters

hdc
Handle to a device context. The function obtains information about the font that is selected into this device context.
lpSig
Pointer to a FONTSIGNATURE data structure that receives font-signature information.

If a TrueType font is currently selected into the device context, the FONTSIGNATURE structure receives information that identifies the codepage and Unicode subranges for which the font provides glyphs.

If a font other than TrueType is currently selected into the device context, the FONTSIGNATURE structure receives zeroes. In this case, use the TranslateCharsetInfo function to obtain generic font-signature information for the character set.

The lpSig parameter can be NULL if you do not need the FONTSIGNATURE information. In this case, you can also call the GetTextCharset function, which is equivalent to calling GetTextCharsetInfo with lpSig set to NULL.

dwFlags
This parameter is reserved for future use. It must be set to zero.

Return Values

If the function succeeds, the return value identifies the character set of the font currently selected into the specified device context. The following character-set identifiers are defined:

ANSI_CHARSET
BALTIC_CHARSET
CHINESEBIG5_CHARSET
DEFAULT_CHARSET
EASTEUROPE_CHARSET
GB2312_CHARSET
GREEK_CHARSET
HANGUL_CHARSET
MAC_CHARSET
OEM_CHARSET
RUSSIAN_CHARSET
SHIFTJIS_CHARSET
SYMBOL_CHARSET
TURKISH_CHARSET

Korean Windows:
JOHAB_CHARSET
Middle-Eastern Windows:
HEBREW_CHARSET
ARABIC_CHARSET
Thai Windows:
THAI_CHARSET

If the function fails, the return value is DEFAULT_CHARSET.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wingdi.h.
Import Library: Use gdi32.lib.

See Also

Unicode and Character Sets Overview, Unicode and Character Set Functions, FONTSIGNATURE, GetTextCharset, TranslateCharsetInfo


IsDBCSLeadByte

The IsDBCSLeadByte function determines whether a character is a lead byte — that is, the first byte of a character in a double-byte character set (DBCS).

BOOL IsDBCSLeadByte(
  BYTE TestChar   // character to test
);

Parameters

TestChar
Specifies the character to be tested.

Return Values

If the character is a lead byte, the return value is nonzero.

If the character is not a lead byte, the return value is zero. To get extended error information, call GetLastError.

Remarks

Lead bytes are unique to double-byte character sets. A lead byte introduces a double-byte character. Lead bytes occupy a specific range of byte values. The IsDBCSLeadByte function uses the ANSI code page to check lead-byte ranges. To specify a different code page, use the IsDBCSLeadByteEx function.

Windows CE: The IsDBCSLeadByte function returns the following values:

TRUE
The character is a lead byte.
FALSE
Either the character is not a lead byte, or an error was generated. Call GetLastError for extended error information.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

Unicode and Character Sets Overview, Unicode and Character Set Functions, IsDBCSLeadByteEx, MultiByteToWideChar


IsDBCSLeadByteEx

The IsDBCSLeadByteEx function determines whether a character is a lead byte — that is, the first byte of a character in a double-byte character set (DBCS).

BOOL IsDBCSLeadByteEx(
  UINT CodePage,   // identifier of code page
  BYTE TestChar    // character to test
);

Parameters

CodePage
Identifier of the code page to use to check lead-byte ranges. Can be one of the code-page values given in the "Code-Page Identifiers" table in Unicode and Character Set Constants or one of the following predefined values:
Value | Meaning
0 | Use system default ANSI code page.
CP_ACP | Use system default ANSI code page.
CP_OEMCP | Use system default OEM code page.

TestChar
Character to test.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Windows CE: The IsDBCSLeadByteEx function returns the following values:

TRUE
The character is a lead byte.
FALSE
Either the character is not a lead byte, or an error was generated. Call GetLastError for extended error information.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

Unicode and Character Sets Overview, Unicode and Character Set Functions


IsTextUnicode

The IsTextUnicode function determines whether a buffer probably contains a form of Unicode text. The function uses various statistical and deterministic methods to make its determination, under the control of flags passed via lpi. When the function returns, the results of such tests are reported via lpi. If all specified tests are passed, the function returns a nonzero value; otherwise, it returns zero.

DWORD IsTextUnicode(
  CONST LPVOID lpBuffer, // pointer to an input buffer to be examined
  int cb,                // the size of the input buffer
  LPINT lpi              // flags that condition examination and receive results
);

Parameters

lpBuffer
Pointer to the input buffer to be examined.
cb
Specifies the size, in bytes, of the input buffer pointed to by lpBuffer.
lpi
Pointer to an int variable that, upon entry to the function, contains a set of flags that specify the tests to be applied to the input buffer text. Upon exit from the function, that same variable contains a set of bit flags indicating the results of the specified tests: 1 if the contents of the buffer pass a test, 0 for failure. Only flags that are set upon entry to the function are significant upon exit.

If lpi is NULL, the function uses all available tests to determine whether the data in the buffer is probably Unicode text.

Here are the constants used with *lpi's bit flags:
Value | Meaning
IS_TEXT_UNICODE_ASCII16 | The text is Unicode, and contains nothing but zero-extended ASCII values/characters.
IS_TEXT_UNICODE_REVERSE_ASCII16 | Same as the preceding, except that the Unicode text is byte-reversed.
IS_TEXT_UNICODE_STATISTICS | The text is probably Unicode, with the determination made by applying statistical analysis. Absolute certainty is not guaranteed. See the note in the following Remarks section.
IS_TEXT_UNICODE_REVERSE_STATISTICS | Same as the preceding, except that the probably-Unicode text is byte-reversed.
IS_TEXT_UNICODE_CONTROLS | The text contains Unicode representations of one or more of these non-printing characters: RETURN, LINEFEED, SPACE, CJK_SPACE, TAB.
IS_TEXT_UNICODE_REVERSE_CONTROLS | Same as the preceding, except that the Unicode characters are byte-reversed.
IS_TEXT_UNICODE_BUFFER_TOO_SMALL | There are too few characters in the buffer for meaningful analysis (fewer than two bytes).
IS_TEXT_UNICODE_SIGNATURE | The text contains the Unicode byte-order mark (BOM) 0xFEFF as its first character.
IS_TEXT_UNICODE_REVERSE_SIGNATURE | The text contains the Unicode byte-reversed byte-order mark (Reverse BOM) 0xFFFE as its first character.
IS_TEXT_UNICODE_ILLEGAL_CHARS | The text contains one of these Unicode-illegal characters: embedded Reverse BOM, UNICODE_NUL, CRLF (packed into one WORD), or 0xFFFF.
IS_TEXT_UNICODE_ODD_LENGTH | The number of characters in the string is odd. A string of odd length cannot (by definition) be Unicode text.
IS_TEXT_UNICODE_NULL_BYTES | The text contains null bytes, which indicate non-ASCII text.
IS_TEXT_UNICODE_UNICODE_MASK | This flag constant is a combination of IS_TEXT_UNICODE_ASCII16, IS_TEXT_UNICODE_STATISTICS, IS_TEXT_UNICODE_CONTROLS, IS_TEXT_UNICODE_SIGNATURE.
IS_TEXT_UNICODE_REVERSE_MASK | This flag constant is a combination of IS_TEXT_UNICODE_REVERSE_ASCII16, IS_TEXT_UNICODE_REVERSE_STATISTICS, IS_TEXT_UNICODE_REVERSE_CONTROLS, IS_TEXT_UNICODE_REVERSE_SIGNATURE.
IS_TEXT_UNICODE_NOT_UNICODE_MASK | This flag constant is a combination of IS_TEXT_UNICODE_ILLEGAL_CHARS, IS_TEXT_UNICODE_ODD_LENGTH, and two currently unused bit flags.
IS_TEXT_UNICODE_NOT_ASCII_MASK | This flag constant is a combination of IS_TEXT_UNICODE_NULL_BYTES and three currently unused bit flags.

Return Values

The function returns nonzero if the data in the buffer passes the specified tests.

The function returns zero if the data in the buffer does not pass the specified tests.

In either case, the int variable pointed to by lpi contains the results of the specific tests the function applied to make its determination.

Remarks

As noted in the preceding table of flag constants, the IS_TEXT_UNICODE_STATISTICS and IS_TEXT_UNICODE_REVERSE_STATISTICS tests use statistical analysis. These tests are not foolproof. The statistical tests assume certain amounts of variation between low and high bytes in a string, and some ASCII strings can slip through. For example, if lpBuffer points to the ASCII string 0x41, 0x0A, 0x0D, 0x1D (A\n\r^Z), the string passes the IS_TEXT_UNICODE_STATISTICS test, though failure would be preferable.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Unicode and Character Sets Overview, Unicode and Character Set Functions


MultiByteToWideChar

The MultiByteToWideChar function maps a character string to a wide-character (Unicode) string. The character string mapped by this function is not necessarily from a multibyte character set.

int MultiByteToWideChar(
  UINT CodePage,         // code page
  DWORD dwFlags,         // character-type options
  LPCSTR lpMultiByteStr, // address of string to map
  int cchMultiByte,      // number of bytes in string
  LPWSTR lpWideCharStr,  // address of wide-character buffer
  int cchWideChar        // size of buffer
);

Parameters

CodePage
Specifies the code page to be used to perform the conversion. This parameter can be given the value of any code page that is installed or available in the system. You can also specify one of the following values:
Value | Meaning
CP_ACP | ANSI code page
CP_MACCP | Macintosh code page
CP_OEMCP | OEM code page
CP_SYMBOL | Symbol code page (42)
CP_THREAD_ACP | The current thread's ANSI code page
CP_UTF7 | Translate using UTF-7
CP_UTF8 | Translate using UTF-8

dwFlags
A set of bit flags that indicate whether to translate to precomposed or composite wide characters (if a composite form exists), whether to use glyph characters in place of control characters, and how to deal with invalid characters. You can specify a combination of the following flag constants:
Value | Meaning
MB_PRECOMPOSED | Always use precomposed characters — that is, characters in which a base character and a nonspacing character have a single character value. This is the default translation option. Cannot be used with MB_COMPOSITE.
MB_COMPOSITE | Always use composite characters — that is, characters in which a base character and a nonspacing character have different character values. Cannot be used with MB_PRECOMPOSED.
MB_ERR_INVALID_CHARS | If the function encounters an invalid input character, it fails and GetLastError returns ERROR_NO_UNICODE_TRANSLATION.
MB_USEGLYPHCHARS | Use glyph characters instead of control characters.

A composite character consists of a base character and a nonspacing character, each having different character values. A precomposed character has a single character value for a base/non-spacing character combination. In the character è, the e is the base character and the accent grave mark is the nonspacing character.

The function's default behavior is to translate to the precomposed form. If a precomposed form does not exist, the function attempts to translate to a composite form.

The flags MB_PRECOMPOSED and MB_COMPOSITE are mutually exclusive. The MB_USEGLYPHCHARS flag and the MB_ERR_INVALID_CHARS can be set regardless of the state of the other flags.

lpMultiByteStr
Points to the character string to be converted.
cchMultiByte
Specifies the size in bytes of the string pointed to by the lpMultiByteStr parameter. If this value is –1, the string is assumed to be null terminated and the length is calculated automatically.
lpWideCharStr
Points to a buffer that receives the translated string.
cchWideChar
Specifies the size, in wide characters, of the buffer pointed to by the lpWideCharStr parameter. If this value is zero, the function returns the required buffer size, in wide characters, and makes no use of the lpWideCharStr buffer.

Return Values

If the function succeeds, and cchWideChar is nonzero, the return value is the number of wide characters written to the buffer pointed to by lpWideCharStr.

If the function succeeds, and cchWideChar is zero, the return value is the required size, in wide characters, for a buffer that can receive the translated string.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INSUFFICIENT_BUFFER
ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER
ERROR_NO_UNICODE_TRANSLATION

Remarks

The lpMultiByteStr and lpWideCharStr pointers must not be the same. If they are the same, the function fails, and GetLastError returns the value ERROR_INVALID_PARAMETER.

The function fails if MB_ERR_INVALID_CHARS is set and it encounters an invalid character in the source string. An invalid character is one that would translate to the default character if MB_ERR_INVALID_CHARS was not set, but is not the default character in the source string, or when a lead byte is found in a string and there is no valid trail byte for DBCS strings. When an invalid character is found, and MB_ERR_INVALID_CHARS is set, the function returns 0 and sets GetLastError with the error ERROR_NO_UNICODE_TRANSLATION.

Windows CE: Windows CE does not support the CP_UTF7 and CP_UTF8 values for the CodePage parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

Unicode and Character Sets Overview, Unicode and Character Set Functions, WideCharToMultiByte


TranslateCharsetInfo

The TranslateCharsetInfo function translates based on the specified character set, code page, or font signature value, setting all members of the destination structure to appropriate values.

UINT TranslateCharsetInfo(
  DWORD FAR *lpSrc,
  LPCHARSETINFO lpCs,
  DWORD dwFlags
);

Parameters

lpSrc
Address or value as defined by the dwFlags parameter. If dwFlags is TCI_SRCFONTSIG, this parameter is the address of the fsCsb member of a FONTSIGNATURE structure. Otherwise, this parameter is a 32-bit value.
lpCs
Pointer to a CHARSETINFO structure that receives the translated character set information.
dwFlags
Translation flags. This parameter can be one of the following values:
Value | Meaning
TCI_SRCCHARSET | Source contains the character set value in the low word, and zero in the high word.
TCI_SRCCODEPAGE | Source is a code-page value in the low word and zero in the high word.
TCI_SRCFONTSIG Source is the code-page bitfield portion of a FONTSIGNATURE structure. On input this should have only one Windows code-page bit set, either for an ANSI code-page value or for a common ANSI and OEM value (for OEM values, bits 32-63 must be clear.). On output this will have only one bit set.

If the TCI_SRCFONTSIG value is given, the lpSrc parameter must be the address of the codepage bit field. If any other TCI_ value is given, the lpSrc parameter must be a value not an address.

Return Values

If the function succeeds, it returns a nonzero value.

If the function fails, it returns zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wingdi.h.
Import Library: Use gdi32.lib.

See Also

Unicode and Character Sets Overview, Unicode and Character Set Functions, CHARSETINFO, FONTSIGNATURE


WideCharToMultiByte

The WideCharToMultiByte function maps a wide-character string to a new character string. The new character string is not necessarily from a multibyte character set.

int WideCharToMultiByte(
  UINT CodePage,         // code page
  DWORD dwFlags,         // performance and mapping flags
  LPCWSTR lpWideCharStr, // address of wide-character string
  int cchWideChar,       // number of characters in string
  LPSTR lpMultiByteStr,  // address of buffer for new string
  int cchMultiByte,      // size of buffer
  LPCSTR lpDefaultChar,  // address of default for unmappable
                         // characters
  LPBOOL lpUsedDefaultChar   // address of flag set when default
                             // char. used
);

Parameters

CodePage
Specifies the code page used to perform the conversion. This parameter can be given the value of any code page that is installed or available in the system. You can also specify one of the following values:
Value | Meaning
CP_ACP | ANSI code page
CP_MACCP | Macintosh code page
CP_OEMCP | OEM code page
CP_SYMBOL | Symbol code page (42)
CP_THREAD_ACP | Current thread's ANSI code page
CP_UTF7 | Translate using UTF-7
CP_UTF8 | Translate using UTF-8

dwFlags
A set of bit flags that specify the handling of unmapped characters. The function performs more quickly when none of these flags is set. The following flag constants are defined:
Value | Meaning
WC_NO_BEST_FIT_CHARS Any Unicode characters that do not translate directly to multibyte equivalents will be translated to the default character (see lpDefaultChar parameter). In other words, if translating from Unicode to multibyte and back to Unicode again does not yield the exact same Unicode character, the default character is used.

This flag may be used by itself or in combination with the other dwFlag options.
WC_COMPOSITECHECK | Convert composite characters to precomposed characters.
WC_DISCARDNS | Discard nonspacing characters during conversion.
WC_SEPCHARS | Generate separate characters during conversion. This is the default conversion behavior.
WC_DEFAULTCHAR | Replace exceptions with the default character during conversion.

When WC_COMPOSITECHECK is specified, the function converts composite characters to precomposed characters. A composite character consists of a base character and a nonspacing character, each having different character values. A precomposed character has a single character value for a base/nonspacing character combination. In the character è, the e is the base character, and the accent grave mark is the nonspacing character.

When an application specifies WC_COMPOSITECHECK, it can use the last 3 flags in this list (WC_DISCARDNS, WC_SEPCHARS, and WC_DEFAULTCHAR) to customize the conversion to precomposed characters. These flags determine the function's behavior when there is no precomposed mapping for a base/nonspace character combination in a wide-character string. These last 3 flags can only be used if the WC_COMPOSITECHECK flag is set.

The function's default behavior is to generate separate characters (WC_SEPCHARS) for unmapped composite characters.

lpWideCharStr
Points to the wide-character string to be converted.
cchWideChar
Specifies the number of Unicode (16-bit) characters in the string pointed to by the lpWideCharStr parameter. If this value is –1, the string is assumed to be null-terminated and the length is calculated automatically.
lpMultiByteStr
Points to the buffer to receive the translated string.
cchMultiByte
Specifies the size in bytes of the buffer pointed to by the lpMultiByteStr parameter. If this value is zero, the function returns the number of bytes required for the buffer. (In this case, the lpMultiByteStr buffer is not used.)
lpDefaultChar
Points to the character used if a wide character cannot be represented in the specified code page. If this parameter is NULL, a system default value is used. The function is faster when both lpDefaultChar and lpUsedDefaultChar are NULL.
lpUsedDefaultChar
Points to a flag that indicates whether a default character was used. The flag is set to TRUE if one or more wide characters in the source string cannot be represented in the specified code page. Otherwise, the flag is set to FALSE. This parameter may be NULL. The function is faster when both lpDefaultChar and lpUsedDefaultChar are NULL.

Return Values

If the function succeeds, and cchMultiByte is nonzero, the return value is the number of bytes written to the buffer pointed to by lpMultiByteStr.

If the function succeeds, and cchMultiByte is zero, the return value is the required size, in bytes, for a buffer that can receive the translated string.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:

ERROR_INSUFFICIENT_BUFFER
ERROR_INVALID_FLAGS
ERROR_INVALID_PARAMETER

Remarks

The lpMultiByteStr and lpWideCharStr pointers must not be the same. If they are the same, the function fails, and GetLastError returns ERROR_INVALID_PARAMETER.

An application can use the lpDefaultChar parameter to change the default character used for the conversion.

As noted earlier, the WideCharToMultiByte function operates most efficiently when both lpDefaultChar and lpUsedDefaultChar are NULL. The following table shows the behavior of WideCharToMultiByte for the four combinations of lpDefaultChar and lpUsedDefaultChar :

lpDefaultChar | lpUsedDefaultChar | Result
NULL | NULL | No default checking. This is the most efficient, quick way to use this function.
non-NULL | NULL | Uses the specified default character, but does not set lpUsedDefaultChar.
NULL | non-NULL | Uses the system default character and sets lpUsedDefaultChar if necessary.
non-NULL | non-NULL | Uses the specified default character and sets lpUsedDefaultChar if necessary.

Windows CE: Windows CE does not support the CP_UTF7 and CP_UTF8 values for the CodePage parameter and the WC_NO_BEST_FIT_CHARS value for the dwFlags parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnls.h.
Import Library: Use kernel32.lib.

See Also

Unicode and Character Sets Overview, Unicode and Character Set Functions, MultiByteToWideChar


Unicode and Character Set Structures

The following structures are used by the character set functions.

CHARSETINFO
FONTSIGNATURE
LOCALESIGNATURE


CHARSETINFO

The CHARSETINFO structure contains information about a character set.

typedef struct {
    UINT ciCharset;
    UINT ciACP;
    FONTSIGNATURE fs;
} CHARSETINFO;

Members

ciCharset
Character set value.
ciACP
ANSI code-page value.
fs
A FONTSIGNATURE structure that identifies the Unicode and code-page font signature values. Only one code-page will be set when this structure is set by the function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wingdi.h.

See Also

Unicode and Character Sets Overview, Unicode and Character Set Structures, FONTSIGNATURE, TranslateCharsetInfo


FONTSIGNATURE

The FONTSIGNATURE structure contains information identifying the code-pages and Unicode subranges for which a given font provides glyphs.

typedef struct tagFONTSIGNATURE {
    DWORD  fsUsb[4];
    DWORD  fsCsb[2];
} FONTSIGNATURE;

Members

fsUsb
A 128-bit Unicode subset bitfield (USB) identifying up to 126 Unicode subranges. Each bit, except the two most significant bits, represents a single subrange. The most significant bit is always 1 and identifies the bitfield as a font signature; the second most significant bit is reserved and must be 0. Unicode subranges are numbered in accordance with the ISO 10646 standard. For more information, see Unicode Subset Bitfields.
fsCsb
A 64-bit, code-page bitfield (CPB) that identifies a specific character set or code page. Code pages are in the lower 32 bits of this bitfield. The high 32 are used for non-Windows code-pages. For more information, see Code-Page Bitfields.

Remarks

GDI relies on Windows code-pages fitting within a 32-bit value. Furthermore, the highest two bits within this value are reserved for GDI internal use and may not be assigned to code-pages.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wingdi.h.

See Also

Unicode and Character Sets Overview, Unicode and Character Set Structures, LOCALESIGNATURE


LOCALESIGNATURE

The LOCALESIGNATURE structure contains extended font-signature information, including two code-page bitfields (CPBs) that define the default and supported character sets and code-pages. This structure is typically used to represent the relationships between font coverage and locales.

typedef struct tagLOCALESIGNATURE {
    DWORD  lsUsb[4];
    DWORD  lsCsbDefault[2];
    DWORD  lsCsbSupported[2];
} LOCALESIGNATURE;

Members

lsUsb
A 128-bit Unicode subset bitfield (USB) identifying up to 126 Unicode subranges. Each bit, except the two most significant bits, represents a single subrange. The most significant bit is always 1 and identifies the bitfield as a font signature; the second most significant is reserved and must be 0. Unicode subranges are numbered in accordance with the ISO 10646 standard.
lsCsbDefault
A code-page bitfield that indicates the default OEM and ANSI code-pages for a locale. The code-pages may be identified by separate bits or a single bit representing a common ANSI and OEM code-page. For a list of possible bitfield values, see Code-Page Bitfields.
lsCsbSupported
A code-page bitfield that indicates all the code-pages in which the locale can be supported. For a list of possible bitfield values, see Code-Page Bitfields.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wingdi.h.

See Also

Unicode and Character Sets Overview, Unicode and Character Set Structures


Unicode and Character Set Macros

The following macro is used in Unicode applications.

TEXT

See Also

Unicode and Character Sets Overview, Unicode and Character Set Structures


TEXT Macro

TEXT

The TEXT macro identifies a string as Unicode when the UNICODE is defined during compilation or as an ANSI string otherwise.

TEXT(
  LPTSTR string  // pointer to an ANSI or Unicode string
);

Parameters

string
Pointer to the string to be interpreted as either Unicode or ANSI.

Remarks

The TEXT macro is defined as follows:

#ifdef UNICODE
    #define TEXT(quote) L##quote
#else
    #define TEXT(quote) quote
#endif

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winnt.h.

See Also

Unicode and Character Sets Overview, Unicode and Character Set Macros


Unicode and Character Set Constants

The following groups of constants are used with the character set functions.

  • ANSI Code-Page Identifiers
  • OEM Code-Page Identifiers
  • Code-Page Identifiers
  • Code-Page Bitfields


ANSI Code-Page Identifiers

Identifier | Meaning
874 | Thai
932 | Japan
936 | Chinese (PRC, Singapore)
949 | Korean
950 | Chinese (Taiwan Region; Hong Kong SAR, PRC)
1200 | Unicode (BMP of ISO 10646)
1250 | Windows 3.1 Eastern European
1251 | Windows 3.1 Cyrillic
1252 | Windows 3.1 Latin 1 (US, Western Europe)
1253 | Windows 3.1 Greek
1254 | Windows 3.1 Turkish
1255 | Hebrew
1256 | Arabic
1257 | Baltic


OEM Code-Page Identifiers

Identifier | Meaning
437 | MS-DOS United States
708 | Arabic (ASMO 708)
709 | Arabic (ASMO 449+, BCON V4)
710 | Arabic (Transparent Arabic)
720 | Arabic (Transparent ASMO)
737 | Greek (formerly 437G)
775 | Baltic
850 | MS-DOS Multilingual (Latin I)
852 | MS-DOS Slavic (Latin II)
855 | IBM Cyrillic (primarily Russian)
857 | IBM Turkish
860 | MS-DOS Portuguese
861 | MS-DOS Icelandic
862 | Hebrew
863 | MS-DOS Canadian-French
864 | Arabic
865 | MS-DOS Nordic
866 | MS-DOS Russian (former USSR)
869 | IBM Modern Greek
874 | Thai
932 | Japan
936 | Chinese (PRC, Singapore)
949 | Korean
950 | Chinese (Taiwan Region; Hong Kong SAR, PRC)
1361 | Korean (Johab)


Code-Page Identifiers

Identifier | Meaning
037 | EBCDIC
437 | MS-DOS United States
500 | EBCDIC "500V1"
708 | Arabic (ASMO 708)
709 | Arabic (ASMO 449+, BCON V4)
710 | Arabic (Transparent Arabic)
720 | Arabic (Transparent ASMO)
737 | Greek (formerly 437G)
775 | Baltic
850 | MS-DOS Multilingual (Latin I)
852 | MS-DOS Slavic (Latin II)
855 | IBM Cyrillic (primarily Russian)
857 | IBM Turkish
860 | MS-DOS Portuguese
861 | MS-DOS Icelandic
862 | Hebrew
863 | MS-DOS Canadian-French
864 | Arabic
865 | MS-DOS Nordic
866 | MS-DOS Russian
869 | IBM Modern Greek
874 | Thai
875 | EBCDIC
932 | Japan
936 | Chinese (PRC, Singapore)
949 | Korean
950 | Chinese (Taiwan Region; Hong Kong SAR, PRC)
1026 | EBCDIC
1200 | Unicode (BMP of ISO 10646)
1250 | Windows 3.1 Eastern European
1251 | Windows 3.1 Cyrillic
1252 | Windows 3.1 US (ANSI)
1253 | Windows 3.1 Greek
1254 | Windows 3.1 Turkish
1255 | Hebrew
1256 | Arabic
1257 | Baltic
1361 | Korean (Johab)
10000 | Macintosh Roman
10001 | Macintosh Japanese
10006 | Macintosh Greek I
10007 | Macintosh Cyrillic
10029 | Macintosh Latin 2
10079 | Macintosh Icelandic
10081 | Macintosh Turkish


Code-Page Bitfields

Bit | Code page | Description
ANSI |  |
0 | 1252 | Latin 1
1 | 1250 | Latin 2: Eastern Europe
2 | 1251 | Cyrillic
3 | 1253 | Greek
4 | 1254 | Turkish
5 | 1255 | Hebrew
6 | 1256 | Arabic
7 | 1257 | Baltic
8 - 15 |  | Reserved for ANSI
ANSI and OEM
16 | 874 | Thai
17 | 932 | Japanese, Shift-JIS
18 | 936 | Chinese: Simplified chars—PRC and Singapore
19 | 949 | Korean Unified Hangeul Code (Hangeul TongHabHyung Code)
20 | 950 | Chinese: Traditional chars—Taiwan Region and Hong Kong SAR, PRC
21 | 1361 | Korean (Johab)
22 - 29 |  | Reserved for alternate ANSI and OEM
30 - 31 |  | Reserved by system.
OEM |  |
32 - 47 |  | Reserved for OEM
48 | 869 | IBM Greek
49 | 866 | MS-DOS Russian
50 | 865 | MS-DOS Nordic
51 | 864 | Arabic
52 | 863 | MS-DOS Canadian French
53 | 862 | Hebrew
54 | 861 | MS-DOS Icelandic
55 | 860 | MS-DOS Portuguese
56 | 857 | IBM Turkish
57 | 855 | IBM Cyrillic; primarily Russian
58 | 852 | Latin 2
59 | 775 | Baltic
60 | 737 | Greek; former 437 G
61 | 708 | Arabic; ASMO 708
62 | 850 | Western European/Latin 1
63 | 437 | US


Unicode Subset Bitfields

Bit | Description
0 | Basic Latin
1 | Latin-1 Supplement
2 | Latin Extended-A
3 | Latin Extended-B
4 | IPA Extensions
5 | Spacing Modifier Letters
6 | Combining Diacritical Marks
7 | Basic Greek
8 | Greek Symbols and Coptic
9 | Cyrillic
10 | Armenian
11 | Basic Hebrew
12 | Hebrew Extended
13 | Basic Arabic
14 | Arabic Extended
15 | Devanagari
16 | Bengali
17 | Gurmukhi
18 | Gujarati
19 | Oriya
20 | Tamil
21 | Telugu
22 | Kannada
23 | Malayalam
24 | Thai
25 | Lao
26 | Basic Georgian
27 | Georgian Extended
28 | Hangul Jamo
29 | Latin Extended Additional
30 | Greek Extended
31 | General Punctuation
32 | Subscripts and Superscripts
33 | Currency Symbols
34 | Combining Diacritical Marks for Symbols
35 | Letter-like Symbols
36 | Number Forms
37 | Arrows
38 | Mathematical Operators
39 | Miscellaneous Technical
40 | Control Pictures
41 | Optical Character Recognition
42 | Enclosed Alphanumerics
43 | Box Drawing
44 | Block Elements
45 | Geometric Shapes
46 | Miscellaneous Symbols
47 | Dingbats
48 | Chinese, Japanese, and Korean (CJK) Symbols and Punctuation
49 | Hiragana
50 | Katakana
51 | Bopomofo
52 | Hangul Compatibility Jamo
53 | CJK Miscellaneous
54 | Enclosed CJK
55 | CJK Compatibility
56 | Hangul
57 | Reserved for Unicode Subranges
58 | Reserved for Unicode Subranges
59 | CJK Unified Ideographs
60 | Private Use Area
61 | CJK Compatibility Ideographs
62 | Alphabetic Presentation Forms
63 | Arabic Presentation Forms-A
64 | Combining Half Marks
65 | CJK Compatibility Forms
66 | Small Form Variants
67 | Arabic Presentation Forms-B
68 | Halfwidth and Fullwidth Forms
69 | Specials
70-127 | Reserved for Unicode Subranges


Locale Identifiers

This overview contains detailed information about national language support provided by the Win32 API. The information presented here pertains to locale identifiers, LCTYPE constants, country codes, and language identifiers.


Locale Identifiers (LCIDs)

A locale identifier (LCID) is a DWORD value containing the language identifier in the lower word and a reserved value in the upper word. The identifier supplied in an LCID is a standard international numeric abbreviation. This LCID has the components necessary to uniquely identify one of the installed system-defined locales.

Applications can use the MAKELCID macro to create LCID values.

There are two predefined LCID values: LOCALE_SYSTEM_DEFAULT is the system default locale, and LOCALE_USER_DEFAULT is the current user's locale.


LCTYPE Constants

An LCTYPE constant is a constant that specifies a particular piece of locale information.

The values in the following list correspond to the names of these values in the configuration registry, under both the user's preferences (as values in the registry key HKEY_CURRENT_USER\Control Panel\International) and the system's installed languages (as files pointed to by registry keys, one key per language installed, under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\NLS). All values are null-terminated Unicode™ strings. If no maximum length is indicated, the strings may vary in length.

Constant | Description
LOCALE_ILANGUAGE | Language identifier indicating the language. The maximum number of characters allowed for this string is 5.
LOCALE_SLANGUAGE | Full localized name of the language.
LOCALE_SENGLANGUAGE | Full English name of the language from the International Organization for Standardization (ISO) Standard 639. This is always restricted to characters mappable into the ASCII 127-character subset.
LOCALE_SABBREVLANGNAME | Abbreviated name of the language, created by taking the 2-letter language abbreviation from the ISO Standard 639 and adding a third letter, as appropriate, to indicate the sublanguage.
LOCALE_SNATIVELANGNAME | Native name of the language.
LOCALE_SSORTNAME | The full localized name of the sort for the given locale ID.
LOCALE_ICOUNTRY | Country code, based on international phone codes, also referred to as IBM country codes. The maximum number of characters allowed for this string is 6.
LOCALE_SCOUNTRY | Full localized name of the country.
LOCALE_SENGCOUNTRY | Full English name of the country. This is always restricted to characters mappable into the ASCII 127-character subset.
LOCALE_SABBREVCTRYNAME | Abbreviated name of the country from the ISO Standard 3166.
LOCALE_SNATIVECTRYNAME | Native name of the country.
LOCALE_IDEFAULTLANGUAGE | Language identifier for the principal language spoken in this locale. This is provided so that partially specified locales can be completed with default values. The maximum number of characters allowed for this string is 5.
LOCALE_IDEFAULTCOUNTRY | Country code for the principal country in this locale. This is provided so that partially specified locales can be completed with default values. The maximum number of characters allowed for this string is 6.
LOCALE_IDEFAULTANSICODEPAGE | American National Standards Institute (ANSI) code page associated with this locale. The maximum number of characters allowed for this string is 6.
LOCALE_IDEFAULTOEMCODEPAGE | Original equipment manufacturer (OEM) code page associated with the locale. The maximum number of characters allowed for this string is 6.
LOCALE_IDEFAULTCODEPAGE | Original equipment manufacturer (OEM) code page associated with the country. The maximum number of characters allowed for this string is 6.
LOCALE_IDEFAULTEBCDICCODEPAGE | Default EBCDIC code page associated with the locale. The maximum number of characters allowed for this string is 6.
LOCALE_SLIST | Character(s) used to separate list items. For example, a comma is used in many locales.
LOCALE_IMEASURE | System of measurement. This value is 0 if the metric system (Systéme International d'Unités, or S.I.) is used and 1 if the U.S. system is used. The maximum number of characters allowed for this string is 2.
LOCALE_SDECIMAL | Character(s) used as the decimal separator.
LOCALE_STHOUSAND | Character(s) used to separate groups of digits to the left of the decimal.
LOCALE_SGROUPING | Sizes for each group of digits to the left of the decimal. An explicit size is needed for each group; sizes are separated by semicolons. If the last value is zero, the preceding value is repeated. To group thousands, specify 3;0, for example.
LOCALE_IDIGITS | Number of fractional digits. The maximum number of characters allowed for this string is 3.
LOCALE_ILZERO | Specifier for leading zeros in decimal fields. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:

Value | Meaning
0 | No leading zeros
1 | Leading zeros

LOCALE_INEGNUMBER Negative number mode. The mode can be one of these values:

Value | Meaning
0 | (1.1)
1 | –1.1
2 | – 1.1
3 | 1.1–
4 | 1.1 –

LOCALE_SNATIVEDIGITS | Native equivalents to ASCII 0 through 9.
LOCALE_SENGCURRNAME | The full English name of the currency associated with the locale.
LOCALE_SNATIVECURRNAME | The native name of the currency associated with the locale.
LOCALE_SCURRENCY | String used as the local monetary symbol.
LOCALE_SINTLSYMBOL | Three characters of the international monetary symbol specified in ISO 4217, "Codes for the Representation of Currencies and Funds," followed by the character separating this string from the amount.
LOCALE_SMONDECIMALSEP | Character(s) used as the monetary decimal separator.
LOCALE_SMONTHOUSANDSEP | Character(s) used as the monetary separator between groups of digits to the left of the decimal.
LOCALE_SMONGROUPING | Sizes for each group of monetary digits to the left of the decimal. An explicit size is needed for each group; sizes are separated by semicolons. If the last value is zero, the preceding value is repeated. To group thousands, specify 3;0, for example.
LOCALE_ICURRDIGITS | Number of fractional digits for the local monetary format. The maximum number of characters allowed for this string is 3.
LOCALE_IINTLCURRDIGITS | Number of fractional digits for the international monetary format. The maximum number of characters allowed for this string is 3.
LOCALE_ICURRENCY | Positive currency mode. The maximum number of characters allowed for this string is 2. The mode can be one of the following values:

Value | Meaning
0 | Prefix, no separation
1 | Suffix, no separation
2 | Prefix, 1-char. separation
3 | Suffix, 1-char. separation

LOCALE_INEGCURR Negative currency mode. The maximum number of characters allowed for this string is 3. The mode can be one of the following values:

Value | Example
0 | ($1.1)
1 | –$1.1
2 | $–1.1
3 | $1.1–
4 | (1.1$)
5 | –1.1$
6 | 1.1–$
7 | 1.1$–
8 | –1.1 $ (space before $)
9 | –$ 1.1 (space after $)
10 | 1.1 $– (space before $)
11 | $ 1.1– (space after $)
12 | $ –1.1 (space after $)
13 | 1.1– $ (space before $)
14 | ($ 1.1) (space after $)
15 | (1.1 $) (space before $)

LOCALE_SDATE | Character(s) for the date separator.
LOCALE_STIME | Character(s) for the time separator.
LOCALE_STIMEFORMAT | Time formatting strings for this locale. The string can consist of a combination of the hour, minute, and second format pictures defined in the Hour, Minute, and Second Format Pictures table in National Language Support Constants.
LOCALE_SYEARMONTH | The Year/Month formatting string for the locale. This string shows the proper format for a date string that contains only the year and the month.
LOCALE_SSHORTDATE | Short date formatting string for this locale. The string can consist of a combination of day, month, and year format pictures defined in Day, Month, Year, and Era Format Pictures table in National Language Support Constants.
LOCALE_SLONGDATE | Long date formatting string for this locale. The string can consist of a combination of day, month, and year format pictures defined in the Day, Month, Year, and Era Format Pictures table in National Language Support Constants and any string of characters enclosed in single quotes. Characters in single quotes remain as given.
LOCALE_IDATE | Short date format-ordering specifier. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:

Value | Meaning
0 | Month-Day-Year
1 | Day-Month-Year
2 | Year-Month-Day

LOCALE_ILDATE Long date format-ordering specifier. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:

Value | Meaning
0 | Month-Day-Year
1 | Day-Month-Year
2 | Year-Month-Day

LOCALE_ITIME Time format specifier. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:

Value | Meaning
0 | AM / PM 12-hour format
1 | 24-hour format

LOCALE_ICENTURY Specifier for full 4-digit century. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:

Value | Meaning
0 | Abbreviated 2-digit century
1 | Full 4-digit century

LOCALE_ITLZERO Specifier for leading zeros in time fields. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:

Value | Meaning
0 | No leading zeros for hours
1 | Leading zeros for hours

LOCALE_IDAYLZERO Specifier for leading zeros in day fields. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:

Value | Meaning
0 | No leading zeros for days
1 | Leading zeros for days

LOCALE_IMONLZERO Specifier for leading zeros in month fields. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:

Value | Meaning
0 | No leading zeros for months
1 | Leading zeros for months

LOCALE_S1159 | String for the AM designator.
LOCALE_S2359 | String for the PM designator.
LOCALE_ICALENDARTYPE | Current calendar type. This type can be one of these values:

Value | Meaning
1 | Gregorian (as in United States)
2 | Gregorian (English strings always)
3 | Era: Year of the Emperor (Japan)
4 | Era: Year of Taiwan Region
5 | Tangun Era (Korea)

LOCALE_IOPTIONALCALENDAR Additional calendar types. This can be a zero-separated list of one or more of these calendars type values:

Value | Meaning
0 | No additional types valid
1 | Gregorian (as in United States)
2 | Gregorian (English strings always)
3 | Era: Year of the Emperor (Japan)
4 | Era: Year of Taiwan Region
5 | Tangun Era (Korea)

LOCALE_IFIRSTDAYOFWEEK Specifier for the first day in a week. The specifier can be one of these values:

Value | Meaning
0 | LOCALE_SDAYNAME1
1 | LOCALE_SDAYNAME2
2 | LOCALE_SDAYNAME3
3 | LOCALE_SDAYNAME4
4 | LOCALE_SDAYNAME5
5 | LOCALE_SDAYNAME6
6 | LOCALE_SDAYNAME7

LOCALE_IFIRSTWEEKOFYEAR Specifier for the first week of the year. The specifier can be one of these values:

Value | Meaning
0 | Week containing 1/1 is the first week of that year.
1 | First full week following 1/1 is the first week of that year.
2 | First week containing at least 4 days is the first week of that year.

LOCALE_SDAYNAME1 | Native long name for Monday.
LOCALE_SDAYNAME2 | Native long name for Tuesday.
LOCALE_SDAYNAME3 | Native long name for Wednesday.
LOCALE_SDAYNAME4 | Native long name for Thursday.
LOCALE_SDAYNAME5 | Native long name for Friday.
LOCALE_SDAYNAME6 | Native long name for Saturday.
LOCALE_SDAYNAME7 | Native long name for Sunday.
LOCALE_SABBREVDAYNAME1 | Native abbreviated name for Monday.
LOCALE_SABBREVDAYNAME2 | Native abbreviated name for Tuesday.
LOCALE_SABBREVDAYNAME3 | Native abbreviated name for Wednesday.
LOCALE_SABBREVDAYNAME4 | Native abbreviated name for Thursday.
LOCALE_SABBREVDAYNAME5 | Native abbreviated name for Friday.
LOCALE_SABBREVDAYNAME6 | Native abbreviated name for Saturday.
LOCALE_SABBREVDAYNAME7 | Native abbreviated name for Sunday.
LOCALE_SMONTHNAME1 | Native long name for January.
LOCALE_SMONTHNAME2 | Native long name for February.
LOCALE_SMONTHNAME3 | Native long name for March.
LOCALE_SMONTHNAME4 | Native long name for April.
LOCALE_SMONTHNAME5 | Native long name for May.
LOCALE_SMONTHNAME6 | Native long name for June.
LOCALE_SMONTHNAME7 | Native long name for July.
LOCALE_SMONTHNAME8 | Native long name for August.
LOCALE_SMONTHNAME9 | Native long name for September.
LOCALE_SMONTHNAME10 | Native long name for October.
LOCALE_SMONTHNAME11 | Native long name for November.
LOCALE_SMONTHNAME12 | Native long name for December.
LOCALE_SMONTHNAME13 | Native name for 13th month, if exists.
LOCALE_SABBREVMONTHNAME1 | Native abbreviated name for January.
LOCALE_SABBREVMONTHNAME2 | Native abbreviated name for February.
LOCALE_SABBREVMONTHNAME3 | Native abbreviated name for March.
LOCALE_SABBREVMONTHNAME4 | Native abbreviated name for April.
LOCALE_SABBREVMONTHNAME5 | Native abbreviated name for May.
LOCALE_SABBREVMONTHNAME6 | Native abbreviated name for June.
LOCALE_SABBREVMONTHNAME7 | Native abbreviated name for July.
LOCALE_SABBREVMONTHNAME8 | Native abbreviated name for August.
LOCALE_SABBREVMONTHNAME9 | Native abbreviated name for September.
LOCALE_SABBREVMONTHNAME10 | Native abbreviated name for October.
LOCALE_SABBREVMONTHNAME11 | Native abbreviated name for November.
LOCALE_SABBREVMONTHNAME12 | Native abbreviated name for December.
LOCALE_SABBREVMONTHNAME13 | Native abbreviated name for 13th month, if exists.
LOCALE_SPOSITIVESIGN | String value for the positive sign.
LOCALE_SNEGATIVESIGN | String value for the negative sign.
LOCALE_IPOSSIGNPOSN | Formatting index for positive values. The maximum number of characters allowed for this string is 2. The index can be one of the following values:

Value | Meaning
0 | Parentheses surround the amount and the monetary symbol.
1 | The sign string precedes the amount and the monetary symbol.
2 | The sign string succeeds the amount and the monetary symbol.
3 | The sign string immediately precedes the monetary symbol.
4 | The sign string immediately succeeds the monetary symbol.

LOCALE_INEGSIGNPOSN | Formatting index for negative values. This index uses the same values as LOCALE_IPOSSIGNPOSN. The maximum number of characters allowed for this string is 2.
LOCALE_IPOSSYMPRECEDES | Position of monetary symbol in a positive monetary value. This value is 1 if the monetary symbol precedes the positive amount, 0 if it follows it. The maximum number of characters allowed for this string is 2.
LOCALE_IPOSSEPBYSPACE | Separation of monetary symbol in a positive monetary value. This value is 1 if the monetary symbol is separated by a space from a positive amount, 0 if it is not. The maximum number of characters allowed for this string is 2.
LOCALE_INEGSYMPRECEDES | Position of monetary symbol in a negative monetary value. This value is 1 if the monetary symbol precedes the negative amount, 0 if it follows it. The maximum number of characters allowed for this string is 2.
LOCALE_INEGSEPBYSPACE | Separation of monetary symbol in a negative monetary value. This value is 1 if the monetary symbol is separated by a space from the negative amount, 0 if it is not. The maximum number of characters allowed for this string is 2.
LOCALE_IPAPERSIZE | Default paper size associated with the locale.
LOCALE_NOUSEROVERRIDE | This constant may be OR'ed with any other LCTYPE constant in a call to the GetLocaleInfo function. This always causes the function to bypass any user overrides, and return the system default value for the other LCTYPE specified in the function call, based on the given LCID.


Language Identifiers and Locales

Applications can use the MAKELANGID macro to create a language identifier.

The following sublanguages/locales use the Latin 1 script:

Latin 1 Script

Identifier | Language | Sublanguage/Locale | Language Code
0x0406 | Danish | Danish | DAN
0x0413 | Dutch | Dutch (Standard) | NLD
0x0813 | Dutch | Belgian (Flemish) | NLB
0x0409 | English | American | ENU
0x0809 | English | British | ENG
0x0c09 | English | Australian | ENA
0x1009 | English | Canadian | ENC
0x1409 | English | New Zealand | ENZ
0x1809 | English | Ireland | ENI
0x040b | Finnish | Finnish | FIN
0x040c | French | French (Standard) | FRA
0x080c | French | Belgian | FRB
0x0c0c | French | Canadian | FRC
0x100c | French | Swiss | FRS
0x0407 | German | German (Standard) | DEU
0x0807 | German | Swiss | DES
0x0c07 | German | Austrian | DEA
0x040f | Icelandic | Icelandic | ISL
0x0410 | Italian | Italian (Standard) | ITA
0x0810 | Italian | Swiss | ITS
0x0414 | Norwegian | Norwegian (Bokmal) | NOR
0x0814 | Norwegian | Norwegian (Nynorsk) | NON
0x0416 | Portuguese | Portuguese (Brazilian) | PTB
0x0816 | Portuguese | Portuguese (Standard) | PTG
0x041D | Swedish | Swedish | SVE
0x040a | Spanish | Spanish (Standard/Traditional) | ESP
0x080a | Spanish | Mexican | ESM
0x0c0a | Spanish | Spanish (Modern) | ESN

The following sublanguages/locales use the Latin 2 script:

Latin 2 Script

Identifier | Sublanguage/Locale | Language Code
0x041f | Turkish | TRK
0x0415 | Polish | PLK
0x0405 | Czech | CSY
0x041b | Slovak | SKY
0x040e | Hungarian | HUN

The following sublanguage/locale uses the Cyrillic script:

Cyrillic Script

Identifier | Sublanguage/Locale | Language Code
0x0419 | Russian | RUS

The following sublanguage/locale uses an other script:

Other Script

Identifier | Sublanguage/Locale | Language Code
0x0408 | Greek | ELL

The following special identifiers are also defined:

Special Identifiers

Identifier | Sublanguage/Locale
0x0000 | Language-Neutral
0x0400 | Process Default Language


Interprocess Communications

The Microsoft® Win32® API provides mechanisms for facilitating communications and data sharing between applications. Collectively, the activities enabled by these mechanisms are called interprocess communications (IPC). Some forms of IPC facilitate the division of labor among several specialized processes. Other forms of IPC facilitate the division of labor among computers on a network.

Typically, applications can use IPC categorized as clients or servers. A client is an application or a process that requests a service from some other application or process. A server is an application or a process that responds to a client request. Many applications act as both a client and a server, depending on the situation. For example, a word processing application might act as a client in requesting a summary table of manufacturing costs from a spreadsheet application acting as a server. The spreadsheet application, in turn, might act as a client in requesting the latest inventory levels from an automated inventory control application.


About Interprocess Communications

As computer users become more sophisticated, they demand more power from the applications they use. To meet this demand, developers add more features to the applications, and the applications become larger. Large applications eventually become unmanageable, both from a development standpoint and from a user-interface standpoint.

One method you can use to manage larger applications is to produce a specialized application that provides a limited number of features, then enable it to communicate and share data with other specialized applications using some form of IPC. It is not necessary for a single application meet all its users' expectations; applications can communicate and cooperate.

The following IPC mechanisms are supported by the Win32 API:

  • Clipboard
  • COM
  • Dynamic Data Exchange (DDE)
  • File Mapping
  • Mailslots
  • Pipes
  • RPC
  • Windows Sockets
  • WM_COPYDATA


Choosing an IPC Mechanism

After you decide that your application would benefit from IPC, you must decide which of the available IPC methods to use. It is likely that an application will use several IPC mechanisms. For example, all Win32-based applications should provide at least minimal support for the clipboard. In addition, COM and DDE offer the application an opportunity to communicate with applications that support these protocols. By supporting the protocols for the clipboard, COM, and DDE, you enable your application to share data with other applications, without knowing anything about the applications themselves.

The answers to these questions determine whether an application can benefit by using one or more of the IPC mechanisms available in the Win32 API.

  • Should the application be able to communicate with other applications running on other computers on a network, or is it sufficient for the application to communicate only with applications on the local computer?
  • Should the application be able to communicate with applications running on other computers that may be running under different operating systems (that is, MS-DOS®, 16-bit Windows®, UNIX)?
  • Should the user of the application have to choose the other application(s) with which the application communicates, or can the application implicitly find its cooperating partners?
  • Should the application communicate with many different applications in a general way, such as allowing cut and paste operations with any other application, or should its communications requirements be limited to a restricted set of interactions with specific other applications?
  • Is performance a critical aspect of the application? All IPC mechanisms include some amount of overhead.
  • Should the application be a GUI application or a console application? Some IPC mechanisms require a GUI application.


Using the Clipboard for IPC

The clipboard acts as a central depository for data sharing among applications. When a user performs a cut or copy operation in an application, the application puts the selected data on the clipboard in one or more standard or application-defined formats. Any other application can then retrieve the data from the clipboard, choosing from the available formats that it understands. The clipboard is a very loosely coupled exchange medium, where applications need only agree on the data format. The applications can reside on the same computer or on different computers on a network.

Key Point All Win32-based applications should support the clipboard for those data formats that they understand. For example, a text editor or word processor should at least be able to produce and accept clipboard data in pure text format. For more information, see Clipboard.


Using COM for IPC

Applications that use OLE manage compound documents — that is, documents made up of data from a variety of different applications. OLE provides services that make it easy for applications to call on other applications for data editing. For example, a word processor that uses OLE could embed a graph from a spreadsheet. The user could start the spreadsheet automatically from within the word processor by choosing the embedded chart for editing. OLE takes care of starting the spreadsheet and presenting the graph for editing. When the user quit the spreadsheet, the graph would be updated in the original word processor document. The spreadsheet appears to be an extension of the word processor.

The foundation of OLE is the Component Object Model (COM). A software component that uses COM can communicate with a wide variety of other components, even those that have not yet been written. The components interact as objects and clients. Distributed COM extends the COM programming model so that it works across a network.

Key Point OLE supports compound documents and enables an application to include embedded or linked data that, when chosen, automatically starts another application for data editing. This enables the application to be extended by any other application that uses OLE. COM objects provide access to an object's data through one or more sets of related functions, known as interfaces. For more information, see COM and ActiveX Object Services.


Using DDE for IPC

DDE is a protocol that enables applications to exchange data in a variety of formats. Applications can use DDE for one-time data exchanges or for ongoing exchanges in which the applications update one another as new data becomes available.

The data formats used by DDE are the same as those used by the clipboard. DDE can be thought of as an extension of the clipboard mechanism. The clipboard is almost always used for a one-time response to a user command, such as choosing the Paste command from a menu. DDE is also usually initiated by a user command, but it often continues to function without further user interaction. You can also define custom DDE data formats for special-purpose IPC between applications with more tightly coupled communications requirements.

DDE exchanges can occur between applications running on the same computer or on different computers on a network.

Key Point DDE is not as efficient as newer technologies. However, you can still use DDE if other IPC mechanisms are not suitable or if you must interface with an existing application that only supports DDE. For more information, see Dynamic Data Exchange and Dynamic Data Exchange Management Library.


Using a File Mapping for IPC

File mapping enables a process to treat the contents of a file as if they were a block of memory in the process's address space. The process can use simple pointer operations to examine and modify the contents of the file. When two or more processes access the same file mapping, each process receives a pointer to memory in its own address space that it can use to read or modify the contents of the file. The processes must use a synchronization object, such as a semaphore, to prevent data corruption in a multitasking environment.

You can use a special case of file mapping to provide named shared memory between processes. If you specify the system swapping file when creating a file-mapping object, the file-mapping object is treated as a shared memory block. Other processes can access the same block of memory by opening the same file-mapping object.

File mapping is quite efficient and also provides operating-system–supported security attributes that can help prevent unauthorized data corruption. File mapping can be used only between processes on a local computer; it cannot be used over a network.

Key Point File mapping is an efficient way for two or more processes on the same computer to share data, but you must provide synchronization between the processes. For more information, see File Mapping and Synchronization.


Using a Mailslot for IPC

Mailslots provide one-way communication. Any process that creates a mailslot is a mailslot server. Other processes, called mailslot clients, send messages to the mailslot server by writing a message to its mailslot. Incoming messages are always appended to the mailslot. The mailslot saves the messages until the mailslot server has read them. A process can be both a mailslot server and a mailslot client, so two-way communication is possible using multiple mailslots.

A mailslot client can send a message to a mailslot on its local computer, to a mailslot on another computer, or to all mailslots with the same name on all computers in a specified network domain. Messages broadcast to all mailslots on a domain can be no longer than 400 bytes, whereas messages sent to a single mailslot are limited only by the maximum message size specified by the mailslot server when it created the mailslot.

Key Point Mailslots offer an easy way for applications to send and receive short messages. They also provide the ability to broadcast messages across all computers in a network domain. For more information, see Mailslots.


Using Pipes for IPC

The Win32 API provides two types of pipes for two-way communication: anonymous pipes and named pipes. Anonymous (or unnamed) pipes enable related processes to transfer information to each other. Typically, an anonymous pipe is used for redirecting the standard input or output of a child process so that it can exchange data with its parent process. To exchange data in both directions (duplex operation), you must create two anonymous pipes. The parent process writes data to one pipe using its write handle, while the child process reads the data from that pipe using its read handle. Similarly, the child process writes data to the other pipe and the parent process reads from it. Anonymous pipes cannot be used over a network, nor can they be used between unrelated processes.

Named pipes are used to transfer data between processes that are not related processes and between processes on different computers. Typically, a named-pipe server process creates a named pipe with a well-known name or a name that is to be communicated to its clients. A named-pipe client process that knows the name of the pipe can open its other end, subject to access restrictions specified by named-pipe server process. After both the server and client have connected to the pipe, they can exchange data by performing read and write operations on the pipe.

Key Point Anonymous pipes provide an efficient way to redirect standard input or output to child processes on the same computer. Named pipes provide a simple programming interface for transferring data between two processes, whether they reside on the same computer or over a network. For more information, see Pipes.


Using RPC for IPC

The Win32 API provides RPC to enable applications to call functions remotely. Therefore, RPC makes IPC as easy as calling a function. RPC operates between processes on a single computer or on different computers on a network.

The RPC provided by the Win32 API is compliant with the Open Software Foundation (OSF) Distributed Computing Environment (DCE). This means that Win32-based applications that use RPC are able to communicate with applications running with other operating systems that support DCE. RPC automatically supports data conversion to account for different hardware architectures and for byte-ordering between dissimilar environments.

RPC clients and servers are tightly coupled but still maintain high performance. The system makes extensive use of RPC to facilitate a client-server relationship between different parts of the operating system.

Key Point RPC is a function-level interface, with support for automatic data conversion and for communications with other operating systems. Using RPC, you can create high-performance, tightly coupled distributed applications. For more information, see Microsoft RPC Components.


Using Windows Sockets for IPC

Windows Sockets is an protocol-independent interface. It take advantage of the communication capabilities of the underlying protocols. In Windows Sockets 2, a socket handle can optionally be used as a file handle with the standard file I/O functions.

Windows Sockets are based on the sockets first popularized by Berkeley Software Distribution (BSD). An application that uses Windows Sockets can communicate with other socket implementation on other types of systems. However, not all transport service providers support all available options.

Key Point Windows Sockets is a protocol-independent interface capable of supporting current and emerging networking capabilities. For more information, see Overview of Windows Sockets 2.


Using WM_COPYDATA for IPC

The WM_COPYDATA message enables you to send data from one application to another. The receiving application gets the data in a COPYDATASTRUCT structure. When data is being passed between a 16-bit Windows-based application and a Win32-based application, the system translates any pointers.

For example code, see the following Platform SDK samples:

  • SPY. This sample, located in MSTOOLS\SAMPLES\SDKTOOLS\SPY, uses WM_COPYDATA to pass data to another application.
  • INTEROP. This sample, located in SCT\SAMPLES, uses WM_COPYDATA to dispatch calls from a 16-bit Windows-based application to a Win32-based DLL.


Interprocess Communications Reference

The following elements are used for interprocess communication.

  • Interprocess Communications Structures
  • Interprocess Communications Messages


Interprocess Communications Structures

The following structure is used for interprocess communication.

COPYDATASTRUCT


COPYDATASTRUCT

The COPYDATASTRUCT structure contains data to be passed to another application by the WM_COPYDATA message.

typedef struct tagCOPYDATASTRUCT {  // cds
    DWORD dwData;
    DWORD cbData;
    PVOID lpData;
} COPYDATASTRUCT;

Members

dwData
Specifies up to 32 bits of data to be passed to the receiving application.
cbData
Specifies the size, in bytes, of the data pointed to by the lpData member.
lpData
Pointer to data to be passed to the receiving application. This member can be NULL.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.

See Also

Interprocess Communications Overview, Interprocess Communications Structures, WM_COPYDATA


Interprocess Communications Messages

The following message is used for interprocess communication.

WM_COPYDATA


WM_COPYDATA

The WM_COPYDATA message is sent when an application passes data to another application.

WM_COPYDATA
wParam = (WPARAM) (HWND) hwnd;            // handle of sending window
lParam = (LPARAM) (PCOPYDATASTRUCT) pcds; // pointer to structure with data

Parameters

hwnd
Handle to the window passing the data.
pcds
Pointer to a COPYDATASTRUCT structure that contains the data to be passed.

Return Values

If the receiving application processes this message, it should return TRUE; otherwise, it should return FALSE.

Remarks

An application must use the SendMessage function to send this message, not the PostMessage function.

The data being passed must not contain pointers or other references to objects not accessible to the application receiving the data.

While this message is being sent, the referenced data must not be changed by another thread of the sending process.

The receiving application should consider the data read-only. The pcds parameter is valid only during the processing of the message. The receiving application should not free the memory referenced by pcds. If the receiving application must access the data after SendMessage returns, it must copy the data into a local buffer.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.

See Also

Interprocess Communications Overview, Interprocess Communications Messages, PostMessage, SendMessage, COPYDATASTRUCT


Atoms

An atom table is a system-defined table that stores strings and corresponding identifiers. An application places a string in an atom table and receives a 16-bit integer, called an atom, that can be used to access the string. A string that has been placed in an atom table is called an atom name.


About Atom Tables

Dynamic data exchange (DDE) applications use an atom table to share item-name and topic-name strings with other applications. Rather than passing actual strings, a DDE application passes atoms to its partner application. The partner uses the atoms to obtain the strings from the atom table.


Global Atom Table

The system global atom table, which can contain up to 37 entries, is available to all applications. When an application places a string in the global atom table, the system generates an atom that is unique throughout the system. Any application that has the atom can obtain the string it identifies by querying the global atom table.

An application that defines a private clipboard-data format or DDE-data format for sharing data with other applications should place the format name in the global atom table. This technique prevents conflicts with the names of formats defined by the system or by other applications, and makes the identifiers (atoms) for the messages or formats available to the other applications.


Local Atom Tables

An application can use a local atom table to efficiently manage a large number of strings used only within the application. These strings, and the associated atoms, are available only to the application that created the table.

An application requiring the same string in a number of structures can reduce memory usage by using a local atom table. Rather than copying the string into each structure, the application can place the string in the atom table and include the resulting atom in the structures. In this way, a string appears only once in memory but can be used many times in the application.

Applications can also use local atom tables to save time when searching for a particular string. To perform a search, an application need only place the search string in the atom table and compare the resulting atom with the atoms in the relevant structures. Comparing atoms is typically faster than comparing strings.

By default, a local atom table can contain up to 37 entries. However, the size of a local atom table, unlike the size of a global atom table, can be changed. An application uses the InitAtomTable function to accomplish this task. If the application calls InitAtomTable, however, it must do so before calling any other atom-management functions.


Atom Types

Applications can use two types of atoms: string and integer. The following sections describe these types.


String Atoms

Applications pass null-terminated strings to atom tables and receive string atoms (16-bit integers) in return. String atoms have the following properties:

  • The values of string atoms are in the range 0xC000 through 0xFFFF.
  • Case is not significant in searches for an atom name in an atom table. Also, the entire string must match in a search operation; no substring matching is performed.
  • The string associated with a string atom can be no more than 255 bytes in size. This limitation applies to all atom functions.
  • A reference count is associated with each atom name. The count is incremented each time the atom name is added to the table and decremented each time the atom name is deleted from it. This prevents different users of the same string atom from destroying each other's atom names. When the reference count for an atom name equals zero, the system removes the atom and the atom name from the table.


Integer Atoms

Integer atoms differ from string atoms in the following ways:

  • The values of integer atoms are in the range 0x0001 through 0xBFFF. The values of integer atoms and string atoms do not overlap, so both types of atoms can be used in the same block of code.
  • The string representation of an integer atom is #dddd, where the values represented by dddd are decimal digits. Leading zeros are ignored.
  • There is no reference count or storage overhead associated with an integer atom.

Several Win32 functions accept either string or integer atoms as parameters. When passing an integer atom to these functions, an application must use the MAKEINTATOM macro to create the atom.


Atom Creation and Usage Count

An application creates a local atom by calling the AddAtom function; it creates a global atom by calling the GlobalAddAtom function. Both functions require a pointer to a string. The system searches the appropriate atom table for the string and returns the corresponding atom to the application. In the case of a string atom, if the string already resides in the atom table, the system increments the reference count for the string during this process.

Repeated calls to add the same atom name return the same atom. If the atom name does not exist in the table when AddAtom is called, the atom name is added to the table and a new atom is returned. If it is a string atom, its reference count is also set to one.

An application should call the DeleteAtom function when it no longer needs to use a local atom; it should call the GlobalDeleteAtom function when it no longer needs a global atom. In the case of a string atom, either of these functions reduces the reference count of the corresponding atom by one. When the reference count reaches zero, the system deletes the atom name from the table.

The atom name of a string atom remains in the global atom table as long as its reference count is greater than zero, even after the application that placed it in the table terminates. A local atom table is destroyed when the associated application terminates, regardless of the reference counts of the atoms in the table.


Atom-Table Queries

An application can determine whether a particular string is already in an atom table by using the FindAtom or GlobalFindAtom function. These functions search an atom table for the specified string and, if the string is there, return the corresponding atom.

An application can use the GetAtomName or GlobalGetAtomName function to retrieve an atom-name string from an atom table, provided the application has the atom corresponding to the string sought. Both functions copy the atom-name string of the specified atom to a buffer and return the length of the string that was copied. GetAtomName retrieves an atom-name string from a local atom table, and GlobalGetAtomName retrieves an atom-name string from the global atom table.


Atom String Formats

The AddAtom, GlobalAddAtom, FindAtom, and GlobalFindAtom functions take a pointer to a null-terminated string. An application can specify this pointer in one of the following ways.

Format | Description
#dddd | An integer specified as a decimal string. Used to create or find an integer atom.
string atom name | A string atom name. Used to add a string atom name to an atom table and receive an atom in return.


Using Atoms

The most typical use for atoms is in DDE applications. In the DDE protocol, applications use global atoms to identify the applications exchanging data, the nature of the data being exchanged, and the actual data items being exchanged. For more information about DDE and for examples that show how to use atoms, see Dynamic Data Exchange.


Atom Reference

The following elements are used with atoms.

  • Atom Functions
  • Atom Macros


Atom Functions

The following functions are used with atoms.

AddAtom
DeleteAtom
FindAtom
GetAtomName
GlobalAddAtom
GlobalDeleteAtom
GlobalFindAtom
GlobalGetAtomName
InitAtomTable


AddAtom

The AddAtom function adds a character string to the local atom table and returns a unique value (an atom) identifying the string.

ATOM AddAtom(
  LPCTSTR lpString   // pointer to string to add
);

Parameters

lpString
Pointer to the null-terminated string to be added. The string can have a maximum size of 255 bytes. Strings differing only in case are considered identical. The case of the first string added is preserved and returned by the GetAtomName function.

Return Values

If the function succeeds, the return value is the newly created atom.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The AddAtom function stores no more than one copy of a given string in the atom table. If the string is already in the table, the function returns the existing atom and, in the case of a string atom, increments the string's reference count.

The MAKEINTATOM macro can be used to convert a WORD value into a string that can be added to the atom table by using the AddAtom function.

AddAtom returns a string atom whose value is in the range 0xC000 through 0xFFFF.

If lpString has the form "#1234", AddAtom returns an integer atom whose value is the 16-bit representation of the decimal number specified in the string (0x04D2, in this example). If the decimal value specified is 0x0000 or a value in the range 0xC000 through 0xFFFF, the return value is zero, indicating an error. If lpString is in the range 0x0001 through 0xBFFF, the return value is the low-order word of lpString.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Atoms Overview, Atom Functions, DeleteAtom, FindAtom, GetAtomName, GlobalAddAtom, GlobalDeleteAtom, GlobalFindAtom, GlobalGetAtomName, MAKEINTATOM


DeleteAtom

The DeleteAtom function decrements the reference count of a local string atom. If the atom's reference count is reduced to zero, DeleteAtom removes the string associated with the atom from the local atom table.

ATOM DeleteAtom(
  ATOM nAtom   // atom to delete
);

Parameters

nAtom
Identifies the atom and character string to be deleted.

Return Values

If the function succeeds, the return value is zero.

If the function fails, the return value is the nAtom parameter. To get extended error information, call GetLastError.

Remarks

A string atom's reference count specifies the number of times the atom has been added to or removed from the atom table. The AddAtom function increments the count on each call. The DeleteAtom function decrements the count on each call but removes the string only if the atom's reference count is zero.

The only way to ensure that an atom has been deleted from the atom table is to call this function repeatedly until it fails. When the reference count is reduced to zero, the next call to the FindAtom or DeleteAtom function fails.

The DeleteAtom function has no effect on an integer atom (an atom created by using the MAKEINTATOM macro). The function always returns zero for an integer atom.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Atoms Overview, Atom Functions, AddAtom, FindAtom, GlobalAddAtom, GlobalDeleteAtom, GlobalFindAtom, MAKEINTATOM


FindAtom

The FindAtom function searches the local atom table for the specified character string and retrieves the atom associated with that string.

ATOM FindAtom(
  LPCTSTR lpString   // pointer to string to find
);

Parameters

lpString
Points to the null-terminated character string to search for.

Return Values

If the function succeeds, the return value is the atom associated with the given string.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Even though the system preserves the case of a string in an atom table, the search performed by the FindAtom function is not case sensitive.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Atoms Overview, Atom Functions, AddAtom, DeleteAtom, GlobalAddAtom, GlobalDeleteAtom, GlobalFindAtom


GetAtomName

The GetAtomName function retrieves a copy of the character string associated with the specified local atom. This function replaces the GetAtomHandle function.

UINT GetAtomName(
  ATOM nAtom,       // atom identifying character string
  LPTSTR lpBuffer,  // address of buffer for atom string
  int nSize         // size of buffer
);

Parameters

nAtom
Specifies the local atom that identifies the character string to be retrieved.
lpBuffer
Points to the buffer for the character string.
nSize
Specifies the size, in characters, of the buffer.

Return Values

If the function succeeds, the return value is the length of the string copied to the buffer, in characters, not including the terminating null character.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The string returned for an integer atom (an atom created by the MAKEINTATOM macro) is a null-terminated string in which the first character is a pound sign (#) and the remaining characters represent the unsigned integer originally passed to MAKEINTATOM.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Atoms Overview, Atom Functions, AddAtom, DeleteAtom, FindAtom, GlobalAddAtom, GlobalDeleteAtom, GlobalFindAtom, GlobalGetAtomName, MAKEINTATOM


GlobalAddAtom

The GlobalAddAtom function adds a character string to the global atom table and returns a unique value (an atom) identifying the string.

ATOM GlobalAddAtom(
  LPCTSTR lpString   // pointer to the string to add
);

Parameters

lpString
Points to the null-terminated string to be added. The string can have a maximum size of 255 bytes. Strings that differ only in case are considered identical. The case of the first string of this name added to the table is preserved and returned by the GlobalGetAtomName function.

Return Values

If the function succeeds, the return value is the newly created atom.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the string already exists in the global atom table, the atom for the existing string is returned and the atom's reference count is incremented.

The string associated with the atom is not deleted from memory until its reference count is zero. For more information, see the GlobalDeleteAtom function.

Global atoms are not deleted automatically when the application terminates. For every call to the GlobalAddAtom function, there must be a corresponding call to the GlobalDeleteAtom function.

GlobalAddAtom returns a string atom whose value is in the range 0xC000 through 0xFFFF.

If the lpString parameter has the form "#1234", GlobalAddAtom returns an integer atom whose value is the 16-bit representation of the decimal number specified in the string (0x04D2, in this example). If the decimal value specified is 0x0000 or a value in the range 0xC000 through 0xFFFF, the return value is zero, indicating an error. If lpString is in the range 0x0001 through 0xBFFF, the return value is the low-order word of lpString.

The MAKEINTATOM macro can be used to convert a WORD value into a string that can be added to the atom table by using the GlobalAddAtom function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Atoms Overview, Atom Functions, AddAtom, DeleteAtom, FindAtom, GetAtomName, GlobalDeleteAtom, GlobalFindAtom, GlobalGetAtomName, MAKEINTATOM


GlobalDeleteAtom

The GlobalDeleteAtom function decrements the reference count of a global string atom. If the atom's reference count reaches zero, GlobalDeleteAtom removes the string associated with the atom from the global atom table.

ATOM GlobalDeleteAtom(
  ATOM nAtom   // atom to delete
);

Parameters

nAtom
Identifies the atom and character string to be deleted.

Return Values

If the function succeeds, the return value is zero.

If the function fails, the return value is the nAtom parameter. To get extended error information, call GetLastError.

Remarks

A string atom's reference count specifies the number of times the string has been added to or removed from the atom table. The GlobalAddAtom function increments the reference count of a string that already exists in the global atom table each time it is called.

The only way to ensure that an atom has been deleted from the atom table is to call this function repeatedly until it fails. When the reference count is decremented to zero, the next GlobalFindAtom or GlobalDeleteAtom function call fails.

GlobalDeleteAtom has no effect on an integer atom (an atom created by using the MAKEINTATOM macro). The function always returns zero for an integer atom.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Atoms Overview, Atom Functions, AddAtom, DeleteAtom, FindAtom, GlobalAddAtom, GlobalFindAtom, MAKEINTATOM


GlobalFindAtom

The GlobalFindAtom function searches the global atom table for the specified character string and retrieves the global atom associated with that string.

ATOM GlobalFindAtom(
  LPCTSTR lpString   // pointer to the string to find
);

Parameters

lpString
Points to the null-terminated character string to search for.

Return Values

If the function succeeds, the return value is the global atom associated with the given string.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Even though the system preserves the case of a string in an atom table as it was originally entered, the search performed by GlobalFindAtom is not case sensitive.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Atoms Overview, Atom Functions, AddAtom, DeleteAtom, FindAtom, GetAtomName, GlobalAddAtom, GlobalDeleteAtom, GlobalGetAtomName


GlobalGetAtomName

The GlobalGetAtomName function retrieves a copy of the character string associated with the specified global atom.

UINT GlobalGetAtomName(
  ATOM nAtom,       // atom identifier
  LPTSTR lpBuffer,  // pointer to the buffer for the atom string
  int nSize         // size of the buffer
);

Parameters

nAtom
Identifies the global atom associated with the character string to be retrieved.
lpBuffer
Points to the buffer for the character string.
nSize
Specifies the size, in characters, of the buffer.

Return Values

If the function succeeds, the return value is the length of the string copied to the buffer, in characters, not including the terminating null character.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The string returned for an integer atom (an atom created by the MAKEINTATOM macro) is a null-terminated string in which the first character is a pound sign (#) and the remaining characters represent the unsigned integer originally passed to MAKEINTATOM.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Atoms Overview, Atom Functions, AddAtom, DeleteAtom, FindAtom, GlobalAddAtom, GlobalDeleteAtom, GlobalFindAtom, MAKEINTATOM


InitAtomTable

The InitAtomTable function initializes the local atom table and sets it to the specified size.

BOOL InitAtomTable(
  DWORD nSize   // size of atom table
);

Parameters

nSize
Specifies the size, in table entries, of the atom table. This value should be a prime number.

The atom table is a hash table. You will get better performance by passing a prime number in nSize, up to the maximum number of atoms possible, which is 0x3FFF (0xC001 through 0xFFFF).

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Remarks

An application need not use this function to use a local atom table. The default size of the local and global atom tables is 37 table entries. If an application does use InitAtomTable, however, it should call the function before any other atom-management function.

If an application uses a large number of local atoms, it can reduce the time required to add an atom to the local atom table or to find an atom in the table by increasing the size of the table. However, this increases the amount of memory required to maintain the table.

The size of the global atom table cannot be changed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Atoms Overview, Atom Functions, AddAtom, DeleteAtom, FindAtom, GetAtomName, GlobalAddAtom, GlobalDeleteAtom, GlobalFindAtom, GlobalGetAtomName


Atom Macros

The following macro is used with atoms.

MAKEINTATOM


MAKEINTATOM

The MAKEINTATOM macro creates an integer atom that represents a character string of decimal digits.

Integer atoms created by this macro can be added to an atom table by using the AddAtom or GlobalAddAtom function.

LPTSTR MAKEINTATOM(
  WORD wInteger  // integer to make into atom
);

Parameters

wInteger
Specifies the numeric value to be made into an integer atom.

Return Values

The return value is a pointer to the atom created for the given integer.

Remarks

Although the return value of the MAKEINTATOM macro is cast as an LPTSTR value, it cannot be used as a string pointer except when it is passed to atom-management functions that require an LPTSTR argument.

The DeleteAtom and GlobalDeleteAtom functions always succeed for integer atoms, even though they do nothing. The string returned by the GetAtomName and GlobalGetAtomName functions for an integer atom is a null-terminated string in which the first character is a pound sign (#) and the remaining characters are the decimal digits used in the MAKEINTATOM macro.

The MAKEINTATOM macro is defined as follows:

#define MAKEINTATOM(i)   (LPTSTR) ((DWORD) ((WORD) (i)))

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Atoms Overview, Atom Macros, AddAtom, DeleteAtom, GetAtomName, GlobalAddAtom, GlobalDeleteAtom, GlobalGetAtomName


Clipboard

The clipboard is a set of functions and messages that enable Win32-based applications to transfer data. Because all applications have access to the clipboard, data can be easily transferred between applications or within an application.

This overview does not describe how to copy and paste linked or embedded objects. For information on these subjects, see the COM documentation.


About the Clipboard

A memory object on the clipboard can be in any data format, called a clipboard format. Each format is identified by an unsigned integer value. For standard (predefined) clipboard formats, this value is a constant defined by the Microsoft® Win32® API; for registered clipboard formats, it is the return value of the RegisterClipboardFormat function.

Except for registering clipboard formats, individual windows perform most clipboard operations. Typically, a window procedure transfers information to or from the clipboard in response to the WM_COMMAND message.

The clipboard is user-driven. A window should transfer data to or from the clipboard only in response to a command from the user. A window must not use the clipboard to transfer data without the user's knowledge.


Clipboard Formats

A window can place more than one object on the clipboard, each representing the same information in a different clipboard format. Users need not be aware of the clipboard formats used for an object on the clipboard. The following topics describe the clipboard formats.

  • Standard Clipboard Formats
  • Registered Clipboard Formats
  • Private Clipboard Formats
  • Multiple Clipboard Formats
  • Synthesized Clipboard Formats


Standard Clipboard Formats

The clipboard formats defined by the system are called standard clipboard formats. These clipboard formats are described in the following table.

Value | Meaning
CF_BITMAP | A handle to a bitmap (HBITMAP).
CF_DIB | A memory object containing a BITMAPINFO structure followed by the bitmap bits.
CF_DIBV5 | Windows NT 5.0: A memory object containing a BITMAPV5HEADER structure followed by the bitmap color space information and the bitmap bits.
CF_DIF | Software Arts' Data Interchange Format.
CF_DSPBITMAP | Bitmap display format associated with a private format. The hMem parameter must be a handle of data that can be displayed in bitmap format in lieu of the privately formatted data.
CF_DSPENHMETAFILE | Enhanced metafile display format associated with a private format. The hMem parameter must be a handle of data that can be displayed in enhanced metafile format in lieu of the privately formatted data.
CF_DSPMETAFILEPICT | Metafile-picture display format associated with a private format. The hMem parameter must be a handle of data that can be displayed in metafile-picture format in lieu of the privately formatted data.
CF_DSPTEXT | Text display format associated with a private format. The hMem parameter must be a handle of data that can be displayed in text format in lieu of the privately formatted data.
CF_ENHMETAFILE | A handle of an enhanced metafile (HENHMETAFILE).
CF_GDIOBJFIRST through CF_GDIOBJLAST | Range of integer values for application-defined GDI object clipboard formats. Handles associated with clipboard formats in this range are not automatically deleted using the GlobalFree function when the clipboard is emptied. Also, when using values in this range, the hMem parameter is not a handle to a GDI object, but is a handle allocated by the GlobalAlloc function with the GMEM_DDESHARE and GMEM_MOVEABLE flags.
CF_HDROP | A handle of type HDROP that identifies a list of files. An application can retrieve information about the files by passing the handle to the DragQueryFile functions.
CF_LOCALE The data is a handle to the locale identifier associated with text in the clipboard. When you close the clipboard, if it contains CF_TEXT data but no CF_LOCALE data, the system automatically sets the CF_LOCALE format to the current input locale. You can use the CF_LOCALE format to associate a different locale with the clipboard text.

An application that pastes text from the clipboard can retrieve this format to determine which character set was used to generate the text.

Note that the clipboard does not support plain text in multiple character sets. To achieve this, use a fomatted text data type such as RTF instead.

Windows NT: The system uses the code page associated with CF_LOCALE to implicitly convert from CF_TEXT to CF_UNICODETEXT. Therefore, the correct code page table is used for the conversion.
CF_METAFILEPICT | Handle of a metafile picture format as defined by the METAFILEPICT structure. When passing a CF_METAFILEPICT handle by means of dynamic data exchange (DDE), the application responsible for deleting hMem should also free the metafile referred to by the CF_METAFILEPICT handle.
CF_OEMTEXT | Text format containing characters in the OEM character set. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data.
CF_OWNERDISPLAY | Owner-display format. The clipboard owner must display and update the clipboard viewer window, and receive the WM_ASKCBFORMATNAME, WM_HSCROLLCLIPBOARD, WM_PAINTCLIPBOARD, WM_SIZECLIPBOARD, and WM_VSCROLLCLIPBOARD messages. The hMem parameter must be NULL.
CF_PALETTE | Handle of a color palette. Whenever an application places data in the clipboard that depends on or assumes a color palette, it should place the palette on the clipboard as well.
If the clipboard contains data in the CF_PALETTE (logical color palette) format, the application should use the SelectPalette and RealizePalette functions to realize (compare) any other data in the clipboard against that logical palette.
When displaying clipboard data, the clipboard always uses as its current palette any object on the clipboard that is in the CF_PALETTE format.
CF_PENDATA | Data for the pen extensions to the Microsoft® Windows® for Pen Computing.
CF_PRIVATEFIRST through CF_PRIVATELAST | Range of integer values for private clipboard formats. Handles associated with private clipboard formats are not freed automatically; the clipboard owner must free such handles, typically in response to the WM_DESTROYCLIPBOARD message.
CF_RIFF | Represents audio data more complex than can be represented in a CF_WAVE standard wave format.
CF_SYLK | Microsoft Symbolic Link (SYLK) format.
CF_TEXT | Text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data. Use this format for ANSI text.
CF_WAVE | Represents audio data in one of the standard wave formats, such as 11 kHz or 22 kHz pulse code modulation (PCM).
CF_TIFF | Tagged-image file format.
CF_UNICODETEXT | Windows NT: Unicode text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data.


Registered Clipboard Formats

Many applications work with data that cannot be translated into a standard clipboard format without loss of information. These applications can create their own clipboard formats. A clipboard format that is defined by an application, is called a registered clipboard format. For example, if a word-processing application copied formatted text to the clipboard using a standard text format, the formatting information would be lost. The solution would be to register a new clipboard format, such as Rich Text Format (RTF).

To register a new clipboard format, use the RegisterClipboardFormat function. This function takes the name of the format and returns and unsigned integer value that represents the registered clipboard format. To retrieve the name of the registered clipboard format, pass the unsigned integer value to the GetClipboardFormatName function.

If more than one application registers a clipboard format with exactly the same name, the clipboard format is registered only once. Both calls to the RegisterClipboardFormat function return the same value. In this way, two different applications can share data by using a registered clipboard format.


Private Clipboard Formats

An application can identify a private clipboard format by defining a value in the range CF_PRIVATEFIRST through CF_PRIVATELAST. An application can use a private clipboard format for an application-defined data format that does not need to be registered with the system.

Data handles associated with private clipboard formats are automatically freed by the system. Windows that use private clipboard formats can use the WM_DESTROYCLIPBOARD message to free any related resources that are no longer needed.

For more information about the WM_DESTROYCLIPBOARD message, see Clipboard Ownership.

An application can place data handles on the clipboard by defining a private format in the range CF_GDIOBJFIRST through CF_GDIOBJLAST. When using values in this range, the data handle is not a handle to a GDI object, but is a handle allocated by the GlobalAlloc function with the GMEM_DDESHARE and GMEM_MOVEABLE flags. When the clipboard is emptied the system automatically deletes the object using the GlobalFree function


Multiple Clipboard Formats

A window can place more than one clipboard object on the clipboard, each representing the same information in a different clipboard format. When placing information on the clipboard, the window should provide data in as many formats as possible. To find out how many formats are currently used on the clipboard, call the CountClipboardFormats function.

Clipboard formats that contain the most information should be placed on the clipboard first, followed by less descriptive formats. A window pasting information from the clipboard typically retrieves a clipboard object in the first format it recognizes. Because clipboard formats are enumerated in the order they are placed on the clipboard, the first recognized format is also the most descriptive.

For example, suppose a user copies styled text from a word-processing document. The window containing the document might first place data on the clipboard in a registered format, such as RTF. Subsequently, the window would place data on the clipboard in a less descriptive format, such as text (CF_TEXT).

When the content of the clipboard is pasted into another window, the window retrieves data in the most descriptive format it recognizes. If the window recognizes RTF, the corresponding data is pasted into the document. Otherwise, the text data is pasted into the document and the formatting information is lost.


Synthesized Clipboard Formats

The system implicitly converts data between certain clipboard formats: if a window requests data in a format that is not on the clipboard, the system converts an available format to the requested format. The system can convert data as indicated in the following table.

Clipboard Format | Conversion Format | Platform Support
CF_BITMAP | CF_DIB | Windows NT, Windows 95, Windows 98
CF_BITMAP | CF_DIBV5 | Windows NT 5.0
CF_DIB | CF_BITMAP | Windows NT, Windows 95, Windows 98
CF_DIB | CF_PALETTE | Windows NT, Windows 95, Windows 98
CF_DIB | CF_DIBV5 | Windows NT 5.0
CF_DIBV5 | CF_BITMAP | Windows NT 5.0
CF_DIBV5 | CF_DIB | Windows NT 5.0
CF_DIBV5 | CF_PALETTE | Windows NT 5.0
CF_ENHMETAFILE | CF_METAFILEPICT | Windows NT, Windows 95, Windows 98
CF_METAFILEPICT | CF_ENHMETAFILE | Windows NT, Windows 95, Windows 98
CF_OEMTEXT | CF_TEXT | Windows NT, Windows 95, Windows 98
CF_OEMTEXT | CF_UNICODETEXT | Windows NT
CF_TEXT | CF_OEMTEXT | Windows NT, Windows 95, Windows 98
CF_TEXT | CF_UNICODETEXT | Windows NT
CF_UNICODETEXT | CF_OEMTEXT | Windows NT
CF_UNICODETEXT | CF_TEXT | Windows NT

If the system provides an automatic type conversion for a particular clipboard format, there is no advantage to placing the conversion format(s) on the clipboard.

If the system provides an automatic type conversion for a particular clipboard format, and you call EnumClipboardFormats to enumerate the clipboard data formats, the system first enumerates the format that is on the clipboard, followed by the formats to which it can be converted.

When copying bitmaps, it is best to place the CF_DIB or CF_DIBV5 format on the clipboard. This is because the colors in a device-dependent bitmap (CF_BITMAP) are relative to the system palette, which may change before the bitmap is pasted. If the CF_DIB or CF_DIBV5 format is on the clipboard and a window requests the CF_BITMAP format, the system renders the device-independent bitmap (DIB) using the current palette at that time.

If you place the CF_BITMAP format on the clipboard (and not CF_DIB), the system renders the CF_DIB or CF_DIBV5 clipboard format as soon as the clipboard is closed. This ensures that the correct palette is used to generate the DIB. If you place the CF_DIBV5 format with the bitmap color space information in the clipboard, the system will convert the bitmap bits from the bitmap color space to the sRGB color space when CF_DIB or CF_DIBV5 is requested. If CF_DIBV5 is requested when there is no color space information in the clipboard, the system returns sRGB color space information in the BITMAPV5HEADER structure. Conversions between other clipboard formats occur upon demand.

If the clipboard contains data in the CF_PALETTE format, the application should use the SelectPalette and RealizePalette functions to realize any other data in the clipboard against that logical palette.

There are two clipboard formats for metafiles: CF_ENHMETAFILE and CF_METAFILEPICT. Specify CF_ENHMETAFILE for enhanced metafiles and CF_METAFILEPICT for Windows metafiles.


Clipboard Operations

A window should use the clipboard when cutting, copying, or pasting data. A window places data on the clipboard for cut and copy operations and retrieves data from the clipboard for paste operations. The following sections describe these operations and related issues.

To place data on or retrieve data from the clipboard, a window must first open the clipboard by using the OpenClipboard function. Only one window can have the clipboard open at a time. To find out which window has the clipboard open, call the GetOpenClipboardWindow function. When it has finished, the window must close the clipboard by calling the CloseClipboard function.


Cut and Copy Operations

To place information on the clipboard, a window first clears any previous clipboard content by using the EmptyClipboard function. This function sends the WM_DESTROYCLIPBOARD message to the previous clipboard owner, frees resources associated with data on the clipboard, and assigns clipboard ownership to the window that has the clipboard open. To find out which window owns the clipboard, call the GetClipboardOwner function.

After emptying the clipboard, the window places data on the clipboard in as many clipboard formats as possible, ordered from the most descriptive clipboard format to the least descriptive. For each format, the window calls the SetClipboardData function, specifying the format identifier and a global memory handle. The memory handle can be NULL, indicating that the window renders the data on request. For more information, see Delayed Rendering.


Paste Operations

To retrieve paste information from the clipboard, a window first determines the clipboard format to retrieve. Typically, a window enumerates the available clipboard formats by using the EnumClipboardFormats function and uses the first format it recognizes. This method selects the best available format according to the priority set when the data was placed on the clipboard.

Alternatively, a window can use the GetPriorityClipboardFormat function. This function identifies the best available clipboard format according to a specified priority. A window that recognizes only one clipboard format can simply determine whether that format is available by using the IsClipboardFormatAvailable function.

After determining the clipboard format to use, a window calls the GetClipboardData function. This function returns the handle of a global memory object containing data in the specified format. A window can briefly lock the memory object in order to examine or copy the data. However, a window should not free the object or leave it locked for a long period of time.


Clipboard Ownership

The clipboard owner is the window associated with the information on the clipboard. A window becomes the clipboard owner when it places data on the clipboard — specifically, when it calls the EmptyClipboard function. The window remains the clipboard owner until it is closed or another window empties the clipboard.

When the clipboard is emptied, the clipboard owner receives a WM_DESTROYCLIPBOARD message. Following are some reasons why a window might process this message:

  • The window delayed rendering of one or more clipboard formats. In response to the WM_DESTROYCLIPBOARD message, the window might free resources it had allocated in order to render data on request. For more information about the rendering of data, see Delayed Rendering.
  • The window placed data on the clipboard in a private clipboard format. The data for private clipboard formats is not freed by the system when the clipboard is emptied. Therefore, the clipboard owner should free the data upon receiving the WM_DESTROYCLIPBOARD message. For more information about private clipboard formats, see Clipboard Formats.
  • The window placed data on the clipboard using the CF_OWNERDISPLAY clipboard format. In response to the WM_DESTROYCLIPBOARD message, the window might free resources it had used to display information in the clipboard viewer window. For more information about this alternative format, see Owner-Display Format.


Delayed Rendering

When placing a clipboard format on the clipboard, a window can delay rendering the data in that format until the data is needed. To do so, an application can specify NULL for the hData parameter of the SetClipboardData function. This is useful if the application supports several clipboard formats, some or all of which are time-consuming to render. By passing a NULL handle, a window renders complex clipboard formats only when and if they are needed.

If a window delays rendering a clipboard format, it must be prepared to render the format upon request for as long as it is the clipboard owner. The system sends the clipboard owner a WM_RENDERFORMAT message when a request is received for a specific format that has not been rendered. Upon receiving this message, the window should call the SetClipboardData function to place a global memory handle on the clipboard in the requested format.

If the clipboard owner is destroyed and has delayed rendering some or all clipboard formats, it receives the WM_RENDERALLFORMATS message. Upon receiving this message, the window should place valid memory handles on the clipboard for all clipboard formats that it provides. This ensures that these formats remain available after the clipboard owner is destroyed.

An application should not open the clipboard before calling SetClipboardData in response to the WM_RENDERFORMAT or WM_RENDERALLFORMATS message.

Any clipboard formats that are not rendered in response to the WM_RENDERALLFORMATS message cease to be available to other applications and are no longer enumerated by the clipboard functions.


Memory and the Clipboard

A memory object that is to be placed on the clipboard should be allocated by using the GlobalAlloc function with the GMEM_DDESHARE and GMEM_MOVEABLE flags.

Once a memory object is placed on the clipboard, ownership of that memory handle is transferred to the system. When the clipboard is emptied and the memory object has one of the following clipboard formats, the system frees the memory object by calling the indicated Win32 function:

Function called to free object | Clipboard format
DeleteMetaFile | CF_DSPENHMETAFILE
CF_DSPMETAFILEPICT
CF_ENHMETAFILE
CF_METAFILEPICT
DeleteObject | CF_BITMAP
CF_DSPBITMAP
CF_PALETTE
GlobalFree | CF_DIB
CF_DIBV5
CF_DSPTEXT
CF_OEMTEXT
CF_TEXT
CF_UNICODETEXT

When the clipboard is emptied of a memory object whose clipboard format is not shown in the preceding list, the application itself must free the memory object.


Clipboard Viewers

A clipboard viewer is a window that displays the current content of the clipboard. The clipboard viewer window is a convenience for the user and does not affect the data-transaction functions of the clipboard.

Typically, a clipboard viewer window can display at least the three most common formats: CF_TEXT, CF_BITMAP, and CF_METAFILEPICT. If a window does not make data available in any of these three formats, it should provide data in a display format or use the owner-display format.

A clipboard viewer chain is the linking together of two or more entities so that they are dependent upon one another for operation. This interdependency (chain) allows all running clipboard viewer applications to receive the messages sent to the current clipboard.


Clipboard Viewer Windows

A window adds itself to the clipboard viewer chain by calling the SetClipboardViewer function. The return value is the handle of the next window in the chain. To retrieve the handle of the first window in the chain, call the GetClipboardViewer function.

Each clipboard viewer window must keep track of the next window in the clipboard viewer chain. When the content of the clipboard changes, the system sends a WM_DRAWCLIPBOARD message to the first window in the chain. After updating its display, each clipboard viewer window must pass this message on to the next window in the chain.

Before closing, a clipboard viewer window must remove itself from the clipboard viewer chain by calling the ChangeClipboardChain function. The system then sends a WM_CHANGECBCHAIN message to the first window in the chain.

For more information about processing the WM_DRAWCLIPBOARD and WM_CHANGECBCHAIN messages, see Creating a Clipboard Viewer Window.


Display Formats

A display format is a clipboard format used to display information in a clipboard viewer window. A clipboard owner that uses a private or registered clipboard format, and none of the most common standard formats, must provide data in a display format for viewing in a clipboard viewer window. The display formats are intended for viewing only and must not be pasted into a document.

The four display formats are: CF_DSPBITMAP, CF_DSPMETAFILEPICT, CF_DSPTEXT, and CF_DSPENHMETAFILE. These display formats are rendered in the same way as the standard formats, which are: CF_BITMAP, CF_TEXT, CF_METAFILEPICT, and CF_ENHMETAFILE.


Owner-Display Format

For a clipboard owner that does not use any of the common standard clipboard formats, an alternative to providing a display format is to use the owner-display (CF_OWNERDISPLAY) clipboard format.

By using the owner-display format, a clipboard owner can avoid the overhead of rendering data in an additional format by taking direct control over painting the clipboard viewer window. The clipboard viewer window sends messages to the clipboard owner whenever a portion of the window must be repainted or when the window is scrolled or resized.


Clipboard Commands

A user typically carries out clipboard operations by choosing commands from an application's Edit menu. Following is a brief description of the standard clipboard commands.

Command | Description
Cut | Places a copy of the current selection on the clipboard and deletes the selection from the document. The previous content of the clipboard is destroyed.
Copy | Places a copy of the current selection on the clipboard. The document remains unchanged. The previous content of the clipboard is destroyed.
Paste | Replaces the current selection with the content of the clipboard. The content of the clipboard is not changed.
Delete | Deletes the current selection from the document. The content of the clipboard is not changed. This command does not involve the clipboard, but it should appear with the clipboard commands on the Edit menu.


Clipboard Sequence Number

The clipboard for each window station has an associated clipboard sequence number. This number is incremented whenever the contents of the clipboard change. To obtain the clipboard sequence number, call the GetClipboardSequenceNumber function.


Using the Clipboard

  • Implementing the Cut, Copy, and Paste commands
  • Creating a clipboard viewer window


Implementing the Cut, Copy, and Paste Commands

This section describes how standard Cut, Copy, and Paste commands are implemented in an application. The example in this section uses these methods to place data on the clipboard using a registered clipboard format, the CF_OWNERDISPLAY format, and the CF_TEXT format. The registered format is used to represent rectangular or elliptical text windows, called labels.


Selecting Data

Before information can be copied to the clipboard, the user must select specific information to be copied or cut. An application should provide a means for the user to select information within a document and some kind of visual feedback to indicate selected data.


Creating an Edit Menu

An application should load an accelerator table containing the standard keyboard accelerators for the Edit menu commands. The TranslateAccelerator function must be added to the application's message loop for the accelerators to take effect. For more information about keyboard accelerators, see Keyboard Accelerators.


Processing the WM_INITMENUPOPUP Message

Not all clipboard commands are available to the user at any given time. An application should process the WM_INITMENUPOPUP message to enable the menu items for available commands and disable unavailable commands.

Following is the WM_INITMENUPOPUP case for an application named Label.

case WM_INITMENUPOPUP:
    InitMenu((HMENU) wParam);
    break;

The InitMenu function is defined as follows.

void WINAPI InitMenu(HMENU hmenu)
{
    int  cMenuItems = GetMenuItemCount(hmenu);
    int  nPos;
    UINT id;
    UINT fuFlags;
    PLABELBOX pbox = (hwndSelected == NULL) ? NULL :
        (PLABELBOX) GetWindowLong(hwndSelected, 0);

    for (nPos = 0; nPos < cMenuItems; nPos++)
    {
        id = GetMenuItemID(hmenu, nPos);

        switch (id)
        {
            case IDM_CUT:
            case IDM_COPY:
            case IDM_DELETE:
                if (pbox == NULL || !pbox->fSelected)
                    fuFlags = MF_BYCOMMAND | MF_GRAYED;
                else if (pbox->fEdit)
                    fuFlags = (id != IDM_DELETE && pbox->ichSel
                            == pbox->ichCaret) ?
                        MF_BYCOMMAND | MF_GRAYED :
                        MF_BYCOMMAND | MF_ENABLED;
                else
                    fuFlags = MF_BYCOMMAND | MF_ENABLED;

                EnableMenuItem(hmenu, id, fuFlags);
                break;

            case IDM_PASTE:
                if (pbox != NULL && pbox->fEdit)
                    EnableMenuItem(hmenu, id,
                        IsClipboardFormatAvailable(CF_TEXT) ?
                            MF_BYCOMMAND | MF_ENABLED :
                            MF_BYCOMMAND | MF_GRAYED
                    );
                else
                    EnableMenuItem(hmenu, id,
                        IsClipboardFormatAvailable(
                                uLabelFormat) ?
                            MF_BYCOMMAND | MF_ENABLED :
                            MF_BYCOMMAND | MF_GRAYED
                    );

        }
    }
}


Processing the WM_COMMAND Message

To process menu commands, add the WM_COMMAND case to your application's main window procedure. Following is the WM_COMMAND case for the Label application's window procedure.

case WM_COMMAND:
    switch (LOWORD(wParam))
    {
        case IDM_CUT:
            if (EditCopy())
                EditDelete();
            break;

        case IDM_COPY:
            EditCopy();
            break;

        case IDM_PASTE:
            EditPaste();
            break;

        case IDM_DELETE:
            EditDelete();
            break;

        case IDM_EXIT:
            DestroyWindow(hwnd);
    }
    break;

To carry out the Copy and Cut commands, the window procedure calls the application-defined EditCopy function. For more information, see Copying Information to the Clipboard. To carry out the Paste command, the window procedure calls the application-defined EditPaste function. For more information about the EditPaste function, see Pasting Information from the Clipboard.


Copying Information to the Clipboard

In the Label application, the application-defined EditCopy function copies the current selection to the clipboard. This function does the following:

  1. Opens the clipboard by calling the OpenClipboard function.
  2. Empties the clipboard by calling the EmptyClipboard function.
  3. Calls the SetClipboardData function once for each clipboard format the application provides.
  4. Closes the clipboard by calling the CloseClipboard function.

Depending on the current selection, the EditCopy function either copies a range of text or copies an application-defined structure representing an entire label. The structure, called LABELBOX, is defined as follows.

#define BOX_ELLIPSE  0
#define BOX_RECT     1

#define CCH_MAXLABEL 80
#define CX_MARGIN    12

typedef struct tagLABELBOX {  // box
    RECT rcText;    // coordinates of rectangle containing text
    BOOL fSelected; // TRUE if the label is selected
    BOOL fEdit;     // TRUE if text is selected
    int nType;      // rectangular or elliptical
    int ichCaret;   // caret position
    int ichSel;     // with ichCaret, delimits selection
    int nXCaret;    // window position corresponding to ichCaret
    int nXSel;      // window position corresponding to ichSel
    int cchLabel;   // length of text in atchLabel
    TCHAR atchLabel[CCH_MAXLABEL];
} LABELBOX, *PLABELBOX;

Following is the EditCopy function.

BOOL WINAPI EditCopy(VOID)
{
    PLABELBOX pbox;
    LPTSTR  lptstrCopy;
    HGLOBAL hglbCopy;
    int ich1, ich2, cch;

    if (hwndSelected == NULL)
        return FALSE;

    // Open the clipboard, and empty it.

    if (!OpenClipboard(hwndMain))
        return FALSE;
    EmptyClipboard();

    // Get a pointer to the structure for the selected label.

    pbox = (PLABELBOX) GetWindowLong(hwndSelected, 0);

    // If text is selected, copy it using the CF_TEXT format.

    if (pbox->fEdit)
    {
        if (pbox->ichSel == pbox->ichCaret)     // zero length
        {
            CloseClipboard();                   // selection
            return FALSE;
        }

        if (pbox->ichSel < pbox->ichCaret)
        {
            ich1 = pbox->ichSel;
            ich2 = pbox->ichCaret;
        }
        else
        {
            ich1 = pbox->ichCaret;
            ich2 = pbox->ichSel;
        }
        cch = ich2 - ich1;

        // Allocate a global memory object for the text.

        hglbCopy = GlobalAlloc(GMEM_DDESHARE,
            (cch + 1) * sizeof(TCHAR));
        if (hglbCopy == NULL)
        {
            CloseClipboard();
            return FALSE;
        }

        // Lock the handle and copy the text to the buffer.

        lptstrCopy = GlobalLock(hglbCopy);
        memcpy(lptstrCopy, &pbox->atchLabel[ich1],
            cch * sizeof(TCHAR));
        lptstrCopy[cch] = (TCHAR) 0;    // null character
        GlobalUnlock(hglbCopy);

        // Place the handle on the clipboard.

        SetClipboardData(CF_TEXT, hglbCopy);
    }

    // If no text is selected, the label as a whole is copied.

    else
    {
        // Save a copy of the selected label as a local memory
        // object. This copy is used to render data on request.
        // It is freed in response to the WM_DESTROYCLIPBOARD
        // message.

        pboxLocalClip = (PLABELBOX) LocalAlloc(
            LMEM_FIXED,
            sizeof(LABELBOX)
        );
        if (pboxLocalClip == NULL)
        {
            CloseClipboard();
            return FALSE;
        }
        memcpy(pboxLocalClip, pbox, sizeof(LABELBOX));
        pboxLocalClip->fSelected = FALSE;
        pboxLocalClip->fEdit = FALSE;

        // Place a registered clipboard format, the owner-display
        // format, and the CF_TEXT format on the clipboard using
        // delayed rendering.

        SetClipboardData(uLabelFormat, NULL);
        SetClipboardData(CF_OWNERDISPLAY, NULL);
        SetClipboardData(CF_TEXT, NULL);
    }

    // Close the clipboard.

    CloseClipboard();

    return TRUE;
}


Pasting Information from the Clipboard

In the Label application, the application-defined EditPaste function pastes the content of the clipboard. This function does the following:

  1. Opens the clipboard by calling the OpenClipboard function.
  2. Determines which of the available clipboard formats to retrieve.
  3. Retrieves the handle of the data in the selected format by calling the GetClipboardData function.
  4. Inserts a copy of the data into the document.

    The handle returned by GetClipboardData is still owned by the clipboard, so an application must not free it or leave it locked.

  5. Closes the clipboard by calling the CloseClipboard function.

If a label is selected and contains an insertion point, the EditPaste function inserts the text from the clipboard at the insertion point. If there is no selection or if a label is selected, the function creates a new label, using the application-defined LABELBOX structure on the clipboard. The LABELBOX structure is placed on the clipboard by using a registered clipboard format.

Following is the EditPaste function.

VOID WINAPI EditPaste(VOID)
{
    PLABELBOX pbox;
    HGLOBAL   hglb;
    LPTSTR    lptstr;
    PLABELBOX pboxCopy;
    int cx, cy;
    HWND hwnd;

    pbox = hwndSelected == NULL ? NULL :
        (PLABELBOX) GetWindowLong(hwndSelected, 0);

    // If the application is in edit mode,
    // get the clipboard text.

    if (pbox != NULL && pbox->fEdit)
    {
        if (!IsClipboardFormatAvailable(CF_TEXT))
            return;
        if (!OpenClipboard(hwndMain))
            return;

        hglb = GetClipboardData(CF_TEXT);
        if (hglb != NULL)
        {
            lptstr = GlobalLock(hglb);
            if (lptstr != NULL)
            {
                // Call the application-defined ReplaceSelection
                // function to insert the text and repaint the
                // window.

                ReplaceSelection(hwndSelected, pbox, lptstr);
                GlobalUnlock(hglb);
            }
        }
        CloseClipboard();

        return;
    }

    // If the application is not in edit mode,
    // create a label window.

    if (!IsClipboardFormatAvailable(uLabelFormat))
        return;
    if (!OpenClipboard(hwndMain))
        return;

    hglb = GetClipboardData(uLabelFormat);
    if (hglb != NULL)
    {
        pboxCopy = GlobalLock(hglb);
        if (pboxCopy != NULL)
        {
            cx = pboxCopy->rcText.right + CX_MARGIN;
            cy = pboxCopy->rcText.top * 2 + cyText;

            hwnd = CreateWindowEx(
                WS_EX_NOPARENTNOTIFY | WS_EX_TRANSPARENT,
                atchClassChild, NULL, WS_CHILD, 0, 0, cx, cy,
                hwndMain, NULL, hinst, NULL
            );
            if (hwnd != NULL)
            {
                pbox = (PLABELBOX) GetWindowLong(hwnd, 0);
                memcpy(pbox, pboxCopy, sizeof(LABELBOX));
                ShowWindow(hwnd, SW_SHOWNORMAL);
                SetFocus(hwnd);
            }
            GlobalUnlock(hglb);
        }
    }
    CloseClipboard();
}


Registering a Clipboard Format

To register a clipboard format, add a call to the RegisterClipboardFormat function to your application's instance initialization function, as follows.

// Register a clipboard format.

LoadString(hinstCurrent, IDS_FORMATNAME, atchTemp,
    sizeof(atchTemp));
uLabelFormat = RegisterClipboardFormat(atchTemp);
if (uLabelFormat == 0)
    return FALSE;


Processing the WM_RENDERFORMAT and WM_RENDERALLFORMATS Messages

If a window passes a NULL handle to the SetClipboardData function, it must process the WM_RENDERFORMAT and WM_RENDERALLFORMATS messages to render data upon request.

If the WM_RENDERFORMAT message delayed rendering a specific format and an application requested data in that format, the message is sent to the clipboard owner. If the WM_RENDERFORMAT message has delayed rendering one or more formats, the message is sent to the clipboard owner before it is destroyed.

To render a clipboard format, the window procedure must place a data handle on the clipboard by using the SetClipboardData function. It must not open the clipboard before calling SetClipboardData.

The Label application processes the WM_RENDERFORMAT and WM_RENDERALLFORMATS messages as follows.

case WM_RENDERFORMAT:
    RenderFormat((UINT) wParam);
    break;

case WM_RENDERALLFORMATS:
    RenderFormat(uLabelFormat);
    RenderFormat(CF_TEXT);
    break;

In both cases, the window procedure calls the application-defined RenderFormat function, defined as follows.

void WINAPI RenderFormat(UINT uFormat)
{
    HGLOBAL hglb;
    PLABELBOX pbox;
    LPTSTR  lptstr;
    int cch;

    if (pboxLocalClip == NULL)
        return;

    if (uFormat == CF_TEXT)
    {
        // Allocate a buffer for the text.

        cch = pboxLocalClip->cchLabel;
        hglb = GlobalAlloc(GMEM_DDESHARE,
            (cch + 1) * sizeof(TCHAR));
        if (hglb == NULL)
            return;

        // Copy the text from pboxLocalClip.

        lptstr = GlobalLock(hglb);
        memcpy(lptstr, pboxLocalClip->atchLabel,
            cch * sizeof(TCHAR));
        lptstr[cch] = (TCHAR) 0;
        GlobalUnlock(hglb);

        // Place the handle on the clipboard.

        SetClipboardData(CF_TEXT, hglb);
    }
    else if (uFormat == uLabelFormat)
    {
        hglb = GlobalAlloc(GMEM_DDESHARE, sizeof(LABELBOX));
        if (hglb == NULL)
            return;
        pbox = GlobalLock(hglb);
        memcpy(pbox, pboxLocalClip, sizeof(LABELBOX));
        GlobalUnlock(hglb);

        SetClipboardData(uLabelFormat, hglb);
    }
}


Processing the WM_DESTROYCLIPBOARD Message

A window can process the WM_DESTROYCLIPBOARD message in order to free any resources that it set aside to support delayed rendering. For example the Label application, when copying a label to the clipboard, allocates a local memory object. It then frees this object in response to the WM_DESTROYCLIPBOARD message, as follows.

case WM_DESTROYCLIPBOARD:
    if (pboxLocalClip != NULL)
    {
        LocalFree(pboxLocalClip);
        pboxLocalClip = NULL;
    }
    break;


Using the Owner-Display Clipboard Format

If a window places information on the clipboard by using the CF_OWNERDISPLAY clipboard format, it must do the following:

  • Process the WM_PAINTCLIPBOARD message. This message is sent to the clipboard owner when a portion of the clipboard viewer window must be repainted.
  • Process the WM_SIZECLIPBOARD message. This message is sent to the clipboard owner when the clipboard viewer window has been resized or its content has changed.

    Typically, a window responds to this message by setting the scroll positions and ranges for the clipboard viewer window. In response to this message, the Label application also updates a SIZE structure for the clipboard viewer window.

  • Process the WM_HSCROLLCLIPBOARD and WM_VSCROLLCLIPBOARD messages. These messages are sent to the clipboard owner when a scroll bar event occurs in the clipboard viewer window.
  • Process the WM_ASKCBFORMATNAME message. The clipboard viewer window sends this message to an application to retrieve the name of the owner-display format.

The window procedure for the Label application processes these messages, as follows.

LRESULT CALLBACK MainWindowProc(hwnd, msg, wParam, lParam)
HWND hwnd;
UINT msg;
WPARAM wParam;
LPARAM lParam;
{
    static RECT rcViewer;

    RECT rc;
    LPRECT lprc;
    LPPAINTSTRUCT lpps;

    switch (msg)
    {
        //
        // Handle other messages.
        //

        case WM_PAINTCLIPBOARD:
            // Determine the dimensions of the label.

            SetRect(&rc, 0, 0,
                pboxLocalClip->rcText.right + CX_MARGIN,
                pboxLocalClip->rcText.top * 2 + cyText
            );

            // Center the image in the clipboard viewer window.

            if (rc.right < rcViewer.right)
            {
                rc.left = (rcViewer.right - rc.right) / 2;
                rc.right += rc.left;
            }
            if (rc.bottom < rcViewer.bottom)
            {
                rc.top = (rcViewer.bottom - rc.bottom) / 2;
                rc.bottom += rc.top;
            }

            // Paint the image, using the specified PAINTSTRUCT
            // structure, by calling the application-defined
            // PaintLabel function.

            lpps = (LPPAINTSTRUCT) GlobalLock((HGLOBAL) lParam);
            PaintLabel(lpps, pboxLocalClip, &rc);
            GlobalUnlock((HGLOBAL) lParam);
            break;

        case WM_SIZECLIPBOARD:
            // Save the dimensions of the window in a static
            // RECT structure.

            lprc = (LPRECT) GlobalLock((HGLOBAL) lParam);
            memcpy(&rcViewer, lprc, sizeof(RECT));
            GlobalUnlock((HGLOBAL) lParam);

            // Set the scroll ranges to zero (thus eliminating
            // the need to process the WM_HSCROLLCLIPBOARD and
            // WM_VSCROLLCLIPBOARD messages).

            SetScrollRange((HWND) wParam, SB_HORZ, 0, 0, TRUE);
            SetScrollRange((HWND) wParam, SB_VERT, 0, 0, TRUE);

            break;

        case WM_ASKCBFORMATNAME:
            LoadString(hinst, IDS_OWNERDISPLAY,
                (LPSTR) lParam, wParam);
            break;

        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}


Creating a Clipboard Viewer Window

A clipboard viewer window displays the current content of the clipboard, and receives messages when the clipboard content changes. To create a clipboard viewer window, your application must do the following:

  • Add the window to the clipboard viewer chain.
  • Process the WM_CHANGECBCHAIN message.
  • Process the WM_DRAWCLIPBOARD message.
  • Remove the window from the clipboard viewer chain before it is destroyed.


Adding a Window to the Clipboard Viewer Chain

A window adds itself to the clipboard viewer chain by calling the SetClipboardViewer function. The return value is the handle of the next window in the chain. A window must keep track of this value — for example, by saving it in a static variable named hwndNextViewer.

The following example adds a window to the clipboard viewer chain in response to the WM_CREATE message.

case WM_CREATE:

    // Add the window to the clipboard viewer chain.

    hwndNextViewer = SetClipboardViewer(hwnd);
    break;


Processing the WM_CHANGECBCHAIN Message

A clipboard viewer window receives the WM_CHANGECBCHAIN message when another window is removing itself from the clipboard viewer chain. If the window being removed is the next window in the chain, the window receiving the message must unlink the next window from the chain. Otherwise, this message should be passed to the next window in the chain.

The following example shows the processing of the WM_CHANGECBCHAIN message.

case WM_CHANGECBCHAIN:

    // If the next window is closing, repair the chain.

    if ((HWND) wParam == hwndNextViewer)
        hwndNextViewer = (HWND) lParam;

    // Otherwise, pass the message to the next link.

    else if (hwndNextViewer != NULL)
        SendMessage(hwndNextViewer, uMsg, wParam, lParam);

    break;


Removing a Window from the Clipboard Viewer Chain

To remove itself from the clipboard viewer chain, a window calls the ChangeClipboardChain function. The following example removes a window from the clipboard viewer chain in response to the WM_DESTROY message.

case WM_DESTROY:
    ChangeClipboardChain(hwnd, hwndNextViewer);
    PostQuitMessage(0);
    break;


Processing the WM_DRAWCLIPBOARD Message

The WM_DRAWCLIPBOARD message notifies a clipboard viewer window that the content of the clipboard has changed. A window should do the following when processing the WM_DRAWCLIPBOARD message:

  1. Determine which of the available clipboard formats to display.
  2. Retrieve the clipboard data and display it in the window. Or if the clipboard format is CF_OWNERDISPLAY, send a WM_PAINTCLIPBOARD message to the clipboard owner.
  3. Send the message to the next window in the clipboard viewer chain.

For an example of processing the WM_DRAWCLIPBOARD message, see the example listing in Example of a Clipboard Viewer.


Example of a Clipboard Viewer

The following example shows a simple clipboard viewer application.

HINSTANCE hinst;
UINT uFormat = (UINT)(-1);
BOOL fAuto = TRUE;

LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)
HWND hwnd;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
{
    static HWND hwndNextViewer;

    HDC hdc;
    HDC hdcMem;
    PAINTSTRUCT ps;
    LPPAINTSTRUCT lpps;
    RECT rc;
    LPRECT lprc;
    HGLOBAL hglb;
    LPSTR lpstr;
    HBITMAP hbm;
    HENHMETAFILE hemf;
    HWND hwndOwner;

    switch (uMsg)
    {
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);

            // Branch depending on the clipboard format.

            switch (uFormat)
            {
                case CF_OWNERDISPLAY:
                    hwndOwner = GetClipboardOwner();
                    hglb = GlobalAlloc(GMEM_DDESHARE,
                        sizeof(PAINTSTRUCT));
                    lpps = GlobalLock(hglb);
                    memcpy(lpps, &ps, sizeof(PAINTSTRUCT));
                    GlobalUnlock(hglb);

                    SendMessage(hwndOwner, WM_PAINTCLIPBOARD,
                        (WPARAM) hwnd, (LPARAM) hglb);

                    GlobalFree(hglb);
                    break;

                case CF_BITMAP:
                    hdcMem = CreateCompatibleDC(hdc);
                    if (hdcMem != NULL)
                    {
                        if (OpenClipboard(hwnd))
                        {
                            hbm = (HBITMAP)
                                GetClipboardData(uFormat);
                            SelectObject(hdcMem, hbm);
                            GetClientRect(hwnd, &rc);

                            BitBlt(hdc, 0, 0, rc.right, rc.bottom,
                                hdcMem, 0, 0, SRCCOPY);
                            CloseClipboard();
                        }
                        DeleteDC(hdcMem);
                    }
                    break;

                case CF_TEXT:
                    if (OpenClipboard(hwnd))
                    {
                        hglb = GetClipboardData(uFormat);
                        lpstr = GlobalLock(hglb);

                        GetClientRect(hwnd, &rc);
                        DrawText(hdc, lpstr, -1, &rc, DT_LEFT);

                        GlobalUnlock(hglb);
                        CloseClipboard();
                    }
                    break;

                case CF_ENHMETAFILE:
                    if (OpenClipboard(hwnd))
                    {
                        hemf = GetClipboardData(uFormat);
                        GetClientRect(hwnd, &rc);
                        PlayEnhMetaFile(hdc, hemf, &rc);
                        CloseClipboard();
                    }
                    break;

                case 0:
                    GetClientRect(hwnd, &rc);
                    DrawText(hdc, "The clipboard is empty.", -1,
                        &rc, DT_CENTER | DT_SINGLELINE |
                        DT_VCENTER);
                    break;

                default:
                    GetClientRect(hwnd, &rc);
                    DrawText(hdc, "Unable to display format.", -1,
                        &rc, DT_CENTER | DT_SINGLELINE |
                        DT_VCENTER);
            }
            EndPaint(hwnd, &ps);
            break;

        case WM_SIZE:
            if (uFormat == CF_OWNERDISPLAY)
            {
                hwndOwner = GetClipboardOwner();
                hglb = GlobalAlloc(GMEM_DDESHARE, sizeof(RECT));
                lprc = GlobalLock(hglb);
                GetClientRect(hwnd, lprc);
                GlobalUnlock(hglb);

                SendMessage(hwndOwner, WM_SIZECLIPBOARD,
                    (WPARAM) hwnd, (LPARAM) hglb);

                GlobalFree(hglb);
            }
            break;

        case WM_CREATE:

            // Add the window to the clipboard viewer chain.

            hwndNextViewer = SetClipboardViewer(hwnd);
            break;

        case WM_CHANGECBCHAIN:

            // If the next window is closing, repair the chain.

            if ((HWND) wParam == hwndNextViewer)
                hwndNextViewer = (HWND) lParam;

            // Otherwise, pass the message to the next link.

            else if (hwndNextViewer != NULL)
                SendMessage(hwndNextViewer, uMsg, wParam, lParam);

            break;

        case WM_DESTROY:
            ChangeClipboardChain(hwnd, hwndNextViewer);
            PostQuitMessage(0);
            break;

        case WM_DRAWCLIPBOARD:  // clipboard contents changed.

            // Update the window by using Auto clipboard format.

            SetAutoView(hwnd);

            // Pass the message to the next window in clipboard
            // viewer chain.

            SendMessage(hwndNextViewer, uMsg, wParam, lParam);
            break;

        case WM_INITMENUPOPUP:
            if (!HIWORD(lParam))
                InitMenu(hwnd, (HMENU) wParam);
            break;

        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
                case IDM_EXIT:
                    DestroyWindow(hwnd);
                    break;

                case IDM_AUTO:
                    SetAutoView(hwnd);
                    break;

                default:
                    fAuto = FALSE;
                    uFormat = LOWORD(wParam);
                    InvalidateRect(hwnd, NULL, TRUE);
            }
            break;

        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return (LRESULT) NULL;
}

void WINAPI SetAutoView(HWND hwnd)
{
    static UINT auPriorityList[] = {
        CF_OWNERDISPLAY,
        CF_TEXT,
        CF_ENHMETAFILE,
        CF_BITMAP
    };

    uFormat = GetPriorityClipboardFormat(auPriorityList, 4);
    fAuto = TRUE;

    InvalidateRect(hwnd, NULL, TRUE);
    UpdateWindow(hwnd);
}

void WINAPI InitMenu(HWND hwnd, HMENU hmenu)
{
    UINT uFormat;
    char szFormatName[80];
    LPCSTR lpFormatName;
    UINT fuFlags;
    UINT idMenuItem;

    // If a menu is not the display menu, no initialization is necessary.

    if (GetMenuItemID(hmenu, 0) != IDM_AUTO)
        return;

    // Delete all menu items except the first.

    while (GetMenuItemCount(hmenu) > 1)
        DeleteMenu(hmenu, 1, MF_BYPOSITION);

    // Check or uncheck the Auto menu item.

    fuFlags = fAuto ? MF_BYCOMMAND | MF_CHECKED :
        MF_BYCOMMAND | MF_UNCHECKED;
    CheckMenuItem(hmenu, IDM_AUTO, fuFlags);

    // If there are no clipboard formats, return.

    if (CountClipboardFormats() == 0)
        return;

    // Open the clipboard.

    if (!OpenClipboard(hwnd))
        return;

    // Add a separator and then a menu item for each format.

    AppendMenu(hmenu, MF_SEPARATOR, 0, NULL);
    uFormat = EnumClipboardFormats(0);

    while (uFormat)
    {
        // Call an application-defined function to get the name
        // of the clipboard format.

        lpFormatName = GetPredefinedClipboardFormatName(uFormat);

        // For registered formats, get the registered name.

        if (lpFormatName == NULL)
        {
            if (GetClipboardFormatName(uFormat, szFormatName,
                    sizeof(szFormatName)))
                lpFormatName = szFormatName;
            else
                lpFormatName = "(unknown)";
        }

        // Add a menu item for the format. For displayable
        // formats, use the format ID for the menu ID.

        if (IsDisplayableFormat(uFormat))
        {
            fuFlags = MF_STRING;
            idMenuItem = uFormat;
        }
        else
        {
            fuFlags = MF_STRING | MF_GRAYED;
            idMenuItem = 0;
        }
        AppendMenu(hmenu, fuFlags, idMenuItem, lpFormatName);

        uFormat = EnumClipboardFormats(uFormat);
    }
    CloseClipboard();

}

BOOL WINAPI IsDisplayableFormat(UINT uFormat)
{
    switch (uFormat)
    {
        case CF_OWNERDISPLAY:
        case CF_TEXT:
        case CF_ENHMETAFILE:
        case CF_BITMAP:
            return TRUE;
    }
    return FALSE;
}


Clipboard Reference

The following elements are associated with using the clipboard.

  • Clipboard Functions
  • Clipboard Structures
  • Clipboard Messages


Clipboard Functions

Following are the functions used with the clipboard.

ChangeClipboardChain
CloseClipboard
CountClipboardFormats
EmptyClipboard
EnumClipboardFormats
GetClipboardData
GetClipboardFormatName
GetClipboardOwner
GetClipboardSequenceNumber
GetClipboardViewer
GetOpenClipboardWindow
GetPriorityClipboardFormat
IsClipboardFormatAvailable
OpenClipboard
RegisterClipboardFormat
SetClipboardData
SetClipboardViewer


ChangeClipboardChain

The ChangeClipboardChain function removes a specified window from the chain of clipboard viewers.

BOOL ChangeClipboardChain(
  HWND hWndRemove,  // handle to window to remove
  HWND hWndNewNext  // handle to next window
);

Parameters

hWndRemove
Handle to the window to be removed from the chain. The handle must have been passed to the SetClipboardViewer function.
hWndNewNext
Handle to the window that follows the hWndRemove window in the clipboard viewer chain. (This is the handle returned by SetClipboardViewer, unless the sequence was changed in response to a WM_CHANGECBCHAIN message.)

Return Values

The return value indicates the result of passing the WM_CHANGECBCHAIN message to the windows in the clipboard viewer chain. Because a window in the chain typically returns FALSE when it processes WM_CHANGECBCHAIN, the return value from ChangeClipboardChain is typically FALSE. If there is only one window in the chain, the return value is typically TRUE.

Remarks

The window identified by hWndNewNext replaces the hWndRemove window in the chain. The SetClipboardViewer function sends a WM_CHANGECBCHAIN message to the first window in the clipboard viewer chain.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions, ChangeClipboardChain, SetClipboardViewer, WM_CHANGECBCHAIN


CloseClipboard

The CloseClipboard function closes the clipboard.

BOOL CloseClipboard(VOID)

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

When the window has finished examining or changing the clipboard, close the clipboard by calling CloseClipboard. This enables other windows to access the clipboard.

Do not place an object on the clipboard after calling CloseClipboard.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions, GetOpenClipboardWindow, OpenClipboard


CountClipboardFormats

The CountClipboardFormats function retrieves the number of different data formats currently on the clipboard.

int CountClipboardFormats(VOID)

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is the number of different data formats currently on the clipboard.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions, EnumClipboardFormats, RegisterClipboardFormat


EmptyClipboard

The EmptyClipboard function empties the clipboard and frees handles to data in the clipboard. The function then assigns ownership of the clipboard to the window that currently has the clipboard open.

BOOL EmptyClipboard(VOID)

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Before calling EmptyClipboard, an application must open the clipboard by using the OpenClipboard function. If the application specifies a NULL window handle when opening the clipboard, EmptyClipboard succeeds but sets the clipboard owner to NULL.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions, OpenClipboard, SetClipboardData, WM_DESTROYCLIPBOARD


EnumClipboardFormats

The EnumClipboardFormats function lets you enumerate the data formats that are currently available on the clipboard.

Clipboard data formats are stored in an ordered list. To perform an enumeration of clipboard data formats, you make a series of calls to the EnumClipboardFormats function. For each call, the format parameter specifies an available clipboard format, and the function returns the next available clipboard format.

UINT EnumClipboardFormats(
  UINT format   // specifies a known available clipboard format
);

Parameters

format
Specifies a clipboard format that is known to be available.

To start an enumeration of clipboard formats, set format to zero. When format is zero, the function retrieves the first available clipboard format. For subsequent calls during an enumeration, set format to the result of the previous EnumClipboardFormat call.

Return Values

If the function succeeds, the return value is the clipboard format that follows the specified format. In other words, the next available clipboard format.

If the function fails, the return value is zero. To get extended error information, call GetLastError. If the clipboard is not open, the function fails.

If there are no more clipboard formats to enumerate, the return value is zero. In this case, the GetLastError function returns the value NO_ERROR. This lets you distinguish between function failure and the end of enumeration.

Remarks

You must open the clipboard before enumerating its formats. Use the OpenClipboard function to open the clipboard. The EnumClipboardFormats function fails if the clipboard is not open.

The EnumClipboardFormats function enumerates formats in the order that they were placed on the clipboard. If you are copying information to the clipboard, add clipboard objects in order from the most descriptive clipboard format to the least descriptive clipboard format. If you are pasting information from the clipboard, retrieve the first clipboard format that you can handle. That will be the most descriptive clipboard format that you can handle.

The system provides automatic type conversions for certain clipboard formats. In the case of such a format, this function enumerates the specified format, then enumerates the formats to which it can be converted. For more information, see Standard Clipboard Formats and Synthesized Clipboard Formats.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions, CountClipboardFormats, OpenClipboard, RegisterClipboardFormat


GetClipboardData

The GetClipboardData function retrieves data from the clipboard in a specified format. The clipboard must have been opened previously.

HANDLE GetClipboardData(
  UINT uFormat   // clipboard format
);

Parameters

uFormat
Specifies a clipboard format. For a description of the standard clipboard formats, see Standard Clipboard Formats.

Return Values

If the function succeeds, the return value is the handle of a clipboard object in the specified format.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

An application can enumerate the available formats in advance by using the EnumClipboardFormats function.

The clipboard controls the handle that the GetClipboardData function returns, not the application. The application should copy the data immediately. The application cannot rely on being able to make long-term use of the handle. The application must not free the handle nor leave it locked.

The system performs implicit data format conversions between certain clipboard formats when an application calls the GetClipboardData function. For example, if the CF_OEMTEXT format is on the clipboard, a window can retrieve data in the CF_TEXT format. The format on the clipboard is converted to the requested format on demand. For more information, see Synthesized Clipboard Formats.

Windows CE: Windows CE does not support automatic data format conversions between clipboard formats.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions, EnumClipboardFormats, SetClipboardData


GetClipboardFormatName

The GetClipboardFormatName function retrieves from the clipboard the name of the specified registered format. The function copies the name to the specified buffer.

int GetClipboardFormatName(
  UINT format,            // clipboard format to retrieve
  LPTSTR lpszFormatName,  // address of buffer for name
  int cchMaxCount         // length of name string in characters
);

Parameters

format
Specifies the type of format to be retrieved. This parameter must not specify any of the predefined clipboard formats.
lpszFormatName
Pointer to the buffer that is to receive the format name.
cchMaxCount
Specifies the maximum length, in characters, of the string to be copied to the buffer. If the name exceeds this limit, it is truncated.

Return Values

If the function succeeds, the return value is the length, in characters, of the string copied to the buffer.

If the function fails, the return value is zero, indicating that the requested format does not exist or is predefined. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Clipboard Overview, Clipboard Functions, EnumClipboardFormats, RegisterClipboardFormat


GetClipboardOwner

The GetClipboardOwner function retrieves the window handle of the current owner of the clipboard.

HWND GetClipboardOwner(VOID)

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is the handle of the window that owns the clipboard.

If the clipboard is not owned, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The clipboard can still contain data even if the clipboard is not currently owned.

In general, the clipboard owner is the window that last placed data in clipboard. The EmptyClipboard function assigns clipboard ownership.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions, EmptyClipboard, GetClipboardViewer


GetClipboardSequenceNumber

[This is preliminary documentation and subject to change.]

The GetClipboardSequenceNumber function returns the clipboard sequence number for the current window station.

DWORD GetClipboardSequenceNumber(VOID)

Parameters

This function has no parameters.

Return Value

The return value is the clipboard sequence number. If you do not have WINSTA_ACCESSCLIPBOARD access to the window station, the function returns zero.

Remarks

The system keeps a 32-bit serial number for the clipboard for each window station. This number is incremented whenever the contents of the clipboard change or the clipboard is emptied. You can track this value to determine whether the clipboard contents have changed and optimize creating DataObjects. If clipboard rendering is delayed, the sequence number is not incremented until the changes are rendered.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions


GetClipboardViewer

The GetClipboardViewer function retrieves the handle of the first window in the clipboard viewer chain.

HWND GetClipboardViewer(VOID)

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is the handle of the first window in the clipboard viewer chain.

If there is no clipboard viewer, the return value is NULL. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions, GetClipboardOwner, SetClipboardViewer


GetOpenClipboardWindow

The GetOpenClipboardWindow function retrieves the handle of the window that currently has the clipboard open.

HWND GetOpenClipboardWindow(VOID)

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is the handle of the window that has the clipboard open. If no window has the clipboard open, the return value is NULL. To get extended error information, call GetLastError.

Remarks

If an application or dynamic-link library (DLL) specifies a NULL window handle when calling the OpenClipboard function, the clipboard is opened but is not associated with a window. In such a case, GetOpenClipboardWindow returns NULL.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions, GetClipboardOwner, GetClipboardViewer, OpenClipboard


GetPriorityClipboardFormat

The GetPriorityClipboardFormat function returns the first available clipboard format in the specified list.

int GetPriorityClipboardFormat(
  UINT *paFormatPriorityList,  // address of priority list
  int cFormats                 // number of entries in list
);

Parameters

paFormatPriorityList
Pointer to an array of unsigned integers identifying clipboard formats, in priority order. For a description of the standard clipboard formats, see Standard Clipboard Formats.
cFormats
Specifies the number of entries in the paFormatPriorityList array. This value must not be greater than the number of entries in the list.

Return Values

If the function succeeds, the return value is the first clipboard format in the list for which data is available. If the clipboard is empty, the return value is NULL. If the clipboard contains data, but not in any of the specified formats, the return value is –1. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions, CountClipboardFormats, EnumClipboardFormats, GetClipboardFormatName, IsClipboardFormatAvailable, RegisterClipboardFormat


IsClipboardFormatAvailable

The IsClipboardFormatAvailable function determines whether the clipboard contains data in the specified format.

BOOL IsClipboardFormatAvailable(
  UINT format   // clipboard format
);

Parameters

format
Specifies a standard or registered clipboard format. For a description of the standard clipboard formats, see Standard Clipboard Formats.

Return Values

If the clipboard format is available, the return value is nonzero.

If the clipboard format is not available, the return value is zero. To get extended error information, call GetLastError.

Remarks

Typically, an application that recognizes only one clipboard format would call this function when processing the WM_INITMENU or WM_INITMENUPOPUP message. The application would then enable or disable the Paste menu item, depending on the return value. Applications that recognize more than one clipboard format should use the GetPriorityClipboardFormat function for this purpose.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions, CountClipboardFormats, EnumClipboardFormats, GetPriorityClipboardFormat, RegisterClipboardFormat, WM_INITMENU, WM_INITMENUPOPUP


OpenClipboard

The OpenClipboard function opens the clipboard for examination and prevents other applications from modifying the clipboard content.

BOOL OpenClipboard(
  HWND hWndNewOwner   // handle to window opening clipboard
);

Parameters

hWndNewOwner
Handle to the window to be associated with the open clipboard. If this parameter is NULL, the open clipboard is associated with the current task.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

OpenClipboard fails if another window has the clipboard open.

An application should call the CloseClipboard function after every successful call to OpenClipboard.

The window identified by the hWndNewOwner parameter does not become the clipboard owner unless the EmptyClipboard function is called.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions, CloseClipboard, EmptyClipboard


RegisterClipboardFormat

The RegisterClipboardFormat function registers a new clipboard format. This format can then be used as a valid clipboard format.

UINT RegisterClipboardFormat(
  LPCTSTR lpszFormat   // address of name string
);

Parameters

lpszFormat
Pointer to a null-terminated string that names the new format.

Return Values

If the function succeeds, the return value identifies the registered clipboard format.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If a registered format with the specified name already exists, a new format is not registered and the return value identifies the existing format. This enables more than one application to copy and paste data using the same registered clipboard format. Note that the format name comparison is case-insensitive.

Registered clipboard formats are identified by values in the range 0xC000 through 0xFFFF.

Windows CE: Windows CE supports only the Unicode version of RegisterClipboardFormat.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Clipboard Overview, Clipboard Functions, CountClipboardFormats, EnumClipboardFormats, GetClipboardFormatName


SetClipboardData

The SetClipboardData function places data on the clipboard in a specified clipboard format. The window must be the current clipboard owner, and the application must have called the OpenClipboard function. (When responding to the WM_RENDERFORMAT and WM_RENDERALLFORMATS messages, the clipboard owner must not call OpenClipboard before calling SetClipboardData.)

HANDLE SetClipboardData(
  UINT uFormat, // clipboard format
  HANDLE hMem   // data handle
);

Parameters

uFormat
Specifies a clipboard format. This parameter can be a registered format or any of the standard clipboard formats. For more information, see Registered Clipboard Formats and Standard Clipboard Formats.
hMem
Handle to the data in the specified format. This parameter can be NULL, indicating that the window provides data in the specified clipboard format (renders the format) upon request. If a window delays rendering, it must process the WM_RENDERFORMAT and WM_RENDERALLFORMATS messages.

After SetClipboardData is called, the system owns the object identified by the hMem parameter. The application can read the data, but must not free the handle or leave it locked. If the hMem parameter identifies a memory object, the object must have been allocated using the GlobalAlloc function with the GMEM_MOVEABLE and GMEM_DDESHARE flags.

Return Values

If the function succeeds, the return value is the handle of the data.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The uFormat parameter can identify a registered clipboard format, or it can be one of the standard clipboard formats. For more information, see Registered Clipboard Formats and Standard Clipboard Formats.

The system performs implicit data format conversions between certain clipboard formats when an application calls the GetClipboardData function. For example, if the CF_OEMTEXT format is on the clipboard, a window can retrieve data in the CF_TEXT format. The format on the clipboard is converted to the requested format on demand. For more information, see Synthesized Clipboard Formats.

Windows CE: The data to be set into the clipboard should be allocated using the LocalAlloc function.

Windows CE does not support the following uFormat values:

CF_GDIOBJFIRST through CF_GDIOBJLAST

CF_DSPBITMAP

CF_DSPENHMETAFILE

CF_DSPMETAFILEPICT

CF_DSPTEXT

CF_HDROP

CF_LOCALE

CF_OWNERDISPLAY

CF_PRIVATEFIRST through CF_PRIVATELAST

Windows CE does not perform any implicit conversions between formats.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions, BITMAPINFO, GetClipboardData, GlobalAlloc, GlobalFree, METAFILEPICT, OpenClipboard, RealizePalette, RegisterClipboardFormat, SelectPalette, WM_ASKCBFORMATNAME, WM_DESTROYCLIPBOARD, WM_HSCROLLCLIPBOARD, WM_PAINTCLIPBOARD, WM_RENDERFORMAT, WM_RENDERALLFORMATS, WM_SIZECLIPBOARD, WM_VSCROLLCLIPBOARD


SetClipboardViewer

The SetClipboardViewer function adds the specified window to the chain of clipboard viewers. Clipboard viewer windows receive a WM_DRAWCLIPBOARD message whenever the content of the clipboard changes.

HWND SetClipboardViewer(
  HWND hWndNewViewer   // handle to clipboard viewer window
);

Parameters

hWndNewViewer
Handle to the window to be added to the clipboard chain.

Return Values

If the function succeeds, the return value identifies the next window in the clipboard viewer chain. If an error occurs or there are no other windows in the clipboard viewer chain, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The windows that are part of the clipboard viewer chain, called clipboard viewer windows, must process the clipboard messages WM_CHANGECBCHAIN and WM_DRAWCLIPBOARD. Each clipboard viewer window calls the SendMessage function to pass these messages to the next window in the clipboard viewer chain.

A clipboard viewer window must eventually remove itself from the clipboard viewer chain by calling the ChangeClipboardChain function — for example, in response to the WM_DESTROY message.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Clipboard Overview, Clipboard Functions, ChangeClipboardChain, GetClipboardViewer, SendMessage


Clipboard Structures

The following structure is used with the clipboard.

METAFILEPICT


METAFILEPICT

The METAFILEPICT structure defines the metafile picture format used for exchanging metafile data through the clipboard.

typedef struct tagMETAFILEPICT { // mfp
    LONG      mm;
    LONG      xExt;
    LONG      yExt;
    HMETAFILE hMF;
} METAFILEPICT;

Members

mm
Specifies the mapping mode in which the picture is drawn.
xExt
Specifies the size of the metafile picture for all modes except the MM_ISOTROPIC and MM_ANISOTROPIC modes. (For more information about these modes, see the yExt member.) The x-extent specifies the width of the rectangle within which the picture is drawn. The coordinates are in units that correspond to the mapping mode.
yExt
Specifies the size of the metafile picture for all modes except the MM_ISOTROPIC and MM_ANISOTROPIC modes. The y-extent specifies the height of the rectangle within which the picture is drawn. The coordinates are in units that correspond to the mapping mode.

For MM_ISOTROPIC and MM_ANISOTROPIC modes, which can be scaled, the xExt and yExt members contain an optional suggested size in MM_HIMETRIC units. For MM_ANISOTROPIC pictures, xExt and yExt can be zero when no suggested size is supplied. For MM_ISOTROPIC pictures, an aspect ratio must be supplied even when no suggested size is given. (If a suggested size is given, the aspect ratio is implied by the size.) To give an aspect ratio without implying a suggested size, set xExt and yExt to negative values whose ratio is the appropriate aspect ratio. The magnitude of the negative xExt and yExt values is ignored; only the ratio is used.

hMF
Handle to a memory metafile.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in wingdi.h.

See Also

Clipboard Overview, Clipboard Structures, SetClipboardData


Clipboard Messages

Following are the messages used with the clipboard.

WM_ASKCBFORMATNAME
WM_CHANGECBCHAIN
WM_CLEAR
WM_COPY
WM_CUT
WM_DESTROYCLIPBOARD
WM_DRAWCLIPBOARD
WM_HSCROLLCLIPBOARD
WM_PAINTCLIPBOARD
WM_PASTE
WM_RENDERALLFORMATS
WM_RENDERFORMAT
WM_SIZECLIPBOARD
WM_VSCROLLCLIPBOARD


WM_ASKCBFORMATNAME

The WM_ASKCBFORMATNAME message is sent to the clipboard owner by a clipboard viewer window to request the name of a CF_OWNERDISPLAY clipboard format.

WM_ASKCBFORMATNAME
cchName = (DWORD) wParam            // size of buffer
lpszFormatName = (LPTSTR) lParam    // buffer to receive format name

Parameters

cchName
Value of wParam. Specifies the size, in characters, of the buffer pointed to by the lpszFormatName parameter.
lpszFormatName
Value of lParam. Pointer to the buffer that is to receive the clipboard format name.

Return Values

If an application processes this message, it should return zero.

Remarks

In response to this message, the clipboard owner should copy the name of the owner-display format to the specified buffer, not exceeding the buffer size specified by the cchName parameter.

A clipboard viewer window sends this message to the clipboard owner to determine the name of the CF_OWNERDISPLAY format — for example, to initialize a menu listing available formats.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Clipboard Overview, Clipboard Messages


WM_CHANGECBCHAIN

The WM_CHANGECBCHAIN message is sent to the first window in the clipboard viewer chain when a window is being removed from the chain.

WM_CHANGECBCHAIN
hwndRemove = (HWND) wParam;     // handle of window being removed
hwndNext = (HWND) lParam;       // handle of next window in chain

Parameters

hwndRemove
Value of wParam. Handle to the window being removed from the clipboard viewer chain.
hwndNext
Value of lParam. Handle to the next window in the chain following the window being removed. This parameter is NULL if the window being removed is the last window in the chain.

Return Values

If an application processes this message, it should return zero.

Remarks

Each clipboard viewer window saves the handle of the next window in the clipboard viewer chain. Initially, this handle is the return value of the SetClipboardViewer function.

When a clipboard viewer window receives the WM_CHANGECBCHAIN message, it should call the SendMessage function to pass the message to the next window in the chain, unless the next window is the window being removed. In this case, the clipboard viewer should save the handle specified by hwndNext as the next window in the chain.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Clipboard Overview, Clipboard Messages, SendMessage, SetClipboardViewer


WM_CLEAR

An application sends a WM_CLEAR message to an edit control or combo box to delete (clear) the current selection, if any, from the edit control.

WM_CLEAR
wParam = 0; // not used; must be zero
lParam = 0; // not used; must be zero

Parameters

This message has no parameters.

Return Values

This message does not return a value.

Remarks

The deletion performed by the WM_CLEAR message can be undone by sending the edit control an EM_UNDO message.

To delete the current selection and place the deleted content on the clipboard, use the WM_CUT message.

When sent to a combo box, the WM_CLEAR message is handled by its edit control. This message has no effect when sent to a combo box with the CBS_DROPDOWNLIST style.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.

See Also

Clipboard Overview, Clipboard Messages, EM_UNDO, WM_COPY, WM_CUT, WM_PASTE


WM_COPY

An application sends the WM_COPY message to an edit control or combo box to copy the current selection to the clipboard in CF_TEXT format.

WM_COPY
wParam = 0; // not used; must be zero
lParam = 0; // not used; must be zero

Parameters

This message has no parameters.

Return Values

This message does not return a value.

Remarks

When sent to a combo box, the WM_COPY message is handled by its edit control. This message has no effect when sent to a combo box with the CBS_DROPDOWNLIST style.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.

See Also

Clipboard Overview, Clipboard Messages, WM_CLEAR, WM_CUT, WM_PASTE


WM_CUT

An application sends a WM_CUT message to an edit control or combo box to delete (cut) the current selection, if any, in the edit control and copy the deleted text to the clipboard in CF_TEXT format.

WM_CUT
wParam = 0; // not used; must be zero
lParam = 0; // not used; must be zero

Parameters

This message has no parameters.

Return Values

This message does not return a value.

Remarks

The deletion performed by the WM_CUT message can be undone by sending the edit control an EM_UNDO message.

To delete the current selection without placing the deleted text on the clipboard, use the WM_CLEAR message.

When sent to a combo box, the WM_CUT message is handled by its edit control. This message has no effect when sent to a combo box with the CBS_DROPDOWNLIST style.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.

See Also

Clipboard Overview, Clipboard Messages, EM_UNDO, WM_CLEAR, WM_COPY, WM_PASTE


WM_DESTROYCLIPBOARD

The WM_DESTROYCLIPBOARD message is sent to the clipboard owner when a call to the EmptyClipboard function empties the clipboard.

WM_DESTROYCLIPBOARD

Parameters

This message has no parameters.

Return Values

If an application processes this message, it should return zero.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.

See Also

Clipboard Overview, Clipboard Messages, EmptyClipboard


WM_DRAWCLIPBOARD

The WM_DRAWCLIPBOARD message is sent to the first window in the clipboard viewer chain when the content of the clipboard changes. This enables a clipboard viewer window to display the new content of the clipboard.

WM_DRAWCLIPBOARD

Parameters

This message has no parameters.

Remarks

Only clipboard viewer windows receive this message. These are windows that have been added to the clipboard viewer chain by using the SetClipboardViewer function.

Each window that receives the WM_DRAWCLIPBOARD message must call the SendMessage function to pass the message on to the next window in the clipboard viewer chain. The handle of the next window in the chain is returned by SetClipboardViewer, and may change in response to a WM_CHANGECBCHAIN message.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Clipboard Overview, Clipboard Messages, SendMessage, SetClipboardViewer, WM_CHANGECBCHAIN


WM_HSCROLLCLIPBOARD

The WM_HSCROLLCLIPBOARD message is sent to the clipboard owner by a clipboard viewer window. This occurs when the clipboard contains data in the CF_OWNERDISPLAY format and an event occurs in the clipboard viewer's horizontal scroll bar. The owner should scroll the clipboard image and update the scroll bar values.

WM_HSCROLLCLIPBOARD
hwndViewer = (HWND) wParam;         // handle of clipboard viewer window
nScrollCode = (int) LOWORD(lParam); // scroll bar code
nPos = (int) HIWORD(lParam);        // scroll box position

Parameters

hwndViewer
Value of wParam. Handle to the clipboard viewer window.
nScrollCode
Value of the low-order word of lParam. Specifies a scroll bar event. This parameter can be one of the following values:
Value | Meaning
SB_ENDSCROLL | End scroll.
SB_LEFT | Scroll to upper left.
SB_RIGHT | Scroll to lower right.
SB_LINELEFT | Scrolls left by one unit.
SB_LINERIGHT | Scrolls right by one unit.
SB_PAGELEFT | Scrolls left by the width of the window.
SB_PAGERIGHT | Scrolls right by the width of the window.
SB_THUMBPOSITION | Scroll to absolute position. The current position is specified by the nPos parameter.

nPos
Value of the high-order word of lParam. Specifies the current position of the scroll box if the nScrollCode parameter is SB_THUMBPOSITION; otherwise, the nPos parameter is not used.

Return Values

If an application processes this message, it should return zero.

Remarks

The clipboard owner can use the ScrollWindow function to scroll the image in the clipboard viewer window and invalidate the appropriate region.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Clipboard Overview, Clipboard Messages, ScrollWindow


WM_PAINTCLIPBOARD

The WM_PAINTCLIPBOARD message is sent to the clipboard owner by a clipboard viewer window when the clipboard contains data in the CF_OWNERDISPLAY format and the clipboard viewer's client area needs repainting.

WM_PAINTCLIPBOARD
hwndViewer = (HWND) wParam;     // handle of clipboard viewer window
hglbPs = (HGLOBAL) lParam;      // handle of PAINTSTRUCT object

Parameters

hwndViewer
Value of wParam. Handle to the clipboard viewer window.
hglbPs
Value of lParam. Handle to a global DDESHARE object that contains a PAINTSTRUCT structure. The structure defines the part of the client area to paint.

Return Values

If an application processes this message, it should return zero.

Remarks

To determine whether the entire client area or just a portion of it needs repainting, the clipboard owner must compare the dimensions of the drawing area given in the rcpaint member of PAINTSTRUCT to the dimensions given in the most recent WM_SIZECLIPBOARD message.

The clipboard owner must use the GlobalLock function to lock the memory that contains the PAINTSTRUCT structure. Before returning, the clipboard owner must unlock that memory by using the GlobalUnlock function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Clipboard Overview, Clipboard Messages, GlobalLock, GlobalUnlock, PAINTSTRUCT, WM_SIZECLIPBOARD


WM_PASTE

An application sends a WM_PASTE message to an edit control or combo box to copy the current content of the clipboard to the edit control at the current caret position. Data is inserted only if the clipboard contains data in CF_TEXT format.

WM_PASTE
wParam = 0; // not used; must be zero
lParam = 0; // not used; must be zero

Parameters

This message has no parameters.

Return Values

This message does not return a value.

Remarks

When sent to a combo box, the WM_PASTE message is handled by its edit control. This message has no effect when sent to a combo box with the CBS_DROPDOWNLIST style.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.

See Also

Clipboard Overview, Clipboard Messages, WM_CLEAR, WM_COPY, WM_CUT


WM_RENDERALLFORMATS

The WM_RENDERALLFORMATS message is sent to the clipboard owner before it is destroyed, if the clipboard owner has delayed rendering one or more clipboard formats. For the content of the clipboard to remain available to other applications, the clipboard owner must render data in all the formats it is capable of generating, and place the data on the clipboard by calling the SetClipboardData function.

WM_RENDERALLFORMATS

Parameters

This message has no parameters.

Return Values

If an application processes this message, it should return zero.

Remarks

When responding to a WM_RENDERALLFORMATS message, the clipboard owner must call the OpenClipboard and EmptyClipboard functions before calling SetClipboardData.

When the application returns, the system removes any unrendered formats from the list of available clipboard formats. For information about delayed rendering, see SetClipboardData.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.

See Also

Clipboard Overview, Clipboard Messages, EmptyClipboard, OpenClipboard, SetClipboardData, WM_RENDERFORMAT


WM_RENDERFORMAT

The WM_RENDERFORMAT message is sent to the clipboard owner if it has delayed rendering a specific clipboard format and if an application has requested data in that format. The clipboard owner must render data in the specified format and place it on the clipboard by calling the SetClipboardData function.

WM_RENDERFORMAT
uFormat = (UINT) wParam;    // clipboard format

Parameters

uFormat
Specifies the clipboard format to be rendered.

Return Values

If an application processes this message, it should return zero.

Remarks

When responding to a WM_RENDERFORMAT message, the clipboard owner must not open the clipboard before calling SetClipboardData.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winuser.h.

See Also

Clipboard Overview, Clipboard Messages, SetClipboardData, WM_RENDERALLFORMATS


WM_SIZECLIPBOARD

The WM_SIZECLIPBOARD message is sent to the clipboard owner by a clipboard viewer window when the clipboard contains data in the CF_OWNERDISPLAY format and the clipboard viewer's client area has changed size.

WM_SIZECLIPBOARD
hwndViewer = (HWND) wParam;  // handle of clipboard viewer window
hglbRc = (HGLOBAL) lParam;   // handle of RECT object

Parameters

hwndViewer
Value of wParam. Handle to the clipboard viewer window.
hglbRc
Value of lParam. Handle to a global memory object that contains a RECT structure. The structure specifies the new dimensions of the clipboard viewer's client area.

Remarks

When the clipboard viewer window is about to be destroyed or resized, a WM_SIZECLIPBOARD message is sent with a null rectangle (0, 0, 0, 0) as the new size. This permits the clipboard owner to free its display resources.

The clipboard owner must use the GlobalLock function to lock the memory object that contains RECT. Before returning, the clipboard owner must unlock the object by using the GlobalUnlock function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Clipboard Overview, Clipboard Messages, GlobalLock, GlobalUnlock, RECT


WM_VSCROLLCLIPBOARD

The WM_VSCROLLCLIPBOARD message is sent to the clipboard owner by a clipboard viewer window when the clipboard contains data in the CF_OWNERDISPLAY format and an event occurs in the clipboard viewer's vertical scroll bar. The owner should scroll the clipboard image and update the scroll bar values.

WM_VSCROLLCLIPBOARD
hwndViewer = (HWND) wParam;         // handle of clipboard viewer window
nScrollCode = (int) LOWORD(lParam); // scroll bar code
nPos = (int) HIWORD(lParam);        // scroll box position

Parameters

hwndViewer
Value of wParam. Handle to the clipboard viewer window.
nScrollCode
Value of the low-order word of lParam. Specifies a scroll bar event. This parameter can be one of the following values:
Value | Meaning
SB_BOTTOM | Scroll to lower right.
SB_ENDSCROLL | End scroll.
SB_LINEDOWN | Scroll one line down.
SB_LINEUP | Scroll one line up.
SB_PAGEDOWN | Scroll one page down.
SB_PAGEUP | Scroll one page up.
SB_THUMBPOSITION | Scroll to absolute position. The current position is specified by the nPos parameter.
SB_TOP | Scroll to upper left.

nPos
Value of the high-order word of lParam. Specifies the current position of the scroll box if the nScrollCode parameter is SB_THUMBPOSITION; otherwise, the nPos parameter is not used.

Return Values

If an application processes this message, it should return zero.

Remarks

The clipboard owner can use the ScrollWindow function to scroll the image in the clipboard viewer window and invalidate the appropriate region.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Clipboard Overview, Clipboard Messages, ScrollWindow


HTML Clipboard Format

The requirements for transferring HTML text by means of the clipboard differ depending on scenario. This article is concerned with cutting and pasting fragments of an HTML document. There may be requirements for transferring entire HTML documents through the clipboard; however, this article is driven by a requirement to transfer fragments of selected HTML text. As such, a method that required the entire HTML document to be copied to the clipboard is seen as too heavyweight.

The CF_HTML clipboard format allows a fragment of raw HTML text and its context to be stored on the clipboard as ASCII. This allows the context of the HTML fragment, which consists of all preceding surrounding tags, to be examined by an application so that the surrounding tags of the HTML fragment can be noted with their attributes. Although it is up to applications to decide how to interpret such fragments, some basic guidelines are included here based on IE4/MSHTML implementations.

The official name of the clipboard (the string used by RegisterClipboardFormat) is HTML Format.

Description

Scenarios

Description

CF_HTML is entirely text format (to be, among other things, in the HTML spirit, and uses UTF-8) and includes a description, an optional context, and, within the context, the fragment.

The following is an example of a clipboard:

Version:0.9
    StartHTML:71
    EndHTML:170
    StartFragment:140
    EndFragment:160
    StartSelection:140
    EndSelection:160
    <!DOCTYPE>
    <HTML>
    <HEAD>
    <TITLE> The HTML Clipboard</TITLE>
    <BASE HREF="http://sample/specs">
    </HEAD>
    <BODY>
    <UL>
    <!--StartFragment -->
    <LI> The Fragment </LI>
    <!--EndFragment -->
    </UL>
    </BODY>
    </HTML>

The description includes the clipboard version number and offsets, indicating where the context and the fragment start and end. The description is a list of ASCII text keywords (min/maj is not meaningful) followed by a string and separated by a colon (:).

Version: vv version number of the clipboard. Starting version is 0.9.
StartHTML: bytecount from the beginning of the clipboard to the start of the context, or -1 if no context.
EndHTML: bytecount from the beginning of the clipboard to the end of the context, or -1 if no context.
StartFragment: bytecount from the beginning of the clipboard to the start of the fragment.
EndFragment: bytecount from the beginning of the clipboard to the end of the fragment.
StartSelection: bytecount from the beginning of the clipboard to the start of the selection.
EndSelection: bytecount from the beginning of the clipboard to the end of the selection.

The StartSelection and EndSelection keywords are optional and must both be omitted if you do not want the application to generate this information.

Other information of this kind could be added here later, since the HTML starts at the StartHTMLoffset. For example, multiple pairs of StartFragment / EndFragment could be added later to support noncontiguous selection of fragments.

For the convenience of the programs generating the bytecounts, bytecounts could be left padded by zeros. For example, programs generating the bytecounts could arbitrarily affect ten (10) zeros to each keyword (StartHTML: 0000000000) and then, when the exact StartHTML bytecount is known (say, 71), the program can replace the appropriate number of zeros by the bytecount (StartHTML: 0000000071).

The only character set supported by the clipboard is Unicode in its UTF-8 encoding. Because the first characters of UTF-8 and ASCII match, the description is always ASCII, but the bytes of the context (starting at StartHTML) could be using any other characters coded in UTF-8.

End of lines in the clipboard format header could be CR or CR/LF or LF.

The fragment contains pure, valid HTML representing the area the user has selected (to Copy, for example). This contains the selected text plus the opening tags and attributes of any element that has an end tag within the selected text, and end tags at the end of the fragment for any start tag included. This is all information required for basic pasting of an HTML fragment.

The fragment should be preceded and followed by the HTML comments <!--StartFragment--> and <!--EndFragment--> (no space allowed between the !-- and the text) to conveniently indicate where the fragment starts and ends. Thus the start and end of the fragment are indicated by the presence of these comments and by StartFragment and EndFragment byte counts in the description. Tools are expected to produce this information. This redundancy has been introduced to be able to rapidly find the start of the fragment (from the byte count) and mark the position of the fragment directly in the HTML tree.

The selection indicates inside the fragment the exact HTML area the user has selected (to Copy, for example). This adds more information to the fragment by indicating the exact selected text, without the opening tags and end tags that have been added to ensure the fragment is well-formed HTML.

The selection is optional, as sufficient information is included in the fragment for basic pasting. If the selection is not stored, both StartSelection and EndSelection are not stored in the header.

The context is a valid, complete HTML document. This article contains the fragment and all preceding surrounding tags (start and end tags; these preceding surrounding tags represent all the parent nodes of the fragment, until the HTML node). The article also contains the complete HEAD, and allows the BASE and TITLE elements, for example, to be included so this additional information can be obtained. An application copying a fragment of HTML to the clipboard can choose to create a BASE element to include in the context if such an element is not already present so that partial URLs in the fragment can be resolved.

The context is optional, as sufficient information is included in the fragment for basic pasting of an HTML fragment to take place. If the context is not stored, the fragment only is stored and the StartHTML=EndHTML=-1.

Scenarios

The following scenarios describe how the IE4/MSHTML HTML editor handles HTML cut and paste; other applications may or may not follow these scenarios. The clipboard format described here is intended to allow flexibility for how an application chooses to function. (These scenarios show only good HTML, that is, no overlapping tags.)

  1. Simple Fragment of HTML.
    • HTML text:
      <BODY>This is normal <B>This is bold </B><I><B>This is bold italic </B>This is italic </I></BODY>
    • Appears as:
      This is normal This is bold This is bold italic This is italic
    • The text between the ** is selected and copied to the clipboard:
      This is normal This is **bold This is bold italic This** is italic
    • This is what will be on the clipboard (note this is IE4/MSHTML's interpretation):
      Version:0.9
      StartHTML:71
      EndHTML:160
      StartFragment:130
      EndFragment:150
      StartSelection:130
      EndSelection:150
      <!DOCTYPE ...>
      <HTML>
      <BODY>
      <!--StartFragment-->
      <B>bold </B><I><B>This is bold italic </B>This</I>
      <!--EndFragment-->
      </BODY>
      </HTML>
    • In this scenario only the BODY tag and the HTML tag appear in the context as it precedes the selected fragment. Note that start tags and end tags are included in the context. The selection, as delimited by StartSelection and EndSelection, is shown in bold.
  2. Fragment of a table in HTML.
    • HTML text:
      <BODY><TABLE BORDER><TR><TH ROWSPAN=2>Head1</TH><TD>Item 1</TD> <TD>Item 2</TD> <TD>Item 3</TD> <TD>Item 4</TD></TR><TR><TD>Item 5</TD> <TD>Item 6</TD> <TD>Item 7</TD> <TD>Item 8</TD></TR><TR><TH>Head2</TH><TD>Item 9</TD> <TD>Item 10</TD> <TD>Item 11</TD> <TD>Item 12</TD></TR></TABLE></BODY>
    • Appears as:
      Head1 | Item 1 | Item 2 | Item 3 | Item 4
      Item 5 | Item 6 | Item 7 | Item 8
      Head2 | Item 9 | Item 10 | Item 11 | Item 12

    • The Item 6, Item7, Item 10, and Item 11 elements of the table are selected as a block and copied to the clipboard.
    • This is what will be on the clipboard (note this is IE4/MSHTML's interpretation):
      <!DOCTYPE ...>
      <HTML><BODY><TABLE BORDER>
      <!--StartFragment-->
      <TR><TD>Item 6</TD> <TD>Item 7</TD></TR><TR><TD>Item 10</TD> <TD>Item 11</TD></TR>
      <!--EndFragment-->
      </TABLE>
      </BODY></HTML>
      The selection, as delimited by StartSelection and EndSelection, is shown in bold.
  3. Pasting a fragment of an ordered list into plain text.
    • HTML text:
      <BODY><OL TYPE = a><LI>Item 1<LI>Item 2<LI>Item 3<LI>Item 4<LI>Item 5<LI>Item 6</OL></BODY>
    • Appears as:
      1. Item 1
      2. Item 2
      3. Item 3
      4. Item 4
      5. Item 5
      6. Item 6
    • The user selects and copies items 3 through 5 to the clipboard.
      The following HTML is in the clipboard:
      <DOCTYPE...><HTML><BODY><OL TYPE = a>
      <!-- StartFragment-->
      <LI>Item 3<LI>Item 4<LI>Item 5
      <!-- EndFragment-->
      </OL></BODY></HTML>
      The selection, as delimited by StartSelection and EndSelection, is show in bold.
    • If this fragment is now pasted into an empty document, the following HTML will be created:
      <BODY><OL TYPE = a><LI>Item 3<LI>Item 4<LI>Item 5</OL></BODY>
    • Appearing as:
      1. Item 3
      2. Item 4
      3. Item 5
  4. Pasting a partially selected region.
    • HTML text:
      <P> IE4/MSHTML is a WYSIWYG Editor that supports :<UL><LI>Cut<LI>Copy<LI>Paste
      </UL> <P>This is a Great Tool !
    • Appears as:
      IE4/MSHTML is a WYSIWYG Editor that supports :
      • Cut
      • Copy
      • Paste
    • The user selects from "WYSIWYG" until "Cop".
      The following HTML is in the clipboard:
      <DOCTYPE...><HTML><BODY>
      <!-- StartFragment-->
      <P>
      WYSIWYG Editor, which supports
      <UL><LI>Cut<LI>Cop
      </UL>
      <!-- EndFragment-->
      </BODY></HTML>
      The selection, as delimited by StartSelection and EndSelection, is shown in bold.
    • The user selects from "opy" until "Great".
      The following HTML is in the clipboard:
      <DOCTYPE...><HTML><BODY>
      <!-- StartFragment-->
      <UL><LI>
      opy<LI>Paste</UL><P> This is a Great
      </P>
      <!-- EndFragment-->
      </BODY></HTML>
      The selection, as delimited by StartSelection and EndSelection, is shown in bold.


Dynamic Data Exchange

This overview provides guidelines for implementing dynamic data exchange for applications that cannot use the Dynamic Data Exchange Management Library (DDEML). For more information about the DDEML, see Dynamic Data Exchange Management Library.


About Dynamic Data Exchange

The Microsoft® Win32® application programming interface (API) provides several methods for transferring data between applications. One method is to use the Win32 dynamic data exchange (DDE) protocol. The DDE protocol is a set of messages and guidelines. It sends messages between applications that share data and uses shared memory to exchange data between applications. Applications can use the DDE protocol for one-time data transfers and for continuous exchanges in which applications send updates to one another as new data becomes available.

The Win32 API also includes the Dynamic Data Exchange Management Library (DDEML). The DDEML is a dynamic-link library (DLL) that Win32-based applications can use to share data. The DDEML provides functions and messages that simplify the task of adding DDE capability to a Win32-based application. Instead of sending, posting, and processing DDE messages directly, an application uses the DDEML functions to manage DDE conversations. (A DDE conversation is the interaction between client and server applications.)

The DDEML also provides a facility for managing the strings and data that DDE applications share. Instead of using atoms and pointers to shared memory objects, DDE applications create and exchange string handles, which identify strings, and data handles, which identify memory objects. The DDEML also makes it possible for a server application to register the service names it supports. The names are broadcast to other applications in the system, which can use the names to connect to the server. Moreover, the DDEML ensures compatibility among DDE applications by forcing them to implement the DDE protocol in a consistent manner.

Existing applications that use the message-based DDE protocol are fully compatible with those that use the DDEML. That is, an application that uses message-based DDE can establish conversations and perform transactions with applications that use the DDEML. Because of the many advantages of the DDEML, new applications should use it rather than the DDE messages. To use the API elements of the DDEML, you must include the DDEML header file in your source files, link with the DDEML library, and ensure that the DDEML dynamic-link library is in the system's search path.


Dynamic Data Exchange Protocol

Because the Win32 API has a message-based architecture, passing messages is the most appropriate method for automatically transferring information between applications. However, Win32 messages contain only two parameters (wParam and lParam) for passing data. As a result, these parameters must refer indirectly to other pieces of data when more than a few words of information pass between applications. The DDE protocol defines exactly how applications should use the wParam and lParam parameters to pass larger pieces of data by means of global atoms and shared memory handles. The DDE protocol has specific rules for allocating and deleting global atoms and shared memory objects.

A global atom is a reference to a character string. In the DDE protocol, atoms identify the applications exchanging data, the nature of the data being exchanged, and the data items themselves. For more information about atoms, see Atoms. A shared memory handle is a handle to a memory object allocated by GlobalAlloc, using the GMEM_DDESHARE flag. In the DDE protocol, shared memory objects store data items passed between applications, protocol options, and remote command execution strings.


Uses for Windows Dynamic Data Exchange

DDE is most appropriate for data exchanges that do not require ongoing user interaction. Usually, an application provides a method for the user to establish the link between the applications exchanging data. Once that link is established, however, the applications exchange data without further user involvement.

DDE can be used to implement a broad range of application features — for example:

  • Linking to real-time data, such as to stock market updates, scientific instruments, or process control.
  • Creating compound documents, such as a word processing document that includes a chart produced by a graphics application. Using DDE, the chart will change when the source data is changed, while the rest of the document remains the same.
  • Performing data queries between applications, such as a spreadsheet querying a database for accounts past due.


Dynamic Data Exchange from the User's Point of View

The following example illustrates illustrates how two DDE applications can cooperate, as seen from the user's point of view.

A spreadsheet user wants to use Microsoft® Excel to track the price of a particular stock on the New York Stock Exchange. The user has a Win32-based application called Quote that in turn has access to NYSE data. The DDE conversation between Microsoft Excel and Quote takes place as follows:

  • The user initiates the conversation by supplying the name of the application (Quote) that will supply the data and the particular topic of interest (NYSE). The resulting DDE conversation is used to request quotes on specific stocks.
  • Microsoft Excel broadcasts the application and topic names to all DDE applications currently running in the system. Quote responds, establishing a conversation with Microsoft Excel about the NYSE topic.
  • The user can then create a spreadsheet formula in a cell that requests that the spreadsheet be automatically updated whenever a particular stock quotation changes. For example, the user could request an automatic update whenever a change occurs in the selling price of ZAXX stock by specifying the following Microsoft Excel formula:
    ='Quote'|'NYSE'!ZAXX
  • The user can terminate the automatic updating of the ZAXX stock quotation at any time. Other data links that were established separately (such as for quotations for other stocks) still will remain active under the same NYSE conversation.
  • The user can also terminate the entire conversation between Microsoft Excel and Quote on the NYSE topic, so that no specific data links on that topic can be established without initiating a new conversation.


Dynamic Data Exchange Concepts

The following sections explain the important concepts and terminology that are key to understanding dynamic data exchange.


Client, Server, and Conversation

Two applications participating in dynamic data exchange are said to be engaged in a DDE conversation. The application that initiates the conversation is the DDE client application; the application that responds to the client is the DDE server application. An application can engage in several conversations at the same time, acting as the client in some and as the server in others.

A DDE conversation takes place between two windows, one for each of the participating applications. A window may be the main window of the application; a window associated with a specific document, as in a multiple document interface (MDI) application; or a hidden (invisible) window whose only purpose is to process DDE messages.

Since a DDE conversation is identified by the pair of handles to the windows engaged in the conversation, no window should be engaged in more than one conversation with another window. Either the client application or the server application must provide a different window for each of its conversations with a particular server or client application.

An application can ensure a pair of client and server windows is never involved in more than one conversation by creating a hidden window for each conversation. The sole purpose of this window is to process DDE messages.


Application, Topic, and Item Names

The DDE protocol identifies the units of data passed between the client and server with a three-level hierarchy of application, topic, and item names.

Each DDE conversation is uniquely defined by the application name and topic. At the beginning of a DDE conversation, the client and server determine the application name and topic. The application name is usually the name of the server application. For example, when Microsoft Excel acts as the server in a conversation, the application name is Excel.

The DDE topic is a general classification of data within which multiple data items may be "discussed" (exchanged) during the conversation. For applications that operate on file-based documents, the topic is usually a filename. For other applications, the topic is an application-specific name.

Because the client and server window handles together identify a DDE conversation, the application name and topic that define a conversation cannot be changed during the course of the conversation.

A DDE data item is information related to the conversation topic exchanged between the applications. Values for the data item can be passed from the server to the client, or from the client to the server. Data can be passed with any of the standard clipboard formats or with a registered clipboard format. A special, registered format named Link identifies an item in a DDE conversation. For more information about clipboard formats, see Clipboard.


The System Topic

Applications should support the system topic at all times. This topic provides a context for information that may be of general interest to another application.

Data-item values must be rendered in the CF_TEXT clipboard format. Individual elements of item values for a system topic must be delimited by tab characters. The following table suggests some items for the system topic.

Item | Description
Formats | Tab-delimited list of clipboard formats the application can render. Typically, CF_ formats are listed with the "CF_" portion of the names removed (for example, CF_TEXT is listed as " TEXT").
Help | Text that briefly explains how to use the DDE server.
ReturnMessage | Supporting detail for the most recently used WM_DDE_ACK message. This item is useful when more than eight bits of application-specific return data are required.
Status | Indication of the current status of the application. When a server receives a WM_DDE_REQUEST message for this system-topic item, it should respond by posting a WM_DDE_DATA message with a string containing either Busy or Ready, as appropriate.
SysItems | List of system-topic items the application supports.
TopicItemList | Similar to the SysItems item, except that TopicItemList should be supported for each topic other than the system topic. This allows browsing of the items supported under any topic. If the items cannot be enumerated, this item should contain only "TopicItemList".
Topics | List of topics the application supports at the current time; this list can vary from moment to moment.


Permanent Data Links

Once a DDE conversation has begun, the client can establish one or more permanent data links with the server. A data link is a communications mechanism by which the server notifies the client whenever the value of a given data item changes. The data link is permanent in the sense that this notification process continues until the data link or the DDE conversation itself is terminated.

There are two kinds of permanent DDE data links: warm and hot. In a warm data link, the server notifies the client that the value of the data item has changed, but the server does not send the data value to the client until the client requests it. In a hot data link, the server immediately sends the changed data value to the client.

Applications that support warm or hot data links typically provide a Copy or Paste Link command in their Edit menu to enable the user to establish links between applications. For more information, see Initiating a Data Link.


Atoms and Shared Memory Objects

Certain arguments of DDE messages are global atoms or shared memory objects. Applications using these arguments must follow explicit rules about when to allocate and delete them. In all cases, the message sender must delete any atom or shared memory object that the intended receiver will not receive because of an error condition, such as failure of the PostMessage function.

DDE uses shared memory objects for three purposes:

  • To carry a data-item value to be exchanged. This is an item referenced by the hData parameter in the WM_DDE_DATA and WM_DDE_POKE messages.
  • To carry options in a message. This is an item referenced by the hOptions parameter in a WM_DDE_ADVISE message.
  • To carry a command execution string. This is an item referenced by the hCommands parameter in the WM_DDE_EXECUTE message and its corresponding WM_DDE_ACK message.

An application that receives a DDE shared memory object must treat it as read only. The application must not use the object as a mutual read-write area for the free exchange of data.

As it does with a DDE atom, an application should free a shared memory object to manage memory effectively. The application should also lock and unlock memory objects.


Dynamic Data Exchange Messages Overview

Because DDE is a message-based protocol, it employs no special Win32 functions or libraries. All DDE transactions are conducted by passing certain defined DDE messages between the client and server windows.

There are nine DDE messages; the symbolic constants for these messages are defined in the DDE header file. Certain structures for the various DDE messages are also defined in this header file.

The following table summarizes the nine DDE messages.

Message | Description
WM_DDE_ACK | Acknowledges receiving or not receiving a message.
WM_DDE_ADVISE | Requests the server application to supply an update or notification for a data item whenever it changes. This establishes a permanent data link.
WM_DDE_DATA | Sends a data-item value to the client application.
WM_DDE_EXECUTE | Sends a string to the server application, which is expected to process the string as a series of commands.
WM_DDE_INITIATE | Initiates a conversation between the client and server applications.
WM_DDE_POKE | Sends a data-item value to the server application.
WM_DDE_REQUEST | Requests the server application to provide the value of a data item.
WM_DDE_TERMINATE | Terminates a conversation.
WM_DDE_UNADVISE | Terminates a permanent data link.

An application calls SendMessage to issue the WM_DDE_INITIATE message or a WM_DDE_ACK message sent in response to WM_DDE_INITIATE. All other messages are sent by PostMessage. The first parameter of these calls is the handle of the receiving window; the second parameter contains the message to be sent; the third parameter identifies the sending window; and the fourth parameter contains the message-specific arguments.


Dynamic Data Exchange Message Flow

A typical DDE conversation consists of the following events:

  1. The client application initiates the conversation, and the server application responds.
  2. The applications exchange data by any or all of the following methods:
    • The server application sends data to the client at the client's request.
    • The client application sends unsolicited data to the server application.
    • The client application requests the server application to notify the client whenever a data item changes (warm data link).
    • The client application requests the server application to send data whenever the data changes (hot data link).
    • The server application carries out a command at the client's request.
  3. Either the client or server application terminates the conversation.

An application window that processes requests from a client or server must process them strictly in the order they are received.

A client can establish conversations with more than one server; a server can have conversations with more than one client. When handling messages from more than one source, a client or server must process the messages of a given conversation synchronously, but need not process all messages synchronously. In other words, it can shift from one conversation to another as needed.

If an application is unable to process an incoming request because it is waiting for a DDE response, it must prevent deadlock by posting a WM_DDE_ACK message with the fBusy member of the DDEACK structure set to 1. An application can also send a busy WM_DDE_ACK message if, for any reason, it cannot process an incoming request within a reasonable amount of time.

An application should be able to handle the failure of a client or server to respond to a message within a certain time. Since the time-out interval may vary depending on the nature of the application and the configuration of the user's system (including whether it is connected to a network), the application should provide a way for the user to specify the interval.


Parameter-Packing Functions

The lParam parameter of many DDE messages contains two pieces of data. For example, the lParam of the WM_DDE_DATA message contains a data handle and an atom. In 16-bit versions of Windows, an application could use the MAKELONG macro to prepare an lParam parameter, and the LOWORD and HIWORD macros to remove the low-order and high-order values from lParam. Because a Win32 data handle is a 32-bit value, a Win32-based application must use the PackDDElParam function to pack the handle and atom into an lParam parameter, and the UnpackDDElParam function to remove the values. DDE applications must use PackDDElParam and UnpackDDElParam for all messages posted during a DDE conversation.

The Win32 API also includes the ReuseDDElParam and FreeDDElParam functions. ReuseDDElParam allows a DDE application to reuse a packed lParam parameter, helping reduce the number of memory reallocations the application must perform during a conversation. An application can use FreeDDElParam to free the memory associated with a data handle received during a DDE conversation.


Dynamic Data Exchange and Impersonation

To allow a server to impersonate a client, the client calls the DdeSetQualityOfService function. The SECURITY_IMPERSONATION_LEVEL structure is used to control the level of impersonation the server may perform.

A DDE server can impersonate a DDE client by calling the ImpersonateDdeClientWindow function. A DDEML server should use the DdeImpersonateClient function.


Using Dynamic Data Exchange

  • Initiating a conversation
  • Transferring a single item
  • Establishing a permanent data link
  • Carrying out commands in a server application
  • Terminating a conversation


Initiating a Conversation

To initiate a DDE conversation, the client sends a WM_DDE_INITIATE message. Usually, the client broadcasts this message by calling SendMessage, with –1 as the first parameter. If the application already has the window handle of the server application, it can send the message directly to that window. The client prepares atoms for the application name and topic name by calling GlobalAddAtom. The client can request conversations with any potential server application and for any potential topic by supplying NULL (wildcard) atoms for the application and topic.

The following example illustrates how the client initiates a conversation, where both the application and topic are specified.

static BOOL fInInitiate = FALSE;
    char *szApplication;
    char *szTopic;
    atomApplication = *szApplication == 0 ?
        NULL : GlobalAddAtom((LPSTR) szApplication);
    atomTopic = *szTopic == 0 ?
        NULL : GlobalAddAtom((LPSTR) szTopic);

    fInInitiate = TRUE;
    SendMessage((HWND) -1,        // broadcasts message
        WM_DDE_INITIATE,          // initiates conversation
        (WPARAM) hwndClientDDE,   // handle of client DDE window
        MAKELONG(atomApplication, // application-name atom
            atomTopic));          // topic-name atom
    fInInitiate = FALSE;
    if (atomApplication != NULL)
        GlobalDeleteAtom(atomApplication);
    if (atomTopic != NULL)
        GlobalDeleteAtom(atomTopic);

Note If your application uses NULL atoms, you need not use the GlobalAddAtom and GlobalDeleteAtom functions. In this example, the client application creates two global atoms containing the name of the server and the name of the topic, respectively.

The client application sends a WM_DDE_INITIATE message with these two atoms in the lParam parameter of the message. In the call to the SendMessage function, the special window handle –1 directs the system to send this message to all other active applications. SendMessage does not return to the client application until all applications that receive the message have, in turn, returned control to the system. This means that all WM_DDE_ACK messages sent in reply by the server applications are guaranteed to have been processed by the client by the time the SendMessage call has returned.

After SendMessage returns, the client application deletes the global atoms.

Server applications respond according to the logic illustrated in the following diagram.

To acknowledge one or more topics, the server must create atoms for each conversation (requiring duplicate application-name atoms if there are multiple topics) and send a WM_DDE_ACK message for each conversation, as illustrated in the following example.

if ((atomApplication = GlobalAddAtom("Server")) != 0)
{
    if ((atomTopic = GlobalAddAtom(szTopic)) != 0)
    {
        SendMessage(hwndClientDDE,
            WM_DDE_ACK,
            (WPARAM) hwndServerDDE,
            MAKELONG(atomApplication, atomTopic));
        GlobalDeleteAtom(atomApplication);
    }

    GlobalDeleteAtom(atomTopic);
}

if ((atomApplication == 0) || (atomTopic == 0))
{

    // Handle errors.

}

When a server responds with a WM_DDE_ACK message, the client application should save the handle of the server window. The client receiving the handle as the wParam parameter of the WM_DDE_ACK message then sends all subsequent DDE messages to the server window this handle identifies.

If your client application uses a NULL atom for the application name or topic name, expect the application to receive acknowledgments from more than one server application. Multiple acknowledgements can also come from multiple instances of a DDE server, even if your client application does not use NULL atoms. A server should always use a unique window for each conversation. The window procedure in the client application can use the handle of the server window (provided as the lParam parameter of WM_DDE_INITIATE) to track multiple conversations. This allows a single client window to process several conversations without needing to terminate and reconnect with a new client window for each conversation.


Transferring a Single Item

Once a DDE conversation has been established, the client can either retrieve the value of a data item from the server by issuing the WM_DDE_REQUEST message, or submit a data-item value to the server by issuing WM_DDE_POKE.


Retrieving an Item from the Server

To retrieve an item from the server, the client sends the server a WM_DDE_REQUEST message specifying the item and format to retrieve, as shown in the following example.

if ((atomItem = GlobalAddAtom(szItemName)) != 0)
{
    if (!PostMessage(hwndServerDDE,
            WM_DDE_REQUEST,
            (WPARAM) hwndClientDDE,
            PackDDElParam(WM_DDE_REQUEST, CF_TEXT, atomItem)))
    {
        GlobalDeleteAtom(atomItem);
    }
}

if (atomItem == 0)
{

    // Handle errors.

}

In this example, the client specifies the clipboard format CF_TEXT as the preferred format for the requested data item.

The receiver (server) of the WM_DDE_REQUEST message typically must delete the item atom, but if the PostMessage call fails, the client must delete the atom.

If the server has access to the requested item and can render it in the requested format, the server copies the item value as a shared memory object and sends the client a WM_DDE_DATA message, as illustrated in the following example.

// Allocate the size of the DDE data header, plus the data: a
// string,<CR><LF><NULL>. The byte for the string's terminating
// null character is counted by DDEDATA.Value[1].

if (!(hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
        (LONG) sizeof(DDEDATA) + lstrlen(szItemValue) + 2)))
{
    return;
}

if (!(lpData = (DDEDATA FAR*) GlobalLock(hData)))
{
    GlobalFree(hData);
    return;
}

lpData->cfFormat = CF_TEXT;
lstrcpy((LPSTR) lpData->Value, (LPSTR) szItemValue);

// Each line of CF_TEXT data is terminated by CR/LF.

lstrcat((LPSTR) lpData->Value, (LPSTR) "\r\n");
GlobalUnlock(hData);

if ((atomItem = GlobalAddAtom((LPSTR) szItemName)) != 0)
{
    lParam = PackDDElParam(WM_DDE_ACK, (UINT) hData, atomItem);
    if (!PostMessage(hwndClientDDE,
            WM_DDE_DATA,
            (WPARAM) hwndServerDDE,
            lParam))
    {
        GlobalFree(hData);
        GlobalDeleteAtom(atomItem);
        FreeDDElParam(WM_DDE_ACK, lParam);
    }
}

if (atomItem == 0)
{

    // Handle errors.

}

In this example, the server application allocates a memory object to contain the data item. The memory is allocated with the GMEM_DDESHARE option, so that the server and client applications can share the memory. After allocating the memory object, the server application locks the object so it can obtain the object's address. The data object is initialized as a DDEDATA structure.

The server application then sets the cfFormat member of the structure to CF_TEXT to inform the client application that the data is in text format. The client responds by copying the value of the requested data into the Value member of the DDEDATA structure. After the server has filled the data object, the server unlocks the data and creates a global atom containing the name of the data item.

Finally, the server issues the WM_DDE_DATA message by calling PostMessage. The handle of the data object and the atom containing the item name are packed into the lParam parameter of the message by the PackDDElParam function.

If PostMessage fails, the server must use the FreeDDElParam function to free the packed lParam parameter. The server must also free the packed lParam parameter for the WM_DDE_REQUEST message it received.

If the server cannot satisfy the request, it sends a negative WM_DDE_ACK message to the client, as shown in the following example.

// Negative acknowledgment.

PostMessage(hwndClientDDE,
    WM_DDE_ACK,
    (WPARAM) hwndServerDDE,
    PackDDElParam(WM_DDE_ACK, 0, atomItem));

Upon receiving a WM_DDE_DATA message, the client processes the data-item value as appropriate. Then, if the fAckReq member pointed to in the WM_DDE_DATA message is 1, the client must send the server a positive WM_DDE_ACK message, as shown in the following example.

UnpackDDElParam(WM_DDE_DATA, lParam, (PUINT) &hData,
    (PUINT) &atomItem);
if (!(lpDDEData = (DDEDATA FAR*) GlobalLock(hData))
        || (lpDDEData->cfFormat != CF_TEXT))
{
    PostMessage(hwndServerDDE,
        WM_DDE_ACK,
        (WPARAM) hwndClientDDE,
        PackDDElParam(WM_DDE_ACK, 0, atomItem)); // Negative ACK.
}

// Copy data from lpDDEData here.

if (lpDDEData->fAckReq)
{
    PostMessage(hwndServerDDE,
        WM_DDE_ACK,
        (WPARAM) hwndClientDDE,
        PackDDElParam(WM_DDE_ACK, 0x8000,
            atomItem)); // Positive ACK
}

bRelease = lpDDEData->fRelease;
GlobalUnlock(hData);
if (bRelease)
    GlobalFree(hData);

In this example, the client examines the format of the data. If the format is not CF_TEXT (or if the client cannot lock the memory for the data), the client sends a negative WM_DDE_ACK message to indicate that it cannot process the data. If the client cannot lock a data handle because the handle contains the fAckReq member, the client should not send a negative WM_DDE_ACK message. Instead, the client should terminate the conversation.

If a client sends a negative acknowledgement in response to a WM_DDE_DATA message, the server is responsible for freeing the memory (but not the lParam parameter) referenced by the WM_DDE_DATA message associated with the negative acknowledgement.

If it can process the data, the client examines the fAckReq member of the DDEDATA structure to determine whether the server requested that it be informed that the client received and processed the data successfully. If the server did request this information, the client sends the server a positive WM_DDE_ACK message.

Because unlocking data invalidates the pointer to the data, the client saves the value of the fRelease member before unlocking the data object. After saving the value, the client then examines it to determine whether the server application requested the client to free the memory containing the data; the client acts accordingly.

Upon receiving a negative WM_DDE_ACK message, the client can ask for the same item value again, specifying a different clipboard format. Typically, a client will first ask for the most complex format it can support, then step down if necessary through progressively simpler formats until it finds one the server can provide.

If the server supports the Formats item of the system topic, the client can determine once what clipboard formats the server supports, instead of determining them each time the client requests an item. For more information about the system topic, see The System Topic.


Submitting an Item to the Server

The client may send an item value to the server by using the WM_DDE_POKE message. The client renders the item to be sent and sends the WM_DDE_POKE message, as illustrated in the following example.

if (!(hPokeData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
        (LONG) sizeof(DDEPOKE) + lstrlen(szValue) + 2)))
{
    return;
}

if (!(lpPokeData = (DDEPOKE FAR*) GlobalLock(hPokeData)))
{
    GlobalFree(hPokeData);
    return;
}

lpPokeData->fRelease = TRUE;
lpPokeData->cfFormat = CF_TEXT;
lstrcpy((LPSTR) lpPokeData->Value, (LPSTR) szValue);

// Each line of CF_TEXT data is terminated by CR/LF.

lstrcat((LPSTR) lpPokeData->Value, (LPSTR) "\r\n");
GlobalUnlock(hPokeData);
if ((atomItem = GlobalAddAtom((LPSTR) szItem)) != 0)
{

        if (!PostMessage(hwndServerDDE,
                WM_DDE_POKE,
                (WPARAM) hwndClientDDE,
                PackDDElParam(WM_DDE_POKE, (UINT) hPokeData,
                    atomItem)))
        {
            GlobalDeleteAtom(atomItem);
            GlobalFree(hPokeData);
        }
}

if (atomItem == 0)
{

    // Handle errors.

}

Note Sending data by using a WM_DDE_POKE message is essentially the same as sending it by using WM_DDE_DATA, except that WM_DDE_POKE is sent from the client to the server.

If the server is able to accept the data-item value in the format rendered by the client, the server processes the item value as appropriate and sends the client a positive WM_DDE_ACK message. If it is unable to process the item value, because of its format or for other reasons, the server sends the client a negative WM_DDE_ACK message.

UnpackDDElParam(WM_DDE_POKE, lParam, (PUINT) &hPokeData,
    (PUINT) &atomItem);
GlobalGetAtomName(atomItem, szItemName, ITEM_NAME_MAX_SIZE);
if (!(lpPokeData = (DDEPOKE FAR*) GlobalLock(hPokeData))
        || lpPokeData->cfFormat != CF_TEXT
        || !IsItemSupportedByServer(szItemName))
{
    PostMessage(hwndClientDDE,
        WM_DDE_ACK,
        (WPARAM) hwndServerDDE,
        PackDDElParam(WM_DDE_ACK, 0, atomItem)); // negative ACK
}

lstrcpy(szItemValue, lpPokeData->Value); // copies value
bRelease = lpPokeData->fRelease;
GlobalUnlock(hPokeData);
if (bRelease)
{
    GlobalFree(hPokeData);
}

PostMessage(hwndClientDDE,
    WM_DDE_ACK,
    (WPARAM) hwndServerDDE,
    PackDDElParam(WM_DDE_ACK,
         0x8000, atomItem));    // positive ACK

In this example, the server calls GlobalGetAtomName to retrieve the name of the item the client sent. The server then determines whether it supports the item and whether the item is rendered in the correct format (that is, CF_TEXT). If the item is not supported and not rendered in the correct format, or if the server cannot lock the memory for the data, the server sends a negative acknowledgment back to the client application. Note that in this case, sending a negative acknowledgement is correct because WM_DDE_POKE messages are always assumed to have the fAckReq member set. The server should ignore the member.

If a server sends a negative acknowledgement in response to a WM_DDE_POKE message, the client is responsible for freeing the memory (but not the lParam parameter) referenced by the WM_DDE_POKE message associated with the negative acknowledgement.


Establishing a Permanent Data Link

A client application can use DDE to establish a link to an item in a server application. After such a link is established, the server sends periodic updates of the linked item to the client, typically, whenever the value of the item changes. Thus, a permanent data stream is established between the two applications; this data stream remains in place until it is explicitly disconnected.


Initiating a Data Link

The client initiates a data link by posting a WM_DDE_ADVISE message, as shown in the following example.

if (!(hOptions = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
        sizeof(DDEADVISE))))
    return;
if (!(lpOptions = (DDEADVISE FAR*) GlobalLock(hOptions)))
{
    GlobalFree(hOptions);
    return;
}

lpOptions->cfFormat = CF_TEXT;
lpOptions->fAckReq = TRUE;
lpOptions->fDeferUpd = FALSE;
GlobalUnlock(hOptions);
if ((atomItem = GlobalAddAtom(szItemName)) != 0)
{
    if (!(PostMessage(hwndServerDDE,
            WM_DDE_ADVISE,
            (WPARAM) hwndClientDDE,
            PackDDElParam(WM_DDE_ADVISE, (UINT) hOptions,
                atomItem))))
    {
        GlobalDeleteAtom(atomItem);
        GlobalFree(hOptions);
        FreeDDElParam(WM_DDE_ADVISE, lParam);
    }
}

if (atomItem == 0)
{

    // Handle errors

}

In this example, the client application sets the fDeferUpd flag of the WM_DDE_ADVISE message to FALSE. This directs the server application to send the data to the client whenever the data changes.

If the server is unable to service the WM_DDE_ADVISE request, it sends the client a negative WM_DDE_ACK message. But if the server has access to the item and can render it in the requested format, the server notes the new link (recalling the flags specified in the hOptions parameter) and sends the client a positive WM_DDE_ACK message. From then on, until the client issues a matching WM_DDE_UNADVISE message, the server sends the new data to the client every time the value of the item changes in the server.

The WM_DDE_ADVISE message establishes the format of the data to be exchanged during the link. If the client attempts to establish another link with the same item but is using a different data format, the server can choose to reject the second data format or attempt to support it. If a warm link has been established for any data item, the server can support only one data format at a time. This is because the WM_DDE_DATA message for a warm link has a NULL data handle, which otherwise contains the format information. Thus, a server must reject all warm links for an item already linked, and must reject all links for an item that has warm links. Another interpretation may be that the server changes the format and the hot or warm state of a link when a second link is requested for the same data item.

In general, client applications should not attempt to establish more than one link at a time for a data item.


Initiating a Data Link with the Paste Link Command

Applications that support hot or warm data links typically support a registered clipboard format named Link. When associated with the application's Copy and Paste Link commands, this clipboard format enables the user to establish DDE conversations between applications simply by copying a data item in the server application and pasting it into the client application.

A server application supports the Link clipboard format by placing in the clipboard a string containing the application, topic, and item names when the user chooses the Copy command from the Edit menu. Following is the standard Link format:

application\0 topic\0 item\0\0

A single null character separates the names, and two null characters terminate the entire string.

Both the client and server applications must register the Link clipboard format, as shown:

cfLink = RegisterClipboardFormat("Link");

A client application supports the Link clipboard format by means of a Paste Link command on its Edit menu. When the user chooses this command, the client application parses the application, topic, and item names from the Link-format clipboard data. Using these names, the client application initiates a conversation for the application and topic, if such a conversation does not already exist. The client application then sends a WM_DDE_ADVISE message to the server application, specifying the item name contained in the Link-format clipboard data.

Following is an example of a client application's response when the user chooses the Paste Link command.

void DoPasteLink(hwndClientDDE)
HWND hwndClientDDE;
{
    HANDLE hData;
    LPSTR lpData;
    HWND hwndServerDDE;
    CHAR szApplication[APP_MAX_SIZE + 1];
    CHAR szTopic[TOPIC_MAX_SIZE + 1];
    CHAR szItem[ITEM_MAX_SIZE + 1];
    int nBufLen;

    if (OpenClipboard(hwndClientDDE))
    {
        if (!(hData = GetClipboardData(cfLink)) ||
                !(lpData = GlobalLock(hData)))
        {
            CloseClipboard();
            return;
        }

        // Parse the clipboard data.

        if ((nBufLen = lstrlen(lpData)) >= APP_MAX_SIZE)
        {
            CloseClipboard();
            GlobalUnlock(hData);
            return;
        }
        lstrcpy(szApplication, lpData);
        lpData += (nBufLen + 1); // skips over null
        if ((nBufLen = lstrlen(lpData)) >= TOPIC_MAX_SIZE)
        {
            CloseClipboard();
            GlobalUnlock(hData);
            return;
        }
        lstrcpy(szTopic, lpData);
        lpData += (nBufLen + 1); // skips over null
        if ((nBufLen = lstrlen(lpData)) >= ITEM_MAX_SIZE)
        {
            CloseClipboard();
            GlobalUnlock(hData);
            return;
        }
        lstrcpy(szItem, lpData);
        GlobalUnlock(hData);
        CloseClipboard();

        if (hwndServerDDE =
                FindServerGivenAppTopic(szApplication, szTopic))
        {
            // App/topic conversation is already started.

            if (DoesAdviseAlreadyExist(hwndServerDDE, szItem))
            {
                MessageBox(hwndMain,
                    "Advisory already established",
                    "Client", MB_ICONEXCLAMATION | MB_OK);
            }
            else SendAdvise(hwndClientDDE, hwndServerDDE, szItem);
        }
        else
        {
            // Client must initiate a new conversation first.
            SendInitiate(szApplication, szTopic);
            if (hwndServerDDE =
                    FindServerGivenAppTopic(szApplication,
                        szTopic))
            {
                SendAdvise(hwndClientDDE, hwndServerDDE, szItem);
            }
        }
    }
    return;
}

In this example, the client application opens the clipboard and determines whether it contains data in the Link format (that is, cfLink) it had previously registered. If not, or if it cannot lock the data in the clipboard, the client returns.

After the client application retrieves a pointer to the clipboard data, it parses the data to extract the application, topic, and item names.

The client application determines whether a conversation on the topic already exists between it and the server application. If a conversation does exist, the client checks whether a link already exists for the data item. If such a link exists, the client displays a message box to the user; otherwise, it calls its own SendAdvise function to send a WM_DDE_ADVISE message to the server for the item.

If a conversation on the topic does not already exist between the client and the server, the client first calls its own SendInitiate function to broadcast the WM_DDE_INITIATE message to request a conversation and, second, calls its own FindServerGivenAppTopic function to establish the conversation with the window that responds on behalf of the server application. After the conversation has begun, the client application calls SendAdvise to request the link.


Notifying the Client that Data Has Changed

When the client establishes a link by using the WM_DDE_ADVISE message, with the fDeferUpd member not set (that is, equal to zero) in the DDEDATA structure, the client has requested the server send the data item each time the item's value changes. In such cases, the server renders the new value of the data item in the previously specified format and sends the client a WM_DDE_DATA message, as shown in the following example.

// Allocate the size of a DDE data header, plus data (a string),
// plus a <CR><LF><NULL>

if (!(hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
        sizeof(DDEDATA) + lstrlen(szItemValue) + 3)))
{
    return;
}
if (!(lpData = (DDEDATA FAR*) GlobalLock(hData)))
{
    GlobalFree(hData);
    return;
}

lpData->fAckReq = bAckRequest;       // as in original WM_DDE_ADVISE
lpData->cfFormat = CF_TEXT;
lstrcpy(lpData->Value, szItemValue); // copies value to be sent
lstrcat(lpData->Value, "\r\n");      // CR/LF for CF_TEXT format
GlobalUnlock(hData);

if ((atomItem = GlobalAddAtom(szItemName)) != 0)
{
    if (!PostMessage(hwndClientDDE,
            WM_DDE_DATA,
            (WPARAM) hwndServerDDE,
            PackDDElParam(WM_DDE_DATA, (UINT) hData, atomItem)))
    {
        GlobalFree(hData);
        GlobalDeleteAtom(atomItem);
        FreeDDElParam(WM_DDE_DATA, lParam);
    }
}

if (atomItem == 0)
{

    // Handle errors.

}

In this example, the client processes the item value as appropriate. If the fAckReq flag for the item is set, the client sends the server a positive WM_DDE_ACK message.

When the client establishes the link, with the fDeferUpd member set (that is, equal to 1), the client has requested that only a notification, not the data itself, be sent each time the data changes. In such cases, when the item value changes, the server does not render the value but simply sends the client a WM_DDE_DATA message with a null data handle, as illustrated in the following example.

if (bDeferUpd)      // check whether flag was set in WM_DDE_ADVISE
{
    if ((atomItem = GlobalAddAtom(szItemName)) != 0)
    {
        if (!PostMessage(hwndClientDDE,
                WM_DDE_DATA,
                (WPARAM) hwndServerDDE,
                PackDDElParam(WM_DDE_DATA, 0,
                    atomItem)))                  // NULL data
        {
            GlobalDeleteAtom(atomItem);
            FreeDDElParam(WM_DDE_DATA, lParam);
        }
    }
}

if (atomItem == 0)
{

     // Handle errors.

}

As necessary, the client can request the latest value of the data item by issuing a normal WM_DDE_REQUEST message, or it can simply ignore the notice from the server that the data has changed. In either case, if fAckReq is equal to 1, the client is expected to send a positive WM_DDE_ACK message to the server.


Terminating a Data Link

If the client requests that a specific data link be terminated, the client sends the server a WM_DDE_UNADVISE message, as shown in the following example.

if ((atomItem = GlobalAddAtom(szItemName)) != 0)
{
    if (!PostMessage(hwndServerDDE,
            WM_DDE_UNADVISE,
            (WPARAM) hwndClientDDE,
            PackDDElParam(WM_DDE_UNADVISE, 0, atomItem)))
    {
        GlobalDeleteAtom(atomItem);
        FreeDDElParam(WM_DDE_UNADVISE, lParam);
    }
}

if (atomItem == 0)
{

    // Handle errors.

}

The server checks whether the client currently has a link to the specific item in this conversation. If a link exists, the server sends the client a positive WM_DDE_ACK message; the server is then no longer required to send updates about the item. If no link exists, the server sends the client a negative WM_DDE_ACK message.

The WM_DDE_UNADVISE message specifies a data format. A format of zero informs the server to stop all links for the specified item, even if several hot links are established and each uses a different format.

To terminate all links for a conversation, the client application sends the server a WM_DDE_UNADVISE message with a null item atom. The server determines whether the conversation has at least one link currently established. If a link exists, the server sends the client a positive WM_DDE_ACK message; the server then no longer has to send any updates in the conversation. If no link exists, the server sends the client a negative WM_DDE_ACK message.


Carrying Out Commands in a Server Application

A Win32-based application can use the WM_DDE_EXECUTE message to cause a certain command or series of commands to be carried out in another application. To do this, the client sends the server a WM_DDE_EXECUTE message containing a handle to a command string, as shown in the following example.

if (!(hCommand = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
        sizeof(szCommandString) + 1)))
{
    return;
}
if (!(lpCommand = GlobalLock(hCommand)))
{
    GlobalFree(hCommand);
    return;
}

lstrcpy(lpCommand, szCommandString);
GlobalUnlock(hCommand);

if (!PostMessage(hwndServerDDE,
        WM_DDE_EXECUTE,
        (WPARAM) hwndClientDDE,
        PackDDElParam(WM_DDE_EXECUTE, 0, (UINT) hCommand)))
{
    GlobalFree(hCommand);
    FreeDDElParam(WM_DDE_EXECUTE, lParam);
}

In this example, the server attempts to carry out the specified command string. If it succeeds, the server sends the client a positive WM_DDE_ACK message; otherwise, it sends a negative WM_DDE_ACK message. This WM_DDE_ACK message reuses the hCommand handle passed in the original WM_DDE_EXECUTE message.

If the client's command execution string requests that the server terminate, the server should respond by sending a positive WM_DDE_ACK message and then post a WM_DDE_TERMINATE message before terminating. All other commands sent with a WM_DDE_EXECUTE message should be executed synchronously; that is, the server should send a WM_DDE_ACK message only after successfully completing the command.


Terminating a Conversation

Either the client or the server can issue a WM_DDE_TERMINATE message to terminate a conversation at any time. Similarly, both the client and server applications should be prepared to receive this message at any time. An application must terminate all of its conversations before shutting down.

In the following example, the application terminating the conversation posts a WM_DDE_TERMINATE message.

PostMessage(hwndServerDDE, WM_DDE_TERMINATE,
    PackDDElParam(WM_DDE_TERMINATE, (UINT) hwndClientDDE, 0), 0);

This informs the other application that the sending application will send no further messages and the recipient can close its window. The recipient is expected in all cases to respond promptly by sending a WM_DDE_TERMINATE message. The recipient must not send a negative, busy, or positive WM_DDE_ACK message.

After an application has sent the WM_DDE_TERMINATE message to the partner in a DDE conversation, it must not respond to messages from that partner, since the partner might have destroyed the window to which the response would be sent.

If an application receives a DDE message other than WM_DDE_TERMINATE after it has posted WM_DDE_TERMINATE, it should free all objects associated with the received messages except the data handles for WM_DDE_DATA or WM_DDE_POKE messages that do not have the fRelease member set.

When an application is about to terminate, it should end all active DDE conversations before completing processing of the WM_DESTROY message. However, if an application does not end its active DDE conversations, the system will terminate any DDE conversations associated with a window when the window is destroyed. The following example shows how a server application terminates all DDE conversations.

void TerminateConversations(hwndServerDDE)
HWND hwndServerDDE;
{
    HWND hwndClientDDE;

    // Terminate each active conversation.

    while (hwndClientDDE = GetNextLink(hwndClientDDE))
    {
        SendTerminate(hwndServerDDE, hwndClientDDE);
    }
    return;
}

BOOL AtLeastOneLinkActive(VOID)
{
    return TRUE;
}

HWND GetNextLink(hwndDummy)
    HWND hwndDummy;
{
    return (HWND) 1;
}

VOID SendTerminate(HWND hwndServerDDE, HWND hwndClientDDE)
{
    return;
}


Dynamic Data Exchange Reference

The following functions, structures and messages are associated with dynamic data exchange.

  • Dynamic Data Exchange Functions
  • Dynamic Data Exchange Structures
  • Dynamic Data Exchange Messages


Dynamic Data Exchange Functions

The following functions are used with DDE.

DdeSetQualityOfService
FreeDDElParam
ImpersonateDdeClientWindow
PackDDElParam
ReuseDDElParam
UnpackDDElParam


DdeSetQualityOfService

The DdeSetQualityOfService function specifies the quality of service a raw DDE application desires for future DDE conversations it initiates. The specified quality of service applies to any conversations started while those settings are in place. A DDE conversation's quality of service lasts for the duration of the conversation; calls to the DdeSetQualityOfService function during a given conversation do not affect that conversation's quality of service.

BOOL DdeSetQualityOfService(
  HWND hwndClient,  // handle to DDE client window that will start
                    // DDE conversations
  CONST SECURITY_QUALITY_OF_SERVICE *pqosNew,
                    // desired quality of service
  PSECURITY_QUALITY_OF_SERVICE pqosPrev
                    // prior quality of service
);

Parameters

hwndClient
Handle to the DDE client window that specifies the source of WM_DDE_INITIATE messages a client will send to start DDE conversations.
pqosNew
Pointer to a SECURITY_QUALITY_OF_SERVICE structure for the desired quality of service values.
pqosPrev
Pointer to a SECURITY_QUALITY_OF_SERVICE structure that the function will fill with the previous quality of service values associated with the window identified by hwndClient.

This parameter is optional. If an application has no interest in hwndClient's previous qos values, it should set pqosPrev to NULL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If a quality of service has not been specified for a given client window, hwndClient, prior to sending a WM_DDE_INITIATE with the wParam set to hwndClient, the system uses the following default quality of service values for the client window:

{
   Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
   ImpersonationLevel = SecurityImpersonation;
   ContextTrackingMode = SECURITY_STATIC_TRACKING;
   EffectiveOnly = TRUE;
}

Use the DdeSetQualityOfService function to associate a different quality of service with the client window. Once you change the quality of service, the new settings affect any subsequent conversations that are started. Once an application starts a DDE conversation using a particular quality of service value, it must terminate the conversation and restart the conversation in order to have a different value take effect.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dde.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Functions, SECURITY_QUALITY_OF_SERVICE, WM_DDE_INITIATE


FreeDDElParam

The FreeDDElParam function frees the memory specified by the lParam parameter of a posted DDE message. An application receiving a posted DDE message should call this function after it has used the UnpackDDElParam function to unpack the lParam value.

BOOL FreeDDElParam(
  UINT msg,     // posted DDE message
  LONG lParam   // lParam of message
);

Parameters

msg
Specifies the posted DDE message.
lParam
Specifies the lParam parameter of the posted DDE message.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Remarks

An application should call this function only for posted DDE messages.

This function frees the memory specified by the lParam parameter. It does not free the contents of lParam.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Functions, PackDDElParam, ReuseDDElParam, UnpackDDElParam


ImpersonateDdeClientWindow

The ImpersonateDdeClientWindow function enables a DDE server application to impersonate a DDE client application's security context in order to protect secure server data from unauthorized DDE clients.

BOOL ImpersonateDdeClientWindow(
  HWND hWndClient,  // handle of DDE client window
  HWND hWndServer   // handle of DDE server window
);

Parameters

hWndClient
Handle to the DDE client window to impersonate. The client window must have established a DDE conversation with the server window identified by the hWndServer parameter.
hWndServer
Handle to the DDE server window. An application must create the server window before calling this function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

An application should call the RevertToSelf function to undo the impersonation set by the ImpersonateDdeClientWindow function.

A DDEML application should use the DdeImpersonateClient function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in dde.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Functions, DdeImpersonateClient, RevertToSelf


PackDDElParam

The PackDDElParam function packs a DDE lParam value into an internal structure used for sharing DDE data between processes.

LONG PackDDElParam(
  UINT msg,  // DDE message to be posted
  UINT uiLo, // low-order word of lParam of message
  UINT uiHi  // high-order word of lParam of message
);

Parameters

msg
Specifies the DDE message to be posted.
uiLo
Specifies a value that corresponds to the 16-bit Windows low-order word of an lParam parameter for the DDE message being posted.
uiHi
Specifies a value that corresponds to the 16-bit Windows high-order word of an lParam parameter for the DDE message being posted.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Remarks

The return value must be posted as the lParam parameter of a DDE message; it must not be used for any other purpose. Once the application posts a return value, it need not perform any action to dispose of the lParam parameter.

PackDDElParam eases the porting of 16-bit Windows-based applications to Win32-based applications.

An application should call this function only for posted DDE messages.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Functions, FreeDDElParam, ReuseDDElParam, UnpackDDElParam


ReuseDDElParam

The ReuseDDElParam function allows an application to reuse a packed DDE lParam parameter, rather than allocating a new packed lParam. Using this function reduces reallocations for applications that pass packed DDE messages.

LONG ReuseDDElParam(
  LONG lParam, // posted lParam to be reused
  UINT msgIn,  // identifier of received message
  UINT msgOut, // identifier of posted message
  UINT uiLo,   // low-order word of new lParam
  UINT uiHi    // high-order word of new lParam
);

Parameters

lParam
Specifies the lParam parameter of the posted DDE message being reused.
msgIn
Specifies the identifier of the received DDE message.
msgOut
Specifies the identifier of the DDE message to be posted. The DDE message will reuse the packed lParam parameter.
uiLo
Specifies the value to be packed into the low-order word of the reused lParam parameter.
uiHi
Specifies the value to be packed into the high-order word of the reused lParam parameter.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Remarks

The return value must be posted as the lParam parameter of a DDE message; it must not be used for any other purpose. Once the return value is posted, the posting application need not perform any action to dispose of the lParam parameter.

Use ReuseDDElParam instead of FreeDDElParam if the lParam parameter will be reused in a responding message. ReuseDDElParam returns the lParam appropriate for reuse.

This function allocates or frees lParam parameters as needed, depending on the packing requirements of the incoming and outgoing messages. This reduces reallocations in passing DDE messages.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Functions, FreeDDElParam, PackDDElParam, UnpackDDElParam


UnpackDDElParam

The UnpackDDElParam function unpacks a DDE lParam value received from a posted DDE message.

BOOL UnpackDDElParam(
  UINT msg,     // posted DDE message
  LONG lParam,  // lParam of posted DDE message
  PUINT puiLo,  // address of low-order word of lParam
  PUINT puiHi   // address of high-order word of lParam
);

Parameters

msg
Specifies the posted DDE message.
lParam
Specifies the lParam parameter of the posted DDE message that was received. The application must free the memory object specified by the lParam parameter by calling the FreeDDElParam function.
puiLo
Pointer to a value the function will set to the low-order word of lParam.
puiHi
Pointer to a value the function will set to the high-order word of lParam.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Remarks

PackDDElParam eases the porting of 16-bit DDE applications to 32-bit DDE applications.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Functions, FreeDDElParam, PackDDElParam, ReuseDDElParam


Dynamic Data Exchange Structures

The following structures are used with DDE.

DDEACK
DDEADVISE
DDEDATA
DDEPOKE
HSZPAIR

Obsolete Structures

DDELN
DDEUP


DDEACK

The DDEACK structure contains status flags that a DDE application passes to its partner as part of the WM_DDE_ACK message. The flags provide details about the application's response to the messages WM_DDE_DATA, WM_DDE_POKE, WM_DDE_EXECUTE, WM_DDE_ADVISE, WM_DDE_UNADVISE, and WM_DDE_REQUEST.

typedef struct { // ddeack
    unsigned short bAppReturnCode:8,
    reserved:6,
    fBusy:1,
    fAck:1;
} DDEACK;

Members

bAppReturnCode
Specifies an application-defined return code.
fBusy
Indicates whether the application was busy and unable to respond to the partner's message at the time the message was received. A nonzero value indicates the partner was busy and unable to respond. The fBusy member is defined only when the fAck member is zero.
fAck
Indicates whether the application accepted the message from its partner. A nonzero value indicates the partner accepted the message.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Structures, WM_DDE_ACK, WM_DDE_ADVISE, WM_DDE_DATA, WM_DDE_EXECUTE, WM_DDE_REQUEST, WM_DDE_POKE, WM_DDE_UNADVISE


DDEADVISE

The DDEADVISE structure contains flags that specify how a DDE server application should send data to a client application during an advise loop. A client passes the handle of a DDEADVISE structure to a server as part of a WM_DDE_ADVISE message. This structure supersedes the DDELN structure.

typedef struct { // ddeadv
    unsigned short reserved:14,
        fDeferUpd:1,
        fAckReq:1;
    short cfFormat;
} DDEADVISE;

Members

fDeferUpd
Indicates whether the server should defer sending updated data to the client. If this value is nonzero, the server should send a WM_DDE_DATA message with a NULL data handle whenever the data item changes. In response, the client can post a WM_DDE_REQUEST message to the server to get a handle of the updated data.
fAckReq
Indicates whether the server should set the fAckReq flag in the WM_DDE_DATA messages it posts to the client. If this value is nonzero, the server should set the fAckReq bit.
cfFormat
Specifies the client application's preferred data format. The format must be a standard or registered clipboard format. The following standard clipboard formats can be used:

CF_BITMAP
CF_DIB
CF_DIF
CF_ENHMETAFILE
CF_METAFILEPICT
CF_OEMTEXT
CF_PALETTE
CF_PENDATA
CF_RIFF
CF_SYLK
CF_TEXT
CF_TIFF
CF_WAVE
CF_UNICODETEXT

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Structures, WM_DDE_ADVISE, WM_DDE_DATA, WM_DDE_UNADVISE


DDEDATA

The DDEDATA structure contains the data, and information about the data, sent as part of a WM_DDE_DATA message. This structure supersedes the DDEUP structure.

typedef struct { // ddedat
    unsigned short unused:12,
        fResponse:1,
        fRelease:1,
        reserved:1,
        fAckReq:1;
    short cfFormat;
    BYTE  Value[1];
} DDEDATA;

Members

fResponse
Indicates whether the data was sent in response to a WM_DDE_REQUEST message or a WM_DDE_ADVISE message. If this value is nonzero, the data was sent in response to a WM_DDE_REQUEST message.
fRelease
Indicates whether the application receiving the WM_DDE_POKE message should free the data. If this value is nonzero, the application should free the data.
fAckReq
Indicates whether the application receiving the WM_DDE_DATA message should acknowledge receipt of the data by sending a WM_DDE_ACK message. If this value is nonzero, the application should send the acknowledgment.
cfFormat
Specifies the format of the data. The format should be a standard or registered clipboard format. The following standard clipboard formats can be used:

CF_BITMAP
CF_DIB
CF_DIF
CF_ENHMETAFILE
CF_METAFILEPICT
CF_OEMTEXT
CF_PALETTE
CF_PENDATA
CF_RIFF
CF_SYLK
CF_TEXT
CF_TIFF
CF_WAVE
CF_UNICODETEXT

Value
Contains the data. The length and type of data depend on the cfFormat member.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Structures, DDEUP, WM_DDE_ACK, WM_DDE_ADVISE, WM_DDE_DATA, WM_DDE_POKE, WM_DDE_REQUEST


DDELN

The DDELN structure is obsolete. Win32-based applications should use the DDEADVISE structure.

typedef struct { // ddeln
    unsigned short unused:13,
        fRelease:1,
        fDeferUpd:1,
        fAckReq:1;
    short cfFormat;
} DDELN;

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Structures, DDEADVISE, WM_DDE_ADVISE, WM_DDE_UNADVISE


DDEPOKE

The DDEPOKE structure contains the data, and information about the data, sent as part of a WM_DDE_POKE message. This structure supersedes the DDEUP structure.

typedef struct { // ddepok
    unsigned short unused:13,
        fRelease:1,
        fReserved:2;
    short cfFormat;
    BYTE  Value[1];
} DDEPOKE;

Members

fRelease
Indicates whether the application receiving the WM_DDE_POKE message should free the data. If this value is nonzero, the application should free the data.
fReserved
Reserved; do not use.
cfFormat
Specifies the format of the data. The format should be a standard or registered clipboard format. The following standard clipboard formats can be used:

CF_BITMAP
CF_DIB
CF_DIF
CF_ENHMETAFILE
CF_METAFILEPICT
CF_OEMTEXT
CF_PALETTE
CF_PENDATA
CF_RIFF
CF_SYLK
CF_TEXT
CF_TIFF
CF_WAVE
CF_UNICODETEXT

Value
Contains the data. The length and type of data depend on the value of the cfFormat member.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Structures, DDEUP, WM_DDE_POKE


DDEUP

The DDEUP structure is obsolete. Win32-based applications should use the DDEDATA and DDEPOKE structures.

typedef struct { // ddeup
    unsigned short unused:12,
        fAck:1,
        fRelease:1,
        fReserved:1,
        fAckReq:1;
    short cfFormat;
    BYTE rgb[1];
} DDEUP;

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Structures, WM_DDE_DATA, WM_DDE_POKE


HSZPAIR

The HSZPAIR structure contains a DDE service name and topic name. A DDE server application can use this structure during an XTYP_WILDCONNECT transaction to enumerate the service-topic pairs that it supports.

typedef struct tagHSZPAIR {   // hp
    HSZ hszSvc;
    HSZ hszTopic;
} HSZPAIR;

Members

hszSvc
Handle to a service name.
hszTopic
Handle to a topic name.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Structures


Dynamic Data Exchange Messages

The following messages are used with DDE.

WM_DDE_ACK
WM_DDE_ADVISE
WM_DDE_DATA
WM_DDE_EXECUTE
WM_DDE_INITIATE
WM_DDE_POKE
WM_DDE_REQUEST
WM_DDE_TERMINATE
WM_DDE_UNADVISE

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Structures


WM_DDE_ACK

The WM_DDE_ACK message notifies a DDE application of the receipt and processing of a WM_DDE_POKE, WM_DDE_EXECUTE, WM_DDE_DATA, WM_DDE_ADVISE, WM_DDE_UNADVISE, or WM_DDE_INITIATE message, and in some cases, of a WM_DDE_REQUEST message.

WM_DDE_ACK
// Response to WM_DDE_INITIATE
wParam = (WPARAM) hwnd;          // handle of posting application
lParam = MAKELPARAM(aApp, aTopic) // application and topic atoms

// Response to WM_DDE_EXECUTE
wParam = (WPARAM) hwnd;         // handle of posting application
lParam = (LPARAM) lPackedVal;   // packed status flags and data handle

// Response to all other messages
wParam = (WPARAM) hwnd;         // handle of posting application
lParam = (LPARAM) lPackedVal;   // packed status flags and item

Parameters

When responding to WM_DDE_INITIATE:
hwnd
Value of wParam. Handle to the server window posting the message.
aApp
Value of the low-order word of lParam. Contains an atom that identifies the replying application.
aTopic
Value of the high-order word of lParam. Contains an atom that identifies the topic for which a conversation is being established.
When responding to WM_DDE_EXECUTE:
hwnd
Value of wParam. Handle to the server window posting the message.
lPackedVal
Value of lParam. The component parameters that are packed into lPackedVal are extracted by calling the UnpackDDElParam function. The low-order word is wStatus. The high-order word is the same hCommands that was received in the WM_DDE_EXECUTE message.
Parameter | Description
wStatus | Specifies a DDEACK structure containing a series of flags that indicate the status of the response.
hCommands | Handle to a global memory object that contains the command string.

When replying to all other messages:
hwnd
Value of wParam. Handle to the client or server window posting the message.
lPackedVal
Value of lParam. The component parameters that are packed into lPackedVal are extracted by calling the UnpackDDElParam function. The low-order word is wStatus. The high-order word is aItem.
Parameter | Description
wStatus | Specifies a DDEACK structure containing a series of flags that indicate the status of the response.
aItem | Contains a global atom that identifies the name of the data item for which the response is sent.

Remarks

Posting

Except in response to the WM_DDE_INITIATE message, the application posts the WM_DDE_ACK message by calling the PostMessage function, not by calling the SendMessage function. When responding to WM_DDE_INITIATE, the application sends the WM_DDE_ACK message by calling SendMessage. In this case, neither the application-name atom nor the topic-name atom should be NULL (even if the WM_DDE_INITIATE message specified NULL atoms).

When acknowledging any message with an accompanying aItem atom, the application posting WM_DDE_ACK can either reuse the aItem atom that accompanied the original message, or it can delete it and create a new one.

When acknowledging WM_DDE_EXECUTE, the application that posts WM_DDE_ACK should reuse the global memory object identified in the original WM_DDE_EXECUTE message.

All posted WM_DDE_ACK messages must create or reuse the lPackedVal parameter by calling the PackDDElParam function or the ReuseDDElParam function.

If an application has initiated the termination of a conversation by posting WM_DDE_TERMINATE and is awaiting confirmation, the waiting application should not acknowledge (positively or negatively) any subsequent messages sent by the other application. The waiting application should delete any atoms or shared memory objects received in these intervening messages. Memory objects should not be freed if the fRelease flag is set to FALSE in WM_DDE_POKE, and WM_DDE_DATA messages.

Receiving

The application that receives a WM_DDE_ACK message should delete all atoms accompanying the message. If the application receives a WM_DDE_ACK in response to a message with an accompanying hData object, and the object was sent with the fRelease flags set to FALSE, the application is responsible for deleteing the hData object.

If the application receives a negative WM_DDE_ACK message posted in reply to a WM_DDE_ADVISE message, the application should delete the global memory object posted with the original WM_DDE_ADVISE message (in hOptions). If the application receives a negative WM_DDE_ACK message posted in reply to a WM_DDE_DATA, WM_DDE_POKE, or WM_DDE_EXECUTE message, the application should delete the global memory object posted with the original WM_DDE_DATA, WM_DDE_POKE, or WM_DDE_EXECUTE message (in hCommands).

The application that receives a posted WM_DDE_ACK message must free the lPackedVal parameter by using the FreeDDElParam function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Messages, DDEACK, FreeDDElParam, PackDDElParam, PostMessage, ReuseDDElParam, SendMessage, UnpackDDElParam, WM_DDE_ADVISE, WM_DDE_DATA, WM_DDE_EXECUTE, WM_DDE_INITIATE, WM_DDE_POKE, WM_DDE_REQUEST, WM_DDE_TERMINATE, WM_DDE_UNADVISE


WM_DDE_ADVISE

A DDE client application posts the WM_DDE_ADVISE message to a DDE server application to request the server to supply an update for a data item whenever the item changes.

WM_DDE_ADVISE
wParam = (WPARAM) hwnd;        // handle of posting application
lParam = (LPARAM) lPackedVal;  // packed DDEADVISE and item atom

Parameters

hwnd
Value of wParam. Handle to the client window posting the message.
lPackedVal
Value of lParam. The component parameters packed into lPackedVal are extracted by calling the UnpackDDElParam function. The low-order word is hOptions. The high-order word is aItem.
Parameter | Description
hOptions | Handle to a global memory object containing a DDEADVISE structure that specifies how the data is to be sent.
aItem | Contains an atom that identifies the requested data item.

Remarks

If a client application supports more than one clipboard format for a single topic and item, it can post multiple WM_DDE_ADVISE messages for the topic and item, specifying a different clipboard format with each message. Note that a server can support multiple formats only for hot data links, not warm data links.

Posting

The client application posts the WM_DDE_ADVISE message by calling the PostMessage function, not the SendMessage function.

The client application allocates hOptions by calling the GlobalAlloc function with the GMEM_DDESHARE option. It allocates aItem by calling the GlobalAddAtom function.

The client application must create or reuse the WM_DDE_ADVISE lPackedVal parameter by calling the PackDDElParam function or the ReuseDDElParam function with hOptions supplied as the low-order word and aItem supplied as the high-order word.

If the receiving (server) application responds with a negative WM_DDE_ACK message, the posting (client) application must delete the hOptions object.

The fRelease flag is not used in WM_DDE_ADVISE messages, but their data-freeing behavior is similar to that of WM_DDE_DATA and WM_DDE_POKE messages where fRelease is TRUE.

Receiving

The server application posts the WM_DDE_ACK message to respond positively or negatively. When posting WM_DDE_ACK, the application can reuse the aItem atom or delete it and create a new one. If the WM_DDE_ACK message is positive, the application should delete the hOptions object; otherwise, the application should not delete the object.

The server must create or reuse the WM_DDE_ACK lPackedVal parameter by calling the PackDDElParam function or the ReuseDDElParam function with wStatus supplied as the low-order word and aItem supplied as the high-order word.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Messages, DDEADVISE, FreeDDElParam, GlobalAddAtom, GlobalAlloc, PackDDElParam, PostMessage, ReuseDDElParam, SendMessage, UnpackDDElParam, WM_DDE_ACK, WM_DDE_DATA, WM_DDE_POKE, WM_DDE_REQUEST


WM_DDE_DATA

A DDE server application posts a WM_DDE_DATA message to a DDE client application to pass a data item to the client or to notify the client of the availability of a data item.

WM_DDE_DATA
wParam = (WPARAM) hwnd;         // handle of posting application
lParam = (LPARAM) lPackedVal;   // packed DDEDATA and item atom

Parameters

hwnd
Value of wParam. Handle to the server window posting the message.
lPackedVal
Value of lParam. The component parameters that are packed into lPackedVal are extracted by calling the UnpackDDElParam function. The low-order word is hData or NULL. The high-order word is aItem.
Parameter | Description
hData | Handle to a global memory object containing a DDEDATA structure with the data and additional information. The handle should be set to NULL if the server is notifying the client that the data-item value has changed during a warm data link. A warm link is established by the client sending a WM_DDE_ADVISE message with the fDeferUpd bit set.
aItem | Contains an atom that identifies the data item for which the data or notification is sent.

Remarks

Posting

The server application posts the WM_DDE_DATA message by calling the PostMessage function, not the SendMessage function.

The server application allocates hData by calling the GlobalAlloc function with the GMEM_DDESHARE option. It allocates aItem by calling the GlobalAddAtom function.

The server must create or reuse the WM_DDE_DATA lPackedVal parameter by calling the PackDDElParam function or the ReuseDDElParam function with hData supplied as the low-order word and aItem supplied as the high-order word.

If the receiving (client) application responds with a negative WM_DDE_ACK message, the posting (server) application must delete the hData object; otherwise, the client must delete the hData object after extracting its contents by calling the UnpackDDElParam function.

If the server application sets the fRelease member of the DDEDATA structure to FALSE, the server is responsible for deleting hData upon receiving either a positive or negative acknowledgement.

The server application should not set both the fAckReq and fRelease members of the DDEDATA structure to FALSE. If both members are set to FALSE, it is impossible for the server to determine when to delete hData.

Receiving

If fAckReq is TRUE, the client application should post the WM_DDE_ACK message to respond positively or negatively. When posting WM_DDE_ACK, the client can either reuse the aItem atom, or it can delete it and create a new one.

The client must create or reuse the WM_DDE_ACK lPackedVal parameter by calling the PackDDElParam function or the ReuseDDElParam function with wStatus supplied as the low-order word and aItem supplied as the high-order word.

If fAckReq is FALSE, the client application should delete the aItem atom.

If the posting (server) application specified hData as NULL, the receiving (client) application can request the server to send the data by posting a WM_DDE_REQUEST message.

After processing a WM_DDE_DATA message in which hData is not NULL, the client should free hData, unless one of the following conditions is true:

  • The fRelease member is FALSE.
  • The fRelease member is TRUE, but the client application responds with a negative WM_DDE_ACK message.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Messages, DDEDATA, FreeDDElParam, GlobalAddAtom, GlobalAlloc, PackDDElParam, PostMessage, ReuseDDElParam, SendMessage, UnpackDDElParam, WM_DDE_ACK, WM_DDE_ADVISE, WM_DDE_POKE, WM_DDE_REQUEST


WM_DDE_EXECUTE

A DDE client application posts a WM_DDE_EXECUTE message to a DDE server application to send a string to the server to be processed as a series of commands. The server application is expected to post a WM_DDE_ACK message in response.

WM_DDE_EXECUTE
wParam = (WPARAM) hwnd;        // handle of posting application
lParam = (LPARAM) hCommands;   // handle to global object

Parameters

hwnd
Value of wParam. Handle to the client window posting the message.
hCommands
Value of lParam. Contains a global memory object that references an ANSI or Unicode command string, depending on the types of windows involved in the conversation.

Remarks

The command string is a null-terminated string consisting of one or more opcode strings enclosed in single brackets ([ ]).

Each opcode string has the following syntax, where the parameters list is optional:

opcode parameters

The opcode is any application-defined single token. It cannot include spaces, commas, parentheses, brackets, or quotation marks.

The parameters list can contain any application-defined value or values. Multiple parameters are separated by commas, and the entire parameter list is enclosed in parentheses. Parameters cannot include commas or parentheses except inside a quoted string. If a bracket or parenthesis character is to appear in a quoted string, it need not be doubled, as was the case under the old rules.

Following are some valid command strings:

[connect][download(query1,results.txt)][disconnect]
[query("sales per employee for each district")]
[open("sample.xlm")][run("r1c1")]
[quote_case("This is a "" character")]
[bracket_or_paren_case("()s or []s should be no problem.")]

Note that, under the old rules, parentheses and brackets had to be doubled, as follows:

[bracket_or_paren_case("(())s or [[]]s should be no problem.")]

Servers should be able to parse commands in either form.

Unicode execute strings should be used only when both the client and server window handles cause the IsWindowUnicode function to return TRUE.

Posting

The client application posts the WM_DDE_EXECUTE message by calling the PostMessage function, not the SendMessage function.

The client application allocates hCommands by calling the GlobalAlloc function with the GMEM_DDESHARE option.

When processing the WM_DDE_ACK message that the server posts in reply to a WM_DDE_EXECUTE message, the client application must delete the hCommands object sent back in the WM_DDE_ACK message.

Receiving

The server application posts the WM_DDE_ACK message to respond positively or negatively. The server should reuse the hCommands object.

Unless specified otherwise by a sub-protocol, the server should not post the WM_DDE_ACK message until all the actions specified by the execute command string are completed. The one exception to this rule is when the string causes the server to terminate the conversation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Messages, GlobalAlloc, IsWindowUnicode, PackDDElParam, PostMessage, ReuseDDElParam, SendMessage, UnpackDDElParam, WM_DDE_ACK


WM_DDE_INITIATE

A DDE client application sends a WM_DDE_INITIATE message to initiate a conversation with a server application responding to the specified application and topic names. Upon receiving this message, all server applications with names that match the specified application and that support the specified topic are expected to acknowledge it. (For more information, see the WM_DDE_ACK message.)

WM_DDE_INITIATE
wParam = (WPARAM) hwnd;             // handle of posting appl.
lParam = MAKELPARAM(aApp, aTopic);  // appl. and topic atoms

Parameters

hwnd
Value of wParam. Handle to the client window sending the message.
aApp
Value of the low-order word of lParam. Contains an atom that identifies the application with which a conversation is requested. The application name cannot contain slashes (/) or backslashes (\). These characters are reserved for network implementations. If aApp is NULL, a conversation with all applications is requested.
aTopic
Value of the high-order word of lParam. Contains an atom that identifies the topic for which a conversation is requested. If the topic is NULL, conversations for all available topics are requested.

Remarks

If aApp is NULL, any server application can respond. If aTopic is NULL, any topic is valid. Upon receiving a WM_DDE_INITIATE request with the aTopic parameter set to NULL, a server must send a WM_DDE_ACK message for each of the topics it supports.

Sending

The client application sends WM_DDE_INITIATE by calling the SendMessage function, not the PostMessage function. The client broadcasts the message to all top-level windows by setting the first parameter of SendMessage to –1.

If the client application has already obtained the window handle of the desired server, it can send WM_DDE_INITIATE directly to the server window by passing the server's window handle as the first parameter of SendMessage.

The client application allocates aApp and aTopic by calling GlobalAddAtom.

When SendMessage returns, the client application must delete the aApp and aTopic atoms.

Receiving

To complete the initiation of a conversation, the server application must respond with one or more WM_DDE_ACK messages, where each message is for a separate topic. When sending WM_DDE_ACK message, the server should create new aApp and aTopic atoms; it should not reuse the atoms sent with WM_DDE_INITIATE.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Messages, GlobalAddAtom, GlobalAlloc, PostMessage, SendMessage, WM_DDE_ACK


WM_DDE_POKE

A DDE client application posts a WM_DDE_POKE message to a DDE server application. A client uses this message to request the server to accept an unsolicited data item. The server is expected to reply with a WM_DDE_ACK message indicating whether it accepted the data item.

WM_DDE_POKE
wParam = (WPARAM) hwnd;        // handle of posting application
lParam = (LPARAM) lPackedVal;  // packed DDEPOKE and item atom

Parameters

hwnd
Value of wParam. Handle to the client window posting the message.
lPackedVal
Value of lParam. The component parameters that are packed into lPackedVal are extracted by calling the UnpackDDElParam function. The low-order word is hData. The high-order word is aItem.
Parameter | Description
hData | Handle to a global memory object containing a DDEPOKE structure with the data and additional information.
aItem | Contains a global atom that identifies the data item for which the data or notification is being sent.

Remarks

Posting

The client application posts the WM_DDE_POKE message by using the PostMessage function.

The client application must allocate memory for the hData object by using the GlobalAlloc function with the GMEM_DDESHARE option. The client application must delete the hData object if either of the following conditions is true:

  • The server application responds with a negative WM_DDE_ACK message.
  • The fRelease member is FALSE, but the server application responds with either a positive or negative WM_DDE_ACK.

The client application must create the aItem atom by using the GlobalAddAtom function.

The client application must create or reuse the WM_DDE_POKE lPackedVal parameter by calling the PackDDElParam function or the ReuseDDElParam function with hData supplied as the low-order word and aItem supplied as the high-order word.

Receiving

The server application should post the WM_DDE_ACK message to respond positively or negatively. When posting WM_DDE_ACK, the server can either reuse the aItem atom, or it can delete it and create a new one.

The server must create or reuse the WM_DDE_ACK lPackedVal parameter by calling the PackDDElParam function or the ReuseDDElParam function with wStatus supplied as the low-order word and aItem supplied as the high-order word.

To free the hData object, the server should call the GlobalFree function. Also, if the data format is either CF_DSPMETAFILEPICT or CF_METAFILEPICT, the server must also call DeleteMetaFile with the embedded metafile handle. These two formats have an extra level of indirection; that is, an application must lock hData to get a pointer to a handle, then lock that handle to get a pointer to a METAFILEPICT structure, and finally call DeleteMetaFile with the handle from the hMF member of the METAFILEPICT structure.

To free the lPackedVal object, the server should call the FreeDDElParam function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Messages, DDEPOKE, DeleteMetaFile, FreeDDElParam, GlobalAddAtom, GlobalAlloc, GlobalFree, METAFILEPICT, PackDDElParam, PostMessage, ReuseDDElParam, SendMessage, UnpackDDElParam, WM_DDE_ACK


WM_DDE_REQUEST

A DDE client application posts a WM_DDE_REQUEST message to a DDE server application to request the value of a data item.

WM_DDE_REQUEST
wParam = (WPARAM) hwnd;        // handle of posting application
lParam = (LPARAM) lParam;      // holds cfFormat and aItem

Parameters

hwnd
Value of wParam. Handle to the client window sending the message.
lParam
Holds the cfFormat and aItem parameters.
Parameter | Description
cfFormat | This is the LOWORD of lParam. Specifies a standard or registered clipboard format.
aItem | This is the HIWORD of lParam. Contains an atom that identifies the data item requested from the server.

Remarks

Posting

The client application posts the WM_DDE_REQUEST message by calling the PostMessage function, not the SendMessage function.

The client application allocates aItem by calling the GlobalAddAtom function.

Receiving

If the receiving (server) application can satisfy the request, it responds with a WM_DDE_DATA message containing the requested data. Otherwise, it responds with a negative WM_DDE_ACK message.

When responding with either a WM_DDE_DATA or WM_DDE_ACK message, the server application can either reuse the aItem atom or it can delete the atom and create a new one.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Messages, GlobalAddAtom, PackDDElParam, PostMessage, ReuseDDElParam, SendMessage, UnpackDDElParam, WM_DDE_ACK, WM_DDE_DATA


WM_DDE_TERMINATE

A DDE application (client or server) posts a WM_DDE_TERMINATE message to terminate a conversation.

WM_DDE_TERMINATE
wParam = (WPARAM) hwnd; // handle of posting window
lParam = 0;             // not used, must be zero

Parameters

hwnd
Value of wParam. Handle to the client or server window posting the message.

Remarks

Posting

The client or server application posts the WM_DDE_TERMINATE message by calling the PostMessage function, not the SendMessage function.

While waiting for confirmation of the termination, the posting application should not post any other messages to the receiving application. If the sending application receives messages (other than WM_DDE_TERMINATE) from the receiving application, it should delete any atoms or shared memory objects accompanying the messages, except hData objects associated with WM_DDE_POKE or WM_DDE_DATA messages that do not have the fRelease flag set.

Receiving

The client or server application should respond by posting a WM_DDE_TERMINATE message.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Messages, PostMessage, SendMessage, WM_DDE_DATA, WM_DDE_POKE


WM_DDE_UNADVISE

A DDE client application posts a WM_DDE_UNADVISE message to inform a DDE server application that the specified item or a particular clipboard format for the item should no longer be updated. This terminates the warm or hot data link for the specified item.

WM_DDE_UNADVISE
wParam = (WPARAM) hwnd;        // handle of posting application
lParam = (LPARAM) lParam;      // format and item atom

Parameters

hwnd
Value of wParam. Handle to the client window sending the message.
lParam
Holds the cfFormat and aItem parameters.
Parameter | Description
cfFormat | This is the LOWORD of lParam. Specifies the clipboard format of the item for which the update request is being retracted. If cfFormat is NULL, all active WM_DDE_ADVISE conversations for the item are to be terminated.
aItem | This is the HIWORD of lParam. Contains a global atom that identifies the item for which the update request is being retracted. When aItem is NULL, all active WM_DDE_ADVISE links associated with the conversation are to be terminated.

Remarks

Posting

The client application posts the WM_DDE_UNADVISE message by calling the PostMessage function, not the SendMessage function.

The client application allocates aItem by calling the GlobalAddAtom function.

Receiving

The server application posts the WM_DDE_ACK message to respond positively or negatively. When posting WM_DDE_ACK, the server can either reuse the aItem atom, or it can delete the atom and create a new one.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in dde.h.

See Also

Dynamic Data Exchange Overview, Dynamic Data Exchange Messages, GlobalAddAtom, PackDDElParam, PostMessage, ReuseDDElParam, SendMessage, UnpackDDElParam, WM_DDE_ACK, WM_DDE_ADVISE


Dynamic Data Exchange Management Library

Dynamic data exchange (DDE) is a form of interprocess communication that uses shared memory to exchange data between applications. Applications can use DDE for one-time data transfers and for ongoing exchanges and updating of data.


About the DDEML

DDE differs from the clipboard data-transfer mechanism. One difference is that the clipboard is almost always used as a one-time response to a specific action by the user — such as clicking Paste from a menu. Although DDE may also be initiated by a user, it typically continues without the user's further involvement.

The dynamic data exchange management library (DDEML) provides an interface that simplifies the task of adding DDE capability to a Win32-based application. Instead of sending, posting, and processing DDE messages directly, an application uses the functions provided by the DDEML to manage DDE conversations. A DDE conversation is the interaction between client and server applications. The DDEML also provides a means for managing the strings and data shared among DDE applications. Instead of using atoms and pointers to shared memory objects, DDE applications create and exchange string handles, which identify strings, and data handles, which identify DDE objects. The DDEML provides a function (DdeNameService) that enables a server application to register the service names it supports. The service names are then broadcast to other applications in the system, which use the names to connect to the server. The DDEML also ensures compatibility among DDE applications by requiring them to implement the DDE protocol in a consistent manner.

Existing applications using the message-based DDE protocol are fully compatible with those that use the DDEML; that is, an application using message-based DDE can establish conversations and perform transactions with applications using the DDEML. Instead of using DDE messages in your new application, take advantage of the DDEML and the many improvements it offers.

To use the DDEML, you must include the DDEML.H header file in your source files, link with the USER32.LIB file, and ensure that the DDEML.DLL file resides in the system's path.


Basic Concepts

The concepts in this section are key to understanding DDE and the DDEML.


Client and Server Interaction

DDE always occurs between a client application and a server application. The DDE client application initiates the exchange by establishing a conversation with the server to send transactions to the server. A transaction is a request for data or services. The DDE server application responds to transactions by providing data or services to the client. For example, a graphics application might contain a bar graph representing a corporation's quarterly profits, but the data for the bar graph might be contained in a spreadsheet application. To obtain the latest profit figures, the graphics application (the client) could establish a conversation with the spreadsheet application (the server). The graphics application could then send a transaction to the spreadsheet application, requesting the latest profit figures.

A server can have many clients at the same time, and a client can request data from multiple servers. An application can also be both a client and a server. Either the client or the server can terminate the conversation at any time.


Transactions and the DDE Callback Function

The DDEML notifies an application about DDE activity that affects the application by sending transactions to the application's DDE callback function. A DDE transaction is similar to a message — it is a named constant accompanied by other parameters that contain additional information about the transaction.

The DDEML passes a transaction to an application-defined DDE callback function that carries out an action appropriate to the type of transaction. For example, when a client application attempts to establish a conversation with a server application, the client calls the DdeConnect function. This function causes the DDEML to send an XTYP_CONNECT transaction to the server's DDE callback function. The callback function can allow the conversation by returning TRUE to the DDEML, or it can deny the conversation by returning FALSE. For a detailed discussion of transactions, see Transaction Management.


Service Names, Topic Names, and Item Names

A DDE server uses a three-level hierarchy — service name (called "application name" in previous DDE documentation), topic name, and item name — to uniquely identify a unit of data the server can exchange during a conversation.

A service name is a string a server application responds to when a client attempts to establish a conversation with the server. A client must specify this service name to establish a conversation with the server. Although a server can respond to many service names, most servers respond to only one name.

A topic name is a string that identifies a logical data context. For servers that operate on file-based documents, topic names are typically filenames; for other servers, they are other application-specific strings. A client must specify a topic name along with a server's service name when it attempts to establish a conversation with a server.

An item name is a string that identifies a unit of data a server can pass to a client during a transaction. For example, an item name might identify an integer, a string, several paragraphs of text, or a bitmap.

The service, topic, and item names enable the client to establish a conversation with a server and to receive data from the server.


System Topic

The System topic provides a context for information of general interest to any DDE client. It is recommended that server applications support the System topic at all times. The System topic is defined in the DDEML.H header file as SZDDESYS_TOPIC.

To determine which servers are present and the kinds of information they can provide, a client application can request a conversation on the System topic upon starting, setting the device name to NULL. Such wildcard conversations are costly in terms of system performance, so they should be kept to a minimum. For more information about initiating DDE conversations, see Conversation Management.

A server must support the following item names within the System topic and any other item names that are useful to a client.

Item | Description
SZDDE_ITEM_ITEMLIST | A list of the items supported under a non-System topic. (This list may vary from moment to moment and from topic to topic.)
SZDDESYS_ITEM_FORMATS | A tab-delimited list of strings representing all clipboard formats potentially supported by the service application. Strings that represent predefined clipboard formats are equivalent to the CF_ values with the "CF_" prefix removed. For example, the CF_TEXT format is represented by the string "TEXT". These strings must be uppercase to further identify them as predefined formats. The list of formats must appear in the order of most rich in content to least rich in content.
 | For more information about clipboard formats and rendering data, see Clipboard.
SZDDESYS_ITEM_HELP | User-readable information of general interest. This item must contain, at a minimum, information on how to use the server application's DDE features. This information may include, but is not limited to, how to specify items within topics, what execute strings the server can perform, what poke transactions are allowed, and how to find help on other System topic items.
SZDDESYS_ITEM_RTNMSG | Supporting detail for the most recently used WM_DDE_ACK message. This item is useful when more than 8 bits of application-specific return data are required.
SZDDESYS_ITEM_STATUS | An indication of the current status of the server. Typically, this item supports only the CF_TEXT format and contains the Ready or Busy string.
SZDDESYS_ITEM_SYSITEMS | A list of the items supported under the System topic by this server.
SZDDESYS_ITEM_TOPICS | A list of the topics supported by the server at the current time. (This list may vary from moment to moment.)

These item names are values defined in the DDEML.H header file. To obtain string handles for these strings, an application must use the DDEML string-management functions, just as it would for any other string in a DDEML application. For more information about managing strings, see String Management.


DDEML and Threads

The DdeInitialize function registers an application with the DDEML, creating a DDEML instance. A DDEML instance is thread-based, associated with the thread that called DdeInitialize.

All DDEML function calls for objects belonging to a DDEML instance must be made from the same thread that called DdeInitialize to create the instance. If you call a DDEML function from a different thread, the function will fail. You cannot access a DDEML conversation from a thread other than the one that allocated the conversation.


Initialization

Before calling any other DDEML function, an application must call the DdeInitialize function. DdeInitialize obtains an instance identifier for the application, registers the application's DDE callback function with the DDEML, and specifies the transaction filter flags for the callback function.

Each instance of an application or a dynamic-link library (DLL) must pass its instance identifier as the idInst parameter to any other DDEML function that requires it. The purpose of multiple DDEML instances is to support DLLs that must use the DDEML at the same time an application is using it. An application must not use more than one instance of the DDEML.

Transaction filters optimize system performance by preventing the DDEML from passing unwanted transactions to the application's DDE callback function. An application sets the transaction filters in the DdeInitialize ufCmd parameter. An application must specify a transaction filter flag for each type of transaction that it does not process in its callback function. An application can change its transaction filters with a subsequent call to DdeInitialize. For more information about transactions, see Transaction Management.

The following example shows how to initialize an application to use the DDEML.

DWORD idInst = 0;
HINSTANCE hinst;

DdeInitialize(&idInst,         // receives instance identifier
    (PFNCALLBACK) DdeCallback, // address of callback function
    CBF_FAIL_EXECUTES |        // filter XTYPE_EXECUTE
    CBF_SKIP_ALLNOTIFICATIONS, // filter notifications
    0);

An application must call the DdeUninitialize function when it is no longer going to use the DDEML. This function terminates any conversations currently open for the application and frees the DDEML resources the system allocated for the application.


Callback Function

An application that uses the DDEML must provide a callback function that processes the DDE events affecting the application. The DDEML notifies an application of such events by sending transactions to the application's DDE callback function. The transactions a callback function receives depend on which callback filter flags the application specified in DdeInitialize and whether the application is a client, a server, or both. For more information, please see DdeCallback.

The following example shows the general structure of a callback function for a typical client application.

HDDEDATA CALLBACK DdeCallback(uType, uFmt, hconv, hsz1,
    hsz2, hdata, dwData1, dwData2)
UINT uType;       // transaction type
UINT uFmt;        // clipboard data format
HCONV hconv;      // handle of conversation
HSZ hsz1;         // handle of string
HSZ hsz2;         // handle of string
HDDEDATA hdata;   // handle of global memory object
DWORD dwData1;    // transaction-specific data
DWORD dwData2;    // transaction-specific data
{
    switch (uType)
    {
        case XTYP_REGISTER:
        case XTYP_UNREGISTER:
            .
            .
            .
            return (HDDEDATA) NULL;

        case XTYP_ADVDATA:
            .
            .
            .
            return (HDDEDATA) DDE_FACK;

        case XTYP_XACT_COMPLETE:

            //

            return (HDDEDATA) NULL;

        case XTYP_DISCONNECT:

            //

            return (HDDEDATA) NULL;

        default:
            return (HDDEDATA) NULL;
    }
}

The uType parameter specifies the transaction type sent to the callback function by the DDEML. The values of the remaining parameters depend on the transaction type. The transaction types and the events that generate them are described in the following topics. For detailed information about each transaction type, see Transaction Management.


String Management

To carry out a DDE task, many DDEML functions require access to strings. For example, a client must specify a service name and a topic name when it calls the DdeConnect function to request a conversation with a server. An application specifies a string by passing a string handle (HSZ) rather than a pointer in a DDEML function. A string handle is a DWORD value, assigned by the system, that identifies a string.

An application can obtain a string handle for a particular string by calling the DdeCreateStringHandle function. This function registers the string with the system and returns a string handle to the application. The application can pass the handle to DDEML functions that must access the string. The following example obtains string handles for the System topic string and the service name string.

HSZ hszServName;
HSZ hszSysTopic;

hszServName = DdeCreateStringHandle(
    idInst,         // instance identifier
    "MyServer",     // string to register
    CP_WINANSI);    // Windows ANSI code page

hszSysTopic = DdeCreateStringHandle(
    idInst,         // instance identifier
    SZDDESYS_TOPIC, // System topic
    CP_WINANSI);    // Windows ANSI code page

The idInst parameter in the preceding example specifies the instance identifier obtained by the DdeInitialize function.

An application's DDE callback function receives one or more string handles during most DDE transactions. For example, a server receives two string handles during the XTYP_REQUEST transaction: one identifies a string specifying a topic name, and the other identifies a string specifying an item name. An application can obtain the length of the string that corresponds to a string handle and copy the string to an application-defined buffer by calling the DdeQueryString function, as shown in the following example.

DWORD idInst;
DWORD cb;
HSZ hszServ;
PSTR pszServName;

cb = DdeQueryString(idInst, hszServ, (LPSTR) NULL, 0,
    CP_WINANSI) + 1;
pszServName = (PSTR) LocalAlloc(LPTR, (UINT) cb);
DdeQueryString(idInst, hszServ, pszServName, cb, CP_WINANSI);

An instance-specific string handle cannot be mapped from string handle to string and back to string handle. For instance, although DdeQueryString creates a string from a string handle and then DdeCreateStringHandle creates a string handle from that string, the two handles are not the same, as shown in the following example.

DWORD idInst;
DWORD cb;
HSZ hszInst, hszNew;
PSZ pszInst;

DdeQueryString(idInst, hszInst, pszInst, cb, CP_WINANSI);
hszNew = DdeCreateStringHandle(idInst, pszInst, CP_WINANSI);

// hszNew != hszInst !

To compare the values of two string handles, use the DdeCmpStringHandles function.

A string handle passed to an application's DDE callback function becomes invalid when the callback function returns. An application can save a string handle for use after the callback function returns by using the DdeKeepStringHandle function.

When an application calls DdeCreateStringHandle, the system enters the specified string into a string table and generates a handle that it uses to access the string. The system also maintains a usage count for each string in the string table.

When an application calls DdeCreateStringHandle and specifies a string that already exists in the table, the system increments the usage count rather than adding another occurrence of the string. (An application can also increment the usage count by using DdeKeepStringHandle.) When an application calls the DdeFreeStringHandle function, the system decrements the usage count.

A string is removed from the table when its usage count equals zero. Because more than one application can obtain the handle of a particular string, an application must not free a string handle more times than it has created or retained the handle. Otherwise, the application can cause the string to be removed from the table, denying other applications access to the string.

The DDEML string-management functions are based on the atom manager and are subject to the same size restrictions as are atoms.


Name Service

The DDEML makes it possible for a server application to register the service names that it supports and to prevent the DDEML from sending XTYP_CONNECT transactions for unsupported service names to the server's DDE callback function. The remaining topics in this section describe the name service.


Service Name Registration

By registering its service names with the DDEML, a server informs other DDE applications in the system that a new server is available. A server registers a service name by calling the DdeNameService function and specifying a string handle that identifies the name. In response, the DDEML sends an XTYP_REGISTER transaction to the callback function of each DDEML application in the system (except those that specified the CBF_SKIP_REGISTRATIONS filter flag in the DdeInitialize function). The XTYP_REGISTER transaction passes two string handles to a callback function: the first identifies the string specifying the base service name, and the second identifies the string specifying the instance-specific service. A client typically uses the base service name in a list of available servers, so the user can select a server from the list. The client uses the instance-specific service name to establish a conversation with a specific instance of a server application, if more than one instance is running.

A server can use DdeNameService to unregister a service name. This function causes the DDEML to send XTYP_UNREGISTER transactions to the other DDE applications in the system, informing them that they can no longer use the name to establish conversations.

A server must call DdeNameService to register its service names soon after calling DdeInitialize. A server must unregister its service names by using DdeNameService just before calling the DdeUninitialize function.


Service Name Filter

In addition to registering service names, DdeNameService enables a server to turn its service name filter on or off. When a server turns off its service name filter, the DDEML sends the XTYP_CONNECT transaction to the server's DDE callback function whenever any client calls the DdeConnect function, regardless of the service name specified in the function. When a server turns on its service name filter, the DDEML sends the XTYP_CONNECT transaction to the server only when DdeConnect specifies a service name the server has specified in a call to DdeNameService.

By default, the service name filter is on when an application calls DdeInitialize. This default prevents the DDEML from sending the XTYP_CONNECT transaction to a server before the server has created the string handles it needs. A server can turn off its service name filter by specifying the DNS_FILTEROFF flag in a call to DdeNameService. The DNS_FILTERON flag turns on the filter.


Conversation Management

A conversation between a client and a server is always established at the request of the client. When a conversation is established, each partner receives a handle that identifies the conversation. The partners use this handle in other DDEML functions to send transactions and manage the conversation. A client can request a conversation with a single server, or it can request multiple conversations with one or more servers.

The remaining topics in this section describe how an application establishes new conversations and gets information about existing conversations.


Single Conversations

A client application requests a single conversation with a server by calling the DdeConnect function and specifying string handles that identify the strings containing the service name of the server application and the topic name for the conversation. The DDEML responds by sending the XTYP_CONNECT transaction to the DDE callback function of each server application that either has registered a service name that matches the one specified in DdeConnect or has turned service name filtering off by calling DdeNameService. A server can also filter XTYP_CONNECT transactions by specifying the CBF_FAIL_CONNECTIONS filter flag in the DdeInitialize function. During the XTYP_CONNECT transaction, the DDEML passes the service name and the topic name to the server. The server must examine the names and return TRUE if it supports the service name and topic name pair or FALSE if it does not.

If no server responds positively to the client's request to connect, the client receives NULL from DdeConnect and no conversation is established. If a server returns TRUE, a conversation is established and the client receives a conversation handle — a doubleword value that identifies the conversation. The client uses the handle in subsequent DDEML calls to obtain data from the server. The server receives the XTYP_CONNECT_CONFIRM transaction (unless the server specified the CBF_SKIP_CONNECT_CONFIRMS filter flag). This transaction passes the conversation handle to the server.

The following example requests a conversation on the System topic with a server that recognizes the service name MyServer. The hszServName and hszSysTopic parameters are previously created string handles.

HCONV hConv;         // conversation handle
HWND hwndParent;     // parent window handle
HSZ hszServName;     // service name string handle
HSZ hszSysTopic;     // System topic string handle

hConv = DdeConnect(
    idInst,               // instance identifier
    hszServName,          // service name string handle
    hszSysTopic,          // System topic string handle
    (PCONVCONTEXT) NULL); // use default context

if (hConv == NULL)
{
    MessageBox(hwndParent, "MyServer is unavailable.",
        (LPSTR) NULL, MB_OK);
    return FALSE;
}

In the preceding example, DdeConnect causes the DDE callback function of the MyServer application to receive an XTYP_CONNECT transaction.

In the following example, the server responds to the XTYP_CONNECT transaction by comparing the topic name string handle the DDEML passed to the server with each element in the array of topic name string handles the server supports. If the server finds a match, it establishes the conversation.

#define CTOPICS 5

HSZ hsz1;                  // string handle passed by DDEML
HSZ ahszTopics[CTOPICS];   // array of supported topics
int i;                     // loop counter

// Use a switch statement to examine transaction types.

// Here is the connect case.

    case XTYP_CONNECT:
        for (i = 0; i < CTOPICS; i++)
        {
            if (hsz1 == ahszTopics[i])
                return TRUE;   // establish a conversation
        }

        return FALSE; // Topic not supported; deny conversation.

// Process other transaction types.

If the server returns TRUE in response to the XTYP_CONNECT transaction, the DDEML sends an XTYP_CONNECT_CONFIRM transaction to the server's DDE callback function. The server can obtain the handle for the conversation by processing this transaction.

A client can establish a wildcard conversation by specifying NULL for the service name string handle, the topic name string handle, or both in a call to DdeConnect. If at least one of the string handles is NULL, the DDEML sends the XTYP_WILDCONNECT transaction to the callback functions of all DDE applications (except those that filter the XTYP_WILDCONNECT transaction). Each server application should respond by returning a data handle that identifies a null-terminated array of HSZPAIR structures. If the server application has not called DdeNameService to register its service names and if filtering is on, the server does not receive XTYP_WILDCONNECT transactions. For more information about data handles, see Data Management.

The array must contain one structure for each service name and topic name pair that matches the pair specified by the client. The DDEML selects one of the pairs to establish a conversation and returns to the client a handle that identifies the conversation. The DDEML sends the XTYP_CONNECT_CONFIRM transaction to the server (unless the server filters this transaction). The following example shows a typical server response to the XTYP_WILDCONNECT transaction.

#define CTOPICS 2

UINT uType;
HSZPAIR ahszp[(CTOPICS + 1)];
HSZ ahszTopicList[CTOPICS];
HSZ hszServ, hszTopic;
WORD i, j;

if (uType == XTYP_WILDCONNECT)
{
    // Scan the topic list and create an array of HSZPAIR structures.

    j = 0;
    for (i = 0; i < CTOPICS; i++)
    {
        if (hszTopic == (HSZ) NULL ||
                hszTopic == ahszTopicList[i])
        {
            ahszp[j].hszSvc = hszServ;
            ahszp[j++].hszTopic = ahszTopicList[i];
        }
    }

    // End the list with an HSZPAIR structure that contains NULL
    // string handles as its members.

    ahszp[j].hszSvc = NULL;
    ahszp[j++].hszTopic = NULL;

    // Return a handle to a global memory object containing the
    // HSZPAIR structures.

    return DdeCreateDataHandle(
        idInst,          // instance identifier
        (LPBYTE) &ahszp, // points to HSZPAIR array
        sizeof(HSZ) * j, // length of the array
        0,               // start at the beginning
        (HSZ) NULL,      // no item name string
        0,               // return the same format
        0);              // let the system own it
}

Either the client or the server can terminate a conversation at any time by calling the DdeDisconnect function. This function causes the callback function of the partner in the conversation to receive the XTYP_DISCONNECT transaction (unless the partner specified the CBF_SKIP_DISCONNECTS filter flag). Typically, an application responds to the XTYP_DISCONNECT transaction by using the DdeQueryConvInfo function to obtain information about the conversation that terminated. After the callback function returns from processing the XTYP_DISCONNECT transaction, the conversation handle is no longer valid.

A client application that receives an XTYP_DISCONNECT transaction in its DDE callback function can attempt to reestablish the conversation by calling the DdeReconnect function. The client must call DdeReconnect from within its DDE callback function.


Multiple Conversations

A client application can use the DdeConnectList function to determine whether any servers of interest are available in the system. A client specifies a service name and topic name when it calls DdeConnectList, causing the DDEML to broadcast the XTYP_WILDCONNECT transaction to the DDE callback functions of all servers that match the service name (except those that filter the transaction). A server's callback function should return a data handle that identifies a null-terminated array of HSZPAIR structures. The array should contain one structure for each service name and topic name pair that matches the pair specified by the client. The DDEML establishes a conversation for each HSZPAIR structure filled by the server and returns a conversation list handle to the client. The server receives the conversation handle by way of the XTYP_CONNECT_CONFIRM transaction (unless the server filters this transaction).

A client can specify NULL for the service name, topic name, or both when it calls DdeConnectList. If the service name is NULL, all servers in the system that support the specified topic name respond. A conversation is established with each responding server, including multiple instances of the same server. If the topic name is NULL, a conversation is established on each topic recognized by each server that matches the service name.

A client can use the DdeQueryNextServer and DdeQueryConvInfo functions to identify the servers that respond to DdeConnectList. DdeQueryNextServer returns the next conversation handle in a conversation list, and DdeQueryConvInfo fills a CONVINFO structure with information about the conversation. The client can keep the conversation handles that it needs and discard the rest from the conversation list.

The following example uses DdeConnectList to establish conversations with all servers that support the System topic and then uses the DdeQueryNextServer and DdeQueryConvInfo functions to obtain the servers' service name string handles and store them in a buffer.

HCONVLIST hconvList; // conversation list
DWORD idInst;        // instance identifier
HSZ hszSystem;       // System topic
HCONV hconv = NULL;  // conversation handle
CONVINFO ci;         // holds conversation data
UINT cConv = 0;      // count of conv. handles
HSZ *pHsz, *aHsz;    // point to string handles

// Connect to all servers that support the System topic.

hconvList = DdeConnectList(idInst, NULL, hszSystem, NULL, NULL);

// Count the number of handles in the conversation list.

while ((hconv = DdeQueryNextServer(hconvList, hconv)) != NULL)
    cConv++;

// Allocate a buffer for the string handles.

hconv = NULL;
aHsz = (HSZ *) LocalAlloc(LMEM_FIXED, cConv * sizeof(HSZ));

// Copy the string handles to the buffer.

pHsz = aHsz;
while ((hconv = DdeQueryNextServer(hconvList, hconv)) != NULL)
{
    DdeQueryConvInfo(hconv, QID_SYNC, (PCONVINFO) &ci);
    DdeKeepStringHandle(idInst, ci.hszSvcPartner);
    *pHsz++ = ci.hszSvcPartner;
}

// Use the handles; converse with the servers.

// Free the memory and terminate the conversations.

LocalFree((HANDLE) aHsz);
DdeDisconnectList(hconvList);

An application can terminate an individual conversation in a conversation list by calling the DdeDisconnect function. An application can terminate all conversations in a conversation list by calling the DdeDisconnectList function. Both functions cause the DDEML to send XTYP_DISCONNECT transactions to each partner's DDE callback function. DdeDisconnectList sends an XTYP_DISCONNECT transaction for each conversation handle in the list.

A client can retrieve a list of the conversation handles in a conversation list by passing an existing conversation list handle to DdeConnectList. The enumeration process removes the handles of terminated conversations from the list, and nonduplicate conversations that fit the specified service name and topic name are added.

If DdeConnectList specifies an existing conversation list handle, the function creates a new conversation list that contains the handles of any new conversations and the handles from the existing list.

If duplicate conversations exist, DdeConnectList attempts to prevent duplicate conversation handles in the conversation list. A duplicate conversation is a second conversation with the same server on the same service name and topic name. Two such conversations would have different handles, yet they would identify the same conversation.


Data Management

Because DDE uses memory objects to pass data from one application to another, the DDEML provides a set of functions that DDE applications can use to create and manage DDE objects.

All transactions that involve the exchange of data require the application supplying the data to create a local buffer containing the data and then to call the DdeCreateDataHandle function. This function allocates a DDE object, copies the data from the buffer to the object, and returns a data handle. A data handle is a doubleword value that the DDEML uses to provide access to data in the DDE object. To share the data in a DDE object, an application passes the data handle to the DDEML, and the DDEML passes the handle to the DDE callback function of the application that is receiving the data transaction.

The following example shows how to create a DDE object and obtain a handle of the object. During the XTYP_ADVREQ transaction, the callback function converts the current time to an ASCII string, copies the string to a local buffer, and then creates a DDE object that contains the string. The callback function returns the handle of the DDE object (HDDEDATA) to the DDEML, which passes the handle to the client application.

typedef struct tagTIME
{
    INT     hour;   // 0 - 11 hours for analog clock
    INT     hour12; // 12-hour format
    INT     hour24; // 24-hour format
    INT     minute;
    INT     second;
    INT     ampm;   // 0 - AM , 1 - PM
} TIME;

HDDEDATA EXPENTRY DdeCallback(uType, uFmt, hconv, hsz1, hsz2,
    hdata, dwData1, dwData2)
UINT uType;
UINT uFmt;
HCONV hconv;
HSZ hsz1;
HSZ hsz2;
HDDEDATA hdata;
DWORD dwData1;
DWORD dwData2;
{

    CHAR szBuf[32];

    switch (uType)
    {
    case XTYP_ADVREQ:
        if ((hsz1 == hszTime && hsz2 == hszNow) &&
                (uFmt == CF_TEXT))
        {
            // Copy the formatted string to a buffer.

            itoa(tmTime.hour, szBuf, 10);
            lstrcat(szBuf, ":");
            if (tmTime.minute < 10)
                lstrcat(szBuf, "0");
            itoa(tmTime.minute, &szBuf[lstrlen(szBuf)], 10);
            lstrcat(szBuf, ":");
            if (tmTime.second < 10)
                strcat(szBuf, "0");
            itoa(tmTime.second, &szBuf[lstrlen(szBuf)], 10);
            szBuf[lstrlen(szBuf)] = '\0';

            // Create a global object and return its data handle.

            return (DdeCreateDataHandle(
                idInst,
                (LPBYTE) szBuf,     // instance identifier
                lstrlen(szBuf) + 1, // source buffer length
                0,                  // offset from beginning
                hszNow,             // item name string
                CF_TEXT,            // clipboard format
                0));                // no creation flags
        } else return (HDDEDATA) NULL;

    // Process other transactions.
    }
}

The receiving application obtains a pointer to the DDE object by passing the data handle to the DdeAccessData function. The pointer returned by DdeAccessData provides read-only access. The application should use the pointer to review the data and then call the DdeUnaccessData function to invalidate the pointer. The application can copy the data to a local buffer by using the DdeGetData function.

The following example obtains a pointer to the DDE object identified by the hData parameter, copies the contents to a local buffer, and then invalidates the pointer.

HDDEDATA hdata;
LPBYTE lpszAdviseData;
DWORD cbDataLen;
DWORD i;
char szData[32];

//

case XTYP_ADVDATA:
    lpszAdviseData = DdeAccessData(hdata, &cbDataLen);
    for (i = 0; i < cbDataLen; i++)
        szData[i] = *lpszAdviseData++;
    DdeUnaccessData(hdata);
    return (HDDEDATA) TRUE;

//

Usually, when an application that created a data handle passes that handle to the DDEML, the handle becomes invalid in the creating application. This situation is not a problem if the application must share data with only a single application. If an application must share the same data with multiple applications, however, the creating application should specify the HDATA_APPOWNED flag in DdeCreateDataHandle. Doing so gives ownership of the DDE object to the creating application and prevents the DDEML from invalidating the data handle. The application can then pass the data handle any number of times after calling DdeCreateDataHandle only once.

If an application specifies the HDATA_APPOWNED flag in the afCmd parameter of DdeCreateDataHandle, it must call the DdeFreeDataHandle function to free the memory handle, regardless of whether it passed the handle to the DDEML. Before it terminates, an application must call DdeFreeDataHandle to free any data handle that it created but did not pass to the DDEML.

An application that has not yet passed the handle of a DDE object to the DDEML can add data to the object or overwrite data in the object by using the DdeAddData function. Typically, an application uses DdeAddData to fill an uninitialized DDE object. After an application passes a data handle to the DDEML, the DDE object identified by the handle cannot be changed; it can only be freed.


Transaction Management

After establishing a conversation with a server, a client can send transactions to obtain data and services from the server. The remaining topics in this section describe the types of transactions that clients can use to interact with a server.


Request Transaction

A client application can use the XTYP_REQUEST transaction to request a data item from a server application. The client calls the DdeClientTransaction function, specifying XTYP_REQUEST as the transaction type and specifying the data item the application needs.

The DDEML passes the XTYP_REQUEST transaction to the server, specifying the topic name, item name, and data format requested by the client. If the server supports the requested topic, item, and format, the server should return a data handle that identifies the current value of the item. The DDEML passes this handle to the client as the return value from DdeClientTransaction. The server should return NULL if it does not support the topic, item, or format requested.

DdeClientTransaction uses the lpdwResult parameter to return a transaction-status flag to the client. If the server does not process the XTYP_REQUEST transaction, DdeClientTransaction returns NULL, and lpdwResult points to the DDE_FNOTPROCESSED or DDE_FBUSY flag. If the DDE_FNOTPROCESSED flag is returned, the client cannot determine why the server did not process the transaction.

If a server does not support the XTYP_REQUEST transaction, it should specify the CBF_FAIL_REQUESTS filter flag in the DdeInitialize function. This flag prevents the DDEML from sending the transaction to the server.


Poke Transaction

A client can send unsolicited data to a server by using DdeClientTransaction to send an XTYP_POKE transaction to a server's callback function.

The client application first creates a buffer that contains the data to send to the server and then passes a pointer to the buffer as a parameter to DdeClientTransaction. Alternatively, the client can use the DdeCreateDataHandle function to obtain a data handle that identifies the data and then pass the handle to DdeClientTransaction. In either case, the client also specifies the topic name, item name, and data format when it calls DdeClientTransaction.

The DDEML passes the XTYP_POKE transaction to the server, specifying the topic name, item name, and data format that the client requested. To accept the data item and format, the server should return DDE_FACK. To reject the data, the server should return DDE_FNOTPROCESSED. If the server is too busy to accept the data, the server should return DDE_FBUSY.

When DdeClientTransaction returns, the client can use the lpdwResult parameter to access the transaction-status flag. If the flag is DDE_FBUSY, the client should send the transaction again later.

If a server does not support the XTYP_POKE transaction, it should specify the CBF_FAIL_POKES filter flag in DdeInitialize. This flag prevents the DDEML from sending this transaction to the server.


Advise Transaction

A client application can use the DDEML to establish one or more links to items in a server application. When such a link has been established, the server sends periodic updates about the linked item to the client (typically, whenever the value of the item associated with the server application changes). Linking establishes an advise loop between the two applications that remains in place until the client ends it.

There are two kinds of advise loops: "hot" and "warm." In a hot advise loop, the server immediately sends a data handle that identifies the changed value. In a warm advise loop, the server notifies the client that the value of the item has changed but does not send the data handle until the client requests it.

A client can request a hot advise loop with a server by specifying the XTYP_ADVSTART transaction type in a call to DdeClientTransaction. To request a warm advise loop, the client must combine the XTYPF_NODATA flag with the XTYP_ADVSTART transaction type. In either event, the DDEML passes the XTYP_ADVSTART transaction to the server's DDE callback function. The server's DDE callback function should examine the parameters that accompany the XTYP_ADVSTART transaction (including the requested format, topic name, and item name) and then return TRUE to allow the advise loop or FALSE to deny it.

After an advise loop has been established, the server application should call the DdePostAdvise function whenever the value of the item associated with the requested item name changes. This call results in an XTYP_ADVREQ transaction being sent to the server's own DDE callback function. The server's DDE callback function should return a data handle that identifies the new value of the data item. The DDEML then notifies the client that the specified item has changed by sending the XTYP_ADVDATA transaction to the client's DDE callback function.

If the client requested a hot advise loop, the DDEML passes the data handle for the changed item to the client during the XTYP_ADVDATA transaction. Otherwise, the client can send an XTYP_REQUEST transaction to obtain the data handle.

It is possible for a server to send updates faster than a client can process the new data. The speed of updates can be a problem for a client that must perform lengthy processing operations on the data. In this case, the client should specify the XTYPF_ACKREQ flag when it requests an advise loop. This flag causes the server to wait for the client to acknowledge that it has received and processed a data item before the server sends the next data item. Advise loops that are established with the XTYPF_ACKREQ flag are more robust with fast servers but may occasionally miss updates. Advise loops established without the XTYPF_ACKREQ flag are guaranteed not to miss updates as long as the client keeps up with the server.

A client can end an advise loop by specifying the XTYP_ADVSTOP transaction type in a call to DdeClientTransaction.

If a server does not support advise loops, it should specify the CBF_FAIL_ADVISES filter flag in the DdeInitialize function. This flag prevents the DDEML from sending the XTYP_ADVSTART and XTYP_ADVSTOP transactions to the server.


Execute Transaction

A client can use the XTYP_EXECUTE transaction to cause a server to execute a command or a series of commands.

To execute a server command, the client first creates a buffer that contains a command string for the server to execute and then passes either a pointer to the buffer or a data handle identifying the buffer when it calls DdeClientTransaction. Other required parameters include the conversation handle, the item name string handle, the format specification, and the XTYP_EXECUTE transaction type. An application that creates a data handle for passing execute data must specify NULL for the hszItem parameter of the DdeCreateDataHandle function and zero for the uFmt parameter.

The DDEML passes the XTYP_EXECUTE transaction to the server's DDE callback function and specifies the format name, conversation handle, topic name, and data handle identifying the command string. If the server supports the command, it should use the DdeAccessData function to obtain a pointer to the command string, execute the command, and then return DDE_FACK. If the server does not support the command or cannot complete the transaction, it should return DDE_FNOTPROCESSED. The server should return DDE_FBUSY if it is too busy to complete the transaction.

In general, a server's callback function should process the XTYP_EXECUTE transaction before returning with the following exceptions:

  1. When the command passed with the XTYP_EXECUTE transaction requests the server to terminate, the server should not terminate until its callback function returns from processing XTYP_EXECUTE.
  2. If the server must perform an operation, such as processing a dialog box or a DDE transaction that might cause DDEML recursion problems, the server should return the CBR_BLOCK return code to block the execute transaction, perform the operation, and then resume processing the execute transaction.

When DdeClientTransaction returns, the client can use the lpdwResult parameter to access the transaction status flag. If the flag is DDE_FBUSY, the client should send the transaction again later.

If a server does not support the XTYP_EXECUTE transaction, it should specify the CBF_FAIL_EXECUTES filter flag in the DdeInitialize function. Doing so prevents the DDEML from sending the transaction to the server.


Synchronous and Asynchronous Transactions

A client can send either synchronous or asynchronous transactions. In a synchronous transaction, the client specifies a time-out value that indicates the maximum amount of time it will wait for the server to process the transaction. DdeClientTransaction does not return until the server processes the transaction, the transaction fails, or the time-out value expires. The client specifies the time-out value when it calls DdeClientTransaction.

During a synchronous transaction, the client enters a modal loop while waiting for the transaction to be processed. The client can still process user input but cannot send another synchronous transaction until DdeClientTransaction returns.

A client sends an asynchronous transaction by specifying the TIMEOUT_ASYNC flag in DdeClientTransaction. The function returns after the transaction has begun, passing a transaction identifier to the client. When the server finishes processing the asynchronous transaction, the DDEML sends an XTYP_XACT_COMPLETE transaction to the client. One of the parameters that the DDEML passes to the client during the XTYP_XACT_COMPLETE transaction is the transaction identifier. By comparing this transaction identifier with the identifier returned by DdeClientTransaction, the client identifies which asynchronous transaction the server has finished processing.

A client can use the DdeSetUserHandle function as an aid in processing an asynchronous transaction. This function makes it possible for a client to associate an application-defined doubleword value with a conversation handle and a transaction identifier. The client can use the DdeQueryConvInfo function during the XTYP_XACT_COMPLETE transaction to obtain the application-defined doubleword value. Because of this function, an application need not maintain a list of active transaction identifiers.

When a client successfully completes a request for data using a synchronous transaction, the DDEML has no way to tell when the client has finished using the data received. The client application must pass the data handle received to the DdeFreeDataHandle function, notifying the DDEML that the handle will no longer be used. Data handles returned by synchronous transactions are effectively owned by the client.

If a server does not process an asynchronous transaction in a timely manner, the client can abandon the transaction by calling the DdeAbandonTransaction function. The DDEML releases all resources associated with the transaction and discards the results of the transaction when the server finishes processing it. A time-out during a synchronous transaction effectively cancels the transaction.

The asynchronous transaction method is provided for applications that must send a high volume of DDE transactions while simultaneously performing a substantial amount of processing, such as performing calculations. The asynchronous method is also useful in applications that must stop processing DDE transactions temporarily so they can complete other tasks without interruption. In most other situations, an application should use the synchronous method.

Synchronous transactions are simpler to maintain and are faster than asynchronous transactions. However, only one synchronous transaction can be performed at a time, whereas many asynchronous transactions can be performed simultaneously. With synchronous transactions, a slow server can cause a client to remain idle while it is waiting for a response. Also, synchronous transactions cause the client to enter a modal loop that could bypass message filtering in the application's own message loop.

If the client has installed a hook procedure to filter messages (that is, specified the WH_MSGFILTER hook type in a call to the SetWindowsHookEx function), a synchronous transaction will not cause the system to bypass the hook procedure. When an input event occurs while the client is waiting for a synchronous transaction to end, the hook procedure receives an MSGF_DDEMGR hook code. The main danger of using a synchronous transaction modal loop is that a modal loop created by a dialog box can interfere with its operation. Asynchronous transactions should always be used when the DDEML is being used by a dynamic-link library (DLL).


Transaction Control

An application can suspend transactions to its DDE callback function — either those transactions associated with a specific conversation handle or all transactions regardless of the conversation handle. This capability is useful when an application receives a transaction that requires lengthy processing. In such a case, the application can return the CBR_BLOCK return code to suspend future transactions associated with the transaction's conversation handle, so that the application is free to process other conversations.

When processing has been completed, the application calls the DdeEnableCallback function to resume transactions associated with the suspended conversation. Calling DdeEnableCallback causes the DDEML to resend the transaction that resulted in the application suspending the conversation. Therefore, the application should store the result of the transaction in such a way that it can obtain and return the result without reprocessing the transaction.

An application can suspend all transactions associated with a specific conversation handle by specifying the handle and the EC_DISABLE flag in a call to DdeEnableCallback. By specifying a NULL handle, an application can suspend all transactions for all conversations.

When a conversation has been suspended, the DDEML saves transactions for the conversation in a transaction queue. When the application reenables the conversation, the DDEML removes the saved transactions from the queue and passes each transaction to the appropriate callback function. The capacity of the transaction queue is large, but an application should reenable a suspended conversation as soon as possible to avoid losing transactions.

An application can resume usual transaction processing by specifying the EC_ENABLEALL flag in DdeEnableCallback. For a more controlled resumption of transaction processing, the application can specify the EC_ENABLEONE flag. This flag removes one transaction from the transaction queue and passes it to the appropriate callback function; after that transaction has been processed, any conversations are again disabled.

If the EC_ENABLEONE flag and a conversation handle are specified in the call to DdeEnableCallback, only that conversation is blocked after the transaction has been processed. If a NULL conversation handle is specified, all conversations are blocked after a transaction has been processed in any conversation.


Transaction Classes

The DDEML has four classes of transactions. Each class is identified by a constant that begins with the XCLASS_ prefix. The classes are defined in the DDEML header file. The class value is combined with the transaction-type value and is passed to the DDE callback function of the receiving application.

A transaction's class determines the return value that a callback function is expected to return if it processes the transaction. The following return values and transaction types are associated with each of the four transaction classes.

Class | Return value | Transaction
XCLASS_BOOL | TRUE or FALSE | XTYP_ADVSTART XTYP_CONNECT
XCLASS_DATA | A data handle, the CBR_BLOCK return code, or NULL | XTYP_ADVREQ XTYP_REQUEST XTYP_WILDCONNECT
XCLASS_FLAGS | A transaction flag: DDE_FACK, DDE_FBUSY, or DDE_FNOTPROCESSED | XTYP_ADVDATA XTYP_EXECUTE XTYP_POKE
XCLASS_NOTIFICATION | None | XTYP_ADVSTOP XTYP_CONNECT_CONFIRM XTYP_DISCONNECT XTYP_ERROR XTYP_REGISTER XTYP_UNREGISTER XTYP_XACT_COMPLETE


Transaction Types

Each DDE transaction type has a receiver and an associated activity that causes the DDEML to generate each type.

Transaction type | Receiver | Cause
XTYP_ADVDATA | Client | A server responded to an XTYP_ADVREQ transaction by returning a data handle.
XTYP_ADVREQ | Server | A server called the DdePostAdvise function, indicating that the value of a data item in an advise loop had changed.
XTYP_ADVSTART | Server | A client specified the XTYP_ADVSTART transaction type in a call to the DdeClientTransaction function.
XTYP_ADVSTOP | Server | A client specified the XTYP_ADVSTOP transaction type in a call to DdeClientTransaction.
XTYP_CONNECT | Server | A client called the DdeConnect function and specified a service name and topic name supported by the server.
XTYP_CONNECT_CONFIRM | Server | The server returned TRUE in response to an XTYP_CONNECT or XTYP_WILDCONNECT transaction.
XTYP_DISCONNECT | Client/Server | A partner in a conversation called the DdeDisconnect function, causing both partners to receive this transaction.
XTYP_ERROR | Client/Server | A critical error has occurred. The DDEML may not have sufficient resources to continue.
XTYP_EXECUTE | Server | A client specified the XTYP_EXECUTE transaction type in a call to DdeClientTransaction.
XTYP_MONITOR | DDE monitoring application | A DDE event occurred in the system. For more information about DDE monitoring applications, see Monitoring Applications.
XTYP_POKE | Server | A client specified the XTYP_POKE transaction type in a call to DdeClientTransaction.
XTYP_REGISTER | Client/Server | A server application used the DdeNameService function to register a service name.
XTYP_REQUEST | Server | A client specified the XTYP_REQUEST transaction type in a call to DdeClientTransaction.
XTYP_UNREGISTER | Client/Server | A server application used DdeNameService to unregister a service name.
XTYP_WILDCONNECT | Server | A client called the DdeConnect or DdeConnectList function, specifying NULL for the service name, the topic name, or both.
XTYP_XACT_COMPLETE | Client | An asynchronous transaction, sent when the client specified the TIMEOUT_ASYNC flag in a call to DdeClientTransaction, has concluded.


Error Detection for DDEML Functions

Whenever a DDEML function fails, an application can call the DdeGetLastError function to determine the cause of the failure. DdeGetLastError returns an error value that specifies the cause of the most recent error.


Monitoring Applications

The application programming interface (API) elements of the DDEML can be used to create an application that monitors DDE activity in the system. Like any DDEML application, a DDE monitoring application contains a DDE callback function. The DDEML notifies a monitoring application's DDE callback function whenever a DDE event occurs, passing information about the event to the callback function. The application typically displays the information in a window or writes it to a file.

To receive notifications from the DDEML, an application must have registered as a DDE monitor by specifying the APPCLASS_MONITOR flag in a call to the DdeInitialize function. In this same call, the application can specify one or more monitor flags to indicate the types of events for which the DDEML is to notify the application's callback function. The following monitor flags can be specified by an application:

Flag | Description
MF_CALLBACKS | Notifies the callback function whenever a transaction is sent to any DDE callback function in the system.
MF_CONV | Notifies the callback function whenever a conversation is established or terminated.
MF_ERRORS | Notifies the callback function whenever a DDEML error occurs.
MF_HSZ_INFO | Notifies the callback function whenever a DDEML application creates, frees, or increments the usage count of a string handle or whenever a string handle is freed as a result of a call to the DdeUninitialize function.
MF_LINKS | Notifies the callback function whenever an advise loop is started or ended.
MF_POSTMSGS | Notifies the callback function whenever the system or an application posts a DDE message.
MF_SENDMSGS | Notifies the callback function whenever the system or an application sends a DDE message.

The following example shows how to register a DDE monitoring application so that its DDE callback function receives notifications of all DDE events.

DWORD idInst;
PFNCALLBACK lpDdeProc;
hInst = hInstance;

if (DdeInitialize(
        (LPDWORD) &idInst,  // instance identifier
        DDECallback,        // points to callback function
        APPCLASS_MONITOR |  // this is a monitoring application
        MF_CALLBACKS     |  // monitor callback functions
        MF_CONV          |  // monitor conversation data
        MF_ERRORS        |  // monitor DDEML errors
        MF_HSZ_INFO      |  // monitor data handle activity
        MF_LINKS         |  // monitor advise loops
        MF_POSTMSGS      |  // monitor posted DDE messages
        MF_SENDMSGS,        // monitor sent DDE messages
        0))                 // reserved
{
    return FALSE;
}

The DDEML informs a monitoring application of a DDE event by sending an XTYP_MONITOR transaction to the application's DDE callback function. During this transaction, the DDEML passes a monitor flag that specifies the type of DDE event that has occurred and a handle of a DDE object that contains detailed information about the event. The DDEML provides a set of structures that the application can use to extract the information from the DDE object. There is a corresponding structure for each type of DDE event.

Structure | Description
MONCBSTRUCT | Contains information about a transaction.
MONCONVSTRUCT | Contains information about a conversation.
MONERRSTRUCT | Contains information about the latest DDE error.
MONLINKSTRUCT | Contains information about an advise loop.
MONHSZSTRUCT | Contains information about a string handle.
MONMSGSTRUCT | Contains information about a DDE message that was sent or posted.

The following example shows the DDE callback function of a DDE monitoring application that formats information about each string handle event and then displays the information in a window. The function uses the MONHSZSTRUCT structure to extract the information from the DDE object.

HDDEDATA CALLBACK DDECallback(uType, uFmt, hconv, hsz1, hsz2,
    hdata, dwData1, dwData2)
UINT uType;
UINT uFmt;
HCONV hconv;
HSZ hsz1;
HSZ hsz2;
HDDEDATA hdata;
DWORD dwData1;
DWORD dwData2;
{
    LPVOID lpData;
    CHAR *szAction;
    CHAR szBuf[256];
    DWORD cb;

    switch (uType)
    {
        case XTYP_MONITOR:
            // Obtain a pointer to the global memory object.

            if (lpData = DdeAccessData(hdata, &cb))
            {
                // Examine the monitor flag.

                switch (dwData2)
                {
                    case MF_HSZ_INFO:

#define PHSZS ((MONHSZSTRUCT FAR *)lpData)

                        // The global memory object contains
                        // string handle data. Use the MONHSZSTRUCT
                        // structure to access the data.

                        switch (PHSZS->fsAction)
                        {
                            // Examine the action flags to determine
                            // the action performed on the handle.

                            case MH_CREATE:
                                szAction = "Created";
                                break;

                            case MH_KEEP:
                                szAction = "Incremented";
                                break;

                            case MH_DELETE:
                                szAction = "Deleted";
                                break;

                            case MH_CLEANUP:
                                szAction = "Cleaned up";
                                break;

                            default:
                                DdeUnaccessData(hdata);
                                return (HDDEDATA) 0;
                        }

                        // Write formatted output to a buffer.

                        wsprintf(szBuf,
                            "Handle %s, Task: %x, Hsz: %lx(%s)",
                            (LPSTR) szAction, PHSZS->hTask,
                            PHSZS->hsz, (LPSTR) PHSZS->str);
                        // Display text or write to a file.

                        break;

#undef PHSZS

                    // Process other MF_* flags.

                    default:
                        break;
                }
            }

            // Free the global memory object.

            DdeUnaccessData(hdata);
            break;

        default:
            break;
    }
    return (HDDEDATA) 0;
}


Dynamic Data Exchange Management Reference

The following elements are used to manage dynamic data exchange.

  • Dynamic Data Exchange Management Functions
  • Dynamic Data Exchange Management Structures
  • Dynamic Data Exchange Management Transactions


Dynamic Data Exchange Management Functions

The following functions are used to manage dynamic data exchange.

DdeAbandonTransaction
DdeAccessData
DdeAddData
DdeCallback
DdeClientTransaction
DdeCmpStringHandles
DdeConnect
DdeConnectList
DdeCreateDataHandle
DdeCreateStringHandle
DdeDisconnect
DdeDisconnectList
DdeEnableCallback
DdeFreeDataHandle
DdeFreeStringHandle
DdeGetData
DdeGetLastError
DdeImpersonateClient
DdeInitialize
DdeKeepStringHandle
DdeNameService
DdePostAdvise
DdeQueryConvInfo
DdeQueryNextServer
DdeQueryString
DdeReconnect
DdeSetUserHandle
DdeUnaccessData
DdeUninitialize


DdeAbandonTransaction

The DdeAbandonTransaction function abandons the specified asynchronous transaction and releases all resources associated with the transaction.

BOOL DdeAbandonTransaction(
  DWORD idInst,         // instance identifier
  HCONV hConv,          // handle to conversation
  DWORD idTransaction   // transaction identifier
);

Parameters

idInst
Specifies the application instance identifier obtained by a previous call to the DdeInitialize function.
hConv
Handle to the conversation in which the transaction was initiated. If this parameter is 0L, all transactions are abandoned (that is, the idTransaction parameter is ignored).
idTransaction
Specifies the identifier of the transaction to abandon. If this parameter is 0L, all active transactions in the specified conversation are abandoned.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR
DMLERR_UNFOUND_QUEUE_ID

Remarks

Only a dynamic data exchange (DDE) client application should call DdeAbandonTransaction. If the server application responds to the transaction after the client has called DdeAbandonTransaction, the system discards the transaction results. This function has no effect on synchronous transactions.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeClientTransaction, DdeInitialize, DdeQueryConvInfo


DdeAccessData

The DdeAccessData function provides access to the data in the specified dynamic data exchange (DDE) object. An application must call the DdeUnaccessData function when it has finished accessing the data in the object.

LPBYTE DdeAccessData(
  HDDEDATA hData,  // handle to DDE object
  LPDWORD pcbDataSize
                   // pointer to variable that receives data length
);

Parameters

hData
Handle to the DDE object to access.
pcbDataSize
Pointer to a variable that receives the size, in bytes, of the DDE object identified by the hData parameter. If this parameter is NULL, no size information is returned.

Return Values

If the function succeeds, the return value is a pointer to the first byte of data in the DDE object.

If the function fails, the return value is NULL.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR

Remarks

If the hData parameter has not been passed to a Dynamic Data Exchange Management Library (DDEML) function, an application can use the pointer returned by DdeAccessData for read-write access to the DDE object. If hData has already been passed to a DDEML function, the pointer should be used only for read access to the memory object.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeAddData, DdeCreateDataHandle, DdeFreeDataHandle, DdeUnaccessData


DdeAddData

The DdeAddData function adds data to the specified dynamic data exchange (DDE) object. An application can add data starting at any offset from the beginning of the object. If new data overlaps data already in the object, the new data overwrites the old data in the bytes where the overlap occurs. The contents of locations in the object that have not been written to are undefined.

HDDEDATA DdeAddData(
  HDDEDATA hData,  // handle to DDE data object
  LPBYTE pSrc,     // pointer to source buffer
  DWORD cb,        // length of data
  DWORD cbOff      // offset within DDE data object
);

Parameters

hData
Handle to the DDE object that receives additional data.
pSrc
Pointer to a buffer containing the data to add to the DDE object.
cb
Specifies the length, in bytes, of the data to be added to the DDE object, including the terminating NULL, if the data is a string.
cbOff
Specifies an offset, in bytes, from the beginning of the DDE object. The additional data is copied to the object beginning at this offset.

Return Values

If the function succeeds, the return value is a new handle to the DDE object. The new handle is used in all references to the object.

If the function fails, the return value is zero.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_MEMORY_ERROR
DMLERR_NO_ERROR

Remarks

After a data handle has been used as a parameter in another Dynamic Data Exchange Management Library function or has been returned by a DDE callback function, the handle may be used only for read access to the DDE object identified by the handle.

If the amount of memory originally allocated is less than is needed to hold the added data, DdeAddData reallocates a global memory object of the appropriate size.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeAccessData, DdeCreateDataHandle, DdeUnaccessData


DdeCallback

The DdeCallbackProc function is an application-defined callback function used with the Dynamic Data Exchange Management Library (DDEML) functions. It processes dynamic data exchange (DDE) transactions. The PFNCALLBACK type defines a pointer to this callback function. DdeCallback is a placeholder for the application-defined function name.

HDDEDATA CALLBACK DdeCallback(
  UINT uType,     // transaction type
  UINT uFmt,      // clipboard data format
  HCONV hconv,    // handle to the conversation
  HSZ hsz1,       // handle to a string
  HSZ hsz2,       // handle to a string
  HDDEDATA hdata, // handle to a global memory object
  DWORD dwData1,  // transaction-specific data
  DWORD dwData2   // transaction-specific data
);

Parameters

uType
Specifies the type of the current transaction. This parameter consists of a combination of transaction class flags and transaction type flags. The following table describes each of the transaction classes and provides a list of the transaction types in each class. For information about a specific transaction type, see the individual description of that type.
Class | Meaning
XCLASS_BOOL | A DDE callback function should return TRUE or FALSE when it finishes processing a transaction that belongs to this class. The XCLASS_BOOL transaction class consists of the following types:

XTYP_ADVSTART
XTYP_CONNECT
XCLASS_DATA | A DDE callback function should return a DDE handle, the CBR_BLOCK return code, or NULL when it finishes processing a transaction that belongs to this class. The XCLASS_DATA transaction class consists of the following types:

XTYP_ADVREQ
XTYP_REQUEST
XTYP_WILDCONNECT
XCLASS_FLAGS | A DDE callback function should return DDE_FACK, DDE_FBUSY, or DDE_FNOTPROCESSED when it finishes processing a transaction that belongs to this class. The XCLASS_FLAGS transaction class consists of the following types:

XTYP_ADVDATA
XTYP_EXECUTE
XTYP_POKE
XCLASS_NOTIFICATION The transaction types that belong to this class are for notification purposes only. The return value from the callback function is ignored. The XCLASS_NOTIFICATION transaction class consists of the following types:

XTYP_ADVSTOP
XTYP_CONNECT_CONFIRM
XTYP_DISCONNECT
XTYP_ERROR
XTYP_MONITOR
XTYP_REGISTER
XTYP_XACT_COMPLETE
XTYP_UNREGISTER

uFmt
Specifies the format in which data is sent or received.
hconv
Handle to the conversation associated with the current transaction.
hsz1
Handle to a string. The meaning of this parameter depends on the type of the current transaction. For the meaning of this parameter, see the description of the transaction type.
hsz2
Handle to a string. The meaning of this parameter depends on the type of the current transaction. For the meaning of this parameter, see the description of the transaction type.
hdata
Handle to DDE data. The meaning of this parameter depends on the type of the current transaction. For the meaning of this parameter, see the description of the transaction type.
dwData1
Specifies transaction-specific data. For the meaning of this parameter, see the description of the transaction type.
dwData2
Specifies transaction-specific data. For the meaning of this parameter, see the description of the transaction type.

Return Values

The return value depends on the transaction class. For more information about the return values, see descriptions of the individual transaction types.

Remarks

The callback function is called asynchronously for transactions that do not involve the creation or termination of conversations. An application that does not frequently accept incoming messages will have reduced DDE performance because the DDEML uses messages to initiate transactions.

An application must register the callback function by specifying a pointer to the function in a call to the DdeInitialize function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: User-defined.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeEnableCallback, DdeInitialize


DdeClientTransaction

The DdeClientTransaction function begins a data transaction between a client and a server. Only a dynamic data exchange (DDE) client application can call this function, and the application can use it only after establishing a conversation with the server.

HDDEDATA DdeClientTransaction(
  LPBYTE pData,       // pointer to data to pass to server
  DWORD cbData,       // length of data
  HCONV hConv,        // handle to conversation
  HSZ hszItem,        // handle to item name string
  UINT wFmt,          // clipboard data format
  UINT wType,         // transaction type
  DWORD dwTimeout,    // time-out duration
  LPDWORD pdwResult   // pointer to transaction result
);

Parameters

pData
Pointer to the beginning of the data the client must pass to the server.

Optionally, an application can specify the data handle (HDDEDATA) to pass to the server and in that case the cbData parameter should be set to 0xFFFFFFFF. This parameter is required only if the wType parameter is XTYP_EXECUTE or XTYP_POKE. Otherwise, this parameter should be NULL.

For the optional usage of this parameter, XTYP_POKE transactions where pData is a data handle, the handle must have been created by a previous call to the DdeCreateDataHandle function, employing the same data format specified in the wFmt parameter.

cbData
Specifies the length, in bytes, of the data pointed to by the pData parameter, including the terminating NULL, if the data is a string. A value of 0xFFFFFFFF indicates that pData is a data handle that identifies the data being sent.
hConv
Handle to the conversation in which the transaction is to take place.
hszItem
Handle to the data item for which data is being exchanged during the transaction. This handle must have been created by a previous call to the DdeCreateStringHandle function. This parameter is ignored (and should be set to 0L) if the wType parameter is XTYP_EXECUTE.
wFmt
Specifies the standard clipboard format in which the data item is being submitted or requested.

If the transaction specified by the wType parameter does not pass data or is XTYP_EXECUTE, this parameter should be zero.

If the transaction specified by the wType parameter references non-execute DDE data (XTYP_POKE, XTYP_ADVSTART, XTYP_ADVSTOP, XTYP_REQUEST), the wFmt value must be either a valid predefined (CF_) DDE format or a valid registered clipboard format.

wType
Specifies the transaction type. This parameter can be one of the following types:
Type | Meaning
XTYP_ADVSTART | Begins an advise loop. Any number of distinct advise loops can exist within a conversation. An application can alter the advise loop type by combining the XTYP_ADVSTART transaction type with one or more of the following flags:

Flag | Meaning
XTYPF_NODATA | Instructs the server to notify the client of any data changes without actually sending the data. This flag gives the client the option of ignoring the notification or requesting the changed data from the server.
XTYPF_ACKREQ | Instructs the server to wait until the client acknowledges that it received the previous data item before sending the next data item. This flag prevents a fast server from sending data faster than the client can process it.
XTYP_ADVSTOP | Ends an advise loop.
XTYP_EXECUTE | Begins an execute transaction.
XTYP_POKE | Begins a poke transaction.
XTYP_REQUEST | Begins a request transaction.

dwTimeout
Specifies the maximum length of time, in milliseconds, that the client will wait for a response from the server application in a synchronous transaction. This parameter should be TIMEOUT_ASYNC for asynchronous transactions.
pdwResult
Pointer to a variable that receives the result of the transaction. An application that does not check the result can use NULL for this value. For synchronous transactions, the low-order word of this variable contains any applicable DDE_ flags resulting from the transaction. This provides support for applications dependent on DDE_APPSTATUS bits. It is, however, recommended that applications no longer use these bits because they may not be supported in future versions of the Dynamic Data Exchange Management Library (DDEML). For asynchronous transactions, this variable is filled with a unique transaction identifier for use with the DdeAbandonTransaction function and the XTYP_XACT_COMPLETE transaction.

Return Values

If the function succeeds, the return value is a data handle that identifies the data for successful synchronous transactions in which the client expects data from the server. The return value is nonzero for successful asynchronous transactions and for synchronous transactions in which the client does not expect data. The return value is zero for all unsuccessful transactions.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_ADVACKTIMEOUT
DMLERR_BUSY
DMLERR_DATAACKTIMEOUT
DMLERR_DLL_NOT_INITIALIZED
DMLERR_EXECACKTIMEOUT
DMLERR_INVALIDPARAMETER
DMLERR_MEMORY_ERROR
DMLERR_NO_CONV_ESTABLISHED
DMLERR_NO_ERROR
DMLERR_NOTPROCESSED
DMLERR_POKEACKTIMEOUT
DMLERR_POSTMSG_FAILED
DMLERR_REENTRANCY
DMLERR_SERVER_DIED
DMLERR_UNADVACKTIMEOUT

Remarks

When an application has finished using the data handle returned by DdeClientTransaction, the application should free the handle by calling the DdeFreeDataHandle function.

Transactions can be synchronous or asynchronous. During a synchronous transaction, DdeClientTransaction does not return until the transaction either completes successfully or fails. Synchronous transactions cause a client to enter a modal loop while waiting for various asynchronous events. Because of this, a client application can still respond to user input while waiting on a synchronous transaction, but the application cannot begin a second synchronous transaction because of the activity associated with the first. DdeClientTransaction fails if any instance of the same task has a synchronous transaction already in progress.

During an asynchronous transaction, DdeClientTransaction returns after the transaction has begun, passing a transaction identifier for reference. When the server's DDE callback function finishes processing an asynchronous transaction, the system sends an XTYP_XACT_COMPLETE transaction to the client. This transaction provides the client with the results of the asynchronous transaction that it initiated by calling DdeClientTransaction. A client application can choose to abandon an asynchronous transaction by calling the DdeAbandonTransaction function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeAbandonTransaction, DdeAccessData, DdeConnect, DdeConnectList, DdeCreateDataHandle, DdeCreateStringHandle, DdeFreeDataHandle, XTYP_ADVSTART, XTYP_ADVSTOP, XTYP_EXECUTE, XTYP_POKE, XTYP_REQUEST


DdeCmpStringHandles

The DdeCmpStringHandles function compares the values of two string handles. The value of a string handle is not related to the case of the associated string.

int DdeCmpStringHandles(
  HSZ hsz1,  // handle to first string
  HSZ hsz2   // handle to second string
);

Parameters

hsz1
Handle to the first string.
hsz2
Handle to the second string.

Return Values

The return value can be one of the following values:

Value | Meaning
–1 | The value of hsz1 is either 0 or less than the value of hsz2.
0 | The values of hsz1 and hsz2 are equal (both can be 0).
1 | The value of hsz2 is either 0 or less than the value of hsz1.

Remarks

An application that must do a case-sensitive comparison of two string handles should compare the string handles directly. An application should use DdeCmpStringHandles for all other comparisons to preserve the case-insensitive nature of dynamic data exchange (DDE).

DdeCmpStringHandles cannot be used to sort string handles alphabetically.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeAccessData, DdeCreateStringHandle, DdeFreeStringHandle


DdeConnect

The DdeConnect function establishes a conversation with a server application that supports the specified service name and topic name pair. If more than one such server exists, the system selects only one.

HCONV DdeConnect(
  DWORD idInst,      // instance identifier
  HSZ hszService,    // handle to service name string
  HSZ hszTopic,      // handle to topic name string
  PCONVCONTEXT pCC   // pointer to structure with context data
);

Parameters

idInst
Specifies the application instance identifier obtained by a previous call to the DdeInitialize function.
hszService
Handle to the string that specifies the service name of the server application with which a conversation is to be established. This handle must have been created by a previous call to the DdeCreateStringHandle function. If this parameter is 0L, a conversation is established with any available server.
hszTopic
Handle to the string that specifies the name of the topic on which a conversation is to be established. This handle must have been created by a previous call to DdeCreateStringHandle. If this parameter is 0L, a conversation on any topic supported by the selected server is established.
pCC
Pointer to the CONVCONTEXT structure that contains conversation context information. If this parameter is NULL, the server receives the default CONVCONTEXT structure during the XTYP_CONNECT or XTYP_WILDCONNECT transaction.

Return Values

If the function succeeds, the return value is the handle to the established conversation.

If the function fails, the return value is 0L.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_CONV_ESTABLISHED
DMLERR_NO_ERROR

Remarks

The client application cannot make assumptions regarding the server selected. If an instance-specific name is specified in the hszService parameter, a conversation is established with only the specified instance. Instance-specific service names are passed to an application's dynamic data exchange (DDE) callback function during the XTYP_REGISTER and XTYP_UNREGISTER transactions.

All members of the default CONVCONTEXT structure are set to zero except cb, which specifies the size of the structure, and iCodePage, which specifies CP_WINANSI (the default code page) or CP_WINUNICODE, depending on whether the ANSI or Unicode version of the DdeInitialize function was called by the client application.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, CONVCONTEXT, DdeConnectList, DdeCreateStringHandle, DdeDisconnect, DdeDisconnectList, DdeInitialize, XTYP_REGISTER, XTYP_UNREGISTER


DdeConnectList

The DdeConnectList function establishes a conversation with all server applications that support the specified service name and topic name pair. An application can also use this function to obtain a list of conversation handles by passing the function an existing conversation handle. The Dynamic Data Exchange Management Library removes the handles of any terminated conversations from the conversation list. The resulting conversation list contains the handles of all currently established conversations that support the specified service name and topic name.

HCONVLIST DdeConnectList(
  DWORD idInst,         // instance identifier
  HSZ hszService,       // handle to service name string
  HSZ hszTopic,         // handle to topic name string
  HCONVLIST hConvList,  // handle to conversation list
  PCONVCONTEXT pCC      // pointer to structure with context data
);

Parameters

idInst
Specifies the application instance identifier obtained by a previous call to the DdeInitialize function.
hszService
Handle to the string that specifies the service name of the server application with which a conversation is to be established. If this parameter is 0L, the system attempts to establish conversations with all available servers that support the specified topic name.
hszTopic
Handle to the string that specifies the name of the topic on which a conversation is to be established. This handle must have been created by a previous call to the DdeCreateStringHandle function. If this parameter is 0L, the system will attempt to establish conversations on all topics supported by the selected server (or servers).
hConvList
Handle to the conversation list to be enumerated. This parameter should be 0L if a new conversation list is to be established.
pCC
Pointer to the CONVCONTEXT structure that contains conversation-context information. If this parameter is NULL, the server receives the default CONVCONTEXT structure during the XTYP_CONNECT or XTYP_WILDCONNECT transaction.

Return Values

If the function succeeds, the return value is the handle to a new conversation list.

If the function fails, the return value is 0L. The handle to the old conversation list is no longer valid.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALID_PARAMETER
DMLERR_NO_CONV_ESTABLISHED
DMLERR_NO_ERROR
DMLERR_SYS_ERROR

Remarks

An application must free the conversation list handle returned by the DdeConnectList function, regardless of whether any conversation handles within the list are active. To free the handle, an application can call DdeDisconnectList.

All members of the default CONVCONTEXT structure are set to zero except cb, specifying the size of the structure, and iCodePage, specifying CP_WINANSI (the default code page) or CP_WINUNICODE, depending on whether the ANSI or Unicode version of the DdeInitialize function was called by the client application.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, CONVCONTEXT, DdeConnect, DdeCreateStringHandle, DdeDisconnect, DdeDisconnectList, DdeInitialize, DdeQueryNextServer


DdeCreateDataHandle

The DdeCreateDataHandle function creates a dynamic data exchange (DDE) object and fills the object with data from the specified buffer. A DDE application uses this function during transactions that involve passing data to the partner application.

HDDEDATA DdeCreateDataHandle(
  DWORD idInst, // instance identifier
  LPBYTE pSrc,  // pointer to source buffer
  DWORD cb,     // length of DDE object
  DWORD cbOff,  // offset from beginning of source buffer
  HSZ hszItem,  // handle to item name string
  UINT wFmt,    // clipboard data format
  UINT afCmd    // creation flags
);

Parameters

idInst
Specifies the application instance identifier obtained by a previous call to the DdeInitialize function.
pSrc
Pointer to a buffer that contains data to be copied to the DDE object. If this parameter is NULL, no data is copied to the object.
cb
Specifies the amount of memory, in bytes, to copy from the buffer pointed to by pSrc. (include the terminating NULL, if the data is a string). If this parameter is zero, the pSrc parameter is ignored.
cbOff
Specifies an offset, in bytes, from the beginning of the buffer pointed to by the pSrc parameter. The data beginning at this offset is copied from the buffer to the DDE object.
hszItem
Handle to the string that specifies the data item corresponding to the DDE object. This handle must have been created by a previous call to the DdeCreateStringHandle function. If the data handle is to be used in an XTYP_EXECUTE transaction, this parameter must be 0L.
wFmt
Specifies the standard clipboard format of the data.
afCmd
Specifies the creation flags. This parameter can be HDATA_APPOWNED, which specifies that the server application calling the DdeCreateDataHandle function owns the data handle this function creates. This flag enables the application to share the data handle with other Dynamic Data Exchange Management Library (DDEML) applications rather than creating a separate handle to pass to each application. If this flag is specified, the application must eventually free the shared memory object associated with the handle by using the DdeFreeDataHandle function. If this flag is not specified, the handle becomes invalid in the application that created the handle after the data handle is returned by the application's DDE callback function or is used as a parameter in another DDEML function.

Return Values

If the function succeeds, the return value is a data handle.

If the function fails, the return value is 0L.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_MEMORY_ERROR
DMLERR_NO_ERROR

Remarks

Any unfilled locations in the DDE object are undefined.

After a data handle has been used as a parameter in another DDEML function or has been returned by a DDE callback function, the handle may be used only for read access to the DDE object identified by the handle.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeAccessData, DdeCreateStringHandle, DdeFreeDataHandle, DdeGetData, DdeInitialize


DdeCreateStringHandle

The DdeCreateStringHandle function creates a handle that identifies the string pointed to by the psz parameter. A dynamic data exchange (DDE) client or server application can pass the string handle as a parameter to other Dynamic Data Exchange Management Library (DDEML) functions.

HSZ DdeCreateStringHandle(
  DWORD idInst,  // instance identifier
  LPTSTR psz,    // pointer to null-terminated string
  int iCodePage  // code page identifier
);

Parameters

idInst
Specifies the application instance identifier obtained by a previous call to the DdeInitialize function.
psz
Pointer to a buffer that contains the null-terminated string for which a handle is to be created. This string may be up to 255 characters. The reason for this limit is that DDEML string management functions are implemented using global atoms.
iCodePage
Specifies the code page used to render the string. This value should be either CP_WINANSI (the default code page) or CP_WINUNICODE, depending on whether the ANSI or Unicode version of DdeInitialize was called by the client application.

Return Values

If the function succeeds, the return value is a string handle.

If the function fails, the return value is 0L.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR
DMLERR_SYS_ERROR

Remarks

The value of a string handle is not related to the case of the string it identifies.

When an application either creates a string handle or receives one in the callback function and then uses the DdeKeepStringHandle function to keep it, the application must free that string handle when it is no longer needed.

An instance-specific string handle cannot be mapped from string handle to string and back to string handle. This is shown in the following example, in which the DdeQueryString function creates a string from a string handle and DdeCreateStringHandle creates a string handle from that string, but the two handles are not the same:

DWORD idInst;
DWORD cb;
HSZ hszInst, hszNew;
PSZ pszInst;

DdeQueryString(idInst, hszInst, pszInst, cb, CP_WINANSI);
hszNew = DdeCreateStringHandle(idInst, pszInst, CP_WINANSI);
// hszNew != hszInst !

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeAccessData, DdeCmpStringHandles, DdeFreeStringHandle, DdeInitialize, DdeKeepStringHandle, DdeQueryString


DdeDisconnect

The DdeDisconnect function terminates a conversation started by either the DdeConnect or DdeConnectList function and invalidates the specified conversation handle.

BOOL DdeDisconnect(
  HCONV hConv   // handle to conversation
);

Parameters

hConv
Handle to the active conversation to be terminated.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_NO_CONV_ESTABLISHED
DMLERR_NO_ERROR

Remarks

Any incomplete transactions started before calling DdeDisconnect are immediately abandoned. The XTYP_DISCONNECT transaction is sent to the dynamic data exchange (DDE) callback function of the partner in the conversation. Generally, only client applications must terminate conversations.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeConnect, DdeConnectList, DdeDisconnectList, XTYP_DISCONNECT


DdeDisconnectList

The DdeDisconnectList function destroys the specified conversation list and terminates all conversations associated with the list.

BOOL DdeDisconnectList(
  HCONVLIST hConvList   // handle to conversation list
);

Parameters

hConvList
Handle to the conversation list. This handle must have been created by a previous call to the DdeConnectList function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR

Remarks

An application can use the DdeDisconnect function to terminate individual conversations in the list.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeConnect, DdeConnectList, DdeDisconnect


DdeEnableCallback

The DdeEnableCallback function enables or disables transactions for a specific conversation or for all conversations currently established by the calling application.

After disabling transactions for a conversation, the operating system places the transactions for that conversation in a transaction queue associated with the application. The application should reenable the conversation as soon as possible to avoid losing queued transactions.

BOOL DdeEnableCallback(
  DWORD idInst, // instance identifier
  HCONV hConv,  // handle to conversation
  UINT wCmd     // enable or disable function code
);

Parameters

idInst
Specifies the application-instance identifier obtained by a previous call to the DdeInitialize function.
hConv
Handle to the conversation to enable or disable. If this parameter is NULL, the function affects all conversations.
wCmd
Specifies the function code. This parameter can be one of the following values:
Value | Meaning
EC_ENABLEALL | Enables all transactions for the specified conversation.
EC_ENABLEONE | Enables one transaction for the specified conversation.
EC_DISABLE Disables all blockable transactions for the specified conversation.

A server application can disable the following transactions:

XTYP_ADVSTART
XTYP_ADVSTOP
XTYP_EXECUTE
XTYP_POKE
XTYP_REQUEST

A client application can disable the following transactions:

XTYP_ADVDATA
XTYP_XACT_COMPLETE
EC_QUERYWAITING | Determines whether any transactions are in the queue for the specified conversation.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

If the wCmd parameter is EC_QUERYWAITING, and the application transaction queue contains one or more unprocessed transactions that are not being processed, the return value is TRUE; otherwise, it is FALSE.

Errors

Use the DdeGetLastError function to retrieve the error code, which may be one of the following:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_NO_ERROR
DMLERR_INVALIDPARAMETER

Remarks

An application can disable transactions for a specific conversation by returning the CBR_BLOCK return code from its dynamic data exchange (DDE) callback function. When you reenable the conversation by using the DdeEnableCallback function, the operating system generates the same transaction that was in process when the conversation was disabled.

Using the EC_QUERYWAITING flag does not change the enable state of the conversation and does not cause transactions to be issued within the context of the call to DdeEnableCallback.

If DdeEnableCallback is called with EC_QUERYWAITING and the function returns a nonzero, an application should try to quickly allow message processing, return from its callback, or enable callbacks. Such a result does not guarantee that subsequent callbacks will be made. Calling DdeEnableCallback with EC_QUERYWAITING lets an application with blocked callbacks determine whether there are any transactions pending on the blocked conversation. Of course, even if such a call returns zero, an application should always process messages in a timely manner.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeConnect, DdeConnectList, DdeDisconnect, DdeInitialize


DdeFreeDataHandle

The DdeFreeDataHandle function frees a dynamic data exchange (DDE) object and deletes the data handle associated with the object.

BOOL DdeFreeDataHandle(
  HDDEDATA hData   // handle to DDE object
);

Parameters

hData
Handle to the DDE object to be freed. This handle must have been created by a previous call to the DdeCreateDataHandle function or returned by the DdeClientTransaction function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR

Remarks

An application must call DdeFreeDataHandle under the following circumstances:

  • To free a DDE object that the application allocated by calling the DdeCreateDataHandle function if the object's data handle was never passed by the application to another Dynamic Data Exchange Management Library (DDEML) function
  • To free a DDE object that the application allocated by specifying the HDATA_APPOWNED flag in a call to DdeCreateDataHandle
  • To free a DDE object whose handle the application received from the DdeClientTransaction function

The system automatically frees an unowned object when its handle is returned by a DDE callback function or is used as a parameter in a DDEML function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeAccessData, DdeCreateDataHandle, DdeClientTransaction


DdeFreeStringHandle

The DdeFreeStringHandle function frees a string handle in the calling application.

BOOL DdeFreeStringHandle(
  DWORD idInst,  // instance identifier
  HSZ hsz        // handle to string
);

Parameters

idInst
Specifies the application instance identifier obtained by a previous call to the DdeInitialize function.
hsz
Handle to the string handle to be freed. This handle must have been created by a previous call to the DdeCreateStringHandle function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Remarks

An application can free string handles it creates with DdeCreateStringHandle but should not free those that the system passed to the application's dynamic data exchange (DDE) callback function or those returned in the CONVINFO structure by the DdeQueryConvInfo function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, CONVINFO, DdeCmpStringHandles, DdeCreateStringHandle, DdeInitialize, DdeKeepStringHandle, DdeQueryConvInfo, DdeQueryString


DdeGetData

The DdeGetData function copies data from the specified dynamic data exchange (DDE) object to the specified local buffer.

DWORD DdeGetData(
  HDDEDATA hData,  // handle to DDE  object
  LPBYTE pDst,     // pointer to destination buffer
  DWORD cbMax,     // amount of data to copy
  DWORD cbOff      // offset to beginning of data
);

Parameters

hData
Handle to the DDE object that contains the data to copy.
pDst
Pointer to the buffer that receives the data. If this parameter is NULL, the DdeGetData function returns the amount of data, in bytes, that would be copied to the buffer.
cbMax
Specifies the maximum amount of data, in bytes, to copy to the buffer pointed to by the pDst parameter. Typically, this parameter specifies the length of the buffer pointed to by pDst.
cbOff
Specifies an offset within the DDE object. Data is copied from the object beginning at this offset.

Return Values

If the pDst parameter points to a buffer, the return value is the size, in bytes, of the memory object associated with the data handle or the size specified in the cbMax parameter, whichever is lower.

If the pDst parameter is NULL, the return value is the size, in bytes, of the memory object associated with the data handle.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeAccessData, DdeCreateDataHandle, DdeFreeDataHandle


DdeGetLastError

The DdeGetLastError function returns the most recent error code set by the failure of a Dynamic Data Exchange Management Library (DDEML) function and resets the error code to DMLERR_NO_ERROR.

UINT DdeGetLastError(
  DWORD idInst   // instance identifier
);

Parameters

idInst
Specifies the application instance identifier obtained by a previous call to the DdeInitialize function.

Return Values

If the function succeeds, the return value is the last error code. Following are the possible DDEML error codes:

Value | Meaning
DMLERR_ADVACKTIMEOUT | A request for a synchronous advise transaction has timed out.
DMLERR_BUSY | The response to the transaction caused the DDE_FBUSY flag to be set.
DMLERR_DATAACKTIMEOUT | A request for a synchronous data transaction has timed out.
DMLERR_DLL_NOT_INITIALIZED | A DDEML function was called without first calling the DdeInitialize function, or an invalid instance identifier was passed to a DDEML function.
DMLERR_DLL_USAGE | An application initialized as APPCLASS_MONITOR has attempted to perform a dynamic data exchange (DDE) transaction, or an application initialized as APPCMD_CLIENTONLY has attempted to perform server transactions.
DMLERR_EXECACKTIMEOUT | A request for a synchronous execute transaction has timed out.
DMLERR_INVALIDPARAMETER | A parameter failed to be validated by the DDEML. Some of the possible causes follow:
The application used a data handle initialized with a different item name handle than was required by the transaction.

The application used a data handle that was initialized with a different clipboard data format than was required by the transaction.

The application used a client-side conversation handle with a server-side function or vice versa.

The application used a freed data handle or string handle.

More than one instance of the application used the same object.
DMLERR_LOW_MEMORY | A DDEML application has created a prolonged race condition (in which the server application outruns the client), causing large amounts of memory to be consumed.
DMLERR_MEMORY_ERROR | A memory allocation has failed.
DMLERR_NO_CONV_ESTABLISHED | A client's attempt to establish a conversation has failed.
DMLERR_NOTPROCESSED | A transaction has failed.
DMLERR_POKEACKTIMEOUT | A request for a synchronous poke transaction has timed out.
DMLERR_POSTMSG_FAILED | An internal call to the PostMessage function has failed.
DMLERR_REENTRANCY | An application instance with a synchronous transaction already in progress attempted to initiate another synchronous transaction, or the DdeEnableCallback function was called from within a DDEML callback function.
DMLERR_SERVER_DIED | A server-side transaction was attempted on a conversation terminated by the client, or the server terminated before completing a transaction.
DMLERR_SYS_ERROR | An internal error has occurred in the DDEML.
DMLERR_UNADVACKTIMEOUT | A request to end an advise transaction has timed out.
DMLERR_UNFOUND_QUEUE_ID | An invalid transaction identifier was passed to a DDEML function. Once the application has returned from an XTYP_XACT_COMPLETE callback, the transaction identifier for that callback function is no longer valid.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeEnableCallback, DdeInitialize, PostMessage


DdeImpersonateClient

The DdeImpersonateClient function impersonates a dynamic data exchange (DDE) client application in a DDE client conversation.

BOOL DdeImpersonateClient(
  HCONV hConv   // handle to DDE conversation
);

Parameters

hConv
Handle to the DDE client conversation to be impersonated.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Impersonation is the ability of a process to take on the security attributes of another process. When a client in a DDE conversation requests information from a DDE server, the server impersonates the client. When the server requests access to an object, the system verifies the access against the client's security attributes.

When the impersonation is complete, the server normally calls the RevertToSelf function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, ImpersonateNamedPipeClient, RevertToSelf


DdeInitialize

The DdeInitialize function registers an application with the Dynamic Data Exchange Management Library (DDEML). An application must call this function before calling any other DDEML function.

UINT DdeInitialize(
  LPDWORD pidInst,          // pointer to instance identifier
  PFNCALLBACK pfnCallback,  // pointer to callback function
  DWORD afCmd,              // set of command and filter flags
  DWORD ulRes               // reserved
);

Parameters

pidInst
Pointer to the application instance identifier. At initialization, this parameter should point to 0. If the function succeeds, this parameter points to the instance identifier for the application. This value should be passed as the idInst parameter in all other DDEML functions that require it. If an application uses multiple instances of the DDEML dynamic-link library (DLL), the application should provide a different callback function for each instance.

If pidInst points to a nonzero value, reinitialization of the DDEML is implied. In this case, pidInst must point to a valid application-instance identifier.

pfnCallback
Pointer to the application-defined dynamic data exchange (DDE) callback function. This function processes DDE transactions sent by the system. For more information, see the DdeCallback callback function.
afCmd
Specifies a set of APPCMD_, CBF_, and MF_ flags. The APPCMD_ flags provide special instructions to DdeInitialize. The CBF_ flags specify filters that prevent specific types of transactions from reaching the callback function. The MF_ flags specify the types of DDE activity that a DDE monitoring application monitors. Using these flags enhances the performance of a DDE application by eliminating unnecessary calls to the callback function.

This parameter can be a combination of the following filter flags:
Flag | Meaning
APPCLASS_MONITOR | Makes it possible for the application to monitor DDE activity in the system. This flag is for use by DDE monitoring applications. The application specifies the types of DDE activity to monitor by combining one or more monitor flags with the APPCLASS_MONITOR flag. For details, see the following Remarks section.
APPCLASS_STANDARD | Registers the application as a standard (nonmonitoring) DDEML application.
APPCMD_CLIENTONLY | Prevents the application from becoming a server in a DDE conversation. The application can only be a client. This flag reduces consumption of resources by the DDEML. It includes the functionality of the CBF_FAIL_ALLSVRXACTIONS flag.
APPCMD_FILTERINITS | Prevents the DDEML from sending XTYP_CONNECT and XTYP_WILDCONNECT transactions to the application until the application has created its string handles and registered its service names or has turned off filtering by a subsequent call to the DdeNameService or DdeInitialize function. This flag is always in effect when an application calls DdeInitialize for the first time, regardless of whether the application specifies the flag. On subsequent calls to DdeInitialize, not specifying this flag turns off the application's service-name filters, but specifying it turns on the application's service name filters.
CBF_FAIL_ALLSVRXACTIONS | Prevents the callback function from receiving server transactions. The system returns DDE_FNOTPROCESSED to each client that sends a transaction to this application. This flag is equivalent to combining all CBF_FAIL_ flags.
CBF_FAIL_ADVISES | Prevents the callback function from receiving XTYP_ADVSTART and XTYP_ADVSTOP transactions. The system returns DDE_FNOTPROCESSED to each client that sends an XTYP_ADVSTART or XTYP_ADVSTOP transaction to the server.
CBF_FAIL_CONNECTIONS | Prevents the callback function from receiving XTYP_CONNECT and XTYP_WILDCONNECT transactions.
CBF_FAIL_EXECUTES | Prevents the callback function from receiving XTYP_EXECUTE transactions. The system returns DDE_FNOTPROCESSED to a client that sends an XTYP_EXECUTE transaction to the server.
CBF_FAIL_POKES | Prevents the callback function from receiving XTYP_POKE transactions. The system returns DDE_FNOTPROCESSED to a client that sends an XTYP_POKE transaction to the server.
CBF_FAIL_REQUESTS | Prevents the callback function from receiving XTYP_REQUEST transactions. The system returns DDE_FNOTPROCESSED to a client that sends an XTYP_REQUEST transaction to the server.
CBF_FAIL_SELFCONNECTIONS | Prevents the callback function from receiving XTYP_CONNECT transactions from the application's own instance. This flag prevents an application from establishing a DDE conversation with its own instance. An application should use this flag if it needs to communicate with other instances of itself but not with itself.
CBF_SKIP_ALLNOTIFICATIONS | Prevents the callback function from receiving any notifications. This flag is equivalent to combining all CBF_SKIP_ flags.
CBF_SKIP_CONNECT_CONFIRMS | Prevents the callback function from receiving XTYP_CONNECT_CONFIRM notifications.
CBF_SKIP_DISCONNECTS | Prevents the callback function from receiving XTYP_DISCONNECT notifications.
CBF_SKIP_REGISTRATIONS | Prevents the callback function from receiving XTYP_REGISTER notifications.
CBF_SKIP_UNREGISTRATIONS | Prevents the callback function from receiving XTYP_UNREGISTER notifications.
MF_CALLBACKS | Notifies the callback function whenever a transaction is sent to any DDE callback function in the system.
MF_CONV | Notifies the callback function whenever a conversation is established or terminated.
MF_ERRORS | Notifies the callback function whenever a DDE error occurs.
MF_HSZ_INFO | Notifies the callback function whenever a DDE application creates, frees, or increments the usage count of a string handle or whenever a string handle is freed as a result of a call to the DdeUninitialize function.
MF_LINKS | Notifies the callback function whenever an advise loop is started or ended.
MF_POSTMSGS | Notifies the callback function whenever the system or an application posts a DDE message.
MF_SENDMSGS | Notifies the callback function whenever the system or an application sends a DDE message.

ulRes
Reserved; must be set to zero.

Return Values

If the function succeeds, the return value is DMLERR_NO_ERROR.

If the function fails, the return value is one of the following values:

DMLERR_DLL_USAGE
DMLERR_INVALIDPARAMETER
DMLERR_SYS_ERROR

Remarks

An application that uses multiple instances of the DDEML must not pass DDEML objects between instances.

A DDE monitoring application should not attempt to perform DDE operations (establish conversations, issue transactions, and so on) within the context of the same application instance.

A synchronous transaction fails with a DMLERR_REENTRANCY error if any instance of the same task has a synchronous transaction already in progress.

The CBF_FAIL_ALLSVRACTIONS flag causes the DDEML to filter all server transactions and can be changed by a subsequent call to DdeInitialize. The APPCMD_CLIENTONLY flag prevents the DDEML from creating key resources for the server and cannot be changed by a subsequent call to DdeInitialize.

There is an ANSI version and a Unicode version of DdeInitialize. The version called determines the type of the window procedures used to control DDE conversations (ANSI or Unicode), and the default value for the iCodePage member of the CONVCONTXT structure (CP_WINANSI or CP_WINUNICODE).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions


DdeKeepStringHandle

The DdeKeepStringHandle function increments the usage count associated with the specified handle. This function enables an application to save a string handle passed to the application's dynamic data exchange (DDE) callback function. Otherwise, a string handle passed to the callback function is deleted when the callback function returns. This function should also be used to keep a copy of a string handle referenced by the CONVINFO structure returned by the DdeQueryConvInfo function.

BOOL DdeKeepStringHandle(
  DWORD idInst,  // instance identifier
  HSZ hsz        // handle to string
);

Parameters

idInst
Specifies the application instance identifier obtained by a previous call to the DdeInitialize function.
hsz
Handle to the string handle to be saved.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, CONVINFO, DdeCreateStringHandle, DdeFreeStringHandle, DdeInitialize, DdeQueryConvInfo, DdeQueryString


DdeNameService

The DdeNameService function registers or unregisters the service names a dynamic data exchange (DDE) server supports. This function causes the system to send XTYP_REGISTER or XTYP_UNREGISTER transactions to other running Dynamic Data Exchange Management Library (DDEML) client applications.

A server application should call this function to register each service name that it supports and to unregister names it previously registered but no longer supports. A server should also call this function to unregister its service names just before terminating.

HDDEDATA DdeNameService(
  DWORD idInst,  // instance identifier
  HSZ hsz1,      // handle to service name string
  HSZ hsz2,      // reserved
  UINT afCmd     // service name flags
);

Parameters

idInst
Specifies the application instance identifier obtained by a previous call to the DdeInitialize function.
hsz1
Handle to the string that specifies the service name the server is registering or unregistering. An application that is unregistering all of its service names should set this parameter to 0L.
hsz2
Reserved; should be set to 0L.
afCmd
Specifies the service name flags. This parameter can be one of the following flags:
Flag | Meaning
DNS_REGISTER | Registers the error code service name.
DNS_UNREGISTER | Unregisters the error code service name. If the hsz1 parameter is 0L, all service names registered by the server will be unregistered.
DNS_FILTERON | Turns on service name initiation filtering. The filter prevents a server from receiving XTYP_CONNECT transactions for service names it has not registered. This is the default setting for this filter.
If a server application does not register any service names, the application cannot receive XTYP_WILDCONNECT transactions.
DNS_FILTEROFF | Turns off service name initiation filtering. If this flag is specified, the server receives an XTYP_CONNECT transaction whenever another DDE application calls the DdeConnect function, regardless of the service name.

Return Values

If the funcion succeeds, it returns a nonzero value. That value is not a true HDDEDATA value, merely a Boolean indicator of success. The function is typed HDDEDATA to allow for possible future expansion of the function and a more sophisticated return value.

If the function fails, the return value is 0L.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_DLL_USAGE
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR

Remarks

The service name identified by the hsz1 parameter should be a base name (that is, the name should contain no instance-specific information). The system generates an instance-specific name and sends it along with the base name during the XTYP_REGISTER and XTYP_UNREGISTER transactions. The receiving applications can then connect to the specific application instance.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeConnect, DdeConnectList, DdeInitialize, XTYP_REGISTER, XTYP_UNREGISTER


DdePostAdvise

The DdePostAdvise function causes the system to send an XTYP_ADVREQ transaction to the calling (server) application's dynamic data exchange (DDE) callback function for each client with an active advise loop on the specified topic and item. A server application should call this function whenever the data associated with the topic name or item name pair changes.

BOOL DdePostAdvise(
  DWORD idInst, // instance identifier
  HSZ hszTopic, // handle to topic name string
  HSZ hszItem   // handle to item name string
);

Parameters

idInst
Specifies the application instance identifier obtained by a previous call to the DdeInitialize function.
hszTopic
Handle to a string that specifies the topic name. To send notifications for all topics with active advise loops, an application can set this parameter to 0L.
hszItem
Handle to a string that specifies the item name. To send notifications for all items with active advise loops, an application can set this parameter to 0L.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_DLL_USAGE
DMLERR_NO_ERROR

Remarks

A server that has nonenumerable topics or items should set the hszTopic and hszItem parameters to NULL so that the system generates transactions for all active advise loops. The server's DDE callback function returns NULL for any advise loops that must not be updated.

If a server calls DdePostAdvise with a topic, item, and format name set that includes the set currently being handled in an XTYP_ADVREQ callback, a stack overflow may result.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeInitialize, XTYP_ADVREQ


DdeQueryConvInfo

The DdeQueryConvInfo function obtains information about a dynamic data exchange (DDE) transaction and about the conversation in which the transaction takes place.

UINT DdeQueryConvInfo(
  HCONV hConv,          // handle to conversation
  DWORD idTransaction,  // transaction identifier
  PCONVINFO pConvInfo   // pointer to structure with conversation
                        // data
);

Parameters

hConv
Handle to the conversation.
idTransaction
Specifies the transaction. For asynchronous transactions, this parameter should be a transaction identifier returned by the DdeClientTransaction function. For synchronous transactions, this parameter should be QID_SYNC.
pConvInfo
Pointer to the CONVINFO structure that receives information about the transaction and conversation. The cb member of the CONVINFO structure must specify the length of the buffer allocated for the structure.

Return Values

If the function succeeds, the return value is the number of bytes copied into the CONVINFO structure.

If the function fails, the return value is FALSE.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_NO_CONV_ESTABLISHED
DMLERR_NO_ERROR
DMLERR_UNFOUND_QUEUE_ID

Remarks

An application should not free a string handle referenced by the CONVINFO structure. If an application must use one of these string handles, it should call the DdeKeepStringHandle function to create a copy of the handle.

If the idTransaction parameter is set to QID_SYNC, the hUser member of the CONVINFO structure is associated with the conversation and can be used to hold data associated with the conversation. If idTransaction is the identifier of an asynchronous transaction, the hUser member is associated only with the current transaction and is valid only for the duration of the transaction.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, CONVINFO, DdeClientTransaction, DdeConnect, DdeConnectList, DdeKeepStringHandle, DdeQueryNextServer


DdeQueryNextServer

The DdeQueryNextServer function obtains the next conversation handle in the specified conversation list.

HCONV DdeQueryNextServer(
  HCONVLIST hConvList,  // handle to conversation list
  HCONV hConvPrev       // previous conversation handle
);

Parameters

hConvList
Handle to the conversation list. This handle must have been created by a previous call to the DdeConnectList function.
hConvPrev
Handle to the conversation handle previously returned by this function. If this parameter is 0L, the function returns the first conversation handle in the list.

Return Values

If the list contains any more conversation handles, the return value is the next conversation handle in the list; otherwise, it is 0L.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeConnectList, DdeDisconnectList


DdeQueryString

The DdeQueryString function copies text associated with a string handle into a buffer.

DWORD DdeQueryString(
  DWORD idInst,  // instance identifier
  HSZ hsz,       // handle to string
  LPTSTR psz,    // pointer to destination buffer
  DWORD cchMax,  // length of buffer
  int iCodePage  // code page identifier
);

Parameters

idInst
Specifies the application instance identifier obtained by a previous call to the DdeInitialize function.
hsz
Handle to the string to copy. This handle must have been created by a previous call to the DdeCreateStringHandle function.
psz
Pointer to a buffer that receives the string. To obtain the length of the string, this parameter should be set to NULL.
cchMax
Specifies the length, in characters, of the buffer pointed to by the psz parameter. If the string is longer than (cchMax – 1), it will be truncated. If the psz parameter is set to NULL, this parameter is ignored.
iCodePage
Specifies the code page used to render the string. This value should be either CP_WINANSI or CP_WINUNICODE.

Return Values

If the psz parameter specified a valid pointer, the return value is the length, in characters, of the returned text (not including the terminating null character). If the psz parameter specified a NULL pointer, the return value is the length of the text associated with the hsz parameter (not including the terminating null character). If an error occurs, the return value is 0L.

Remarks

The string returned in the buffer is always null-terminated. If the string is longer than (cchMax – 1), only the first (cchMax – 1) characters of the string are copied.

If the psz parameter is NULL, the DdeQueryString function obtains the length, in bytes, of the string associated with the string handle. The length does not include the terminating null character.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeCmpStringHandles, DdeCreateStringHandle, DdeFreeStringHandle, DdeInitialize


DdeReconnect

The DdeReconnect function allows a client Dynamic Data Exchange Management Library (DDEML) application to attempt to reestablish a conversation with a service that has terminated a conversation with the client. When the conversation is reestablished, the DDEML attempts to reestablish any preexisting advise loops.

HCONV DdeReconnect(
  HCONV hConv   // handle to conversation to reestablish
);

Parameters

hConv
Handle to the conversation to be reestablished. A client must have obtained the conversation handle by a previous call to the DdeConnect function or from an XTYP_DISCONNECT transaction.

Return Values

If the function succeeds, the return value is the handle to the reestablished conversation.

If the function fails, the return value is 0L.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_CONV_ESTABLISHED
DMLERR_NO_ERROR

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeConnect, DdeDisconnect


DdeSetUserHandle

The DdeSetUserHandle function associates an application-defined 32-bit value with a conversation handle or a transaction identifier. This is useful for simplifying the processing of asynchronous transactions. An application can use the DdeQueryConvInfo function to retrieve this value.

BOOL DdeSetUserHandle(
  HCONV hConv,  // handle to conversation
  DWORD id,     // transaction identifier
  DWORD hUser   // handle to application-defined value
);

Parameters

hConv
Handle to the conversation.
id
Specifies the transaction identifier to associate with the value specified by the hUser parameter. An application should set this parameter to QID_SYNC to associate hUser with the conversation identified by the hConv parameter.
hUser
Handle to the value to associate with the conversation handle.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR
DMLERR_UNFOUND_QUEUE_ID

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeQueryConvInfo


DdeUnaccessData

The DdeUnaccessData function unaccesses a dynamic data exchange (DDE) object. An application must call this function after it has finished accessing the object.

BOOL DdeUnaccessData(
  HDDEDATA hData   // handle to DDE object
);

Parameters

hData
Handle to the DDE object.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Errors

The DdeGetLastError function can be used to get the error code, which may be one of the following values:

DMLERR_DLL_NOT_INITIALIZED
DMLERR_INVALIDPARAMETER
DMLERR_NO_ERROR

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeAccessData, DdeAddData, DdeCreateDataHandle, DdeFreeDataHandle


DdeUninitialize

The DdeUninitialize function frees all Dynamic Data Exchange Management Library (DDEML) resources associated with the calling application.

BOOL DdeUninitialize(
  DWORD idInst   // instance identifier
);

Parameters

idInst
Specifies the application instance identifier obtained by a previous call to the DdeInitialize function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Remarks

DdeUninitialize terminates any conversations currently open for the application.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Import Library: Use user32.lib.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Functions, DdeDisconnect, DdeDisconnectList, DdeInitialize


Dynamic Data Exchange Management Structures

The following structures are used to manage dynamic data exchange.

CONVCONTEXT
CONVINFO
DDEML_MSG_HOOK_DATA
MONCBSTRUCT
MONCONVSTRUCT
MONERRSTRUCT
MONHSZSTRUCT
MONLINKSTRUCT
MONMSGSTRUCT


CONVCONTEXT

The CONVCONTEXT structure contains information supplied by a DDE client application. The information is useful for specialized or cross-language DDE conversations.

typedef struct tagCONVCONTEXT {   // cc
    UINT  cb;
    UINT  wFlags;
    UINT  wCountryID;
    int   iCodePage;
    DWORD dwLangID;
    DWORD dwSecurity;
    SECURITY_QUALITY_OF_SERVICE qos;  // client side's quality of service
} CONVCONTEXT;

Members

cb
Specifies the structure's size, in bytes.
wFlags
Specifies conversation context flags. Currently, no flags are defined for this member.
wCountryID
Specifies the country-code identifier for topic-name and item-name strings.
iCodePage
Specifies the code page for topic-name and item-name strings. Non-multilingual clients should set this member to CP_WINANSI. Unicode clients should set this value to CP_WINUNICODE.
dwLangID
Specifies the language identifier for topic-name and item-name strings.
dwSecurity
Specifies a private (application-defined) security code.
qos
Specifies the quality of service a DDE client wants from the system during a given conversation. The quality of service level specified lasts for the duration of the conversation. It cannot be changed once the conversation is started.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Structures


CONVINFO

The CONVINFO structure contains information about a DDE conversation.

typedef struct tagCONVINFO {  // ci
    DWORD       cb;
    DWORD       hUser;
    HCONV       hConvPartner;
    HSZ         hszSvcPartner;
    HSZ         hszServiceReq;
    HSZ         hszTopic;
    HSZ         hszItem;
    UINT        wFmt;
    UINT        wType;
    UINT        wStatus;
    UINT        wConvst;
    UINT        wLastError;
    HCONVLIST   hConvList;
    CONVCONTEXT ConvCtxt;
    HWND        hwnd;
    HWND        hwndPartner;
} CONVINFO;

Members

cb
Specifies the structure's size, in bytes.
hUser
Handle to application-defined data.
hConvPartner
Handle to the partner application in the DDE conversation. This member is zero if the partner has not registered itself (using the DdeInitialize function) to make DDE Management Library (DDEML) function calls. An application should not pass this member to any DDEML function except DdeQueryConvInfo.
hszSvcPartner
Handle to the service name of the partner application.
hszServiceReq
Handle to the service name of the server application that was requested for connection.
hszTopic
Handle to the name of the requested topic.
hszItem
Handle to the name of the requested item. This member is transaction specific.
wFmt
Specifies the format of the data being exchanged. This member is transaction specific.
wType
Specifies the type of the current transaction. This member is transaction specific; it can be one of the following values:
Value | Meaning
XTYP_ADVDATA | Informs a client that advise data from a server has arrived.
XTYP_ADVREQ | Requests a server to send updated data to the client during an advise loop. This transaction results when the server calls DdePostAdvise.
XTYP_ADVSTART | Requests a server to begin an advise loop with a client.
XTYP_ADVSTOP | Notifies a server that an advise loop is stopping.
XTYP_CONNECT | Requests a server to establish a conversation with a client.
XTYP_CONNECT_CONFIRM | Notifies a server that a conversation with a client has been established.
XTYP_DISCONNECT | Notifies a server that a conversation has terminated.
XTYP_EXECUTE | Requests a server to execute a command sent by a client.
XTYP_MONITOR | Notifies an application registered as APPCMD_MONITOR that DDE data is being transmitted.
XTYP_POKE | Requests a server to accept unsolicited data from a client.
XTYP_REGISTER | Notifies other DDEML applications that a server has registered a service name.
XTYP_REQUEST | Requests a server to send data to a client.
XTYP_UNREGISTER | Notifies other DDEML applications that a server has unregistered a service name.
XTYP_WILDCONNECT | Requests a server to establish multiple conversations with the same client.
XTYP_XACT_COMPLETE | Notifies a client that an asynchronous data transaction has been completed.

wStatus
Specifies the status of the current conversation. This member can be a combination of the following values:
Value | Meaning
ST_ADVISE | One or more links are in progress.
ST_BLOCKED | The conversation is blocked.
ST_BLOCKNEXT | The conversation will block after calling the next callback.
ST_CLIENT | The conversation handle passed to the DdeQueryConvInfo function is a client-side handle. If the handle is zero, the conversation handle passed to the DdeQueryConvInfo function is a server-side handle.
ST_CONNECTED | The conversation is connected.
ST_INLIST | The conversation is a member of a conversation list.
ST_ISLOCAL | Both sides of the conversation are using the DDEML.
ST_ISSELF | Both sides of the conversation are using the same instance of the DDEML.
ST_TERMINATED | The conversation has been terminated by the partner.

wConvst
Specifies the conversation state. This member can be one of the following values:
Value | Meaning
XST_ADVACKRCVD | The advise transaction has just been completed.
XST_ADVDATAACKRCVD | The advise data transaction has just been completed.
XST_ADVDATASENT | Advise data has been sent and is awaiting an acknowledgement.
XST_ADVSENT | An advise transaction is awaiting an acknowledgement.
XST_CONNECTED | The conversation has no active transactions.
XST_DATARCVD | The requested data has just been received.
XST_EXECACKRCVD | An execute transaction has just been completed.
XST_EXECSENT | An execute transaction is awaiting an acknowledgement.
XST_INCOMPLETE | The last transaction failed.
XST_INIT1 | Mid-initiate state 1.
XST_INIT2 | Mid-initiate state 2.
XST_NULL | Pre-initiate state.
XST_POKEACKRCVD | A poke transaction has just been completed.
XST_POKESENT | A poke transaction is awaiting an acknowledgement.
XST_REQSENT | A request transaction is awaiting an acknowledgement.
XST_UNADVACKRCVD | An unadvise transaction has just been completed.
XST_UNADVSENT | An unadvise transaction is awaiting an acknowledgement.

wLastError
Specifies the error value associated with the last transaction.
hConvList
Handle to the conversation list if the handle of the current conversation is in a conversation list. This member is NULL if the conversation is not in a conversation list.
ConvCtxt
Specifies the conversation context.
hwnd
Handle to the window of the calling application involved in the conversation.
hwndPartner
Handle to the window of the partner application involved in the current conversation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Structures, CONVCONTEXT, DdeInitialize, DdePostAdvise, DdeQueryConvInfo


DDEML_MSG_HOOK_DATA

The DDEML_MSG_HOOK_DATA structure contains information about a DDE message, and provides read access to the data referenced by the message. This structure is intended to be used by a DDE Management Library (DDEML) monitoring application.

typedef struct tagDDEML_MSG_HOOK_DATA { // dmhd
    UINT  uiLo;
    UINT  uiHi;
    DWORD cbData;
    DWORD Data[8];
} DDEML_MSG_HOOK_DATA;

Members

uiLo
Specifies the unpacked low-order word of the lParam parameter associated with the DDE message.
uiHi
Specifies the unpacked high-order word of the lParam parameter associated with the DDE message.
cbData
Specifies the amount, in bytes, of data being passed with the message. This value can be greater than 32.
Data
Contains the first 32 bytes of data being passed with the message
(8 * sizeof(DWORD)).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Structures, MONCBSTRUCT, MONCONVSTRUCT, MONERRSTRUCT, MONHSZSTRUCT, MONLINKSTRUCT, MONMSGSTRUCT


MONCBSTRUCT

The MONCBSTRUCT structure contains information about the current DDE transaction. A DDE debugging application can use this structure when monitoring transactions that the system passes to the DDE callback functions of other applications.

typedef struct tagMONCBSTRUCT { // mcbst
    UINT   cb;
    DWORD  dwTime;
    HANDLE hTask;
    DWORD  dwRet;
    UINT   wType;
    UINT   wFmt;
    HCONV  hConv;
    HSZ    hsz1;
    HSZ    hsz2;
    HDDEDATA hData;
    DWORD    dwData1;
    DWORD    dwData2;
    CONVCONTEXT cc;
    DWORD  cbData;
    DWORD  Data[8];
} MONCBSTRUCT;

Members

cb
Specifies the structure's size, in bytes.
dwTime
Specifies the Windows time at which the transaction occurred. Windows time is the number of milliseconds that have elapsed since the system was booted.
hTask
Handle to the task (application instance) containing the DDE callback function that received the transaction.
dwRet
Specifies the value returned by the DDE callback function that processed the transaction.
wType
Specifies the transaction type.
wFmt
Specifies the format of the data exchanged (if any) during the transaction.
hConv
Handle to the conversation in which the transaction took place.
hsz1
Handle to a string.
hsz2
Handle to a string.
hData
Handle to the data exchanged (if any) during the transaction.
dwData1
Specifies additional data.
dwData2
Specifies additional data.
cc
Specifies a CONVCONTEXT structure containing language information used to share data in different languages.
cbData
Specifies the amount, in bytes, of data being passed with the transaction. This value may be more than 32 bytes.
Data
Contains the first 32 bytes of data being passed with the transaction
(8 * sizeof(DWORD)).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Structures, CONVCONTEXT, MONERRSTRUCT, MONHSZSTRUCT, MONLINKSTRUCT, MONMSGSTRUCT


MONCONVSTRUCT

The MONCONVSTRUCT structure contains information about a DDE conversation. A DDE monitoring application can use this structure to obtain information about a conversation that has been established or has terminated.

typedef struct tagMONCONVSTRUCT { // mcvst
    UINT   cb;
    BOOL   fConnect;
    DWORD  dwTime;
    HANDLE hTask;
    HSZ    hszSvc;
    HSZ    hszTopic;
    HCONV  hConvClient;
    HCONV  hConvServer;
} MONCONVSTRUCT;

Members

cb
Specifies the structure's size, in bytes.
fConnect
Indicates whether the conversation is currently established. A value of TRUE indicates the conversation is established; FALSE indicates it is not.
dwTime
Specifies the Windows time at which the conversation was established or terminated. Windows time is the number of milliseconds that have elapsed since the system was booted.
hTask
Handle to a task (application instance) that is a partner in the conversation.
hszSvc
Handle to the service name on which the conversation is established.
hszTopic
Handle to the topic name on which the conversation is established.
hConvClient
Handle to the client conversation.
hConvServer
Handle to the server conversation.

Remarks

Because string handles are local to the process, the hszSvc and hszTopic members are global atoms. Similarly, conversation handles are local to the instance; therefore, the hConvClient and hConvServer members are window handles.

The hConvClient and hConvServer members of the MONCONVSTRUCT structure do not hold the same value as would be seen by the applications engaged in the conversation. Instead, they hold a globally unique pair of values that identify the conversation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Structures, MONCBSTRUCT, MONERRSTRUCT, MONHSZSTRUCT, MONLINKSTRUCT, MONMSGSTRUCT


MONERRSTRUCT

The MONERRSTRUCT structure contains information about the current DDE error. A DDE monitoring application can use this structure to monitor errors returned by DDE Management Library functions.

typedef struct tagMONERRSTRUCT { // mest
    UINT   cb;
    UINT   wLastError;
    DWORD  dwTime;
    HANDLE hTask;
} MONERRSTRUCT;

Members

cb
Specifies the structure's size, in bytes.
wLastError
Specifies the current error.
dwTime
Specifies the Windows time at which the error occurred. Windows time is the number of milliseconds that have elapsed since the system was booted.
hTask
Handle to the task (application instance) that called the DDE function that caused the error.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Structures, MONCBSTRUCT, MONCONVSTRUCT, MONHSZSTRUCT, MONLINKSTRUCT, MONMSGSTRUCT


MONHSZSTRUCT

The MONHSZSTRUCT structure contains information about a DDE string handle. A DDE monitoring application can use this structure when monitoring the activity of the string manager component of the DDE Management Library.

typedef struct tagMONHSZSTRUCT { // mhst
    UINT   cb;
    BOOL   fsAction;
    DWORD  dwTime;
    HSZ    hsz;
    HANDLE hTask;
    TCHAR   str[1];
} MONHSZSTRUCT;

Members

cb
Specifies the structure's size, in bytes.
fsAction
Specifies the action being performed on the string identified by the hsz member.
Value | Meaning
MH_CLEANUP | An application is freeing its DDE resources, causing the system to delete string handles the application had created. (The application called the DdeUninitialize function.)
MH_CREATE | An application is creating a string handle. (The application called the DdeCreateStringHandle function.)
MH_DELETE | An application is deleting a string handle. (The application called the DdeFreeStringHandle function.)
MH_KEEP | An application is increasing the usage count of a string handle. (The application called the DdeKeepStringHandle function.)

dwTime
Specifies the Windows time at which the action specified by the fsAction member takes place. Windows time is the number of milliseconds that have elapsed since the system was booted.
hsz
Handle to the string. Because string handles are local to the process, this member is a global atom.
hTask
Handle to the task (application instance) performing the action on the string handle.
str
Pointer to the string identified by the hsz member.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Structures, MONCBSTRUCT, MONCONVSTRUCT, MONERRSTRUCT, MONLINKSTRUCT, MONMSGSTRUCT


MONLINKSTRUCT

The MONLINKSTRUCT structure contains information about a DDE advise loop. A DDE monitoring application can use this structure to obtain information about an advise loop that has started or ended.

typedef struct tagMONLINKSTRUCT { // mlst
    UINT   cb;
    DWORD  dwTime;
    HANDLE hTask;
    BOOL   fEstablished;
    BOOL   fNoData;
    HSZ    hszSvc;
    HSZ    hszTopic;
    HSZ    hszItem;
    UINT   wFmt;
    BOOL   fServer;
    HCONV  hConvServer;
    HCONV  hConvClient;
} MONLINKSTRUCT;

Members

cb
Specifies the structure's size, in bytes.
dwTime
Specifies the Windows time at which the advise loop was started or ended. Windows time is the number of milliseconds that have elapsed since the system was booted.
hTask
Handle to a task (application instance) that is a partner in the advise loop.
fEstablished
Indicates whether an advise loop was successfully established. A value of TRUE indicates an advise loop was established; FALSE indicates it was not.
fNoData
Indicates whether the XTYPF_NODATA flag is set for the advise loop. A value of TRUE indicates the flag is set; FALSE indicates it is not.
hszSvc
Handle to the service name of the server in the advise loop.
hszTopic
Handle to the topic name on which the advise loop is established.
hszItem
Handle to the item name that is the subject of the advise loop.
wFmt
Specifies the format of the data exchanged (if any) during the advise loop.
fServer
Indicates whether the link notification came from the server. A value of TRUE indicates the notification came from the server; FALSE indicates otherwise.
hConvServer
Handle to the server conversation.
hConvClient
Handle to the client conversation.

Remarks

Because string handles are local to the process, the hszSvc, hszTopic, and hszItem members are global atoms.

The hConvClient and hConvServer members of the MONLINKSTRUCT structure do not hold the same value as would be seen by the applications engaged in the conversation. Instead, they hold a globally unique pair of values that identify the conversation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Structures, MONCBSTRUCT, MONERRSTRUCT, MONHSZSTRUCT, MONMSGSTRUCT


MONMSGSTRUCT

The MONMSGSTRUCT structure contains information about a DDE message. A DDE monitoring application can use this structure to obtain information about a DDE message that was sent or posted.

typedef struct tagMONMSGSTRUCT { // mmst
    UINT   cb;
    HWND   hwndTo;
    DWORD  dwTime;
    HANDLE hTask;
    UINT   wMsg;
    WPARAM wParam;
    LPARAM lParam;
    DDEML_MSG_HOOK_DATA dmhd;
} MONMSGSTRUCT;

Members

cb
Specifies the structure's size, in bytes.
hwndTo
Handle to the window that receives the DDE message.
dwTime
Specifies the Windows time at which the message was sent or posted. Windows time is the number of milliseconds that have elapsed since the system was booted.
hTask
Handle to the task (application instance) containing the window that receives the DDE message.
wMsg
Specifies the identifier of the DDE message.
wParam
Specifies the wParam parameter of the DDE message.
lParam
Specifies the lParam parameter of the DDE message.
dmhd
Specifies a DDEML_MSG_HOOK_DATA structure that contains additional information about the DDE message.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Structures, DDEML_MSG_HOOK_DATA, MONCBSTRUCT, MONCONVSTRUCT, MONERRSTRUCT, MONHSZSTRUCT, MONLINKSTRUCT


Dynamic Data Exchange Management Transactions

The following transactions are used to manage dynamic data exchange.

XTYP_ADVDATA
XTYP_ADVREQ
XTYP_ADVSTART
XTYP_ADVSTOP
XTYP_CONNECT
XTYP_CONNECT_CONFIRM
XTYP_DISCONNECT
XTYP_ERROR
XTYP_EXECUTE
XTYP_MONITOR
XTYP_POKE
XTYP_REGISTER
XTYP_REQUEST
XTYP_UNREGISTER
XTYP_WILDCONNECT
XTYP_XACT_COMPLETE


XTYP_ADVDATA

XTYP_ADVDATA

A dynamic data exchange (DDE) client callback function receives the XTYP_ADVDATA transaction after establishing an advise loop with a server. This transaction informs the client that the value of the data item has changed.

Parameters

uFmt
Specifies the format atom of the data sent from the server.
hconv
Handle to the conversation.
hsz1
Handle to the topic name.
hsz2
Handle to the item name.
hdata
Handle to the data associated with the topic name and item name pair. This parameter is NULL if the client specified the XTYPF_NODATA flag when it requested the advise loop.
dwData1
Not used.
dwData2
Not used.

Return Values

A DDE callback function should return DDE_FACK if it processes this transaction, DDE_FBUSY if it is too busy to process this transaction, or DDE_FNOTPROCESSED if it rejects this transaction.

Remarks

An application must not free the data handle obtained during this transaction. An application must, however, copy the data associated with the data handle if the application must process the data after the callback function returns. An application can use the DdeGetData function to copy the data.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, DdeClientTransaction, DdeGetData, DdePostAdvise


XTYP_ADVREQ

XTYP_ADVREQ

The system sends the XTYP_ADVREQ transaction to a server after the server calls the DdePostAdvise function. This transaction informs the server that an advise transaction is outstanding on the specified topic name and item name pair and that data corresponding to the topic name and item name pair has changed.

Parameters

uFmt
Specifies the format in which the data should be submitted to the client.
hconv
Handle to the conversation.
hsz1
Handle to the topic name.
hsz2
Handle to the item name that has changed.
hdata
Not used.
dwData1
Specifies the count, in the low-order word, of XTYP_ADVREQ transactions that remain to be processed on the same topic, item, and format name set within the context of the current call to the DdePostAdvise function. The count is zero if the current XTYP_ADVREQ transaction is the last one. A server can use this count to determine whether to create an HDATA_APPOWNED data handle for the advise data.

The low-order word is set to CADV_LATEACK if the Dynamic Data Exchange Management Library (DDEML) issued the XTYP_ADVREQ transaction because of a late-arriving DDE_ACK message from a client being outrun by the server.

The high-order word is not used.

dwData2
Not used.

Return Values

The server should first call the DdeCreateDataHandle function to create a data handle that identifies the changed data and then return the handle. The server should return NULL if it is unable to complete the transaction.

Remarks

A server cannot block this transaction type; the CBR_BLOCK return code is ignored.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, DdeCreateDataHandle, DdeInitialize, DdePostAdvise


XTYP_ADVSTART

XTYP_ADVSTART

A dynamic data exchange (DDE) server callback function receives the XTYP_ADVSTART transaction when a client specifies XTYP_ADVSTART as the uType parameter of the DdeClientTransaction function. A client uses this transaction to establish an advise loop with a server.

Parameters

uFmt
Specifies the data format requested by the client.
hconv
Handle to the conversation.
hsz1
Handle to the topic name.
hsz2
Handle to the item name.
hdata
Not used.
dwData1
Not used.
dwData2
Not used.

Return Values

A server callback function should return TRUE to allow an advise loop on the specified topic name and item name pair, or FALSE to deny the advise loop. If the callback function returns TRUE, any subsequent calls to the DdePostAdvise function by the server on the same topic name and item name pair causes the system to send XTYP_ADVREQ transactions to the server.

Remarks

If a client requests an advise loop on a topic name, item name, and data format for an advise loop that is already established, the Dynamic Data Exchange Management Library (DDEML) does not create a duplicate advise loop but instead alters the advise loop flags (XTYPF_ACKREQ and XTYPF_NODATA) to match the latest request.

This transaction is filtered if the server application specified the CBF_FAIL_ADVISES flag in the DdeInitialize function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, DdeClientTransaction, DdeInitialize, DdePostAdvise


XTYP_ADVSTOP

XTYP_ADVSTOP

A dynamic data exchange (DDE) server callback function receives the XTYP_ADVSTOP transaction when a client specifies XTYP_ADVSTOP in the DdeClientTransaction function. A client uses this transaction to end an advise loop with a server.

Parameters

uFmt
Specifies the data format associated with the advise loop being ended.
hconv
Handle to the conversation.
hsz1
Handle to the topic name.
hsz2
Handle to the item name.
hdata
Not used.
dwData1
Not used.
dwData2
Not used.

Remarks

This transaction is filtered if the server application specified the CBF_FAIL_ADVISES flag in the DdeInitialize function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, DdeClientTransaction, DdeInitialize, DdePostAdvise


XTYP_CONNECT

XTYP_CONNECT

A dynamic data exchange (DDE) server callback function receives the XTYP_CONNECT transaction when a client specifies a service name that the server supports and a topic name that is not NULL in a call to the DdeConnect function.

Parameters

uFmt
Not used.
hconv
Not used.
hsz1
Handle to the topic name.
hsz2
Handle to the service name.
hdata
Not used.
dwData1
Pointer to a CONVCONTEXT structure that contains context information for the conversation. If the client is not a Dynamic Data Exchange Management Library (DDEML) application, this parameter is 0.
dwData2
Specifies whether the client is the same application instance as the server. If the parameter is 1, the client is the same instance. If the parameter is 0, the client is a different instance.

Return Values

A server callback function should return TRUE to allow the client to establish a conversation on the specified service name and topic name pair, or the function should return FALSE to deny the conversation. If the callback function returns TRUE and a conversation is successfully established, the system passes the conversation handle to the server by issuing an XTYP_CONNECT_CONFIRM transaction to the server's callback function (unless the server specified the CBF_SKIP_CONNECT_CONFIRMS flag in the DdeInitialize function).

Remarks

This transaction is filtered if the server application specified the CBF_FAIL_CONNECTIONS flag in the DdeInitialize function.

A server cannot block this transaction type; the CBR_BLOCK return code is ignored.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, CONVCONTEXT, DdeConnect, DdeInitialize


XTYP_CONNECT_CONFIRM

XTYP_CONNECT_CONFIRM

A dynamic data exchange (DDE) server callback function receives the XTYP_CONNECT_CONFIRM transaction to confirm that a conversation has been established with a client and to provide the server with the conversation handle. The system sends this transaction as a result of a previous XTYP_CONNECT or XTYP_WILDCONNECT transaction.

Parameters

uFmt
Not used.
hconv
Handle to the new conversation.
hsz1
Handle to the topic name on which the conversation has been established.
hsz2
Handle to the service name on which the conversation has been established.
hdata
Not used.
dwData1
Not used.
dwData2
Specifies whether the client is the same application instance as the server. If the parameter is 1, the client is the same instance. If the parameter is 0, the client is a different instance.

Remarks

This transaction is filtered if the server application specified the CBF_SKIP_CONNECT_CONFIRMS flag in the DdeInitialize function.

A server cannot block this transaction type; the CBR_BLOCK return code is ignored.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, DdeConnect, DdeConnectList, DdeInitialize


XTYP_DISCONNECT

XTYP_DISCONNECT

An application's dynamic data exchange (DDE) callback function receives the XTYP_DISCONNECT transaction when the application's partner in a conversation uses the DdeDisconnect function to terminate the conversation.

Parameters

uFmt
Not used.
hconv
Handle to that the conversation was terminated.
hsz1
Not used.
hsz2
Not used.
hdata
Not used.
dwData1
Not used.
dwData2
Specifies whether the partners in the conversation are the same application instance. If this parameter is 1, the partners are the same instance. If this parameter is 0, the partners are different instances.

Remarks

This transaction is filtered if the application specified the CBF_SKIP_DISCONNECTS flag in the DdeInitialize function.

The application can obtain the status of the terminated conversation by calling the DdeQueryConvInfo function while processing this transaction. The conversation handle becomes invalid after the callback function returns.

An application cannot block this transaction type; the CBR_BLOCK return code is ignored.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, DdeDisconnect, DdeInitialize, DdeQueryConvInfo


XTYP_ERROR

XTYP_ERROR

A dynamic data exchange (DDE) callback function receives the XTYP_ERROR transaction when a critical error occurs.

Parameters

uFmt
Not used.
hconv
Handle to the conversation associated with the error. This parameter is NULL if the error is not associated with a conversation.
hsz1
Not used.
hsz2
Not used.
hdata
Not used.
dwData1
Specifies the error code in the low-order word. Currently, only the following error code is supported:
Error Code | Description
DMLERR_LOW_MEMORY | Memory is low; advise, poke, or execute data may be lost, or the system may fail.

dwData2
Not used.

Remarks

An application cannot block this transaction type; the CBR_BLOCK return code is ignored. The DDEML attempts to free memory by removing noncritical resources. An application that has blocked conversations should unblock them.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions


XTYP_EXECUTE

XTYP_EXECUTE

A dynamic data exchange (DDE) server callback function receives the XTYP_EXECUTE transaction when a client specifies XTYP_EXECUTE in the DdeClientTransaction function. A client uses this transaction to send a command string to the server.

Parameters

uFmt
Not used.
hconv
Handle to the conversation.
hsz1
Handle to the topic name.
hsz2
Not used.
hdata
Handle to the command string.
dwData1
Not used.
dwData2
Not used.

Return Values

A server callback function should return DDE_FACK if it processes this transaction, DDE_FBUSY if it is too busy to process this transaction, or DDE_FNOTPROCESSED if it rejects this transaction.

Remarks

This transaction is filtered if the server application specified the CBF_FAIL_EXECUTES flag in the DdeInitialize function.

An application must free the data handle obtained during this transaction. An application must, however, copy the command string associated with the data handle if the application must process the string after the callback function returns. An application can use the DdeGetData function to copy the data.

Because most client applications expect a server application to perform an XTYP_EXECUTE transaction synchonrously, a server should attempt to perform all processing of the XTYP_EXECUTE transaction either from within the DDE callback function or by returning the CBR_BLOCK return code. If the hdata parameter is a command that instructs the server to terminate, the server should do so after processing the XTYP_EXECUTE transaction.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, DdeClientTransaction, DdeGetData, DdeInitialize


XTYP_MONITOR

XTYP_MONITOR

The dynamic data exchange (DDE) callback function of a DDE debugging application receives the XTYP_MONITOR transaction whenever a DDE event occurs in the system. To receive this transaction, an application must specify the APPCLASS_MONITOR flag when it calls the DdeInitialize function.

Parameters

uFmt
Not used.
hconv
Not used.
hsz1
Not used.
hsz2
Not used.
hdata
Handle to a DDE object that contains information about the DDE event. The application should use the DdeAccessData function to obtain a pointer to the object.
dwData1
Not used.
dwData2
Specifies the DDE event. This parameter may be one of the following values:
Value | Meaning
MF_CALLBACKS | The system sent a transaction to a DDE callback function. The DDE object contains a MONCBSTRUCT structure that provides information about the transaction.
MF_CONV | A DDE conversation was established or terminated. The DDE object contains a MONCONVSTRUCT structure that provides information about the conversation.
MF_ERRORS | A DDE error occurred. The DDE object contains a MONERRSTRUCT structure that provides information about the error.
MF_HSZ_INFO | A DDE application created, freed, or incremented the usage count of a string handle, or a string handle was freed as a result of a call to the DdeUninitialize function. The DDE object contains a MONHSZSTRUCT structure that provides information about the string handle.
MF_LINKS | A DDE application started or stopped an advise loop. The DDE object contains a MONLINKSTRUCT structure that provides information about the advise loop.
MF_POSTMSGS | The system or an application posted a DDE message. The DDE object contains a MONMSGSTRUCT structure that provides information about the message.
MF_SENDMSGS | The system or an application sent a DDE message. The DDE object contains a MONMSGSTRUCT structure that provides information about the message.

Return Value

If the callback function processes this transaction, it should return 0.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, DdeAccessData, DdeInitialize, DdeUninitialize, MONCBSTRUCT, MONCONVSTRUCT, MONERRSTRUCT, MONHSZSTRUCT, MONLINKSTRUCT, MONMSGSTRUCT


XTYP_POKE

XTYP_POKE

A dynamic data exchange (DDE) server callback function receives the XTYP_POKE transaction when a client specifies XTYP_POKE in DdeClientTransaction function. A client uses this transaction to send unsolicited data to the server.

Parameters

uFmt
Specifies the format of the data sent from the server.
hconv
Handle to the conversation.
hsz1
Handle to the topic name.
hsz2
Handle to the item name.
hdata
Handle to the data that the client is sending to the server.
dwData1
Not used.
dwData2
Not used.

Return Value

A server callback function should return the DDE_FACK flag if it processes this transaction, the DDE_FBUSY flag if it is too busy to process this transaction, or the DDE_FNOTPROCESSED flag if it rejects this transaction.

Remarks

This transaction is filtered if the server application specified the CBF_FAIL_POKES flag in the DdeInitialize function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, DdeClientTransaction, DdeInitialize


XTYP_REGISTER

XTYP_REGISTER

A dynamic data exchange (DDE) callback function receives the XTYP_REGISTER transaction type whenever a Dynamic Data Exchange Library (DDEML) server application uses the DdeNameService function to register a service name, or whenever a non-DDEML application that supports the System topic is started.

Parameters

uFmt
Not used.
hconv
Not used.
hsz1
Handle to the base service name being registered.
hsz2
Handle to the instance-specific service name being registered.
hdata
Not used.
dwData1
Not used.
dwData2
Not used.

Remarks

This transaction is filtered if the application specified the CBF_SKIP_REGISTRATIONS flag in the DdeInitialize function.

A application cannot block this transaction type; the CBR_BLOCK return code is ignored.

An application should use the hsz1 parameter to add the service name to the list of servers available to the user. An application should use the hsz2 parameter to identify which application instance has started.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, DdeInitialize, DdeNameService


XTYP_REQUEST

XTYP_REQUEST

A dynamic data exchange (DDE) server callback function receives the XTYP_REQUEST transaction when a client specifies XTYP_REQUEST in the DdeClientTransaction function. A client uses this transaction to request data from a server.

Parameters

uFmt
Specifies the format in which the server should submit data to the client.
hconv
Handle to the conversation.
hsz1
Handle to the topic name.
hsz2
Handle to the item name.
hdata
Not used.
dwData1
Not used.
dwData2
Not used.

Return Value

The server should call the DdeCreateDataHandle function to create a data handle that identifies the data and then return the handle. The server should return NULL if it is unable to complete the transaction. If the server returns NULL, the client will receive a DDE_FNOTPROCESSED flag.

Remarks

This transaction is filtered if the server application specified the CBF_FAIL_REQUESTS flag in the DdeInitialize function.

If responding to this transaction requires lengthy processing, the server can return the CBR_BLOCK return code to suspend future transactions on the current conversation and then process the transaction asynchronously. When the server has finished and the data is ready to pass to the client, the server can call the DdeEnableCallback function to resume the conversation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, DdeClientTransaction, DdeCreateDataHandle, DdeEnableCallback, DdeInitialize


XTYP_UNREGISTER

XTYP_UNREGISTER

A dynamic data exchange (DDE) callback function receives the XTYP_UNREGISTER transaction whenever a Dynamic Data Exchange Management Library (DDEML) server application uses the DdeNameService function to unregister a service name, or whenever a non-DDEML application that supports the System topic is terminated.

Parameters

uFmt
Not used.
hconv
Not used.
hsz1
Handle to the base service name being unregistered.
hsz2
Handle to the instance-specific service name being unregistered.
hdata
Not used.
dwData1
Not used.
dwData2
Not used.

Remarks

This transaction is filtered if the application specified the CBF_SKIP_REGISTRATIONS flag in the DdeInitialize function.

A application cannot block this transaction type; the CBR_BLOCK return code is ignored.

An application should use the hsz1 parameter to remove the service name from the list of servers available to the user. An application should use the hsz2 parameter to identify which application instance has terminated.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, DdeInitialize, DdeNameService


XTYP_WILDCONNECT

XTYP_WILDCONNECT

A dynamic data exchange (DDE) server callback function receives the XTYP_WILDCONNECT transaction when a client specifies a NULL service name, a NULL topic name, or both in a call to the DdeConnect or DdeConnectList function. This transaction allows a client to establish a conversation on each of the server's service name and topic name pairs that match the specified service name and topic name.

Parameters

uFmt
Not used.
hconv
Not used.
hsz1
Handle to the topic name. If this parameter is NULL, the client is requesting a conversation on all topic names that the server supports.
hsz2
Handle to the service name. If this parameter is NULL, the client is requesting a conversation on all service names that the server supports.
hdata
Not used.
dwData1
Pointer to a CONVCONTEXT structure that contains context information for the conversation. If the client is not a Dynamic Data Exchange Management Library (DDEML) application, this parameter is set to 0.
dwData2
Specifies whether the client is the same application instance as the server. If the parameter is 1, the client is same instance. If the parameter is 0, the client is a different instance.

Return Value

The server should return a data handle that identifies an array of HSZPAIR structures. The array should contain one structure for each service-name and topic-name pair that matches the service-name and topic-name pair requested by the client. The array must be terminated by a NULL string handle. The system sends the XTYP_CONNECT_CONFIRM transaction to the server to confirm each conversation and to pass the conversation handles to the server. The server will not receive these confirmations if it specified the CBF_SKIP_CONNECT_CONFIRMS flag in the DdeInitialize function.

The server should return NULL to refuse the XTYP_WILDCONNECT transaction.

Remarks

This transaction is filtered if the server application specified the CBF_FAIL_CONNECTIONS flag in the DdeInitialize function.

A server cannot block this transaction type; the CBR_BLOCK return code is ignored.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, CONVCONTEXT, DdeConnect, DdeInitialize, HSZPAIR


XTYP_XACT_COMPLETE

XTYP_XACT_COMPLETE

A dynamic data exchange (DDE) client callback function receives the XTYP_XACT_COMPLETE transaction when an asynchronous transaction, initiated by a call to the DdeClientTransaction function, has completed.

Parameters

uFmt
Specifies the format of the data associated with the completed transaction (if applicable) or NULL if no data was exchanged during the transaction.
hconv
Handle to the conversation.
hsz1
Handle to the topic name involved in the completed transaction.
hsz2
Handle to the item name involved in the completed transaction.
hdata
Handle to the data involved in the completed transaction, if applicable. If the transaction was successful but involved no data, this parameter is TRUE. This parameter is NULL if the transaction was unsuccessful.
dwData1
Specifies the transaction identifier of the completed transaction.
dwData2
Specifies any applicable DDE_ status flags in the low word. This parameter provides support for applications dependent on DDE_APPSTATUS bits. It is recommended that applications no longer use these bits — future versions of the Dynamic Data Exchange Management Library (DDEML) may not support them.

Remarks

An application must not free the data handle obtained during this transaction. An application must, however, copy the data associated with the data handle if the application must process the data after the callback function returns. An application can use the DdeGetData function to copy the data.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in ddeml.h.

See Also

Dynamic Data Exchange Management Library Overview, Dynamic Data Exchange Management Transactions, DdeClientTransaction, DdeGetData


Hooks

A hook is a point in the system message-handling mechanism where an application can install a subroutine to monitor the message traffic in the system and process certain types of messages before they reach the target window procedure.

This overview describes hooks and explains how to use them in a Win32-based application.


About Hooks

Hooks tend to slow down the system because they increase the amount of processing the system must perform for each message. You should install a hook only when necessary, and remove it as soon as possible.


Hook Chains

The system supports many different types of hooks; each type provides access to a different aspect of its message-handling mechanism. For example, an application can use the WH_MOUSE hook to monitor the message traffic for mouse messages.

The system maintains a separate hook chain for each type of hook. A hook chain is a list of pointers to special, application-defined callback functions called hook procedures. When a message occurs that is associated with a particular type of hook, the system passes the message to each hook procedure referenced in the hook chain, one after the other. The action a hook procedure can take depends on the type of hook involved. The hook procedures for some types of hooks can only monitor messages; others can modify messages or stop their progress though the chain, preventing them from reaching the next hook procedure or the destination window.


Hook Procedures

To take advantage of a particular type of hook, the developer provides a hook procedure and uses the SetWindowsHookEx function to install it into the chain associated with the hook. A hook procedure must have the following syntax:

LRESULT CALLBACK HookProc(
  int nCode,
  WPARAM wParam,
  LPARAM lParam
);

HookProc is a placeholder for an application-defined name.

The nCode parameter is a hook code that the hook procedure uses to determine the action to perform. The value of the hook code depends on the type of the hook; each type has its own characteristic set of hook codes. The values of the wParam and lParam parameters depend on the hook code, but they typically contain information about a message that was sent or posted.

The SetWindowsHookEx function always installs a hook procedure at the beginning of a hook chain. When an event occurs that is monitored by a particular type of hook, the system calls the procedure at the beginning of the hook chain associated with the hook. Each hook procedure in the chain determines whether to pass the event to the next procedure. A hook procedure passes an event to the next procedure by calling the CallNextHookEx function.

Note that the hook procedures for some types of hooks can only monitor messages. the system passes messages to each hook procedure, regardless of whether a particular procedure calls CallNextHookEx.

A hook procedure can be global, monitoring messages for all threads in the system, or it can be thread specific, monitoring messages for only an individual thread. A global hook procedure can be called in the context of any application, so the procedure must be in a separate dynamic-link library (DLL) module. A thread specific hook procedure is called only in the context of the associated thread. If an application installs a hook procedure for one of its own threads, the hook procedure can be in either the same module as the rest of the application's code or in a DLL. If the application installs a hook procedure for a thread of a different application, the procedure must be in a DLL. For information, see Dynamic-Link Libraries.

Note You should use global hooks only for debugging purposes; otherwise, you should avoid them. Global hooks hurt system performance and cause conflicts with other applications that implement the same type of global hook.


Hook Types

Each type of hook enables an application to monitor a different aspect of the system's message-handling mechanism. The following sections describe the available hooks.

  • WH_CALLWNDPROC and WH_CALLWNDPROCRET Hooks
  • WH_CBT Hook
  • WH_DEBUG Hook
  • WH_FOREGROUNDIDLE Hook
  • WH_GETMESSAGE Hook
  • WH_JOURNALPLAYBACK Hook
  • WH_JOURNALRECORD Hook
  • WH_KEYBOARD Hook
  • WH_KEYBOARD_LL Hook
  • WH_MOUSE Hook
  • WH_MOUSE_LL Hook
  • WH_MSGFILTER and WH_SYSMSGFILTER Hooks
  • WH_SHELL Hook


WH_CALLWNDPROC and WH_CALLWNDPROCRET Hooks

The WH_CALLWNDPROC and WH_CALLWNDPROCRET hooks enable you to monitor messages sent to window procedures by the SendMessage function. The system calls a WH_CALLWNDPROC hook procedure before passing the message to the receiving window procedure, and calls the WH_CALLWNDPROCRET hook procedure after the window procedure has processed the message.

The WH_CALLWNDPROCRET hook passes the address of a CWPRETSTRUCT structure to the hook procedure. The structure contains the return value from the window procedure that processed the message, as well as the message parameters associated with the message. Subclassing the window does not work for messages set between processes.

For more information, see the CallWndProc and CallWndRetProc functions.


WH_CBT Hook

The system calls a WH_CBT hook procedure before activating, creating, destroying, minimizing, maximizing, moving, or sizing a window; before completing a system command; before removing a mouse or keyboard event from the system message queue; before setting the input focus; or before synchronizing with the system message queue. The value the hook procedure returns determines whether the system allows or prevents one of these operations. The WH_CBT hook is intended primarily for computer-based training (CBT) applications.

For more information, see the CBTProc function.


WH_DEBUG Hook

The system calls a WH_DEBUG hook procedure before calling hook procedures associated with any other hook in the system. You can use this hook to determine whether to allow the system to call hook procedures associated with other types of hooks.

For more information, see the DebugProc function.


WH_FOREGROUNDIDLE Hook

The WH_FOREGROUNDIDLE hook enables you to perform low priority tasks during times when its foreground thread is idle. The system calls a WH_FOREGROUNDIDLE hook procedure when the application's foreground thread is about to become idle.

For more information, see the ForegroundIdleProc function.


WH_GETMESSAGE Hook

The WH_GETMESSAGE hook enables an application to monitor messages about to be returned by the GetMessage or PeekMessage function. You can use the WH_GETMESSAGE hook to monitor mouse and keyboard input and other messages posted to the message queue.

For more information, see the GetMsgProc function.


WH_JOURNALPLAYBACK Hook

The WH_JOURNALPLAYBACK hook enables an application to insert messages into the system message queue. You can use this hook to play back a series of mouse and keyboard events recorded earlier by using the WH_JOURNALRECORD hook. Regular mouse and keyboard input is disabled as long as a WH_JOURNALPLAYBACK hook is installed. A WH_JOURNALPLAYBACK hook is a global hook — it cannot be used as a thread-specific hook.

The WH_JOURNALPLAYBACK hook returns a time-out value. This value tells the system how many milliseconds to wait before processing the current message from the playback hook. This enables the hook to control the timing of the events it plays back.

For more information, see the JournalPlaybackProc function.


WH_JOURNALRECORD Hook

The WH_JOURNALRECORD hook enables you to monitor and record input events. Typically, you use this hook to record a sequence of mouse and keyboard events to play back later by using the WH_JOURNALPLAYBACK hook. The WH_JOURNALRECORD hook is a global hook — it cannot be used as a thread-specific hook.

For more information, see the JournalRecordProc function.


WH_KEYBOARD Hook

The WH_KEYBOARD hook enables an application to monitor message traffic for WM_KEYDOWN and WM_KEYUP messages about to be returned by the GetMessage or PeekMessage function. You can use the WH_KEYBOARD hook to monitor keyboard input posted to a message queue.

For more information, see the KeyboardProc function.


WH_KEYBOARD_LL Hook

[New for Windows NT 4.0 Service Pack 3.]

The WH_KEYBOARD_LL hook enables you to monitor keyboard input events about to be posted in a thread input queue.

For more information, see the LowLevelKeyboardProc function.


WH_MOUSE Hook

The WH_MOUSE hook enables you to monitor mouse messages about to be returned by the GetMessage or PeekMessage function. You can use the WH_MOUSE hook to monitor mouse input posted to a message queue.

For more information, see the MouseProc function.


WH_MOUSE_LL Hook

[New for Windows NT 4.0 Service Pack 3.]

The WH_MOUSE_LL hook enables you to monitor mouse input events about to be posted in a thread input queue.

For more information, see the LowLevelMouseProc function.


WH_MSGFILTER and WH_SYSMSGFILTER Hooks

The WH_MSGFILTER and WH_SYSMSGFILTER hooks enable you to monitor messages about to be processed by a menu, scroll bar, message box, or dialog box, and to detect when a different window is about to be activated as a result of the user's pressing the alt+tab or alt+esc key combination. The WH_MSGFILTER hook can only monitor messages passed to a menu, scroll bar, message box, or dialog box created by the application that installed the hook procedure. The WH_SYSMSGFILTER hook monitors such messages for all applications.

The WH_MSGFILTER and WH_SYSMSGFILTER hooks enable you to perform message filtering during modal loops that is equivalent to the filtering done in the main message loop. For example, an application often examines a new message in the main loop between the time it retrieves the message from the queue and the time it dispatches the message, performing special processing as appropriate. However, during a modal loop, the system retrieves and dispatches messages without allowing an application the chance to filter the messages in its main message loop. If an application installs a WH_MSGFILTER or WH_SYSMSGFILTER hook procedure, the system calls the procedure during the modal loop.

An application can call the WH_MSGFILTER hook directly by calling the CallMsgFilter function. By using this function, the application can use the same code to filter messages during modal loops as it uses in the main message loop. To do so, encapsulate the filtering operations in a WH_MSGFILTER hook procedure and call CallMsgFilter between the calls to the GetMessage and DispatchMessage functions.

while (GetMessage(&msg, (HWND) NULL, 0, 0))
{
    if (!CallMsgFilter(&qmsg, 0))
        DispatchMessage(&qmsg);
}

The last argument of CallMsgFilter is simply passed to the hook procedure; you can enter any value. The hook procedure, by defining a constant such as MSGF_MAINLOOP, can use this value to determine where the procedure was called from.

For more information, see the MessageProc and SysMsgProc functions.


WH_SHELL Hook

A shell application can use the WH_SHELL hook to receive important notifications. The system calls a WH_SHELL hook procedure when the shell application is about to be activated and when a top-level window is created or destroyed.

For more information, see the ShellProc function.


Using Hooks

  • Installing and Releasing Hook Procedures
  • Monitoring System Events


Installing and Releasing Hook Procedures

You can install a hook procedure by calling the SetWindowsHookEx function and specifying the type of hook calling the procedure, whether the procedure should be associated with all threads or with a particular thread, and a pointer to a procedure entry point.

You must place a global hook procedure in a DLL separate from the application installing the hook procedure. The installing application must have the handle to the DLL module before it can install the hook procedure. The LoadLibrary function, when given the name of the DLL, returns the handle to the DLL module. After you have the handle, you can call the GetProcAddress function to retrieve the address of the hook procedure. Finally, you use SetWindowsHookEx to install the hook procedure address in the appropriate hook chain. SetWindowsHookEx passes the module handle, a pointer to the hook-procedure entry point, and 0 for the thread identifier, indicating that the hook procedure should be associated with all threads in the system. This sequence is shown in the following example.

HOOKPROC hkprcSysMsg;
static HINSTANCE hinstDLL;
static HHOOK hhookSysMsg;

hinstDLL = LoadLibrary((LPCTSTR) "c:\\windows\\sysmsg.dll");
hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc");
hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER,
    hkprcSysMsg, hinstDLL, 0);

You can release a thread-specific hook procedure (remove its address from the hook chain) by calling the UnhookWindowsHookEx function, specifying the handle to the hook procedure to release. Release a hook procedure as soon as your application no longer needs it.

You can release a global hook procedure by using UnhookWindowsHookEx, but this function does not free the DLL containing the hook procedure. This is because global hook procedures are called in the process context of every application in the system, causing an implicit call to the LoadLibrary function for all of those processes. Because a call to the FreeLibrary function cannot be made for another process, there is then no way to free the DLL. The system eventually frees the DLL after all processes explicitly linked to the DLL have either terminated or called FreeLibrary and all processes that called the hook procedure have resumed processing outside the DLL.

An alternative method for installing a global hook procedure is to provide an installation function in the DLL, along with the hook procedure. With this method, the installing application does not need the handle to the DLL module. By linking with the DLL, the application gains access to the installation function. The installation function can supply the DLL module handle and other details in the call to SetWindowsHookEx. The DLL can also contain a function that releases the global hook procedure; the application can call this hook-releasing function when terminating.


Monitoring System Events

The following example uses a variety of thread-specific hook procedures to monitor the system for events affecting a thread. It demonstrates how to process events for the following types of hook procedures:

WH_CALLWNDPROC
WH_CBT
WH_DEBUG
WH_GETMESSAGE
WH_KEYBOARD
WH_MOUSE
WH_MSGFILTER

The user can install and remove a hook procedure by using the menu. When a hook procedure is installed and an event that is monitored by the procedure occurs, the procedure writes information about the event to the client area of the application's main window.

#define NUMHOOKS 7

// Global variables

typedef struct _MYHOOKDATA
{
    int nType;
    HOOKPROC hkprc;
    HHOOK hhook;
} MYHOOKDATA;

MYHOOKDATA myhookdata[NUMHOOKS];

LRESULT WINAPI MainWndProc(HWND hwndMain, UINT uMsg, WPARAM wParam,
    LPARAM lParam)
{
    static BOOL afHooks[NUMHOOKS];
    int index;
    static HMENU hmenu;

    switch (uMsg)
    {
        case WM_CREATE:

            // Save the menu handle.

            hmenu = GetMenu(hwndMain);

            // Initialize structures with hook data. The menu-item
            // identifiers are defined as 0 through 6 in the
            // header file. They can be used to identify array
            // elements both here and during the WM_COMMAND
            // message.

            myhookdata[IDM_CALLWNDPROC].nType = WH_CALLWNDPROC;
            myhookdata[IDM_CALLWNDPROC].hkprc = CallWndProc;
            myhookdata[IDM_CBT].nType = WH_CBT;
            myhookdata[IDM_CBT].hkprc = CBTProc;
            myhookdata[IDM_DEBUG].nType = WH_DEBUG;
            myhookdata[IDM_DEBUG].hkprc = DebugProc;
            myhookdata[IDM_GETMESSAGE].nType = WH_GETMESSAGE;
            myhookdata[IDM_GETMESSAGE].hkprc = GetMsgProc;
            myhookdata[IDM_KEYBOARD].nType = WH_KEYBOARD;
            myhookdata[IDM_KEYBOARD].hkprc = KeyboardProc;
            myhookdata[IDM_MOUSE].nType = WH_MOUSE;
            myhookdata[IDM_MOUSE].hkprc = MouseProc;
            myhookdata[IDM_MSGFILTER].nType = WH_MSGFILTER;
            myhookdata[IDM_MSGFILTER].hkprc = MessageProc;

            // Initialize all flags in the array to FALSE.

            memset(afHooks, FALSE, sizeof(afHooks));

            return 0;

        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
                 // The user selected a hook command from the menu.

                case IDM_CALLWNDPROC:
                case IDM_CBT:
                case IDM_DEBUG:
                case IDM_GETMESSAGE:
                case IDM_KEYBOARD:
                case IDM_MOUSE:
                case IDM_MSGFILTER:

                    // Use the menu-item identifier as an index
                    // into the array of structures with hook data.

                    index = LOWORD(wParam);

                    // If the selected type of hook procedure isn't
                    // installed yet, install it and check the
                    // associated menu item.

                    if (!afHooks[index])
                    {
                        myhookdata[index].hhook = SetWindowsHookEx(
                            myhookdata[index].nType,
                            myhookdata[index].hkprc,
                            (HINSTANCE) NULL, GetCurrentThreadId());
                        CheckMenuItem(hmenu, index,
                            MF_BYCOMMAND | MF_CHECKED);
                        afHooks[index] = TRUE;
                    }

                    // If the selected type of hook procedure is
                    // already installed, remove it and remove the
                    // check mark from the associated menu item.

                    else
                    {
                        UnhookWindowsHookEx(myhookdata[index].hhook);
                        CheckMenuItem(hmenu, index,
                            MF_BYCOMMAND | MF_UNCHECKED);
                        afHooks[index] = FALSE;
                    }

                default:
                    return (DefWindowProc(hwndMain, uMsg, wParam,
                        lParam));
            }
            break;

            //
            // Process other messages.
            //

        default:
            return DefWindowProc(hwndMain, uMsg, wParam, lParam);
    }
    return NULL;
}

/****************************************************************
  WH_CALLWNDPROC hook procedure
 ****************************************************************/

LRESULT WINAPI CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CHAR szCWPBuf[256];
    CHAR szMsg[16];
    HDC hdc;
    static int c = 0;
    int cch;

    if (nCode < 0)  // do not process message
        return CallNextHookEx(myhookdata[CALLWNDPROC].hhook, nCode,
                wParam, lParam);

    // Call an application-defined function that converts a message
    // constant to a string and copies it to a buffer.

    LookUpTheMessage((PMSG) lParam, szMsg);

    hdc = GetDC(hwndMain);

    switch (nCode)
    {
        case HC_ACTION:
            cch = wsprintf(szCWPBuf,
               "CALLWNDPROC - tsk: %ld, msg: %s, %d times   ",
                wParam, szMsg, c++);
            TextOut(hdc, 2, 15, szCWPBuf, cch);
            break;

        default:
            break;
    }

    ReleaseDC(hwndMain, hdc);
    return CallNextHookEx(myhookdata[CALLWNDPROC].hhook, nCode,
        wParam, lParam);
}

/****************************************************************
  WH_GETMESSAGE hook procedure
 ****************************************************************/

LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CHAR szMSGBuf[256];
    CHAR szRem[16];
    CHAR szMsg[16];
    HDC hdc;
    static int c = 0;
    int cch;

    if (nCode < 0) // do not process message
        return CallNextHookEx(myhookdata[GETMESSAGE].hhook, nCode,
            wParam, lParam);

    switch (nCode)
    {
        case HC_ACTION:
            switch (wParam)
            {
                case PM_REMOVE:
                    lstrcpy(szRem, "PM_REMOVE");
                    break;

                case PM_NOREMOVE:
                    lstrcpy(szRem, "PM_NOREMOVE");
                    break;

                default:
                    lstrcpy(szRem, "Unknown");
                    break;
            }

            // Call an application-defined function that converts a
            // message constant to a string and copies it to a
            // buffer.

            LookUpTheMessage((PMSG) lParam, szMsg);

            hdc = GetDC(hwndMain);
            cch = wsprintf(szMSGBuf,
                "GETMESSAGE - wParam: %s, msg: %s, %d times   ",
                szRem, szMsg, c++);
            TextOut(hdc, 2, 35, szMSGBuf, cch);
            break;

        default:
            break;
    }

    ReleaseDC(hwndMain, hdc);
    return CallNextHookEx(myhookdata[GETMESSAGE].hhook, nCode,
        wParam, lParam);
}

/****************************************************************
  WH_DEBUG hook procedure
 ****************************************************************/

LRESULT CALLBACK DebugProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CHAR szBuf[128];
    HDC hdc;
    static int c = 0;
    int cch;

    if (nCode < 0)  // do not process message
        return CallNextHookEx(myhookdata[DEBUG].hhook, nCode,
            wParam, lParam);

    hdc = GetDC(hwndMain);

    switch (nCode)
    {
        case HC_ACTION:
            cch = wsprintf(szBuf,
                "DEBUG - nCode: %d, tsk: %ld, %d times   ",
                nCode,wParam, c++);
            TextOut(hdc, 2, 55, szBuf, cch);
            break;

        default:
            break;
    }

    ReleaseDC(hwndMain, hdc);
    return CallNextHookEx(myhookdata[DEBUG].hhook, nCode, wParam,
        lParam);
}

/****************************************************************
  WH_CBT hook procedure
 ****************************************************************/

LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CHAR szBuf[128];
    CHAR szCode[128];
    HDC hdc;
    static int c = 0;
    int cch;

    if (nCode < 0)  // do not process message
        return CallNextHookEx(myhookdata[CBT].hhook, nCode, wParam,
            lParam);

    hdc = GetDC(hwndMain);

    switch (nCode)
    {
        case HCBT_ACTIVATE:
            lstrcpy(szCode, "HCBT_ACTIVATE");
            break;

        case HCBT_CLICKSKIPPED:
            lstrcpy(szCode, "HCBT_CLICKSKIPPED");
            break;

        case HCBT_CREATEWND:
            lstrcpy(szCode, "HCBT_CREATEWND");
            break;

        case HCBT_DESTROYWND:
            lstrcpy(szCode, "HCBT_DESTROYWND");
            break;

        case HCBT_KEYSKIPPED:
            lstrcpy(szCode, "HCBT_KEYSKIPPED");
            break;

        case HCBT_MINMAX:
            lstrcpy(szCode, "HCBT_MINMAX");
            break;

        case HCBT_MOVESIZE:
            lstrcpy(szCode, "HCBT_MOVESIZE");
            break;

        case HCBT_QS:
            lstrcpy(szCode, "HCBT_QS");
            break;

        case HCBT_SETFOCUS:
            lstrcpy(szCode, "HCBT_SETFOCUS");
            break;

        case HCBT_SYSCOMMAND:
            lstrcpy(szCode, "HCBT_SYSCOMMAND");
            break;

        default:
            lstrcpy(szCode, "Unknown");
            break;
    }

    cch = wsprintf(szBuf, "CBT - nCode: %s, tsk: %ld, %d times   ",
        szCode, wParam, c++);
    TextOut(hdc, 2, 75, szBuf, cch);
    ReleaseDC(hwndMain, hdc);
    return CallNextHookEx(myhookdata[CBT].hhook, nCode, wParam,
        lParam);
}

/****************************************************************
  WH_MOUSE hook procedure
 ****************************************************************/

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CHAR szBuf[128];
    CHAR szMsg[16];
    HDC hdc;
    static int c = 0;
    int cch;

    if (nCode < 0)  // do not process the message
        return CallNextHookEx(myhookdata[MOUSE].hhook, nCode,
            wParam, lParam);

    // Call an application-defined function that converts a message
    // constant to a string and copies it to a buffer.

    LookUpTheMessage((PMSG) lParam, szMsg);

    hdc = GetDC(hwndMain);
    cch = wsprintf(szBuf,
        "MOUSE - nCode: %d, msg: %s, x: %d, y: %d, %d times   ",
        nCode, szMsg, LOWORD(lParam), HIWORD(lParam), c++);
    TextOut(hdc, 2, 95, szBuf, cch);
    ReleaseDC(hwndMain, hdc);
    return CallNextHookEx(myhookdata[MOUSE].hhook, nCode, wParam,
        lParam);
}

/****************************************************************
  WH_KEYBOARD hook procedure
 ****************************************************************/

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CHAR szBuf[128];
    HDC hdc;
    static int c = 0;
    int cch;

    if (nCode < 0)  // do not process message
        return CallNextHookEx(myhookdata[KEYBOARD].hhook, nCode,
            wParam, lParam);

    hdc = GetDC(hwndMain);
    cch = wsprintf(szBuf, "KEYBOARD - nCode: %d, vk: %d, %d times ",
        nCode, wParam, c++);
    TextOut(hdc, 2, 115, szBuf, cch);
    ReleaseDC(hwndMain, hdc);
    return CallNextHookEx(myhookdata[KEYBOARD].hhook, nCode, wParam,
        lParam);
}

/****************************************************************
  WH_MSGFILTER hook procedure
 ****************************************************************/

LRESULT CALLBACK MessageProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CHAR szBuf[128];
    CHAR szMsg[16];
    CHAR szCode[32];
    HDC hdc;
    static int c = 0;
    int cch;

    if (nCode < 0)  // do not process message
        return CallNextHookEx(myhookdata[MSGFILTER].hhook, nCode,
            wParam, lParam);

    switch (nCode)
    {
        case MSGF_DIALOGBOX:
            lstrcpy(szCode, "MSGF_DIALOGBOX");
            break;

        case MSGF_MENU:
            lstrcpy(szCode, "MSGF_MENU");
            break;

        case MSGF_SCROLLBAR:
            lstrcpy(szCode, "MSGF_SCROLLBAR");
            break;

        case MSGF_NEXTWINDOW:
            lstrcpy(szCode, "MSGF_NEXTWINDOW");
            break;

        default:
            wsprintf(szCode, "Unknown: %d", nCode);
            break;
    }

    // Call an application-defined function that converts a message
    // constant to a string and copies it to a buffer.

    LookUpTheMessage((PMSG) lParam, szMsg);

    hdc = GetDC(hwndMain);
    cch = wsprintf(szBuf,
        "MSGFILTER  nCode: %s, msg: %s, %d times    ",
        szCode, szMsg, c++);
    TextOut(hdc, 2, 135, szBuf, cch);
    ReleaseDC(hwndMain, hdc);
    return CallNextHookEx(myhookdata[MSGFILTER].hhook, nCode,
        wParam, lParam);
}


Hook Reference

The following elements are associated with hooks.

  • Hook Functions
  • Hook Structures
  • Hook Messages


Hook Functions

The following functions are used with hooks.

CallMsgFilter
CallNextHookEx
CallWndProc
CallWndRetProc
CBTProc
DebugProc
ForegroundIdleProc
GetMsgProc
JournalPlaybackProc
JournalRecordProc
KeyboardProc
LowLevelKeyboardProc
LowLevelMouseProc
MessageProc
MouseProc
SetWindowsHookEx
ShellProc
SysMsgProc
UnhookWindowsHookEx

Obsolete Functions

DefHookProc
SetWindowsHook
UnhookWindowsHook


CallMsgFilter

The CallMsgFilter function passes the specified message and hook code to the hook procedures associated with the WH_SYSMSGFILTER and WH_MSGFILTER hooks. A WH_SYSMSGFILTER or WH_MSGFILTER hook procedure is an application-defined callback function that examines and, optionally, modifies messages for a dialog box, message box, menu, or scroll bar.

BOOL CallMsgFilter(
  LPMSG lpMsg,  // pointer to structure with message data
  int nCode     // hook code
);

Parameters

lpMsg
Pointer to an MSG structure that contains the message to be passed to the hook procedures.
nCode
Specifies an application-defined code used by the hook procedure to determine how to process the message. The code must not have the same value as system-defined hook codes (MSGF_ and HC_) associated with the WH_SYSMSGFILTER and WH_MSGFILTER hooks.

Return Values

If the application should process the message further, the return value is zero.

If the application should not process the message further, the return value is nonzero.

Remarks

The system calls CallMsgFilter to enable applications to examine and control the flow of messages during internal processing of dialog boxes, message boxes, menus, and scroll bars, or when the user activates a different window by pressing the alt+tab key combination.

Install this hook procedure by using the SetWindowsHookEx function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Hooks Overview, Hook Functions, MessageProc, MSG, SetWindowsHookEx, SysMsgProc


CallNextHookEx

The CallNextHookEx function passes the hook information to the next hook procedure in the current hook chain. A hook procedure can call this function either before or after processing the hook information.

LRESULT CallNextHookEx(
  HHOOK hhk,      // handle to current hook
  int nCode,      // hook code passed to hook procedure
  WPARAM wParam,  // value passed to hook procedure
  LPARAM lParam   // value passed to hook procedure
);

Parameters

hhk
Handle to the current hook. An application receives this handle as a result of a previous call to the SetWindowsHookEx function.
nCode
Specifies the hook code passed to the current hook procedure. The next hook procedure uses this code to determine how to process the hook information.
wParam
Specifies the wParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain.
lParam
Specifies the lParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain.

Return Values

The return value is the value returned by the next hook procedure in the chain. The current hook procedure must also return this value. The meaning of the return value depends on the hook type. For more information, see the descriptions of the individual hook procedures.

Remarks

Hook procedures are installed in chains for particular hook types. CallNextHookEx calls the next hook in the chain.

Calling CallNextHookEx is optional, but it is highly recommended; otherwise, other applications that have installed hooks will not receive hook notifications and may behave incorrectly as a result. You should call CallNextHookEx unless you absolutely need to prevent the notification from being seen by other applications.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Hooks Overview, Hook Functions, SetWindowsHookEx, UnhookWindowsHookEx


CallWndProc

The CallWndProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function whenever the SendMessage function is called. Before passing the message to the destination window procedure, the system passes the message to the hook procedure. The hook procedure can examine the message; it cannot modify it.

The HOOKPROC type defines a pointer to this callback function. CallWndProc is a placeholder for the application-defined or library-defined function name.

LRESULT CALLBACK CallWndProc(
  int nCode,      // hook code
  WPARAM wParam,  // current-process flag
  LPARAM lParam   // address of structure with message data
);

Parameters

nCode
Specifies whether the hook procedure must process the message. If nCode is HC_ACTION, the hook procedure must process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and must return the value returned by CallNextHookEx.
wParam
Specifies whether the message was sent by the current thread. If the message was sent by the current thread, it is nonzero; otherwise, it is zero.
lParam
Pointer to a CWPSTRUCT structure that contains details about the message.

Return Values

If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If nCode is greater than or equal to zero, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_CALLWNDPROC hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure does not call CallNextHookEx, the return value should be zero.

Remarks

The CallWndProc hook procedure can examine the message, but it cannot modify it. After the hook procedure returns control to the system, the message is passed to the window procedure.

An application installs the hook procedure by specifying the WH_CALLWNDPROC hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

The WM_CALLWNDPROC hook is called in the context of the thread that calls SendMessage, not the thread that receives the message.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, CWPSTRUCT, SendMessage, SetWindowsHookEx


CallWndRetProc

The CallWndRetProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function after the SendMessage function is called. The hook procedure can examine the message; it cannot modify it.

The HOOKPROC type defines a pointer to this callback function. CallWndRetProc is a placeholder for the application-defined or library-defined function name.

LRESULT CALLBACK CallWndRetProc(
  int nCode,     // hook code
  WPARAM wParam, // current-process flag
  LPARAM lParam  // address of structure with message data
);

Parameters

nCode
Specifies whether the hook procedure must process the message. If nCode is HC_ACTION, the hook procedure must process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.
wParam
Specifies whether the message is sent by the current process. If the message is sent by the current process, it is nonzero; otherwise, it is NULL.
lParam
Pointer to a CWPRETSTRUCT structure that contains details about the message.

Return Values

If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If nCode is greater than or equal to zero, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_CALLWNDPROCRET hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure does not call CallNextHookEx, the return value should be zero.

Remarks

An application installs the hook procedure by specifying the WH_CALLWNDPROCRET hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, CallWndProc, CWPRETSTRUCT, SendMessage, SetWindowsHookEx


CBTProc

The CBTProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function before activating, creating, destroying, minimizing, maximizing, moving, or sizing a window; before completing a system command; before removing a mouse or keyboard event from the system message queue; before setting the keyboard focus; or before synchronizing with the system message queue. A computer-based training (CBT) application uses this hook procedure to receive useful notifications from the system.

The HOOKPROC type defines a pointer to this callback function. CBTProc is a placeholder for the application-defined or library-defined function name.

LRESULT CALLBACK CBTProc(
  int nCode,      // hook code
  WPARAM wParam,  // depends on hook code
  LPARAM lParam   // depends on hook code
);

Parameters

nCode
Specifies a code that the hook procedure uses to determine how to process the message. This parameter can be one of the following values:
Value | Meaning
HCBT_ACTIVATE | The system is about to activate a window.
HCBT_CLICKSKIPPED | The system has removed a mouse message from the system message queue. Upon receiving this hook code, a CBT application must install a WH_JOURNALPLAYBACK hook procedure in response to the mouse message.
HCBT_CREATEWND | A window is about to be created. The system calls the hook procedure before sending the WM_CREATE or WM_NCCREATE message to the window. If the hook procedure returns a nonzero value, the system destroys the window; the CreateWindow function returns NULL, but the WM_DESTROY message is not sent to the window. If the hook procedure returns zero, the window is created normally.
At the time of the HCBT_CREATEWND notification, the window has been created, but its final size and position may not have been determined and its parent window may not have been established. It is possible to send messages to the newly created window, although it has not yet received WM_NCCREATE or WM_CREATE messages. It is also possible to change the position in the Z order of the newly created window by modifying the hwndInsertAfter member of the CBT_CREATEWND structure.
HCBT_DESTROYWND | A window is about to be destroyed.
HCBT_KEYSKIPPED | The system has removed a keyboard message from the system message queue. Upon receiving this hook code, a CBT application must install a WH_JOURNALPLAYBACK_hook hook procedure in response to the keyboard message.
HCBT_MINMAX | A window is about to be minimized or maximized.
HCBT_MOVESIZE | A window is about to be moved or sized.
HCBT_QS | The system has retrieved a WM_QUEUESYNC message from the system message queue.
HCBT_SETFOCUS | A window is about to receive the keyboard focus.
HCBT_SYSCOMMAND | A system command is about to be carried out. This allows a CBT application to prevent task switching by means of hot keys.

If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam
Depends on the nCode parameter. For details, see the following Remarks section.
lParam
Depends on the nCode parameter. For details, see the following Remarks section.

Return Values

The value returned by the hook procedure determines whether the system allows or prevents one of these operations. For operations corresponding to the following CBT hook codes, the return value must be 0 to allow the operation, or 1 to prevent it:

HCBT_ACTIVATE
HCBT_CREATEWND
HCBT_DESTROYWND
HCBT_MINMAX
HCBT_MOVESIZE
HCBT_SETFOCUS
HCBT_SYSCOMMAND

For operations corresponding to the following CBT hook codes, the return value is ignored:

HCBT_CLICKSKIPPED
HCBT_KEYSKIPPED
HCBT_QS

Remarks

The hook procedure should not install a WH_JOURNALPLAYBACK_hook hook procedure except in the situations described in the preceding list of hook codes.

This hook procedure must be in a dynamic-link library (DLL). An application installs the hook procedure by specifying the WH_CBT hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

The following table describes the wParam and lParam parameters for each HCBT_ hook code:

Value | wParam | lParam
HCBT_ACTIVATE | Specifies the handle to the window about to be activated. | Specifies a long pointer to a CBTACTIVATESTRUCT structure containing the handle to the active window and specifies whether the activation is changing because of a mouse click.
HCBT_CLICKSKIPPED Identifies the mouse message removed from the system message queue. Specifies a long pointer to a MOUSEHOOKSTRUCT structure containing the hit-test code and the handle to the window for which the mouse message is intended.

The HCBT_CLICKSKIPPED value is sent to a CBTProc hook procedure only if a WH_MOUSE hook is installed. For a list of hit-test codes, see WM_NCHITTEST.

HCBT_CREATEWND | Specifies the handle to the new window. | Specifies a long pointer to a CBT_CREATEWND structure containing initialization parameters for the window. The parameters include the coordinates and dimensions of the window. By changing these parameters, a CBTProc hook procedure can set the initial size and position of the window.
HCBT_DESTROYWND | Specifies the handle to the window about to be destroyed. | Is undefined and must be set to zero.
HCBT_KEYSKIPPED | Identifies the virtual-key code. | Specifies the repeat count, scan code, key-transition code, previous key state, and context code. The HCBT_KEYSKIPPED value is sent to a CBTProc hook procedure only if a WH_KEYBOARD hook is installed. For more information, see WM_KEYUP or WM_KEYDOWN.
HCBT_MINMAX | Specifies the handle to the window being minimized or maximized. | Specifies, in the low-order word, a show-window value (SW_) specifying the operation. For a list of show-window values, see the ShowWindow. The high-order word is undefined.
HCBT_MOVESIZE | Specifies the handle to the window to be moved or sized. | Specifies a long pointer to a RECT structure containing the coordinates of the window. By changing the values in the structure, a CBTProc hook procedure can set the final coordinates of the window.
HCBT_QS | Is undefined and must be zero. | Is undefined and must be zero.
HCBT_SETFOCUS | Specifies the handle to the window gaining the keyboard focus. | Specifies the handle to the window losing the keyboard focus.
HCBT_SYSCOMMAND | Specifies a system-command value (SC_) specifying the system command. For more information about system-command values, see WM_SYSCOMMAND. | Contains the same data as the lParam value of a WM_SYSCOMMAND message: If a system menu command is chosen with the mouse, the low-order word contains the x-coordinate of the cursor, in screen coordinates, and the high-order word contains the y-coordinate; otherwise, the parameter is not used.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, CreateWindow, SetWindowsHookEx, WM_SYSCOMMAND


DebugProc

The DebugProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function before calling the hook procedures associated with any type of hook. The system passes information about the hook to be called to the DebugProc hook procedure, which examines the information and determines whether to allow the hook to be called.

The HOOKPROC type defines a pointer to this callback function. DebugProc is a placeholder for the application-defined or library-defined function name.

LRESULT CALLBACK DebugProc(
  int nCode,      // hook code
  WPARAM wParam,  // type of hook about to be called
  LPARAM lParam   // address of structure with debugging information
);

Parameters

nCode
Specifies whether the hook procedure must process the message. If nCode is HC_ACTION, the hook procedure must process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.
wParam
Specifies the type of hook about to be called. This parameter can be one of the following values:
Value | Description
WH_CALLWNDPROC | Installs a hook procedure that monitors messages sent to a window procedure. For more information, see the description of the CallWndProc hook procedure.
WH_CALLWNDPROCRET | Installs a hook procedure that monitors messages that have just been processed by a window procedure. For more information, see the description of the CallWndRetProc hook procedure.
WH_CBT | Installs a hook procedure that receives notifications useful to a computer-based training (CBT) application. For more information, see the description of the CBTProc hook procedure.
WH_DEBUG | Installs a hook procedure useful for debugging other hook procedures. For more information, see the description of the DebugProc hook procedure.
WH_GETMESSAGE | Installs a hook procedure that monitors messages posted to a message queue. For more information, see the description of the GetMsgProc hook procedure.
WH_JOURNALPLAYBACK | Installs a hook procedure that posts messages previously recorded by a WH_JOURNALRECORD hook procedure. For more information, see the description of the JournalPlaybackProc hook procedure.
WH_JOURNALRECORD | Installs a hook procedure that records input messages posted to the system message queue. This hook is useful for recording macros. For more information, see the description of the JournalRecordProc hook procedure.
WH_KEYBOARD | Installs a hook procedure that monitors keystroke messages. For more information, see the description of the KeyboardProc hook procedure.
WH_MOUSE | Installs a hook procedure that monitors mouse messages. For more information, see the description of the MouseProc hook procedure.
WH_MSGFILTER | Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. The hook procedure monitors these messages only for the application that installed the hook procedure. For more information, see the description of the MessageProc hook procedure.
WH_SHELL | Installs a hook procedure that receives notifications useful to a shell application. For more information, see the description of the ShellProc hook procedure.
WH_SYSMSGFILTER | Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. The hook procedure monitors these messages for all applications in the system. For more information, see the description of the SysMsgProc hook procedure.

lParam
Pointer to a DEBUGHOOKINFO structure that contains the parameters to be passed to the destination hook procedure.

Return Values

To prevent the system from calling the hook, the hook procedure must return a nonzero value. Otherwise, the hook procedure must call CallNextHookEx.

Remarks

An application installs this hook procedure by specifying the WH_DEBUG hook type and the pointer to the hook procedure in a call to the SetWindowsHookEx function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, CallWndProc, CallWndRetProc, CBTProc, DEBUGHOOKINFO, GetMsgProc, JournalPlaybackProc, JournalRecordProc, KeyboardProc, MessageProc, MouseProc, SetWindowsHookEx, ShellProc, SysMsgProc


DefHookProc

The DefHookProc function is obsolete. It is provided only for compatibility with 16-bit versions of Windows. Win32-based applications should use the CallNextHookEx function.

See Also

Hooks Overview, Hook Functions


ForegroundIdleProc

The ForegroundIdleProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function whenever the foreground thread is about to become idle.

The HOOKPROC type defines a pointer to this callback function. ForegroundIdleProc is a placeholder for the application-defined or library-defined function name.

DWORD CALLBACK ForegroundIdleProc(
  int code,      // hook code
  DWORD wParam,  // not used
  LONG lParam    // not used
);

Parameters

code
Specifies whether the hook procedure must process the message. If code is HC_ACTION, the hook procedure must process the message. If code is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.
wParam
Not used.
lParam
Not used.

Return Values

If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If nCode is greater than or equal to zero, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_FOREGROUNDIDLE hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure does not call CallNextHookEx, the return value should be zero.

Remarks

An application installs this hook procedure by specifying the WH_FOREGROUNDIDLE hook type and the pointer to the hook procedure in a call to the SetWindowsHookEx function.

This is a thread-specific hook.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, SetWindowsHookEx


GetMsgProc

The GetMsgProc function is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function whenever the GetMessage function has retrieved a message from an application message queue. Before passing the retrieved message to the destination window procedure, the system passes the message to the hook procedure.

The HOOKPROC type defines a pointer to this callback function. GetMsgProc is a placeholder for the application-defined or library-defined function name.

LRESULT CALLBACK GetMsgProc(
  int code,       // hook code
  WPARAM wParam,  // removal flag
  LPARAM lParam   // address of structure with message
);

Parameters

code
Specifies whether the hook procedure must process the message. If code is HC_ACTION, the hook procedure must process the message. If code is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.
wParam
Specifies whether the message has been removed from the queue. This parameter can be one of the following values:
Value | Meaning
PM_NOREMOVE | Specifies that the message has not been removed from the queue. (An application called the PeekMessage function, specifying the PM_NOREMOVE flag.)
PM_REMOVE | Specifies that the message has been removed from the queue. (An application called GetMessage, or it called the PeekMessage function, specifying the PM_REMOVE flag.)

lParam
Pointer to an MSG structure that contains details about the message.

Return Values

If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If nCode is greater than or equal to zero, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_GETMESSAGE hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure does not call CallNextHookEx, the return value should be zero.

Remarks

The GetMsgProc hook procedure can examine or modify the message. After the hook procedure returns control to the system, the GetMessage function returns the message, along with any modifications, to the application that originally called it.

An application installs this hook procedure by specifying the WH_GETMESSAGE hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, GetMessage, MSG, PeekMessage, SetWindowsHookEx


JournalPlaybackProc

The JournalPlaybackProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. Typically, an application uses this function to play back a series of mouse and keyboard messages recorded previously by the JournalRecordProc hook procedure. As long as a JournalPlaybackProc hook procedure is installed, regular mouse and keyboard input is disabled.

The HOOKPROC type defines a pointer to this callback function. JournalPlaybackProc is a placeholder for the application-defined or library-defined function name.

LRESULT CALLBACK JournalPlaybackProc(
  int code,       // hook code
  WPARAM wParam,  // undefined
  LPARAM lParam   // address of message being processed
);

Parameters

code
Specifies a code the hook procedure uses to determine how to process the message. This parameter can be one of the following values:
Value | Meaning
HC_GETNEXT | The hook procedure must copy the current mouse or keyboard message to the EVENTMSG structure pointed to by the lParam parameter.
HC_NOREMOVE | An application has called the PeekMessage function with wRemoveMsg set to PM_NOREMOVE, indicating that the message is not removed from the message queue after PeekMessage processing.
HC_SKIP | The hook procedure must prepare to copy the next mouse or keyboard message to the EVENTMSG structure pointed to by lParam. Upon receiving the HC_GETNEXT code, the hook procedure must copy the message to the structure.
HC_SYSMODALOFF | A system-modal dialog box has been destroyed. The hook procedure must resume playing back the messages.
HC_SYSMODALON | A system-modal dialog box is being displayed. Until the dialog box is destroyed, the hook procedure must stop playing back messages.

If code is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam
Specifies a NULL value.
lParam
Pointer to an EVENTMSG structure that represents a message being processed by the hook procedure. This parameter is valid only when the code parameter is HC_GETNEXT.

Return Values

To have the system wait before processing the message, the return value must be the amount of time, in clock ticks, that the system should wait. (This value can be computed by calculating the difference between the time members in the current and previous input messages.) To process the message immediately, the return value should be zero. The return value is used only if the hook code is HC_GETNEXT; otherwise, it is ignored.

Remarks

A JournalPlaybackProc hook procedure should copy an input message to the lParam parameter. The message must have been previously recorded by using a JournalRecordProc hook procedure, which should not modify the message.

To retrieve the same message over and over, the hook procedure can be called several times with the code parameter set to HC_GETNEXT without an intervening call with code set to HC_SKIP.

If code is HC_GETNEXT and the return value is greater than zero, the system sleeps for the number of milliseconds specified by the return value. When the system continues, it calls the hook procedure again with code set to HC_GETNEXT to retrieve the same message. The return value from this new call to JournalPlaybackProc should be zero; otherwise, the system will go back to sleep for the number of milliseconds specified by the return value, call JournalPlaybackProc again, and so on. The system will appear to be hung.

Unlike most other global hook procedures, the JournalRecordProc and JournalPlaybackProc hook procedures are always called in the context of the thread that set the hook.

After the hook procedure returns control to the system, the message continues to be processed. If code is HC_SKIP, the hook procedure must prepare to return the next recorded event message on its next call.

Install the JournalPlaybackProc hook procedure by specifying the WH_JOURNALPLAYBACK hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

If the user presses ctrl+esc or ctrl+alt+del during journal playback, the system stops the playback, unhooks the journal playback procedure, and posts a WM_CANCELJOURNAL message to the journaling application.

If the hook procedure returns a message in the range WM_KEYFIRST to WM_KEYLAST, the following conditions apply:

  • The paramL member of the EVENTMSG structure specifies the virtual key code of the key that was pressed.
  • The paramH member of the EVENTMSG structure specifies the scan code.
  • There's no way to specify a repeast count. The event is always taken to represent one key event.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, EVENTMSG, JournalRecordProc, PeekMessage, SetWindowsHookEx, WM_CANCELJOURNAL


JournalRecordProc

The JournalRecordProc hook procedure is an application-defined callback function used with the SetWindowsHookEx function. The function records messages the system removes from the system message queue. Later, an application can use a JournalPlaybackProc hook procedure to play back the messages.

The HOOKPROC type defines a pointer to this callback function. JournalRecordProc is a placeholder for the application-defined or library-defined function name.

LRESULT CALLBACK JournalRecordProc(
  int code,       // hook code
  WPARAM wParam,  // undefined
  LPARAM lParam   // address of message being processed
);

Parameters

code
Specifies how to process the message. This parameter can be one of the following values:
Value | Meaning
HC_ACTION | The lParam parameter points to an EVENTMSG structure containing information about a message removed from the system queue. The hook procedure must record the contents of the structure by copying them to a buffer or file.
HC_SYSMODALOFF | A system-modal dialog box has been destroyed. The hook procedure must resume recording.
HC_SYSMODALON | A system-modal dialog box is being displayed. Until the dialog box is destroyed, the hook procedure must stop recording.

If code is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam
Specifies a NULL value.
lParam
Pointer to an EVENTMSG structure that contains the message to be recorded.

Return Values

The return value is ignored.

Remarks

A JournalRecordProc hook procedure must copy but not modify the messages. After the hook procedure returns control to the system, the message continues to be processed.

Install the JournalRecordProc hook procedure by specifying the WH_JOURNALRECORD hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

A JournalRecordProc hook procedure does not need to live in a dynamic-link library. A JournalRecordProc hook procedure can live in the application itself.

Unlike most other global hook procedures, the JournalRecordProc and JournalPlaybackProc hook procedures are always called in the context of the thread that set the hook.

An application that has installed a JournalRecordProc hook procedure should watch for the VK_CANCEL virtual keycode (which is implemented as the ctrl+break key combination on most keyboards). This virtual keycode should be interpreted by the application as a signal that the user wishes to stop journal recording. The application should respond by ending the recording sequence and removing the JournalRecordProc hook procedure. Removal is important. It prevents a journaling application from locking up the system by hanging inside a hook procedure.

This role as a signal to stop journal recording means that a ctrl+break key combination cannot itself be recorded. Since the ctrl+c key combination has no such role as a journaling signal, it can be recorded. There are two other key combinations that cannot be recorded: ctrl+esc and ctrl+alt+del. Those two key combinations cause the system to stop all journaling activities (record or playback), remove all journaling hooks, and post a WM_CANCELJOURNAL message to the journaling application.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, EVENTMSG, JournalPlaybackProc, SetWindowsHookEx, WM_CANCELJOURNAL


KeyboardProc

The KeyboardProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function whenever an application calls the GetMessage or PeekMessage function and there is a keyboard message ( WM_KEYUP or WM_KEYDOWN) to be processed.

The HOOKPROC type defines a pointer to this callback function. KeyboardProc is a placeholder for the application-defined or library-defined function name.

LRESULT CALLBACK KeyboardProc(
  int code,       // hook code
  WPARAM wParam,  // virtual-key code
  LPARAM lParam   // keystroke-message information
);

Parameters

code
Specifies a code the hook procedure uses to determine how to process the message. This parameter can be one of the following values:
Value | Meaning
HC_ACTION | The wParam and lParam parameters contain information about a keystroke message.
HC_NOREMOVE | The wParam and lParam parameters contain information about a keystroke message, and the keystroke message has not been removed from the message queue. (An application called the PeekMessage function, specifying the PM_NOREMOVE flag.)

If code is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam
Specifies the virtual-key code of the key that generated the keystroke message.
lParam
Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag. This parameter can be a combination of the following values:
Value | Description
0–15 | Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user's holding down the key.
16–23 | Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
24 | Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if the key is an extended key; otherwise, it is 0.
25–28 | Reserved.
29 | Specifies the context code. The value is 1 if the alt key is down; otherwise, it is 0.
30 | Specifies the previous key state. The value is 1 if the key is down before the message is sent; it is 0 if the key is up.
31 | Specifies the transition state. The value is 0 if the key is being pressed and 1 if it is being released.

For more information about the lParam parameter, see Keystroke Message Flags.

Return Values

If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If nCode is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_KEYBOARD hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.

Remarks

An application installs the hook procedure by specifying the WH_KEYBOARD hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, GetMessage, PeekMessage, SetWindowsHookEx, WM_KEYUP, WM_KEYDOWN


LowLevelKeyboardProc

The LowLevelKeyboardProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function every time a new keyboard input event is about to be posted into a thread input queue. The keyboard input can come from the local keyboard driver or from calls to the keybd_event function. If the input comes from a call to keybd_event, the input was "injected".

The HOOKPROC type defines a pointer to this callback function. LowLevelKeyboardProc is a placeholder for the application-defined or library-defined function name.

LRESULT CALLBACK LowLevelKeyboardProc(
  int nCode,     // hook code
  WPARAM wParam, // message identifier
  LPARAM lParam  // pointer to structure with message data
);

Parameters

nCode
Specifies a code the hook procedure uses to determine how to process the message. This parameter can be one of the following values:
Value | Meaning
HC_ACTION | The wParam and lParam parameters contain information about a keyboard message.

If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam
Specifies the identifier of the keyboard message. This parameter can be one of the following messages: WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, or WM_SYSKEYUP.
lParam
Pointer to the KBDLLHOOKSTRUCT structure.

Return Values

If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If nCode is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_KEYBOARD_LL hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.

Remarks

An application installs the hook procedure by specifying the WH_KEYBOARD_LL hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop.

The hook procedure should process a message in less time than the data entry specified in the LowLevelHooksTimeout value in the following registry key:

HKEY_CURRENT_USER\Control Panel\Desktop

The value is in milliseconds. If the hook procedure does not return during this interval, the system will pass the message to the next hook.

Note that debug hooks cannot track this type of hook.

QuickInfo

Windows NT: Requires version 4.0 SP3 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, KBDLLHOOKSTRUCT, keybd_event, SetWindowsHookEx, WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP


LowLevelMouseProc

The LowLevelMouseProc hook procedure is an application-defined callback function used with the SetWindowsHookEx function. The system call this function every time a new mouse input event is about to be posted into a thread input queue. The mouse input can come from the local mouse driver or from calls to the mouse_event function. If the input comes from a call to mouse_event, the input was "injected".

The HOOKPROC type defines a pointer to this callback function. LowLevelMouseProc is a placeholder for the application-defined or library-defined function name.

LRESULT CALLBACK LowLevelMouseProc(
  int nCode,     // hook code
  WPARAM wParam, // message identifier
  LPARAM lParam  // pointer to structure with message data
);

Parameters

nCode
Specifies a code the hook procedure uses to determine how to process the message. This parameter can be one of the following values:
Value | Meaning
HC_ACTION | The wParam and lParam parameters contain information about a mouse message.

If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam
Specifies the identifier of the mouse message. This parameter can be one of the following messages: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_RBUTTONDOWN, or WM_RBUTTONUP.
lParam
Pointer to the MSLLHOOKSTRUCT structure.

Return Values

If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If nCode is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_MOUSE_LL hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.

Remarks

An application installs the hook procedure by specifying the WH_MOUSE_LL hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop.

The hook procedure should process a message in less time than the data entry specified in the LowLevelHooksTimeout value in the following registry key:

HKEY_CURRENT_USER\Control Panel\Desktop

The value is in milliseconds. If the hook procedure does not return during this interval, the system will pass the message to the next hook.

Note that debug hooks can not track this type of hook.

QuickInfo

Windows NT: Requires version 4.0 SP3 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, mouse_event, MSLLHOOKSTRUCT, SetWindowsHookEx, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_RBUTTONDOWN, WM_RBUTTONUP.


MessageProc

The MessageProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function after an input event occurs in a dialog box, message box, menu, or scroll bar, but before the message generated by the input event is processed. The hook procedure can monitor messages for a dialog box, message box, menu, or scroll bar created by a particular application or all applications.

The HOOKPROC type defines a pointer to this callback function. MessageProc is a placeholder for the application-defined or library-defined function name.

LRESULT CALLBACK MessageProc(
  int code,       // hook code
  WPARAM wParam,  // undefined
  LPARAM lParam   // address of structure with message data
);

Parameters

code
Specifies the type of input event that generated the message. This parameter can be one of the following values:
Value | Meaning
MSGF_DDEMGR | The input event occurred while the Dynamic Data Exchange Management Library (DDEML) was waiting for a synchronous transaction to finish. For more information about DDEML, see Dynamic Data Exchange Management Library.
MSGF_DIALOGBOX | The input event occurred in a message box or dialog box.
MSGF_MENU | The input event occurred in a menu.
MSGF_NEXTWINDOW | The input event occurred as a result of the user's pressing the alt+tab key combination to activate a different window.
MSGF_SCROLLBAR | The input event occurred in a scroll bar.

If code is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and return the value returned by CallNextHookEx.

wParam
Specifies a NULL value.
lParam
Pointer to an MSG structure.

Return Values

If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If nCode is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_MSGFILTER hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.

Remarks

An application installs the hook procedure by specifying the WH_MSGFILTER hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

If an application that uses the DDEML and performs synchronous transactions must process messages before they are dispatched, it must use the WH_MSGFILTER hook.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, SetWindowsHookEx, MSG


MouseProc

The MouseProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function whenever an application calls the GetMessage or PeekMessage function and there is a mouse message to be processed.

The HOOKPROC type defines a pointer to this callback function. MouseProc is a placeholder for the application-defined or library-defined function name.

LRESULT CALLBACK MouseProc(
  int nCode,      // hook code
  WPARAM wParam,  // message identifier
  LPARAM lParam   // mouse coordinates
);

Parameters

nCode
Specifies a code the hook procedure uses to determine how to process the message. This parameter can be one of the following values:
Value | Meaning
HC_ACTION | The wParam and lParam parameters contain information about a mouse message.
HC_NOREMOVE | The wParam and lParam parameters contain information about a mouse message, and the mouse message has not been removed from the message queue. (An application called the PeekMessage function, specifying the PM_NOREMOVE flag.)

If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam
Specifies the identifier of the mouse message.
lParam
Pointer to a MOUSEHOOKSTRUCT structure.

Return Values

If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If nCode is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_MOUSE hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the target window procedure.

Remarks

An application installs the hook procedure by specifying the WH_MOUSE hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

The hook procedure must not install a JournalPlaybackProc callback function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, GetMessage, JournalPlaybackProc, MOUSEHOOKSTRUCT, PeekMessage, SetWindowsHookEx


SetWindowsHook

The SetWindowsHook function is obsolete. This function is provided only for compatibility with 16-bit versions of Windows. Win32-based applications should use the SetWindowsHookEx function.

See Also

Hooks Overview, Hook Functions


SetWindowsHookEx

The SetWindowsHookEx function installs an application-defined hook procedure into a hook chain. You would install a hook procedure to monitor the system for certain types of events. These events are associated either with a specific thread or with all threads in the system.

HHOOK SetWindowsHookEx(
  int idHook,        // type of hook to install
  HOOKPROC lpfn,     // address of hook procedure
  HINSTANCE hMod,    // handle to application instance
  DWORD dwThreadId   // identity of thread to install hook for
);

Parameters

idHook
Specifies the type of hook procedure to be installed. This parameter can be one of the following values:
Value | Description
WH_CALLWNDPROC | Installs a hook procedure that monitors messages before the system sends them to the destination window procedure. For more information, see the CallWndProc hook procedure.
WH_CALLWNDPROCRET | Installs a hook procedure that monitors messages after they have been processed by the destination window procedure. For more information, see the CallWndRetProc hook procedure.
WH_CBT | Installs a hook procedure that receives notifications useful to a computer-based training (CBT) application. For more information, see the CBTProc hook procedure.
WH_DEBUG | Installs a hook procedure useful for debugging other hook procedures. For more information, see the DebugProc hook procedure.
WH_FOREGROUNDIDLE | Installs a hook procedure that will be called when the application's foreground thread is about to become idle. This hook is useful for performing low priority tasks during idle time. For more information, see the ForegroundIdleProc hook procedure.
WH_GETMESSAGE | Installs a hook procedure that monitors messages posted to a message queue. For more information, see the GetMsgProc hook procedure.
WH_JOURNALPLAYBACK | Installs a hook procedure that posts messages previously recorded by a WH_JOURNALRECORD hook procedure. For more information, see the JournalPlaybackProc hook procedure.
WH_JOURNALRECORD | Installs a hook procedure that records input messages posted to the system message queue. This hook is useful for recording macros. For more information, see the JournalRecordProc hook procedure.
WH_KEYBOARD | Installs a hook procedure that monitors keystroke messages. For more information, see the KeyboardProc hook procedure.
WH_KEYBOARD_LL | Windows NT: Installs a hook procedure that monitors low-level keyboard input events. For more information, see the LowLevelKeyboardProc hook procedure.
WH_MOUSE | Installs a hook procedure that monitors mouse messages. For more information, see the MouseProc hook procedure.
WH_MOUSE_LL | Windows NT: Installs a hook procedure that monitors low-level mouse input events. For more information, see the LowLevelMouseProc hook procedure.
WH_MSGFILTER | Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. For more information, see the MessageProc hook procedure.
WH_SHELL | Installs a hook procedure that receives notifications useful to shell applications. For more information, see the ShellProc hook procedure.
WH_SYSMSGFILTER | Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. The hook procedure monitors these messages for all applications in the system. For more information, see the SysMsgProc hook procedure.

lpfn
Pointer to the hook procedure. If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a dynamic-link library (DLL). Otherwise, lpfn can point to a hook procedure in the code associated with the current process.
hMod
Handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
dwThreadId
Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads.

Return Values

If the function succeeds, the return value is the handle to the hook procedure.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

An error may occur if the hMod parameter is NULL and the dwThreadId parameter is zero or specifies the identifier of a thread created by another process.

Calling the CallNextHookEx function to chain to the next hook procedure is optional, but it is highly recommended; otherwise, other applications that have installed hooks will not receive hook notifications and may behave incorrectly as a result. You should call CallNextHookEx unless you absolutely need to prevent the notification from being seen by other applications.

Before terminating, an application must call the UnhookWindowsHookEx function to free system resources associated with the hook.

The scope of a hook depends on the hook type. Some hooks can be set only with system scope; others can also be set for only a specific thread, as shown in the following list:

Hook | Scope
WH_CALLWNDPROC | Thread or system
WH_CALLWNDPROCRET | Thread or system
WH_CBT | Thread or system
WH_DEBUG | Thread or system
WH_FOREGROUNDIDLE | Thread or system
WH_GETMESSAGE | Thread or system
WH_JOURNALPLAYBACK | System only
WH_JOURNALRECORD | System only
WH_KEYBOARD | Thread or system
WH_KEYBOARD_LL | Thread or system
WH_MOUSE | Thread or system
WH_MOUSE_LL | Thread or system
WH_MSGFILTER | Thread or system
WH_SHELL | Thread or system
WH_SYSMSGFILTER | System only

For a specified hook type, thread hooks are called first, then system hooks.

The system hooks are a shared resource, and installing one affects all applications. All system hook functions must be in libraries. System hooks should be restricted to special-purpose applications or to use as a development aid during application debugging. Libraries that no longer need a hook should remove the hook procedure.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, CallWndProc, CallWndRetProc, CBTProc, DebugProc, ForegroundIdleProc, GetMsgProc, JournalPlaybackProc, JournalRecordProc, LowLevelKeyboardProc, LowLevelMouseProc KeyboardProc, MouseProc, MessageProc, ShellProc, SysMsgProc, UnhookWindowsHookEx


ShellProc

The ShellProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The function receives notifications of shell events from the system.

The HOOKPROC type defines a pointer to this callback function. ShellProc is a placeholder for the application-defined or library-defined function name.

LRESULT CALLBACK ShellProc(
  int nCode,      // hook code
  WPARAM wParam,  // event-specific information
  LPARAM lParam   // event-specific information
);

Parameters

nCode
Specifies the hook code. This parameter can be one of the following values.
Value | Meaning
HSHELL_ACCESSIBILITYSTATE | Windows NT 5.0 and later: The accessibility state has changed.
HSHELL_ACTIVATESHELLWINDOW | The shell should activate its main window.
HSHELL_GETMINRECT | A window is being minimized or maximized. The system needs the coordinates of the minimized rectangle for the window.
HSHELL_LANGUAGE | Keyboard language was changed or a new keyboard layout was loaded.
HSHELL_REDRAW | The title of a window in the task bar has been redrawn.
HSHELL_TASKMAN | The user has selected the task list. A shell application that provides a task list should return TRUE to prevent Windows from starting its task list.
HSHELL_WINDOWACTIVATED | The activation has changed to a different top-level, unowned window.
HSHELL_WINDOWCREATED | A top-level, unowned window has been created. The window exists when the system calls a ShellProc function.
HSHELL_WINDOWDESTROYED | A top-level, unowned window is about to be destroyed. The window still exists when the system calls a ShellProc function.

If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam
The value depends on the value of the nCode parameter, as shown in the following table.
nCode | wParam
HSHELL_ACCESSIBILITYSTATE | Indicates which accessibility feature has changed state. This value is one of the following: ACCESS_FILTERKEYS, ACCESS_MOUSEKEYS, or ACCESS_STICKYKEYS.
HSHELL_GETMINRECT | Handle to the minimized or maximized window.
HSHELL_LANGUAGE | Handle to the window.
HSHELL_REDRAW | Handle to the redrawn window.
HSHELL_WINDOWACTIVATED | Handle to the activated window.
HSHELL_WINDOWCREATED | Handle to the created window.
HSHELL_WINDOWDESTROYED | Handle to the destroyed window.

lParam
The value depends on the value of the nCode parameter, as shown in the following table.
nCode | lParam
HSHELL_GETMINRECT | Pointer to a RECT structure.
HSHELL_LANGUAGE | Handle to a keyboard layout.
HSHELL_REDRAW | The value is TRUE if the window is flashing, or FALSE otherwise.
HSHELL_WINDOWACTIVATED | The value is TRUE if the window is in full-screen mode, or FALSE otherwise.

Return Values

The return value should be zero.

Remarks

Install this hook procedure by specifying the WH_SHELL hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, SendMessage, SetWindowsHookEx


SysMsgProc

The SysMsgProc hook procedure is a library-defined callback function used with the SetWindowsHookEx function. The system calls this function after an input event occurs in a dialog box, message box, menu, or scroll bar, but before the message generated by the input event is processed. The function can monitor messages for any dialog box, message box, menu, or scroll bar in the system.

The HOOKPROC type defines a pointer to this callback function. SysMsgProc is a placeholder for the library-defined function name.

LRESULT CALLBACK SysMsgProc(
  int nCode,      // message flag
  WPARAM wParam,  // undefined
  LPARAM lParam   // address of structure with message data
);

Parameters

nCode
Specifies the type of input event that generated the message. This parameter can be one of the following values:
Value | Meaning
MSGF_DIALOGBOX | The input event occurred in a message box or dialog box.
MSGF_MENU | The input event occurred in a menu.
MSGF_SCROLLBAR | The input event occurred in a scroll bar.
MSGF_NEXTWINDOW | The input event occurred as a result of the user's pressing the alt+tab key combination to activate a different window.

If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.

wParam
Specifies a NULL value.
lParam
Pointer to an MSG message structure.

Return Values

If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If nCode is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_SYSMSGFILTER hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the target window procedure.

Remarks

An application installs the hook procedure by specifying the WH_SYSMSGFILTER hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.

See Also

Hooks Overview, Hook Functions, CallNextHookEx, MSG, SetWindowsHookEx


UnhookWindowsHook

The UnhookWindowsHook function is obsolete, but is provided for compatibility with 16-bit versions of Windows. For Win32-based applications, use the UnhookWindowsHookEx function.

See Also

Hooks Overview, Hook Functions


UnhookWindowsHookEx

The UnhookWindowsHookEx function removes a hook procedure installed in a hook chain by the SetWindowsHookEx function.

BOOL UnhookWindowsHookEx(
  HHOOK hhk   // handle to hook procedure to remove
);

Parameters

hhk
Handle to the hook to be removed. This parameter is a hook handle obtained by a previous call to SetWindowsHookEx.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The hook procedure can be in the state of being called by another thread even after UnhookWindowsHookEx returns. If the hook procedure is not being called concurrently, the hook procedure is removed immediately before UnhookWindowsHookEx returns.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Hooks Overview, Hook Functions, SetWindowsHookEx, UnhookWindowsHook


Hook Structures

The following structures are used with hooks.

CBT_CREATEWND
CBTACTIVATESTRUCT
CWPRETSTRUCT
CWPSTRUCT
DEBUGHOOKINFO
EVENTMSG
KBDLLHOOKSTRUCT
MOUSEHOOKSTRUCT
MSLLHOOKSTRUCT


CBT_CREATEWND

The CBT_CREATEWND structure contains information passed to a WH_CBT hook procedure, CBTProc, before a window is created.

typedef struct tagCBT_CREATEWND { // cbtcw
    LPCREATESTRUCT lpcs;
    HWND           hwndInsertAfter;
} CBT_CREATEWND;

Members

lpcs
Pointer to a CREATESTRUCT structure that contains initialization parameters for the window about to be created.
hwndInsertAfter
Handle to the window whose position in the Z order precedes that of the window being created.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Hooks Overview, Hook Structures, CBTProc, CREATESTRUCT, SetWindowsHookEx


CBTACTIVATESTRUCT

The CBTACTIVATESTRUCT structure contains information passed to a WH_CBT hook procedure, CBTProc, before a window is activated.

typedef struct tagCBTACTIVATESTRUCT { // cas
    BOOL fMouse;
    HWND hWndActive;
} CBTACTIVATESTRUCT;

Members

fMouse
Specifies whether the window is being activated as a result of a mouse click. This value is TRUE if a mouse click is causing the activation or FALSE if it is not.
hWndActive
Handle to the active window.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Hooks Overview, Hook Structures, CBTProc, SetWindowsHookEx


CWPRETSTRUCT

The CWPRETSTRUCT structure defines the message parameters passed to a WH_CALLWNDPROCRET hook procedure, CallWndRetProc.

typedef struct tagCWPRETSTRUCT { // cwprs
    LRESULT lResult;
    LPARAM  lParam;
    WPARAM  wParam;
    DWORD   message;
    HWND    hwnd;
} CWPRETSTRUCT;

Members

lResult
Specifies the return value of the window procedure that processed the message specified by the message value.
lParam
Specifies additional information about the message. The exact meaning depends on the message value.
wParam
Specifies additional information about the message. The exact meaning depends on the message value.
message
Specifies the message.
hwnd
Handle to the window that processed the message specified by the message value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Hooks Overview, Hook Structures, CallWndRetProc, SetWindowsHookEx


CWPSTRUCT

The CWPSTRUCT structure defines the message parameters passed to a WH_CALLWNDPROC hook procedure, CallWndProc.

typedef struct tagCWPSTRUCT { // cwps
    LPARAM  lParam;
    WPARAM  wParam;
    UINT    message;
    HWND    hwnd;
} CWPSTRUCT;

Members

lParam
Specifies additional information about the message. The exact meaning depends on the message value.
wParam
Specifies additional information about the message. The exact meaning depends on the message value.
message
Specifies the message.
hwnd
Handle to the window to receive the message.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Hooks Overview, Hook Structures, CallWndProc, SetWindowsHookEx


DEBUGHOOKINFO

The DEBUGHOOKINFO structure contains debugging information passed to a WH_DEBUG hook procedure, DebugProc.

typedef struct tagDEBUGHOOKINFO { // dh
    DWORD  idThread;
    DWORD  idThreadInstaller;
    LPARAM lParam;
    WPARAM wParam;
    int    code;
} DEBUGHOOKINFO;

Members

idThread
Handle to the thread containing the filter function.
idThreadInstaller
Handle to the thread that installed the debugging filter function.
lParam
Specifies the value to be passed to the hook in the lParam parameter of the DebugProc callback function.
wParam
Specifies the value to be passed to the hook in the wParam parameter of the DebugProc callback function.
code
Specifies the value to be passed to the hook in the nCode parameter of the DebugProc callback function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Hooks Overview, Hook Structures, DebugProc, SetWindowsHookEx


EVENTMSG

The EVENTMSG structure contains information about a hardware message sent to the system message queue. This structure is used to store message information for the JournalPlaybackProc callback function.

typedef struct tagEVENTMSG {    // em
    UINT  message;
    UINT  paramL;
    UINT  paramH;
    DWORD time;
    HWND  hwnd;
} EVENTMSG;

Members

message
Specifies the message.
paramL
Specifies additional information about the message. The exact meaning depends on the message value.
paramH
Specifies additional information about the message. The exact meaning depends on the message value.
time
Specifies the time at which the message was posted.
hwnd
Handle to the window to which the message was posted.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Hooks Overview, Hook Structures, JournalPlaybackProc, SetWindowsHookEx


KBDLLHOOKSTRUCT

The KBDLLHOOKSTRUCT structure contains information about a low-level keyboard input event.

typedef struct tagKBDLLHOOKSTRUCT {
    DWORD vkCode;      // virtual key code
    DWORD scanCode;    // scan code
    DWORD flags;       // flags
    DWORD time;        // time stamp for this message
    DWORD dwExtraInfo; // extra info from the driver or keybd_event
} KBDLLHOOKSTRUCT, FAR *LPKBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;

Members

vkCode
Specifies a virtual-key code. The code must be a value in the range 1 to 254.
scanCode
Specifies a hardware scan code for the key.
flags
Specifies the extended-key flag, event-injected flag, context code, and transition-state flag.
Value | Description
0 | Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if the key is an extended key; otherwise, it is 0.
1-3 | Reserved.
4 | Specifies whether the event was injected. The value is 1 if the event was injected; otherwise, it is 0.
5 | Specifies the context code. The value is 1 if the ALT key is pressed; otherwise, it is 0.
6 | Reserved.
7 | Specifies the transition state. The value is 0 if the key is pressed and 1 if it is being released.

An application can use the following values to test the keystroke flags:
Value | Purpose
LLKHF_EXTENDED | Test the extended-key flag.
LLKHF_INJECTED | Test the event-injected flag.
LLKHF_ALTDOWN | Test the context code.
LLKHF_UP | Test the transition-state flag.

time
Specifies the time stamp for this message.
dwExtraInfo
Specifies extra information associated with the message.

QuickInfo

Windows NT: Requires version 4.0 SP3 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Hooks Overview, Hook Structures, LowLevelKeyboardProc, SetWindowsHookEx


MOUSEHOOKSTRUCT

The MOUSEHOOKSTRUCT structure contains information about a mouse event passed to a WH_MOUSE hook procedure, MouseProc.

typedef struct tagMOUSEHOOKSTRUCT { // ms
    POINT pt;
    HWND  hwnd;
    UINT  wHitTestCode;
    DWORD dwExtraInfo;
} MOUSEHOOKSTRUCT;

Members

pt
Specifies a POINT structure that contains the x- and y-coordinates of the cursor, in screen coordinates.
hwnd
Handle to the window that will receive the mouse message corresponding to the mouse event.
wHitTestCode
Specifies the hit-test value. For a list of hit-test values, see the description of the WM_NCHITTEST message.
dwExtraInfo
Specifies extra information associated with the message.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Hooks Overview, Hook Structures, MouseProc, POINT, SetWindowsHookEx, WM_NCHITTEST


MSLLHOOKSTRUCT

The MSLLHOOKSTRUCT structure contains information about a low-level keyboard input event.

typedef struct tagMSLLHOOKSTRUCT {
    DWORD pt;
    DWORD mouseData;
    DWORD flags;
    DWORD time;
    DWORD dwExtraInfo;
} MSLLHOOKSTRUCT, FAR *LPMSLLHOOKSTRUCT, *PMSLLHOOKSTRUCT;

Members

pt
Specifies a POINT structure that contains the x- and y-coordinates of the cursor, in screen coordinates.
mouseData
Used by the WM_MOUSEWHEEL message.
flags
Specifies the event-injected flag.
Value | Description
0 | Specifies whether the event was injected. The value is 1 if the event was injected; otherwise, it is 0.
1-15 | Reserved.

An application can use the following value to test the mouse flags:
Value | Purpose
LLMHF_INJECTED | Test the event-injected flag.

time
Specifies the time stamp for this message.
dwExtraInfo
Specifies extra information associated with the message.

QuickInfo

Windows NT: Requires version 4.0 SP3 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Hooks Overview, Hook Structures, LowLevelMouseProc, POINT, SetWindowsHookEx, WM_MOUSEWHEEL


Hook Messages

The following messages are used with hooks.

WM_CANCELJOURNAL
WM_QUEUESYNC


WM_CANCELJOURNAL

The WM_CANCELJOURNAL message is posted to an application when a user cancels the application's journaling activities. The message is posted with a NULL window handle.

WM_CANCELJOURNAL
wParam = 0; // not used, must be zero
lParam = 0; // not used, must be zero

Parameters

This message has no parameters.

Return Values

This message does not return a value. It is meant to be processed from within an application's main loop or a GetMessage hook procedure, not from a window procedure.

Remarks

Journal record and playback modes are modes imposed on the system that let an application sequentially record or play back user input. The system enters these modes when an application installs a JournalRecordProc or JournalPlaybackProc hook procedure. When the system is in either of these journaling modes, applications must take turns reading input from the input queue. If any one application stops reading input while the system is in a journaling mode, other applications are forced to wait.

To ensure a robust system, one that cannot be hung up by any one application, the system automatically cancels any journaling activities when a user presses CTRL+ESC or CTRL+ALT+DEL. The system then unhooks any journaling hook procedures, and posts a WM_CANCELJOURNAL message, with a NULL window handle, to the application that set the journaling hook.

Since the WM_CANCELJOURNAL has a NULL window handle, it cannot be dispatched to a window procedure. There are two ways for an application to see a WM_CANCELJOURNAL message: If the application is running in its own main loop, it must catch the message between its call to GetMessage or PeekMessage and its call to DispatchMessage. If the application is not running in its own main loop, it must set a GetMsgProc hook procedure (via a call to SetWindowsHookEx specifying the WH_GETMESSAGE hook type) that watches for the message.

When an application sees a WM_CANCELJOURNAL message, it can assume two things: the user has intentionally cancelled the journal record or playback mode, and the system has already unhooked any journal record or playback hook procedures.

Note that the key combinations mentioned above (CTRL+ESC or CTRL+ALT+DEL) cause the system to cancel journaling. If any one application is hung, they give the user a means of recovery. The VK_CANCEL virtual keycode (usually implemented as the CTRL+BREAK key combination) is what an application that is in journal record mode should watch for as a signal that the user wishes to cancel the journaling activity. The difference is that watching for VK_CANCEL is a suggested behavior for journaling applications, whereas CTRL+ESC or CTRL+ALT+DEL cause the system to cancel journalling regardless of a journalling application's behavior.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Hooks Overview, Hook Messages, DispatchMessage, GetMessage, JournalPlaybackProc, JournalRecordProc, GetMsgProc, PeekMessage, SetWindowsHookEx


WM_QUEUESYNC

The WM_QUEUESYNC message is sent by a computer-based training (CBT) application to separate user-input messages from other messages sent through the WH_JOURNALPLAYBACK hook procedure.

WM_QUEUESYNC
wParam = 0; // not used, must be zero
lParam = 0; // not used, must be zero

Parameters

This message has no parameters.

Return Values

A CBT application should return zero if it processes this message.

Remarks

Whenever a CBT application uses the WH_JOURNALPLAYBACK hook procedure, the first and last messages are WM_QUEUESYNC. This allows the CBT application to intercept and examine user-initiated messages without doing so for events that it sends.

If an application specifies a NULL window handle, the message is posted to the message queue of the active window.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Hooks Overview, Hook Messages, SetWindowsHookEx


File Mapping

This overview describes file mapping and how to use the file-mapping functions provided in the Microsoft® Win32® application programming interface (API).


About File Mapping

File mapping is the association of a file's contents with a portion of the virtual address space of a process. The system creates a file-mapping object to maintain this association. A file view is the portion of virtual address space that the process uses to access the file's contents. Processes read from and write to the file view using pointers, just as they would with dynamically allocated memory. Processes can also manipulate the file view with the virtual memory function VirtualProtect.

The file-mapping functions allow a process to create file-mapping objects and file views to easily access and share data. The following illustration shows the relationship between the file on disk, a file-mapping object, and a file view.

The file on disk can be any file that you want to map into memory, or it can be the system pagefile.

The file-mapping object can consist of all or only part of the file. It is backed by the file on disk. This means that when the system swaps out pages of the file-mapping object, any changes made to the file-mapping object are written to the file. When the pages of the file-mapping object are swapped back in, they are restored from the file.

A file view can consist of all or only part of the file-mapping object. A process manipulates the file through the file views. A process can create multiple views for a file-mapping object.

Windows NT: The file views created by each process reside in the virtual address space of that process.

Windows 95: All file views reside in the shared address space. The shared address space exists in the range between 2 and 3 gigabytes in the virtual address space for each process. It contains the 16-bit heap and shared system DLLs, as well as file views.

When multiple processes use the same file-mapping object to create views for a local file, the data is coherent. That is, the views contain identical copies of the file on disk. The file cannot reside on a remote computer if you want to share memory between multiple processes.


Advantages of File Mapping

File mapping provides two major advantages:

  • Shared memory
  • Faster and easier file access

File mapping allows two or more applications to share memory. Win32-based applications cannot share memory by any other means.

File mapping allows a process to access files more quickly and easily by using a pointer to a file view. Using a pointer improves efficiency because the file resides on disk, but the file view resides in memory. File mapping allows the process to use both random I/O and sequential I/O. It also allows the process to efficiently work with a large data file, such as a database, without having to map the whole file into memory. When the process needs data from a portion of the file other than what is in the current file view, it can unmap the current file view, then create a new file view.


Creating a File-Mapping Object

The first step in mapping a file is to open the file by calling the CreateFile function. To ensure that other processes cannot write to the portion of the file that is mapped, you should open the file with exclusive access. In addition, the file handle should remain open until the process no longer needs the file-mapping object. An easy way to obtain exclusive access is to specify zero in the fdwShareMode parameter of CreateFile. The handle returned by CreateFile is used by the CreateFileMapping function to create a file-mapping object.

The CreateFileMapping function returns a handle to the file-mapping object. This handle will be used when creating a file view so that you can access the shared memory. When you call CreateFileMapping, you specify an object name, the number of bytes to be mapped from the file, and the read/write permission for the mapped memory. The first process that calls CreateFileMapping creates the file-mapping object. Processes calling CreateFileMapping for an existing object receive a handle to the existing object. You can tell whether or not a successful call to CreateFileMapping created or opened the file-mapping object by calling the GetLastError function. GetLastError returns NO_ERROR to the creating process and ERROR_ALREADY_EXISTS to subsequent processes.

The CreateFileMapping function fails if the access flags conflict with those specified when the CreateFile function opened the file. For example, to read and write to the file:

  • Specify the GENERIC_READ and GENERIC_WRITE values in the fdwAccess parameter of CreateFile.
  • Specify the PAGE_READWRITE value in the fdwProtect parameter of CreateFileMapping.

File Mapping Size

The size of the file-mapping object is independent of the size of the file being mapped. However, if the file-mapping object is larger than the file, the system expands the file before CreateFileMapping returns. If the file-mapping object is smaller than the file, the system maps only the specified number of bytes from the file.

The dwMaximumSizeHigh and dwMaximumSizeLow parameters of CreateFileMapping allow you to specify the number of bytes to be mapped from the file.

Windows 95: The dwMaximumSizeHigh parameter is not used because it is not supported by the 32-bit file system. The value should be zero.

When you do not want the size of the file to change (for example, when mapping read-only files), call CreateFileMapping and specify zero for both dwMaximumSizeHigh and dwMaximumSizeLow. Doing this creates a file-mapping object exactly the same size as the file. Otherwise, you must calculate or estimate the size of the finished file because file-mapping objects are static in size; once created, their size cannot increase or decrease.

Windows NT: The size of a file-mapping object backed by a named file is limited by disk space. The size of a file view is limited to the largest available contiguous block of unreserved virtual memory. This is at most 2 GB minus the virtual memory already reserved by the process.

Windows 95: The size of a file-mapping object backed by a named file is also limited by disk space. The size of a file view is limited to the largest available contiguous block of unreserved virtual memory in the shared address space. This is at most 1 GB minus the virtual memory in use by other processes, such as 16-bit Windows-based applications or Win32-based applications using file mapping.


Creating a File View

To map the data from a file to the virtual memory of a process, you must create a view of the file. The MapViewOfFile and MapViewOfFileEx functions use the file-mapping object handle returned by CreateFileMapping to create a view of the file or a portion of the file in the process's virtual address space. These functions fail if the access flags conflict with those specified when CreateFileMapping created the file-mapping object.

The MapViewOfFile function returns a pointer to the file view. By dereferencing a pointer in the range of addresses specified in MapViewOfFile, an application can read data from the file and write data to the file. Writing to the file view results in changes to the file-mapping object. The actual writing to the file on disk is handled by the system. Data is not actually transferred at the time the file-mapping object is written to. Instead, much of the file input and output (I/O) is cached to improve general system performance. Applications can override this behavior by calling the FlushViewOfFile function to force the system to perform disk transactions immediately.

The MapViewOfFileEx function works exactly like the MapViewOfFile function except that it allows a process to specify the base address of the view of the file in the process's virtual address space in the lpvBase parameter. If there is not enough space at the specified address, the call fails. Therefore, if you must map a file to the same address in multiple processes, the processes should negotiate an appropriate address.

Windows NT: The lpvBase parameter must be an integral multiple of the system memory allocation granularity or the call fails. To obtain the system's memory allocation granularity, use the GetSystemInfo function, which fills in the members of a SYSTEM_INFO structure.

Windows 95: The address is rounded down to the nearest integral multiple of the system's memory allocation granularity. For subsequent file views, if the address specified does not match the address to which the system mapped the file view, MapViewOfFileEx fails.

An application can create multiple file views from the same file-mapping object. A file view can be a different size than the file-mapping object from which it is derived, but it must be smaller than the file-mapping object. The offset specified by the dwOffsetHigh and dwOffsetLow parameters of MapViewOfFile must be a multiple of the allocation granularity of the system.


Closing the File-Mapping Object

When a process has finished with the file-mapping object, it should destroy all file views in its address space by using the UnmapViewOfFile function for each file view. This function invalidates the pointer to the process's virtual address space. If any of the pages of the file view have changed since the view was mapped, the system writes the changed pages of the file to disk using caching. To commit the data to disk immediately, call the FlushViewOfFile function before unmapping the file view.

You must call the CloseHandle function to first close the file-mapping object and then close the file on disk. These calls to CloseHandle succeed even when there are file views that are still open. However, leaving file views mapped causes memory leaks.


Sharing Files and Memory

File mapping can be used to share a file or memory between two or more processes. To share a file or memory, all of the processes must use the name or the handle of the same file-mapping object.

To share a file, the first process creates or opens a file by using the CreateFile function. Next, it creates a file-mapping object by using the CreateFileMapping function, specifying the file handle and a name for the file-mapping object. The names of event, semaphore, mutex, and file-mapping objects share the same name space. Therefore, the CreateFileMapping and OpenFileMapping functions fail if they specify a name that is in use by an object of another type.

To share memory that is not associated with a file, a process must use the CreateFileMapping function and specify (HANDLE)0xFFFFFFFF as the hfile parameter instead of an existing file handle. The corresponding file-mapping object accesses memory backed by the system paging file. You must specify a size greater than zero when you specify an hfile of (HANDLE)0xFFFFFFFF in a call to CreateFileMapping.

The easiest way for other processes to obtain a handle of the file-mapping object created by the first process is to use the OpenFileMapping function and specify the object's name. This is referred to as named shared memory. If the file-mapping object does not have a name, the process must obtain a handle to it through inheritance or duplication. For more information on inheritance and duplication, see Inheritance.

Processes that share files or memory must create file views by using the MapViewOfFile or MapViewOfFileEx function. They must coordinate their access using semaphores, mutexes, events, or some other mutual exclusion technique. For more information, see Synchronization.

A shared file-mapping object will not be destroyed until all processes that use it close their handles to it by using the CloseHandle function.


Using File Mapping

The following code samples illustrate how two processes might access an existing file as named shared memory.

  • Creating named shared memory
  • Reading and writing
  • Cleaning up

As discussed earlier in this overview, the processes must synchronize their access to the memory. For more information, see Synchronization.


Creating Named Shared Memory

The first process calls the CreateFileMapping function to create a file-mapping object and give it the name MyFileMappingObject. By using the PAGE_READWRITE flag, the processes will have read/write permission to the memory through any file views that are created.

HANDLE hMapFile;

hMapFile = CreateFileMapping(hFile,    // Current file handle.
    NULL,                              // Default security.
    PAGE_READWRITE,                    // Read/write permission.
    0,                                 // Max. object size.
    0,                                 // Size of hFile.
    "MyFileMappingObject");            // Name of mapping object.

if (hMapFile == NULL)
{
    ErrorHandler("Could not create file-mapping object.");
}

The process then uses the file-mapping object handle returned by CreateFileMapping in the call to MapViewOfFile to create a view of the file in the process's address space. The MapViewOfFile function returns a pointer to the file view.

LPVOID lpMapAddress;
lpMapAddress = MapViewOfFile(hMapFile, // Handle to mapping object.
    FILE_MAP_ALL_ACCESS,               // Read/write permission
    0,                                 // Max. object size.
    0,                                 // Size of hFile.
    0);                                // Map entire file.

if (lpMapAddress == NULL)
{
    ErrorHandler("Could not map view of file.");
}

The second process calls the OpenFileMapping function with the name MyFileMappingObject to use the same file-mapping object as the first process. Like the first process, the second process uses the MapViewOfFile function to obtain a pointer to the file view.

HANDLE hMapFile;
LPVOID lpMapAddress;

hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, // Read/write permission.
    FALSE,                             // Do not inherit the name
    "MyFileMappingObject");            // of the mapping object.

if (hMapFile == NULL)
{
    ErrorHandler("Could not open file-mapping object.");
}

lpMapAddress = MapViewOfFile(hMapFile, // Handle to mapping object.
    FILE_MAP_ALL_ACCESS,               // Read/write permission.
    0,                                 // Max. object size.
    0,                                 // Size of hFile.
    0);                                // Map entire file.

if (lpMapAddress == NULL)
{
    ErrorHandler("Could not map view of file.");
}


Reading and Writing

To read from a file view, a process dereferences the pointer returned by the MapViewOfFile function:

DWORD dwLength;

dwLength = *((LPDWORD) lpMapAddress);

The process also uses the pointer returned by MapViewOfFile to write to the file view:

*((LPDWORD) lpMapAddress) = dwLength;

The FlushViewOfFile function copies the specified number of bytes of the file view to the physical file, without waiting for the cached write operation to occur:

if (!FlushViewOfFile(lpMapAddress, dwBytesToFlush))
{
    ErrorHandler("Could not flush memory to disk.");
}

Note Reading from or writing to a file view can cause an exception. For example, accessing a mapped file that resides on a remote server can generate an exception if the connection to the server is lost. Exceptions can also occur because of a full disk, because the file is shared and a different process has locked a byte range, or because of an underlying device failure or memory allocation failure. To guard against access violations, all accesses to memory mapped files should be wrapped in structured exception handlers.

If you are mapping a compressed or sparse file on an NTFS partition, there is additional potential for an access violation. In this case, the address space mapped by MapViewOfFile may not be backed by allocated disk space. This is because a sparse file can have regions of zeroes for which NTFS does not allocate disk space, and a compressed file can take up less disk space than the actual data that it represents. If you read from or write to a portion of a sparse or compressed file that is not backed by disk space, the system may try to allocate disk space. If the disk is full, this can result in an access violation.

For more information, see File Compression, Sparse Files, and Structured Exception Handling.


Cleaning Up

Each process uses the UnmapViewOfFile function to invalidate the pointer to the mapped memory. This destroys the file view in the address space of the process. If any pages of the file view have changed since the file view was mapped, UnmapViewOfFile also copies the changed pages to the file on disk.

if (!UnmapViewOfFile(lpMapAddress))
{
    ErrorHandler("Could not unmap view of file.");
}

When each process finishes using the file-mapping object and has umapped all views, it must close the file mapping object's handle by calling CloseHandle.

CloseHandle(hMapFile);


File Mapping Reference

The following elements are used with file mapping.

  • File Mapping Functions


File Mapping Functions

The following functions are used with file mapping.

CreateFileMapping
FlushViewOfFile
MapViewOfFile
MapViewOfFileEx
MapViewOfFileVlm
OpenFileMapping
UnmapViewOfFile
UnmapViewOfFileVlm


CreateFileMapping

The CreateFileMapping function creates a named or unnamed file-mapping object for the specified file.

HANDLE CreateFileMapping(
  HANDLE hFile,              // handle to file to map
  LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
                             // optional security attributes
  DWORD flProtect,           // protection for mapping object
  DWORD dwMaximumSizeHigh,   // high-order 32 bits of object size
  DWORD dwMaximumSizeLow,    // low-order 32 bits of object size
  LPCTSTR lpName             // name of file-mapping object
);

Parameters

hFile
Handle to the file from which to create a mapping object. The file must be opened with an access mode compatible with the protection flags specified by the flProtect parameter. It is recommended, though not required, that files you intend to map be opened for exclusive access.

If hFile is (HANDLE)0xFFFFFFFF, the calling process must also specify a mapping object size in the dwMaximumSizeHigh and dwMaximumSizeLow parameters. The function creates a file-mapping object of the specified size backed by the operating-system paging file rather than by a named file in the file system. The file-mapping object can be shared through duplication, through inheritance, or by name.

lpFileMappingAttributes
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpFileMappingAttributes is NULL, the handle cannot be inherited.

Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new file-mapping object. If lpFileMappingAttributes is NULL, the file-mapping object gets a default security descriptor.

flProtect
Specifies the protection desired for the file view, when the file is mapped. This parameter can be one of the following values:
Value | Description
PAGE_READONLY | Gives read-only access to the committed region of pages. An attempt to write to or execute the committed region results in an access violation. The file specified by the hFile parameter must have been created with GENERIC_READ access.
PAGE_READWRITE | Gives read-write access to the committed region of pages. The file specified by hFile must have been created with GENERIC_READ and GENERIC_WRITE access.
PAGE_WRITECOPY | Gives copy on write access to the committed region of pages. The files specified by the hFile parameter must have been created with GENERIC_READ and GENERIC_WRITE access.

In addition, an application can specify certain section attributes by combining (using the bitwise OR operator) one or more of the following section attribute values with one of the preceding page protection values:
Value | Description
SEC_COMMIT | Allocates physical storage in memory or in the paging file on disk for all pages of a section. This is the default setting.
SEC_IMAGE | The file specified for a section's file mapping is an executable image file. Because the mapping information and file protection are taken from the image file, no other attributes are valid with SEC_IMAGE.
SEC_NOCACHE | All pages of a section are to be set as non-cacheable. This attribute is intended for architectures requiring various locking structures to be in memory that is never fetched into the processor's. On 80x86 and MIPS machines, using the cache for these structures only slows down the performance as the hardware keeps the caches coherent. Some device drivers require noncached data so that programs can write through to the physical memory. SEC_NOCACHE requires either the SEC_RESERVE or SEC_COMMIT to also be set.
SEC_RESERVE | Reserves all pages of a section without allocating physical storage. The reserved range of pages cannot be used by any other allocation operations until it is released. Reserved pages can be committed in subsequent calls to the VirtualAlloc function. This attribute is valid only if the hFile parameter is (HANDLE)0xFFFFFFFF; that is, a file mapping object backed by the operating sytem paging file.

dwMaximumSizeHigh
Specifies the high-order 32 bits of the maximum size of the file-mapping object.
dwMaximumSizeLow
Specifies the low-order 32 bits of the maximum size of the file-mapping object. If this parameter and dwMaximumSizeHig are zero, the maximum size of the file-mapping object is equal to the current size of the file identified by hFile.
lpName
Pointer to a null-terminated string specifying the name of the mapping object. The name can contain any character except the backslash character (\).

If this parameter matches the name of an existing named mapping object, the function requests access to the mapping object with the protection specified by flProtect.

If this parameter is NULL, the mapping object is created without a name.

If lpName matches the name of an existing event, semaphore, mutex, waitable timer, or job, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space.

Return Values

If the function succeeds, the return value is a handle to the file-mapping object. If the object existed before the function call, the function returns a handle to the existing object (with its current size, not the specified size) and GetLastError returns ERROR_ALREADY_EXISTS.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

After a file-mapping object has been created, the size of the file must not exceed the size of the file-mapping object; if it does, not all of the file's contents will be available for sharing.

If an application specifies a size for the file-mapping object that is larger than the size of the actual named file on disk, the file on disk is grown to match the specified size of the file-mapping object. If the file cannot be grown, this results in a failure to create the file-mapping object. GetLastError will return ERROR_DISK_FULL.

The handle that CreateFileMapping returns has full access to the new file-mapping object. It can be used with any function that requires a handle to a file-mapping object. File-mapping objects can be shared either through process creation, through handle duplication, or by name. For information on duplicating handles, see DuplicateHandle. For information on opening a file-mapping object by name, see OpenFileMapping.

Windows 95: File handles that have been used to create file-mapping objects must not be used in subsequent calls to file I/O functions, such as ReadFile and WriteFile. In general, if a file handle has been used in a successful call to the CreateFileMapping function, do not use that handle unless you first close the corresponding file-mapping object.

Creating a file-mapping object creates the potential for mapping a view of the file but does not map the view. The MapViewOfFile and MapViewOfFileEx functions map a view of a file into a process's address space.

With one important exception, file views derived from a single file-mapping object are coherent, or identical, at a given time. If multiple processes have handles of the same file-mapping object, they see a coherent view of the data when they map a view of the file.

The exception has to do with remote files. Although CreateFileMapping works with remote files, it does not keep them coherent. For example, if two computers both map a file as writeable, and both change the same page, each computer will only see its own writes to the page. When the data gets updated on the disk, it is not merged.

A mapped file and a file accessed by means of the input and output (I/O) functions (ReadFile and WriteFile) are not necessarily coherent.

To fully close a file mapping object, an application must unmap all mapped views of the file mapping object by calling UnmapViewOfFile, and close the file mapping object handle by calling CloseHandle. The order in which these functions are called does not matter. The call to UnmapViewOfFile is necessary because mapped views of a file mapping object maintain internal open handles to the object, and a file mapping object will not close until all open handles to it are closed.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory mapped view. For more information, see Reading and Writing.

Windows CE: Windows CE does not use the lpFileMappingAttributes parameter. It must be NULL.

This function will not work on a device that does not support Page-In.

Example

To implement a mapping-object creation function that fails if the object already exists, an application can use the following code.

hMap = CreateFileMapping(...);

if (hMap != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
{
    CloseHandle(hMap);
    hMap = NULL;
}
return hMap;

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File Mapping Overview, File Mapping Functions, CloseHandle, DuplicateHandle, MapViewOfFile, MapViewOfFileEx, MapViewOfFileVlm, OpenFileMapping, ReadFile, SECURITY_ATTRIBUTES, UnmapViewOfFile, UnmapViewOfFileVlm, VirtualAlloc, WriteFile


FlushViewOfFile

The FlushViewOfFile function writes to the disk a byte range within a mapped view of a file.

BOOL FlushViewOfFile(
  LPCVOID lpBaseAddress,       // start address of byte range to flush
  DWORD dwNumberOfBytesToFlush // number of bytes in range
);

Parameters

lpBaseAddress
Pointer to the base address of the byte range to be flushed to the disk representation of the mapped file.
dwNumberOfBytesToFlush
Specifies the number of bytes to flush.

If dwNumberOfBytesToFlush is zero, the file is flushed from the base address to the end of the mapping.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Flushing a range of a mapped view causes any dirty pages within that range to be written to the disk. Dirty pages are those whose contents have changed since the file view was mapped.

When flushing a memory-mapped file over a network, FlushViewOfFile guarantees that the data has been written from the local computer, but not that the data resides on the remote computer. The server can cache the data on the remote side. Therefore, FlushViewOfFile can return before the data has been physically written to disk. However, you can cause FlushViewOfFile to return only when the physical write is complete by specifying the FILE_FLAG_WRITE_THROUGH flag when you open the file with the CreateFile function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File Mapping Overview, File Mapping Functions, CreateFile , MapViewOfFile, UnmapViewOfFile


MapViewOfFile

The MapViewOfFile function maps a view of a file into the address space of the calling process.

LPVOID MapViewOfFile(
  HANDLE hFileMappingObject,  // file-mapping object to map into
                              // address space
  DWORD dwDesiredAccess,      // access mode
  DWORD dwFileOffsetHigh,     // high-order 32 bits of file offset
  DWORD dwFileOffsetLow,      // low-order 32 bits of file offset
  DWORD dwNumberOfBytesToMap  // number of bytes to map
);

Parameters

hFileMappingObject
Handle to an open handle of a file-mapping object. The CreateFileMapping and OpenFileMapping functions return this handle.
dwDesiredAccess
Specifies the type of access to the file view and, therefore, the protection of the pages mapped by the file. This parameter can be one of the following values:
Value | Meaning
FILE_MAP_WRITE | Read-write access. The hFileMappingObject parameter must have been created with PAGE_READWRITE protection. A read-write view of the file is mapped.
FILE_MAP_READ | Read-only access. The hFileMappingObject parameter must have been created with PAGE_READWRITE or PAGE_READONLY protection. A read-only view of the file is mapped.
FILE_MAP_ALL_ACCESS | Same as FILE_MAP_WRITE.
FILE_MAP_COPY Copy on write access. If you create the map with PAGE_WRITECOPY and the view with FILE_MAP_COPY, you will receive a view to file. If you write to it, the pages are automatically swappable and the modifications you make will not go to the original data file.

Windows 95: You must pass PAGE_WRITECOPY to CreateFileMapping; otherwise, an error will be returned.

If you share the mapping between multiple processes using DuplicateHandle or OpenFileMapping and one process writes to a view, the modification is propagated to the other process. The original file does not change.

Windows NT: There is no restriction as to how the hFileMappingObject parameter must be created. Copy on write is valid for any type of view.

If you share the mapping between multiple processes using DuplicateHandle or OpenFileMapping and one process writes to a view, the modification is not propagated to the other process. The original file does not change.

dwFileOffsetHigh
Specifies the high-order 32 bits of the file offset where mapping is to begin.
dwFileOffsetLow
Specifies the low-order 32 bits of the file offset where mapping is to begin. The combination of the high and low offsets must specify an offset within the file that matches the system's memory allocation granularity, or the function fails. That is, the offset must be a multiple of the allocation granularity. Use the GetSystemInfo function, which fills in the members of a SYSTEM_INFO structure, to obtain the system's memory allocation granularity.
dwNumberOfBytesToMap
Specifies the number of bytes of the file to map. If dwNumberOfBytesToMap is zero, the entire file is mapped.

Return Values

If the function succeeds, the return value is the starting address of the mapped view.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

Mapping a file makes the specified portion of the file visible in the address space of the calling process.

Multiple views of a file (or a file-mapping object and its mapped file) are said to be "coherent" if they contain identical data at a specified time. This occurs if the file views are derived from the same file-mapping object. A process can duplicate a file-mapping object handle into another process by using the DuplicateHandle function, or another process can open a file-mapping object by name by using the OpenFileMapping function.

A mapped view of a file is not guaranteed to be coherent with a file being accessed by the ReadFile or WriteFile function.

Windows 95: MapViewOfFile may require the swapfile to grow. If the swapfile cannot grow, the function fails.

Windows NT: If the file-mapping object is backed by the paging file (handle = 0xFFFFFFFF), the paging file must be large enough to hold the entire mapping. If it is not, MapViewOfFile fails.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory mapped view. For more information, see Reading and Writing.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File Mapping Overview, File Mapping Functions, CreateFileMapping, DuplicateHandle, GetSystemInfo, MapViewOfFileEx, MapViewOfFileVlm, OpenFileMapping, UnmapViewOfFile, UnmapViewOfFileVlm, SYSTEM_INFO


MapViewOfFileEx

The MapViewOfFileEx function maps a view of a file into the address space of the calling process. This extended function allows the calling process to specify a suggested memory address for the mapped view.

This function is available for Win32-based applications only.

LPVOID MapViewOfFileEx(
  HANDLE hFileMappingObject,  // file-mapping object to map into
                              // address space
  DWORD dwDesiredAccess,      // access mode
  DWORD dwFileOffsetHigh,     // high-order 32 bits of file offset
  DWORD dwFileOffsetLow,      // low-order 32 bits of file offset
  DWORD dwNumberOfBytesToMap, // number of bytes to map
  LPVOID lpBaseAddress        // suggested starting address for mapped
                              // view
);

Parameters

hFileMappingObject
Handle to an open handle to a file-mapping object. The CreateFileMapping and OpenFileMapping functions return this handle.
dwDesiredAccess
Specifies the type of access to the file-mapping object and, therefore, the page protection of the pages mapped by the file. This parameter can be one of the following values:
Value | Meaning
FILE_MAP_WRITE | Read-and-write access. The hFileMappingObject parameter must have been created with PAGE_READWRITE protection. A read-write view of the file is mapped.
FILE_MAP_READ | Read-only access. The hFileMappingObject parameter must have been created with PAGE_READWRITE or PAGE_READONLY protection. A read-only view of the file is mapped.
FILE_MAP_ALL_ACCESS | Same as FILE_MAP_WRITE.
FILE_MAP_COPY Copy on write access. If you create the map with PAGE_WRITECOPY and the view with FILE_MAP_COPY, you will receive a view to the file. If you write to it, the pages are automatically swappable and the modifications you make will not go to the original data file.

Windows 95: You must pass PAGE_WRITECOPY to CreateFileMapping; otherwise, an error will be returned.

If you share the mapping between multiple processes using DuplicateHandle or OpenFileMapping and one process writes to a view, the modification is propagated to the other process. The original file does not change.

Windows NT: There is no restriction as to how the hFileMappingObject parameter must be created. Copy on write is valid for any type of view.

If you share the mapping between multiple processes using DuplicateHandle or OpenFileMapping and one process writes to a view, the modification is not propagated to the other process. The original file does not change.

dwFileOffsetHigh
Specifies the high-order 32 bits of the file offset where mapping is to begin.
dwFileOffsetLow
Specifies the low-order 32 bits of the file offset where mapping is to begin. The combination of the high and low offsets must specify an offset within the file that matches the system's memory allocation granularity, or the function fails. That is, the offset must be a multiple of the allocation granularity. Use the GetSystemInfo function, which fills in the members of a SYSTEM_INFO structure, to obtain the system's memory allocation granularity.
dwNumberOfBytesToMap
Specifies the number of bytes of the file to map. If dwNumberOfBytesToMap is zero, the entire file is mapped.
lpBaseAddress
Pointer to the memory address in the calling process's address space where mapping should begin. This must be a multiple of the system's memory allocation granularity, or the function fails. Use the GetSystemInfo function, which fills in the members of a SYSTEM_INFO structure, to obtain the system's memory allocation granularity. If there is not enough address space at the specified address, the function fails.

If lpBaseAddress is NULL, the operating system chooses the mapping address. In this case, this function is equivalent to the MapViewOfFile function.

Return Values

If the function succeeds, the return value is the starting address of the mapped view.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

Mapping a file makes the specified portion of the file visible in the address space of the calling process.

If a suggested mapping address is supplied, the file is mapped at the specified address (rounded down to the nearest 64K boundary) if there is enough address space at the specified address. If there is not, the function fails.

Typically, the suggested address is used to specify that a file should be mapped at the same address in multiple processes. This requires the region of address space to be available in all involved processes. No other memory allocation, including use of the VirtualAlloc function to reserve memory, can take place in the region used for mapping.

Windows 95: If the lpBaseAddress parameter specifies a base offset, the function succeeds only if the same memory region is available for the memory mapped file in all other 32-bit processes.

Windows NT: If the lpBaseAddress parameter specifies a base offset, the function succeeds if the given memory region is not already in use by the calling process. the system does not guarantee that the same memory region is available for the memory mapped file in other 32-bit processes.

Multiple views of a file (or a file-mapping object and its mapped file) are said to be "coherent" if they contain identical data at a specified time. This occurs if the file views are derived from the same file-mapping object. A process can duplicate a file-mapping object handle into another process by using the DuplicateHandle function, or another process can open a file-mapping object by name by using the OpenFileMapping function.

A mapped view of a file is not guaranteed to be coherent with a file being accessed by the ReadFile or WriteFile function.

Note To guard against an access violation, use structured exception handling to protect any code that writes to or reads from a memory mapped view. For more information, see Reading and Writing.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File Mapping Overview, File Mapping Functions, CreateFileMapping, DuplicateHandle, GetSystemInfo, MapViewOfFile, MapViewOfFileVlm, OpenFileMapping, ReadFile, UnmapViewOfFile, UnmapViewOfFileVlm, SYSTEM_INFO, VirtualAlloc, WriteFile


OpenFileMapping

The OpenFileMapping function opens a named file-mapping object.

HANDLE OpenFileMapping(
  DWORD dwDesiredAccess,  // access mode
  BOOL bInheritHandle,    // inherit flag
  LPCTSTR lpName          // pointer to name of file-mapping object
);

Parameters

dwDesiredAccess
Specifies the access to the file-mapping object.

Windows NT: This access is checked against any security descriptor on the target file-mapping object.

Windows 95 and Windows 98: Security descriptors on file mapping objects are not supported.

This parameter can be one of the following values:
Value | Meaning
FILE_MAP_WRITE | Read-write access. The target file-mapping object must have been created with PAGE_READWRITE protection. A read-write view of the file is mapped.
FILE_MAP_READ | Read-only access. The target file-mapping object must have been created with PAGE_READWRITE or PAGE_READ protection. A read-only view of the file is mapped.
FILE_MAP_ALL_ACCESS | Same as FILE_MAP_WRITE.
FILE_MAP_COPY | Copy-on-write access. The target file-mapping object must have been created with PAGE_WRITECOPY protection. A copy-on-write view of the file is mapped.

bInheritHandle
Specifies whether the returned handle is to be inherited by a new process during process creation. A value of TRUE indicates that the new process inherits the handle.
lpName
Pointer to a string that names the file-mapping object to be opened. If there is an open handle to a file-mapping object by this name and the security descriptor on the mapping object does not conflict with the dwDesiredAccess parameter, the open operation succeeds.

Return Values

If the function succeeds, the return value is an open handle to the specified file-mapping object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The handle that OpenFileMapping returns can be used with any function that requires a handle to a file-mapping object.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

File Mapping Overview, File Mapping Functions, CreateFileMapping


UnmapViewOfFile

The UnmapViewOfFile function unmaps a mapped view of a file from the calling process's address space.

BOOL UnmapViewOfFile(
  LPCVOID lpBaseAddress   // address where mapped view begins
);

Parameters

lpBaseAddress
Pointer to the base address of the mapped view of a file that is to be unmapped. This value must be identical to the value returned by a previous call to the MapViewOfFile or MapViewOfFileEx function.

Return Values

If the function succeeds, the return value is nonzero, and all dirty pages within the specified range are written "lazily" to disk.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Although an application may close the file handle used to create a file mapping object, the system holds the corresponding file open until the last view of the file is unmapped.

Windows 95: Files for which the last view has not yet been unmapped are held open with the same sharing restrictions as the original file handle.

Windows NT: Files for which the last view has not yet been unmapped are held open with no sharing restrictions.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

File Mapping Overview, File Mapping Functions, MapViewOfFile, MapViewOfFileEx, UnmapViewOfFileVlm


Mailslots

A mailslot is a mechanism for one-way interprocess communications (IPC). A Win32-based application can store messages in a mailslot. The owner of the mailslot can retrieve messages that are stored there. These messages are typically sent over a network to either a specified computer or to all computers in a specified domain. A domain is a group of workstations and servers that share a group name.

You can choose to use named pipes instead of mailslots for interprocess communications. Named pipes are a simple way for two processes to exchange messages. Mailslots, on the other hand, are a simple way for a process to broadcast messages to multiple processes. One important consideration is that mailslots use datagrams, and named pipes do not. A datagram is a small packet of information that the network sends along the wire. Like a radio or television broadcast, a datagram offers no confirmation of receipt; there is no way to guarantee that a datagram has been received. Just as mountains, large buildings, or interfering signals might cause a radio or television signal to get lost, there are things that can prevent a datagram from reaching a particular destination. Named pipes are like telephone calls: you talk only to one party, but you know that the conversation is occurring. For more information about named pipes, see Pipes.


About Mailslots

A mailslot is a pseudofile; it resides in memory, and you use standard Win32 file functions to access it. The data in a mailslot message can be in any form. Unlike disk files, however, mailslots are temporary. When all handles to a mailslot are closed, the mailslot and all the data it contains are deleted.

A mailslot server is a process that creates and owns a mailslot. When the server creates a mailslot, it receives a mailslot handle. This handle must be used when a process reads messages from the mailslot. Only the process that creates a mailslot or has obtained the handle by some other mechanism (such as inheritance) can read from the mailslot. All mailslots are local to the process that creates them; a process cannot create a remote mailslot.

A mailslot client is a process that writes a message to a mailslot. Any process that has the name of a mailslot can put a message there. New messages follow any existing messages in the mailslot.

Mailslots can broadcast messages within a domain. If several processes in a domain each create a mailslot using the same name, every message that is addressed to that mailslot and sent to the domain is received by the participating processes. Because one process can control both a server mailslot handle and the client handle retrieved when the mailslot is opened for a write operation, applications can easily implement a simple message-passing facility within a domain.


Mailslot Names

When a process creates a mailslot, the mailslot name must have the following form.

\\.\mailslot\[path]name

A mailslot name requires the following elements: two backslashes to begin the name, a period, a backslash following the period, the word mailslot, and a trailing backslash. Names are not case sensitive. A mailslot name can be preceded by a path consisting of the names of one or more directories, separated by backslashes. For example, if a user expects messages on the subject of taxes from Bob, Pete, and Sue, the user's mailslot application might allow the user to create individual mailslots for each sender, as shown here:

\\.\mailslot\taxes\bobs_comments
\\.\mailslot\taxes\petes_comments
\\.\mailslot\taxes\sues_comments

To put a message into a mailslot, a process opens a mailslot by name. To write to a mailslot on the local computer, a process can use a mailslot name that has the same form used for creating a mailslot. This situation, however, is relatively uncommon. More frequently, you would use the following form to write to a mailslot on a specific remote computer:

\\ComputerName\mailslot\[path]name

To put a message into every mailslot in the specified domain with a given name, use the following form:

\\DomainName\mailslot\[path]name

To put a message into every mailslot with a given name in the system's primary domain, use the following form:

\\*\mailslot\[path]name


Server and Client Functions

Clients and servers when working with mailslots should use only the functions discussed in the following sections.

  • Mailslot Server Functions
  • Mailslot Client Functions

You should not use other functions, even if they accept file handles or filenames as arguments.


Mailslot Server Functions

Mailslot servers have exclusive use of three functions, as shown in the following table.

Function | Description
CreateMailslot | Creates a mailslot and returns a mailslot handle.
GetMailslotInfo | Retrieves the maximum message size, the mailslot size, the size of the next message in the mailslot, the number of messages in the mailslot, and the amount of time a read operation can wait for a message.
SetMailslotInfo | Changes the read time-out for a mailslot.

The following functions are also used by mailslot servers.

Function | Description
DuplicateHandle | Duplicates the mailslot handle.
ReadFile, ReadFileEx | Retrieves messages from a mailslot.
GetFileTime | Retrieves the date and time a mailslot was created.
SetFileTime | Sets the date and time a mailslot was created.
GetHandleInformation | Retrieves properties of the mailslot handle.
SetHandleInformation | Sets properties of the mailslot handle.


Mailslot Client Functions

A client process uses the following functions when interacting with a mailslot.

Function | Description
CloseHandle | Closes a mailslot handle for a client process.
CreateFile | Creates a mailslot handle for a client process.
DuplicateHandle | Duplicates a mailslot handle.
WriteFile, WriteFileEx | Writes data to a mailslot.


Using Mailslots

  • Creating a mailslot
  • Writing to a mailslot
  • Reading from a mailslot


Creating a Mailslot

Mailslots are supported by three specialized functions: CreateMailslot, GetMailslotInfo, and SetMailslotInfo. These functions are used by the mailslot server.

The following code sample uses the CreateMailslot function to retrieve the handle to a mailslot named sample_mailslot.

BOOL FAR PASCAL Makeslot(HWND hwnd, HDC hdc)
{
    LPSTR lpszSlotName = "\\\\.\\mailslot\\sample_mailslot";

    // The mailslot handle "hSlot1" is declared globally.

    hSlot1 = CreateMailslot(lpszSlotName,
        0,                             // no maximum message size
        MAILSLOT_WAIT_FOREVER,         // no time-out for operations
        (LPSECURITY_ATTRIBUTES) NULL); // no security attributes

    if (hSlot1 == INVALID_HANDLE_VALUE)
    {
        ErrorHandler(hwnd, "CreateMailslot"); // local error handler
        return FALSE;
    }

    TextOut(hdc, 10, 10, "CreateMailslot successful.", 26);
    return TRUE;
}

To create a mailslot that can be inherited by child processes, an application should change the SECURITY_ATTRIBUTES structure passed as the last parameter of CreateMailslot. To do this, the application sets the bInheritHandle member of this structure to TRUE (the default setting is FALSE).


Writing to a Mailslot

Writing to a mailslot is similar to writing to a standard disk file. The following code uses the CreateFile, WriteFile, and CloseHandle functions to put a short message in a mailslot. The message is broadcast to every computer in the primary domain of the system.

LPSTR lpszMessage = "Message for sample_mailslot in primary domain.";
BOOL fResult;
HANDLE hFile;
DWORD cbWritten;

hFile = CreateFile("\\\\*\\mailslot\\sample_mailslot",
    GENERIC_WRITE,
    FILE_SHARE_READ,  // required to write to a mailslot
    (LPSECURITY_ATTRIBUTES) NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    (HANDLE) NULL);

if (hFile == INVALID_HANDLE_VALUE)
{
    ErrorHandler(hwnd, "Primary domain"); // local error handler
    return FALSE;
}

fResult = WriteFile(hFile,
    lpszMessage,
    (DWORD) lstrlen(lpszMessage) + 1,  // include terminating null
    &cbWritten,
    (LPOVERLAPPED) NULL);

if (!fResult)
{
    ErrorHandler(hwnd, "WriteFile");
    return FALSE;
}

TextOut(hdc, 10, 10, "WriteFile successful.", 21);

fResult = CloseHandle(hFile);

if (!fResult)
{
    ErrorHandler(hwnd, "CloseHandle");
    return FALSE;
}

TextOut(hdc, 10, 30, "CloseHandle successful.", 23);
return TRUE;

Messages broadcast to a domain must be no longer than 400 bytes. Messages that are not broadcast should be smaller than 64 kilobytes. There is no limit to the number of messages that can be sent to a mailslot.


Reading from a Mailslot

The process that creates a mailslot can read messages from it by using the mailslot handle in a call to the ReadFile function. The code in the following example calls the GetMailslotInfo function to determine whether there are messages in the mailslot. If messages are waiting, each is displayed in a message box along with the number of messages remaining to be read.

BOOL WINAPI Readslot(HWND hwnd, HDC hdc)
{
    DWORD cbMessage, cMessage, cbRead;
    BOOL fResult;
    LPSTR lpszBuffer;
    CHAR achID[80];
        DWORD cAllMessages;

    cbMessage = cMessage = cbRead = 0;

    // Mailslot handle "hSlot1" is declared globally.

    fResult = GetMailslotInfo(hSlot1, // mailslot handle
        (LPDWORD) NULL,               // no maximum message size
        &cbMessage,                   // size of next message
        &cMessage,                    // number of messages
        (LPDWORD) NULL);              // no read time-out

    if (!fResult)
    {
        ErrorHandler(hwnd, "GetMailslotInfo");
        return FALSE;
    }

    if (cbMessage == MAILSLOT_NO_MESSAGE)
    {
        TextOut(hdc, 10, 10, "No waiting messages.", 20);
        return TRUE;
    }

    cAllMessages = cMessage;

    while (cMessage != 0)  // retrieve all messages
    {
        // Create a message-number string.

        wsprintf((LPSTR) achID,
            "\nMessage #%d of %d\n", cAllMessages - cMessage + 1,
            cAllMessages);

        // Allocate memory for the message.

        lpszBuffer = (LPSTR) GlobalAlloc(GPTR,
            lstrlen((LPSTR) achID) + cbMessage);

        lpszBuffer[0] = '\0';

        fResult = ReadFile(hSlot1,
            lpszBuffer,
            cbMessage,
            &cbRead,
            (LPOVERLAPPED) NULL);

        if (!fResult)
        {
            ErrorHandler(hwnd, "ReadFile");
            GlobalFree((HGLOBAL) lpszBuffer);
            return FALSE;
        }

        // Concatenate the message and the message-number string.

        lstrcat(lpszBuffer, (LPSTR) achID);

        // Display the message.

        MessageBox(hwnd,
            lpszBuffer,
            "Contents of Mailslot",
            MB_OK);

        GlobalFree((HGLOBAL) lpszBuffer);

        fResult = GetMailslotInfo(hSlot1, // mailslot handle
            (LPDWORD) NULL,               // no maximum message size
            &cbMessage,                   // size of next message
            &cMessage,                    // number of messages
            (LPDWORD) NULL);              // no read time-out

        if (!fResult)
        {
            ErrorHandler(hwnd, "GetMailslotInfo");
            return FALSE;
        }
    }
    return TRUE;
}

A mailslot exists until the CloseHandle function is called for all open server handles or until all server processes that own a mailslot handle exit. In both cases, any unread messages are deleted from the mailslot, all client handles to the mailslot are closed, and the mailslot itself is deleted from memory.


Mailslot Reference

The following elements can be used with mailslots.

  • Mailslot Functions


Mailslot Functions

The following functions can be used with mailslots.

CreateMailslot
GetMailslotInfo
SetMailslotInfo


CreateMailslot

The CreateMailslot function creates a mailslot with the specified name and returns a handle that a mailslot server can use to perform operations on the mailslot. The mailslot is local to the computer that creates it. An error occurs if a mailslot with the specified name already exists.

HANDLE CreateMailslot(
  LPCTSTR lpName,         // pointer to string for mailslot name
  DWORD nMaxMessageSize,  // maximum message size
  DWORD lReadTimeout,     // milliseconds before read time-out
  LPSECURITY_ATTRIBUTES lpSecurityAttributes
                          // pointer to security structure
);

Parameters

lpName
Pointer to a null-terminated string specifying the name of the mailslot. This name must have the following form:

\\.\mailslot\[path]name

The name field must be unique. The name may include multiple levels of pseudodirectories separated by backslashes. For example, both \\.\mailslot\example_mailslot_name and \\.\mailslot\abc\def\ghi are valid names.

nMaxMessageSize
Specifies the maximum size, in bytes, of a single message that can be written to the mailslots. To specify that the message can be of any size, set this value to zero.
lReadTimeout
Specifies the amount of time, in milliseconds, a read operation can wait for a message to be written to the mailslot before a time-out occurs. The following values have special meanings:
Value | Meaning
0 | Returns immediately if no message is present. (The system does not treat an immediate return as an error.)
MAILSLOT_WAIT_FOREVER | Waits forever for a message.

This time-out value applies to all subsequent read operations and all inherited mailslot handles.

lpSecurityAttributes
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpSecurityAttributes is NULL, the handle cannot be inherited.

Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new mailslot. If lpSecurityAttributes is NULL, the mailslot gets a default security descriptor.

Return Values

If the function succeeds, the return value is a handle to the mailslot, for use in server mailslot operations.

If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.

Remarks

The mailslot exists until one of the following conditions is true:

  • The last (possibly inherited or duplicated) handle to it is closed using the CloseHandle function.
  • The process owning the last (possibly inherited or duplicated) handle exits.

The system uses the second method to destroy mailslots.

To write a message to a mailslot, a process uses the CreateFile function, specifying the mailslot name by using one of the following formats:

Format | Usage
\\.\mailslot\name | Retrieves a client handle to a local mailslot.
\\computername\mailslot\name | Retrieves a client handle to a remote mailslot.
\\domainname\mailslot\name | Retrieves a client handle to all mailslots with the specified name in the specified domain.
\\*\mailslot\name | Retrieves a client handle to all mailslots with the specified name in the system's primary domain.

If CreateFile specifies a domain or uses the asterisk format to specify the system's primary domain, the application cannot write more than 400 bytes at a time to the mailslot. If the application attempts to do so, the WriteFile function fails and GetLastError returns ERROR_BAD_NETPATH.

An application must specify the FILE_SHARE_READ flag when using CreateFile to retrieve a client handle to a mailslot.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Mailslots Overview, Mailslot Functions, CloseHandle, CreateFile, GetMailslotInfo, SECURITY_ATTRIBUTES, SetMailslotInfo, WriteFile


GetMailslotInfo

The GetMailslotInfo function retrieves information about the specified mailslot.

BOOL GetMailslotInfo(
  HANDLE hMailslot,       // mailslot handle
  LPDWORD lpMaxMessageSize,  // address of maximum message size
  LPDWORD lpNextSize,     // address of size of next message
  LPDWORD lpMessageCount,  // address of number of messages
  LPDWORD lpReadTimeout   // address of read time-out
);

Parameters

hMailslot
Handle to a mailslot. The CreateMailslot function must create this handle.
lpMaxMessageSize
Pointer to a buffer specifying the maximum message size, in bytes, allowed for this mailslot, when the function returns. This value can be greater than or equal to the value specified in the cbMaxMsg parameter of the CreateMailslot function that created the mailslot. This parameter can be NULL.
lpNextSize
Pointer to a buffer specifying the size, in bytes, of the next message, when the function returns. The following value has special meaning:
Value | Meaning
MAILSLOT_NO_MESSAGE | There is no next message.

This parameter can be NULL.

lpMessageCount
Pointer to a buffer specifying the total number of messages waiting to be read, when the function returns. This parameter can be NULL.
lpReadTimeout
Pointer to a buffer specifying the amount of time, in milliseconds, a read operation can wait for a message to be written to the mailslot before a time-out occurs. This parameter is filled in when the function returns. This parameter can be NULL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Mailslots Overview, Mailslot Functions, CreateMailslot, SetMailslotInfo


SetMailslotInfo

The SetMailslotInfo function sets the time-out value used by the specified mailslot for a read operation.

BOOL SetMailslotInfo(
  HANDLE hMailslot,    // mailslot handle
  DWORD lReadTimeout   // read time-out
);

Parameters

hMailslot
Handle to a mailslot. The CreateMailslot function must create this handle.
lReadTimeout
Specifies the amount of time, in milliseconds, a read operation can wait for a message to be written to the mailslot before a time-out occurs. The following values have special meanings:
Value | Meaning
0 | Returns immediately if no message is present. (The system does not treat an immediate return as an error.)
MAILSLOT_WAIT_FOREVER | Waits forever for a message.

This time-out value applies to all subsequent read operations and to all inherited mailslot handles.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The initial time-out value used by a mailslot for a read operation is typically set by CreateMailslot when the mailslot is created.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Mailslots Overview, Mailslot Functions, CreateMailslot, GetMailslotInfo


Pipes

A pipe is a section of shared memory that processes use for communication. The process that creates a pipe is the pipe server. A process that connects to a pipe is a pipe client. One process writes information to the pipe, then the other process reads the information from the pipe. This overview describes how to create, manage, and use pipes.


About Pipes

The Microsoft® Win32® API supports both anonymous pipes and named pipes. Anonymous pipes require less overhead than named pipes, but offer limited services.

The term pipe, as used here, implies that a pipe is used as an information conduit. Conceptually, a pipe has two ends. A one-way pipe allows the process at one end to write to the pipe, and allows the process at the other end to read from the pipe. A two-way (or duplex) pipe allows a process to read and write from its end of the pipe.


Anonymous Pipes

An anonymous pipe is an unnamed, one-way pipe that typically transfers data between a parent process and a child process. Anonymous pipes are always local; they cannot be used for communication over a network.

Windows NT: Anonymous pipes are implemented using a named pipe with a unique name. Therefore, you can often pass a handle to an anonymous pipe to a function that requires a handle to a named pipe.


Anonymous Pipe Operations

The CreatePipe function creates an anonymous pipe and returns two handles: a read handle to the pipe and a write handle to the pipe. The read handle has read-only access to the pipe, and the write handle has write-only access to the pipe. To communicate using the pipe, the pipe server must pass one of the handles to another process. Usually, this is done through inheritance; that is, the process allows the handle to be inherited by a child process. The process can also send the handle to an unrelated process using some form of interprocess communication, such as DDE or shared memory.

A pipe server can send either the read handle or the write handle to the pipe client, depending on whether the client should use the anonymous pipe to send information or receive information. To read from the pipe, use the pipe's read handle in a call to the ReadFile function. The ReadFile call returns when another process has written to the pipe. The ReadFile call can also return if all write handles to the pipe have been closed or if an error occurs before the read operation has been completed.

To write to the pipe, use the pipe's write handle in a call to the WriteFile function. The WriteFile call does not return until it has written the specified number of bytes to the pipe or an error occurs. If the pipe buffer is full and there are more bytes to be written, WriteFile does not return until another process reads from the pipe, making more buffer space available. The pipe server specifies the buffer size for the pipe when it calls CreatePipe.

Asynchronous (overlapped) read and write operations are not supported by anonymous pipes. This means that you cannot use the ReadFileEx and WriteFileEx functions with anonymous pipes. In addition, the lpOverLapped parameter of ReadFile and WriteFile is ignored when these functions are used with anonymous pipes.

An anonymous pipe exists until all pipe handles, both read and write, have been closed. A process can close its pipe handles by using the CloseHandle function. All pipe handles are also closed when the process terminates.


Pipe Handle Inheritance

The pipe server controls whether its handles can be inherited in the following ways:

  • The CreatePipe function receives a SECURITY_ATTRIBUTES structure. If the pipe server sets the bInheritHandle member of this structure to TRUE, the handles created by CreatePipe can be inherited.
  • The pipe server can use the DuplicateHandle function to change the inheritance of a pipe handle. The pipe server can create a noninheritable duplicate of an inheritable pipe handle or an inheritable duplicate of a noninheritable pipe handle.
  • The CreateProcess function enables the pipe server to specify whether a child process inherits all or none of its inheritable handles.

When a child process inherits a pipe handle, the system enables the process to access the pipe. However, the parent process must communicate the handle value to the child process. The parent process typically does this by redirecting the standard output handle to the child process, as shown in the following steps:

  1. Call the GetStdHandle function to get the current standard output handle; save this handle so you can restore the original standard output handle after the child process has been created.
  2. Call the SetStdHandle function to set the standard output handle to the write handle to the pipe. Now the parent process can create the child process.
  3. Call the CloseHandle function to close the write handle to the pipe. After the child process inherits the write handle, the parent process no longer needs its copy.
  4. Call SetStdHandle to restore the original standard output handle.

The child process uses the GetStdHandle function to get its standard output handle, which is now a handle to the write end of a pipe. The child process then uses the WriteFile function to send its output to the pipe. When the child has finished with the pipe, it should close the pipe handle by calling CloseHandle or by terminating, which automatically closes the handle.

The parent process uses the ReadFile function to receive input from the pipe. Data is written to an anonymous pipe as a stream of bytes. This means that the parent process reading from a pipe cannot distinguish between the bytes written in separate write operations, unless both the parent and child processes use a protocol to indicate where the write operation ends. When all write handles to the pipe are closed, the ReadFile function returns zero. It is important for the parent process to close its handle to the write end of the pipe before calling ReadFile. If this is not done, the ReadFile operation cannot return zero because the parent process has an open handle to the write end of the pipe.

The procedure for redirecting the standard input handle is similar to that for redirecting the standard output handle, except that the pipe's read handle is used as the child's standard input handle. In this case, the parent process must ensure that the child process does not inherit the pipe's write handle. If this is not done, the ReadFile operation performed by the child process cannot return zero because the child process has an open handle to the write end of the pipe.

For an example program that uses anonymous pipes to redirect the standard handles of a child process, see Creating a Child Process with Redirected Input and Output.


Named Pipes

A named pipe is a named, one-way or duplex pipe for communication between the pipe server and one or more pipe clients. All instances of a named pipe share the same pipe name, but each instance has its own buffers and handles, and provides a separate conduit for client-server communication. The use of instances enables multiple pipe clients to use the same named pipe simultaneously.

Any process can access named pipes, subject to security checks, making named pipes an easy form of communication between related or unrelated processes. Named pipes can be used to provide communication between processes on the same computer or between processes on different computers across a network.

Any process can act as both a server and a client, making peer-to-peer communication possible. As used here, the term pipe server refers to a process that creates a named pipe, and the term pipe client refers to a process that connects to an instance of a named pipe.


Pipe Names

Each named pipe has a unique name that distinguishes it from other named pipes in the system's list of named objects. A pipe server specifies a name for the pipe when it calls the CreateNamedPipe function to create one or more instances of a named pipe. Pipe clients specify the pipe name when they call the CreateFile or CallNamedPipe function to connect to an instance of the named pipe.

Use the following form when specifying the name of a pipe in the CreateFile, WaitNamedPipe, or CallNamedPipe function:

\\ServerName\pipe\PipeName

where ServerName is either the name of a remote computer or a period, to specify the local computer. The pipe name string specified by PipeName can include any character, including numbers and special characters. The entire pipe name string can be up to 256 characters long. Pipe names are not case-sensitive.

The pipe server cannot create a pipe on another computer, so CreateNamedPipe must use a period for the server name, as shown in the following example.

\\.\pipe\PipeName

A pipe server often passes the pipe name to its pipe clients so they can connect to the pipe. Otherwise, the clients must know the pipe name at compile time.


Named Pipe Open Modes

The pipe server specifies the pipe access, overlap, and write-through modes in the dwOpenMode parameter of the CreateNamedPipe function. The pipe clients can specify these open modes for their pipe handles using the CreateFile function.

Access Mode

Setting the pipe access mode is equivalent to specifying read or write access associated with the pipe server's handles. The following table shows the CreateFile equivalent for each access mode you can specify with CreateNamedPipe.

CreateNamedPipe Access Mode | CreateFile Equivalent
PIPE_ACCESS_INBOUND | GENERIC_READ (server only reads and client only writes)
PIPE_ACCESS_OUTBOUND | GENERIC_WRITE (server only writes and client only reads)
PIPE_ACCESS_DUPLEX | GENERIC_READ | GENERIC_WRITE (server and client both read and write)

Pipe clients using CreateFile to connect to a named pipe must specify an access mode in the dwDesiredAccess parameter that is compatible with the access mode specified by the pipe server. For example, a client must specify GENERIC_READ access for a pipe created with PIPE_ACCESS_OUTBOUND. The access modes must be the same for all instances of a pipe.

Overlap Mode

In overlapped mode, functions performing lengthy read, write, and connect operations can return immediately. This enables the thread to perform other operations while a time-consuming operation is executing in the background. To specify overlapped mode, use the FILE_FLAG_OVERLAPPED flag. For more information, see Synchronous and Overlapped Input and Output.

The CreateFile function allows the pipe client to set overlapped mode (FILE_FLAG_OVERLAPPED) for its pipe handles using the dwFlagsAndAttributes parameter.

Write-Through Mode

Specify write-through mode with FILE_FLAG_WRITE_THROUGH. This mode affects only write operations to byte-type pipes between pipe clients and pipe servers on different computers. In write-through mode, the functions that write to a named pipe do not return until the data is transmitted across the network and into the pipe's buffer on the remote computer. Write-through mode is useful for applications that require synchronization for every write operation.

If write-through mode is not enabled, the system enhances the efficiency of network operations by buffering data until a minimum number of bytes have accumulated or until a maximum time period has elapsed. Buffering enables the system to combine multiple write operations into a single network transmission. This means that a write operation can be successfully completed after the system puts the data in the outbound buffer, but before the system transmits it across the network.

The CreateFile function allows the pipe client to set write-through mode (FILE_FLAG_WRITE_THROUGH) for its pipe handles using the dwFlagsAndAttributes parameter. The write-through mode of a pipe handle cannot be changed after the pipe handle has been created. The write-through mode can be different for server and client handles to the same pipe instance.

A pipe client can use the SetNamedPipeHandleState function to control the number of bytes and the time-out period before transmission for a pipe on which write-through mode is disabled.


Named Pipe Type, Read, and Wait Modes

The pipe server specifies the pipe type, read, and wait modes in the dwPipeMode parameter of the CreateNamedPipe function. Pipe clients can specify these pipe modes for their pipe handles using the CreateFile function.

Type Mode

The type mode of a pipe determines how data is written to a named pipe. Data can be transmitted through a named pipe as either a stream of bytes or as a stream of messages. The pipe server specifies the pipe type when calling CreateNamedPipe to create an instance of a named pipe. The type modes must be the same for all instances of a pipe.

To create a byte-type pipe, specify PIPE_TYPE_BYTE or use the default value. The data is written to the pipe as a stream of bytes, and the system does not differentiate between the bytes written in different write operations.

To create a message-type pipe, specify PIPE_TYPE_MESSAGE. The system treats the bytes written in each write operation to the pipe as a message unit. The system always performs write operations on message-type pipes as if write-through mode were enabled.

Read Mode

The read mode of a pipe determines how data is read from a named pipe. The pipe server specifies the initial read mode for a pipe handle when calling CreateNamedPipe. Data can be read in byte-read mode or message-read mode. A handle to a byte-type pipe can be in byte-read mode only. A handle to a message-type pipe can be in either byte-read or message-read mode. For a message-type pipe, the read mode can be different for server and client handles to the same pipe instance.

To create the pipe handle in byte-read mode, specify PIPE_READMODE_BYTE or use the default value. Data is read from the pipe as a stream of bytes. A read operation is completed successfully when all available bytes in the pipe are read or when the specified number of bytes is read.

To create the pipe handle in message-read mode, specify PIPE_READMODE_MESSAGE. Data is read from the pipe as a stream of messages. A read operation is completed successfully only when the entire message is read. If the specified number of bytes to read is less than the size of the next message, the function reads as much of the message as possible before returning zero (the GetLastError function returns ERROR_MORE_DATA). The remainder of the message can be read using another read operation.

For a pipe client, a pipe handle returned by CreateFile is always in byte-read mode initially. Both pipe clients and pipe servers can use the SetNamedPipeHandleState function to change the read mode of a pipe handle.

Wait Mode

The wait mode of a pipe handle determines how the ReadFile, WriteFile, and ConnectNamedPipe functions handle lengthy operations. In blocking-wait mode, the functions wait indefinitely for a process on the other end of the pipe to complete an operation. In nonblocking-wait mode, the functions return immediately in situations that would otherwise require an indefinite wait.

A ReadFile operation is affected by the wait mode of a pipe handle when the pipe is empty. With a blocking-wait handle, the operation is not completed successfully until data is available from a thread writing to the other end of the pipe. Using a nonblocking-wait handle, the function returns zero immediately, and the GetLastError function returns ERROR_NO_DATA.

A WriteFile operation is affected by the wait mode of a pipe handle when there is insufficient space in the pipe's buffer. With a blocking-wait handle, the write operation cannot succeed until sufficient space is created in the buffer by a thread reading from the other end of the pipe. With a nonblocking-wait handle, the write operation returns a nonzero value immediately, without writing any bytes (for a message-type pipe) or after writing as many bytes as the buffer holds (for a byte-type pipe).

A ConnectNamedPipe operation is affected by the wait mode of a pipe handle when there is no client connected or waiting to connect to the pipe instance. With a blocking-wait handle, the connect operation does not succeed until a pipe client connects to the pipe instance by calling either the CreateFile or CallNamedPipe function. With a nonblocking-wait handle, the connect operation returns zero immediately, and the GetLastError function returns ERROR_PIPE_LISTENING.

By default, all named pipe handles returned by the CreateNamedPipe or CreateFile function are created with blocking-wait mode enabled. To create the pipe in nonblocking-wait mode, the pipe server specifies PIPE_NOWAIT when calling CreateNamedPipe.

Both pipe clients and pipe servers can change a pipe handle's wait mode by specifying either PIPE_WAIT or PIPE_NOWAIT in a call to the SetNamedPipeHandleState function.

Note The nonblocking-wait mode is supported for compatibility with Microsoft® LAN Manager version 2.0. This mode should not be used to achieve overlapped input and output (I/O) with named pipes. Overlapped I/O should be used instead, because it enables time-consuming operations to run in the background after the function returns. For more information about overlapped I/O, see Synchronous and Overlapped Input and Output.


Named Pipe Instances

The simplest pipe server creates a single instance of a pipe, connects to a single client, communicates with the client, disconnects from the client, closes the pipe handle, and terminates. However, it is more common for a pipe server to communicate with multiple pipe clients. A pipe server could use a single pipe instance to connect with multiple pipe clients by connecting to and disconnecting from each client in sequence, but performance would be poor. The pipe server must create multiple pipe instances to efficiently handle multiple clients simultaneously.

There are three basic strategies for servicing multiple pipe instances.

  • Create a separate thread for each instance of the pipe. For an example of a multithreaded pipe server, see Multithreaded Pipe Server.
  • Use overlapped operations by specifying an OVERLAPPED structure in the ReadFile, WriteFile, and ConnectNamedPipe functions. For an example, see Named Pipe Server Using Overlapped I/O.
  • Use overlapped operations by using the ReadFileEx and WriteFileEx functions, which specify a completion routine to be executed when the operation is completed. For an example, see Named Pipe Server Using Completion Routines.

The multithreaded pipe server is easiest to write, because the thread for each instance handles communications for a single pipe client. The system allocates processor time to each thread as needed. But each thread uses system resources, which is a disadvantage for a pipe server that handles a large number of clients.

With a single-threaded server, it is easier to coordinate operations that affect multiple clients, and it is easier to protect shared resources from simultaneous access by multiple clients. The challenge of a single-threaded server is that it requires coordination of overlapped operations to allocate processor time for handling the simultaneous needs of clients.


Named Pipe Operations

The first time the pipe server calls the CreateNamedPipe function, it uses the nMaxInstances parameter to specify the maximum number of instances of the pipe that can exist simultaneously. The server can call CreateNamedPipe repeatedly to create additional instances of the pipe, as long as it doesn't exceed the maximum number of instances. If the function succeeds, each call returns a handle to the server end of a named pipe instance.

As soon as the pipe server creates a pipe instance, a pipe client can connect to it by calling the CreateFile or CallNamedPipe function. If a pipe instance is available, CreateFile returns a handle to the client end of the pipe instance. If no instances of the pipe are available, a pipe client can use the WaitNamedPipe function to wait until a pipe becomes available.

A pipe server can determine when a pipe client is connected to a pipe instance by calling the ConnectNamedPipe function. If the pipe handle is in blocking-wait mode, ConnectNamedPipe does not return until a client is connected.

Pipe clients and servers can call one of several functions — in addition to CallNamedPipe — to read from and write to a named pipe. The behavior of these functions depends on the type of pipe and the modes in effect for the specified pipe handle, as follows:

  • The ReadFile and WriteFile functions can be used with either byte-type or message-type pipes.
  • The ReadFileEx and WriteFileEx functions can be used with either byte-type or message-type pipes if the pipe handle was opened for overlapped operations.
  • The PeekNamedPipe function can be used to read without removing the contents of either a byte-type pipe or a message-type pipe. PeekNamedPipe can also return additional information about the pipe instance.
  • The TransactNamedPipe function can be used with message-type duplex pipes if the pipe handle to the calling process is set to message-read mode. The function writes a request message and reads a reply message in a single operation, enhancing network performance.

The pipe server should not perform a blocking read operation until the pipe client has started. Otherwise, a race condition can occur. This typically occurs when initialization code, such as that of the C run-time library, needs to lock and examine inherited handles.

When a client and server finish using a pipe instance, the server should first call the FlushFileBuffers function, to ensure that all bytes or messages written to the pipe are read by the client. FlushFileBuffers does not return until the client has read all data from the pipe. The server then calls the DisconnectNamedPipe function to close the connection to the pipe client. This function makes the client's handle invalid, if it has not already been closed. Any unread data in the pipe is discarded. After the client is disconnected, the server calls the CloseHandle function to close its handle to the pipe instance. Alternatively, the server can use ConnectNamedPipe to enable a new client to connect to this instance of the pipe.

A process can retrieve information about a named pipe by calling the GetNamedPipeInfo function, which returns the type of the pipe, the size of the input and output buffers, and the maximum number of pipe instances that can be created. The GetNamedPipeHandleState function reports on the read and wait modes of a pipe handle, the current number of pipe instances, and additional information for pipes that communicate over a network. The SetNamedPipeHandleState function sets the read mode and wait modes of a pipe handle. For pipe clients communicating with a remote server, the function also controls the maximum number of bytes to collect or the maximum time to wait before transmitting a message (assuming the client's handle was not opened with write-through mode enabled).


Synchronous and Overlapped Input and Output

The ReadFile, WriteFile, TransactNamedPipe, and ConnectNamedPipe functions can run either synchronously or asynchronously. When a function runs synchronously, it does not return until the operation it is performing is completed. This means that the execution of the calling thread can be blocked for an indefinite period while it waits for a time-consuming operation to be completed. When a function runs asynchronously, it returns immediately, even if the operation has not been completed. This enables a time-consuming operation to be executed in the background while the calling thread is free to perform other tasks.

Using synchronous I/O enables a pipe server to use a loop that performs the following steps:

  1. Specify multiple event objects in a call to the wait function, and wait for one of the objects to be set to the signaled state.
  2. Use the wait function's return value to determine which overlapped operation has finished.
  3. Perform the tasks necessary to clean up the completed operation and initiate the next operation for that pipe handle. This can involve starting another overlapped operation for the same pipe handle.

Overlapped operations make it possible for one pipe to read and write data simultaneously and for a single thread to perform simultaneous I/O operations on multiple pipe handles. This enables a single-threaded pipe server to handle communications with multiple pipe clients efficiently. For an example, see Named Pipe Server Using Overlapped I/O.

For a pipe server to use synchronous operations to communicate with more than one client, it must create a separate thread for each pipe client so that one or more threads can run while other threads are waiting. For an example of a multithreaded pipe server that uses synchronous operations, see Multithreaded Pipe Server.

Enabling Asynchronous Operation

The ReadFile, WriteFile, TransactNamedPipe, and ConnectNamedPipe functions can be performed asynchronously only if you enable overlapped mode for the specified pipe handle and specify a valid pointer to an OVERLAPPED structure. If the OVERLAPPED pointer is NULL, the function return value can incorrectly indicate that the operation has been completed. Therefore, it is strongly recommended that if you create a handle with FILE_FLAG_OVERLAPPED and want asynchronous behavior, you should always specify a valid OVERLAPPED structure.

The hEvent member of the specified OVERLAPPED structure must contain a handle to a manual-reset event object. This is a synchronization object created by the CreateEvent function. The thread that initiates the overlapped operation uses the event object to determine when the operation has finished. You should not use the pipe handle for synchronization when performing simultaneous operations on the same handle because there is no way of knowing which operation's completion caused the pipe handle to be signaled. The only reliable technique for performing simultaneous operations on the same pipe handle is to use a separate OVERLAPPED structure with its own event object for each operation. For more information about event objects, see Synchronization.

When ReadFile, WriteFile, TransactNamedPipe, and ConnectNamedPipe operations are performed asynchronously, one of the following occurs:

  • If the operation is complete when the function returns, the return value indicates the success or failure of the operation. If an error occurs, the return value is zero and the GetLastError function returns something other than ERROR_IO_PENDING.
  • If the operation has not finished when the function returns, the return value is zero and GetLastError returns ERROR_IO_PENDING. In this case, the calling thread must wait until the operation has finished. The calling thread must then call the GetOverlappedResult function to determine the results.

Using Completion Routines

The ReadFileEx and WriteFileEx functions provide another form of overlapped I/O. Unlike the overlapped ReadFile and WriteFile functions, which use an event object to signal completion, the extended functions specify a completion routine. A completion routine is a function that is queued for execution when the read or write operation is finished. The completion routine is not executed until the thread that called ReadFileEx and WriteFileEx starts an alertable wait operation by calling one of the alertable wait functions with the fAlertable parameter set to TRUE. In an alertable wait operation, the functions also return when a ReadFileEx or WriteFileEx completion routine is queued for execution. A pipe server can use the extended functions to perform a sequence of read and write operations for each client that connects to it. Each read or write operation in the sequence specifies a completion routine, and each completion routine initiates the next step in the sequence. For an example, see Named Pipe Server Using Completion Routines.


Named Pipe Security

Impersonation is the ability of a thread to execute in a security context different from that of the process that own the thread. A pipe server uses the ImpersonateNamedPipeClient function to assume the security token of the pipe client connected to the specified pipe instance. This function can be useful in determining whether to grant the request of a pipe client. For example, a named pipe server can provide access to a database or file system to which the pipe server has privileged access. When a pipe client makes a request from the server, the client typically has some lesser level of security access. By assuming the security token of the client, the server can attempt to access the protected database. The system then grants or denies the server's access, based on the security level of the client. When the server is finished, it uses the RevertToSelf function to restore its original security token.


Using Pipes

Pipes are useful in applications that must pass a continuous stream of data between processes. The examples in this section illustrate the following tasks:

  • Multithreaded pipe server
  • Named pipe server using overlapped I/O
  • Named pipe server using completion routines
  • Named pipe client
  • Transactions on named pipes


Multithreaded Pipe Server

The following example is a multithreaded pipe server. It has a main thread with a loop that creates a pipe instance and waits for a pipe client to connect. When a pipe client connects, the pipe server creates a thread to service that client and then continues to execute the loop. It is possible for a pipe client to connect successfully to the pipe instance in the interval between calls to the CreateNamedPipe and ConnectNamedPipe functions. If this happens, ConnectNamedPipe returns zero, and GetLastError returns ERROR_PIPE_CONNECTED.

The thread created to service each pipe instance reads requests from the pipe and writes replies to the pipe until the pipe client closes its handle. When this happens, the thread flushes the pipe, disconnects, closes its pipe handle, and terminates.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

VOID InstanceThread(LPVOID);
VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD);

int xx = 0;

DWORD main(VOID)
{
   BOOL fConnected;
   DWORD dwThreadId;
   HANDLE hPipe, hThread;
   LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe";

// The main loop creates an instance of the named pipe and
// then waits for a client to connect to it. When the client
// connects, a thread is created to handle communications
// with that client, and the loop is repeated.

   for (;;)
   {
      hPipe = CreateNamedPipe(
          lpszPipename,             // pipe name
          PIPE_ACCESS_DUPLEX,       // read/write access
          PIPE_TYPE_MESSAGE |       // message type pipe
          PIPE_READMODE_MESSAGE |   // message-read mode
          PIPE_WAIT,                // blocking mode
          PIPE_UNLIMITED_INSTANCES, // max. instances
          BUFSIZE,                  // output buffer size
          BUFSIZE,                  // input buffer size
          PIPE_TIMEOUT,             // client time-out
          NULL);                    // no security attribute

      if (hPipe == INVALID_HANDLE_VALUE)
          MyErrExit("CreatePipe");

      // Wait for the client to connect; if it succeeds,
      // the function returns a nonzero value. If the function returns
      // zero, GetLastError returns ERROR_PIPE_CONNECTED.

      fConnected = ConnectNamedPipe(hPipe, NULL) ?
         TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);

      if (fConnected)
      {
      // Create a thread for this client.
         hThread = CreateThread(
            NULL,              // no security attribute
            0,                 // default stack size
            (LPTHREAD_START_ROUTINE) InstanceThread,
            (LPVOID) hPipe,    // thread parameter
            0,                 // not suspended
            &dwThreadId);      // returns thread ID

         if (hThread == NULL)
            MyErrExit("CreateThread");

      }
      else
        // The client could not connect, so close the pipe.
         CloseHandle(hPipe);
   }
   return 1;
}

VOID InstanceThread(LPVOID lpvParam)
{
   CHAR chRequest[BUFSIZE];
   CHAR chReply[BUFSIZE];
   DWORD cbBytesRead, cbReplyBytes, cbWritten;
   BOOL fSuccess;
   HANDLE hPipe;

// The thread's parameter is a handle to a pipe instance.

   hPipe = (HANDLE) lpvParam;

   while (1)
   {
   // Read client requests from the pipe.
      fSuccess = ReadFile(
         hPipe,        // handle to pipe
         chRequest,    // buffer to receive data
         BUFSIZE,      // size of buffer
         &cbBytesRead, // number of bytes read
         NULL);        // not overlapped I/O

      if (! fSuccess || cbBytesRead == 0)
         break;
      GetAnswerToRequest(chRequest, chReply, &cbReplyBytes);

   // Write the reply to the pipe.
      fSuccess = WriteFile(
         hPipe,        // handle to pipe
         chReply,      // buffer to write from
         cbReplyBytes, // number of bytes to write
         &cbWritten,   // number of bytes written
         NULL);        // not overlapped I/O

      if (! fSuccess || cbReplyBytes != cbWritten) break;
  }

// Flush the pipe to allow the client to read the pipe's contents
// before disconnecting. Then disconnect the pipe, and close the
// handle to this pipe instance.

   FlushFileBuffers(hPipe);
   DisconnectNamedPipe(hPipe);
   CloseHandle(hPipe);
}


Named Pipe Server Using Overlapped I/O

This topic includes an example of a single-threaded pipe server that uses overlapped operations to service simultaneous connections to multiple pipe clients. The pipe server creates a fixed number of pipe instances. Each pipe instance can be connected to a separate pipe client. When a pipe client has finished using its pipe instance, the server disconnects from the client and reuses the pipe instance to connect to a new client.

The OVERLAPPED structure is specified as a parameter in each ReadFile, WriteFile, and ConnectNamedPipe operation on the pipe instance. Although the example shows simultaneous operations on different pipe instances, it avoids simultaneous operations on a single pipe instance by using the event object in the OVERLAPPED structure. Because the same event object is used for read, write, and connect operations for each instance, there is no way to know which operation's completion caused the event to be set to the signaled state for simultaneous operations using the same pipe instance.

The event handles for each pipe instance are stored in an array that is passed to the WaitForMultipleObjects function. This function waits for one of the events to be signaled, and returns the array index of the event that caused the wait operation to complete. The example in this topic uses this array index to retrieve a structure containing information for the pipe instance. The server uses the fPendingIO member of the structure to keep track of whether the most recent I/O operation on the instance was pending, which requires a call to the GetOverlappedResult function. The server uses the dwState member of the structure to determine the next operation that must be performed for the pipe instance.

Overlapped ReadFile, WriteFile, and ConnectNamedPipe operations can finish by the time the function returns. Otherwise, if the operation is pending, the event object in the specified OVERLAPPED structure is set to the nonsignaled state before the function returns. When the pending operation finishes, the system sets the state of the event object to signaled. The state of the event object is not changed if the operation finishes before the function returns.

Because the example uses manual-reset event objects, the state of an event object is not changed to nonsignaled by the WaitForMultipleObjects function. This is important, because the example relies on the event objects remaining in the signaled state, except when there is a pending operation.

If the operation has already finished when ReadFile, WriteFile, or ConnectNamedPipe returns, the function's return value indicates the result. For read and write operations, the number of bytes transferred is also returned. If the operation is still pending, the ReadFile, WriteFile, or ConnectNamedPipe function returns zero and the GetLastError function returns ERROR_IO_PENDING. In this case, use the GetOverlappedResult function to retrieve the results after the operation has finished. GetOverlappedResult returns only the results of pending operations. It does not report the results of operations that were completed before the overlapped ReadFile, WriteFile, or ConnectNamedPipe function returned.

Before disconnecting from a client, the multithreaded server example in the previous topic used FlushFileBuffers to ensure that the client had read everything written to the pipe. This would defeat the purpose of overlapped I/O, because the flush operation would block the execution of the server thread while it waits for the client to empty the pipe. Consequently, before disconnecting, you must wait for a signal indicating the client has finished. In the following example, the signal is the error generated by trying to read from the pipe after the pipe client closes its handle.

#include <windows.h>

#define CONNECTING_STATE 0
#define READING_STATE 1
#define WRITING_STATE 2
#define INSTANCES 4

typedef struct
{
   OVERLAPPED oOverlap;
   HANDLE hPipeInst;
   CHAR chBuf[BUFSIZE];
   DWORD cbToWrite;
   DWORD dwState;
   BOOL fPendingIO;
} PIPEINST, *LPPIPEINST;

VOID DisconnectAndReconnect(DWORD);
BOOL ConnectToNewClient(HANDLE, LPOVERLAPPED);
VOID GetDataToWriteToClient(LPPIPEINST);

PIPEINST Pipe[INSTANCES];
HANDLE hEvents[INSTANCES];

DWORD main(VOID)
{
   DWORD i, dwWait, cbBytes, dwErr;
   BOOL fSuccess;
   LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe";

// The initial loop creates several instances of a named pipe
// along with an event object for each instance.  An
// overlapped ConnectNamedPipe operation is started for
// each instance.

   for (i = 0; i < INSTANCES; i++)
   {

   // Create an event object for this instance.

      hEvents[i] = CreateEvent(
         NULL,    // no security attribute
         TRUE,    // manual-reset event
         TRUE,    // initial state = signaled
         NULL);   // unnamed event object

      if (hEvents[i] == NULL)
         MyErrExit("CreateEvent");

      Pipe[i].oOverlap.hEvent = hEvents[i];

      Pipe[i].hPipeInst = CreateNamedPipe(
         lpszPipename,            // pipe name
         PIPE_ACCESS_DUPLEX |     // read/write access
         FILE_FLAG_OVERLAPPED,    // overlapped mode
         PIPE_TYPE_MESSAGE |      // message-type pipe
         PIPE_READMODE_MESSAGE |  // message-read mode
         PIPE_WAIT,               // blocking mode
         INSTANCES,               // number of instances
         BUFSIZE,                 // output buffer size
         BUFSIZE,                 // input buffer size
         PIPE_TIMEOUT,            // client time-out
         NULL);                   // no security attributes

      if (Pipe[i].hPipeInst == INVALID_HANDLE_VALUE)
          MyErrExit("CreatePipe");

   // Call the subroutine to connect to the new client

      Pipe[i].fPendingIO = ConnectToNewClient(
         Pipe[i].hPipeInst,
         &Pipe[i].oOverlap);

      Pipe[i].dwState = Pipe[i].fPendingIO ?
         CONNECTING_STATE : // still connecting
         READING_STATE;     // ready to read
   }

   while (1)
   {
   // Wait for the event object to be signaled, indicating
   // completion of an overlapped read, write, or
   // connect operation.

      dwWait = WaitForMultipleObjects(
         INSTANCES,    // number of event objects
         hEvents,      // array of event objects
         FALSE,        // does not wait for all
         INFINITE);    // waits indefinitely

   // dwWait shows which pipe completed the operation.

      i = dwWait - WAIT_OBJECT_0;  // determines which pipe
      if (i < 0 || i > (INSTANCES - 1))
         MyErrExit("index out of range");

   // Get the result if the operation was pending.

      if (Pipe[i].fPendingIO)
      {
         fSuccess = GetOverlappedResult(
            Pipe[i].hPipeInst, // handle to pipe
            &Pipe[i].oOverlap, // OVERLAPPED structure
            &cbBytes,          // bytes transferred
            FALSE);            // do not wait

         switch (Pipe[i].dwState)
         {
         // Pending connect operation
            case CONNECTING_STATE:
               if (! fSuccess)
                  MyErrExit("ConnectNamedPipe");
               Pipe[i].dwState = READING_STATE;
               break;

         // Pending read operation
            case READING_STATE:
               if (! fSuccess || cbBytes == 0)
               {
                  DisconnectAndReconnect(i);
                  continue;
               }
               Pipe[i].dwState = WRITING_STATE;
               break;

         // Pending write operation
            case WRITING_STATE:
               if (! fSuccess || cbBytes != Pipe[i].cbToWrite)
               {
                  DisconnectAndReconnect(i);
                  continue;
               }
               Pipe[i].dwState = READING_STATE;
               break;

            default:
               MyErrExit("invalid pipe state");
         }
      }

   // The pipe state determines which operation to do next.

      switch (Pipe[i].dwState)
      {
      // READING_STATE:
      // The pipe instance is connected to the client
      // and is ready to read a request from the client.

         case READING_STATE:
            fSuccess = ReadFile(
               Pipe[i].hPipeInst,
               Pipe[i].chBuf,
               BUFSIZE,
               &cbBytes,
               &Pipe[i].oOverlap);

         // The read operation completed successfully.

            if (fSuccess && cbBytes != 0)
            {
               Pipe[i].fPendingIO = FALSE;
               Pipe[i].dwState = WRITING_STATE;
               continue;
            }

         // The read operation is still pending.

            dwErr = GetLastError();
            if (! fSuccess && (dwErr == ERROR_IO_PENDING))
            {
               Pipe[i].fPendingIO = TRUE;
               continue;
            }

         // An error occurred; disconnect from the client.

            DisconnectAndReconnect(i);
            break;

      // WRITING_STATE:
      // The request was successfully read from the client.
      // Get the reply data and write it to the client.

         case WRITING_STATE:
            GetDataToWriteToClient(&Pipe[i]);

            fSuccess = WriteFile(
               Pipe[i].hPipeInst,
               Pipe[i].chBuf,
               Pipe[i].cbToWrite,
               &cbBytes,
               &Pipe[i].oOverlap);

         // The write operation completed successfully.

            if (fSuccess && cbBytes == Pipe[i].cbToWrite)
            {
               Pipe[i].fPendingIO = FALSE;
               Pipe[i].dwState = READING_STATE;
               continue;
            }

         // The write operation is still pending.

            dwErr = GetLastError();
            if (! fSuccess && (dwErr == ERROR_IO_PENDING))
            {
               Pipe[i].fPendingIO = TRUE;
               continue;
            }

         // An error occurred; disconnect from the client.

            DisconnectAndReconnect(i);
            break;

         default:
            MyErrExit("invalid pipe state");
      }
  }

  return 0;
}

// DisconnectAndReconnect(DWORD)
// This function is called when an error occurs or when the client
// closes its handle to the pipe. Disconnect from this client, then
// call ConnectNamedPipe to wait for another client to connect.

VOID DisconnectAndReconnect(DWORD i)
{
// Disconnect the pipe instance.

   if (! DisconnectNamedPipe(Pipe[i].hPipeInst) )
      MyErrExit("DisconnectNamedPipe");

// Call a subroutine to connect to the new client.

   Pipe[i].fPendingIO = ConnectToNewClient(
      Pipe[i].hPipeInst,
      &Pipe[i].oOverlap);

   Pipe[i].dwState = Pipe[i].fPendingIO ?
      CONNECTING_STATE : // still connecting
      READING_STATE;     // ready to read
}

// ConnectToNewClient(HANDLE, LPOVERLAPPED)
// This function is called to start an overlapped connect operation.
// It returns TRUE if an operation is pending or FALSE if the
// connection has been completed.

BOOL ConnectToNewClient(HANDLE hPipe, LPOVERLAPPED lpo)
{
   BOOL fConnected, fPendingIO = FALSE;

// Start an overlapped connection for this pipe instance.
   fConnected = ConnectNamedPipe(hPipe, lpo);

// Overlapped ConnectNamedPipe should return zero.
   if (fConnected)
      MyErrExit("ConnectNamedPipe");

   switch (GetLastError())
   {
   // The overlapped connection in progress.
      case ERROR_IO_PENDING:
         fPendingIO = TRUE;
         break;

   // Client is already connected, so signal an event.

      case ERROR_PIPE_CONNECTED:
         if (SetEvent(lpo->hEvent))
            break;

   // If an error occurs during the connect operation...
      default:
         MyErrExit("ConnectNamedPipe");
   }

   return fPendingIO;
}


Named Pipe Server Using Completion Routines

Like the previous example, the following example is a single-threaded pipe server that creates a message-type pipe and uses overlapped operations. The pipe servers differ, in that this example uses the extended functions ReadFileEx and WriteFileEx to perform overlapped I/O. Unlike the overlapped ReadFile and WriteFile functions, which signal an event object when completed, the extended functions specify a completion routine, which is queued for execution when the operation is finished. The pipe server uses the WaitForSingleObjectEx function, which performs an alertable wait operationthat returns when a completion routine is ready to execute. The wait function also returns when an event object is signaled, which in this example indicates that the overlapped ConnectNamedPipe operation has finished (a new client has connected).

Initially, the pipe server creates a single instance of the pipe and starts an overlapped ConnectNamedPipe operation. When a client connects, the server allocates a structure to provide storage for that pipe instance and then calls the ReadFileEx function to start a sequence of I/O operations to handle communications with the client. Each operation specifies a completion routine that performs the next operation in the sequence. The sequence terminates when the client is disconnected and the pipe instance closed. After starting the sequence of operations for the new client, the server creates another pipe instance and waits for the next client to connect.

The parameters of the ReadFileEx and WriteFileEx functions specify a completion routine and a pointer to an OVERLAPPED structure. This pointer is passed to the completion routine in its lpOverLap parameter. Because the OVERLAPPED structure points to the first member in the structure allocated for each pipe instance, the completion routine can use its lpOverLap parameter to access the structure for the pipe instance.

To avoid duplication, the listing for the ConnectToNewClient subroutine is not shown; it is identical to the one used by the overlapped pipe server in the previous example.

#include <windows.h>

typedef struct
{
   OVERLAPPED oOverlap;
   HANDLE hPipeInst;
   CHAR chBuf[BUFSIZE];
   DWORD cbToWrite;
} PIPEINST, *LPPIPEINST;

BOOL CreateAndConnectInstance();
BOOL ConnectToNewClient(HANDLE, LPOVERLAPPED);
VOID GetDataToWriteToClient(LPPIPEINST);
VOID DisconnectAndClose(LPPIPEINST);
VOID WINAPI CompletedWriteRoutine(DWORD, DWORD, LPOVERLAPPED);
VOID WINAPI CompletedReadRoutine(DWORD, DWORD, LPOVERLAPPED);

HANDLE hPipe;

DWORD main(VOID)
{
   HANDLE hConnectEvent;
   OVERLAPPED oConnect;
   LPPIPEINST lpPipeInst;
   DWORD dwWait, cbBytes;
   BOOL fSuccess, fPendingIO;

// Create one event object for the connect operation.

   hConnectEvent = CreateEvent(
      NULL,    // no security attribute
      TRUE,    // manual reset event
      TRUE,    // initial state = signaled
      NULL);   // unnamed event object

  if (hConnectEvent == NULL)
      MyErrExit("CreateEvent");

   oConnect.hEvent = hConnectEvent;

// Call a subroutine to create one instance, and wait for
// the client to connect.

   fPendingIO = CreateAndConnectInstance(&oConnect);

   while (1)
   {
   // Wait for a client to connect, or for a read or write
   // operation to be completed, which causes a completion
   // routine to be queued for execution.

      dwWait = WaitForSingleObjectEx(
         hConnectEvent,  // event object to wait for
         INFINITE,       // waits indefinitely
         TRUE);          // alertable wait enabled

      switch (dwWait)
      {
      // The wait conditions are satisfied by a completed connect
      // operation.
         case 0:
         // If an operation is pending, get the result of the
         // connect operation.

         if (fPendingIO)
         {
            fSuccess = GetOverlappedResult(
               hPipe,     // pipe handle
               &oConnect, // OVERLAPPED structure
               &cbBytes,  // bytes transferred
               FALSE);    // does not wait
            if (!fSuccess)
               MyErrExit("ConnectNamedPipe");
         }

         // Allocate storage for this instance.

            lpPipeInst = (LPPIPEINST) GlobalAlloc(
               GPTR, sizeof(PIPEINST));
            if (lpPipeInst == NULL)
               MyErrExit("GlobalAlloc lpPipeInst");

            lpPipeInst->hPipeInst = hPipe;

         // Start the read operation for this client.
         // Note that this same routine is later used as a
         // completion routine after a write operation.

            lpPipeInst->cbToWrite = 0;
            CompletedWriteRoutine(0, 0, (LPOVERLAPPED) lpPipeInst);

         // Create new pipe instance for the next client.

            fPendingIO = CreateAndConnectInstance(
               &oConnect);
            break;

      // The wait is satisfied by a completed read or write
      // operation. This allows the system to execute the
      // completion routine.

         case WAIT_IO_COMPLETION:
            break;

      // An error occurred in the wait function.

         default:
            MyErrExit("WaitForSingleObjectEx");
      }
   }
   return 0;
}

// CompletedWriteRoutine(DWORD, DWORD, LPOVERLAPPED)
// This routine is called as a completion routine after writing to
// the pipe, or when a new client has connected to a pipe instance. It
// starts another read operation.

VOID WINAPI CompletedWriteRoutine(DWORD dwErr, DWORD cbWritten,
   LPOVERLAPPED lpOverLap)
{
   LPPIPEINST lpPipeInst;
   BOOL fRead = FALSE;

// lpOverlap points to storage for this instance.

   lpPipeInst = (LPPIPEINST) lpOverLap;

// The write operation has finished, so read the next request (if
// there is no error).

   if ((dwErr == 0) && (cbWritten == lpPipeInst->cbToWrite))
      fRead = ReadFileEx(
         lpPipeInst->hPipeInst,
         lpPipeInst->chBuf,
         BUFSIZE,
         (LPOVERLAPPED) lpPipeInst,
         (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedReadRoutine);

// Disconnect if an error occurred.

   if (! fRead)
      DisconnectAndClose(lpPipeInst);
}

// CompletedReadRoutine(DWORD, DWORD, LPOVERLAPPED)
// This routine is called as an I/O completion routine after reading a
// request from the client. It gets data and writes it to the pipe.

VOID WINAPI CompletedReadRoutine(DWORD dwErr, DWORD cbBytesRead,
    LPOVERLAPPED lpOverLap)
{
   LPPIPEINST lpPipeInst;
   BOOL fWrite = FALSE;

// lpOverlap points to storage for this instance.

   lpPipeInst = (LPPIPEINST) lpOverLap;

// The read operation has finished, so write a response (if no
// error occurred).

   if ((dwErr == 0) && (cbBytesRead != 0))
   {
      GetDataToWriteToClient(lpPipeInst);

      fWrite = WriteFileEx(
         lpPipeInst->hPipeInst,
         lpPipeInst->chBuf,
         lpPipeInst->cbToWrite,
         (LPOVERLAPPED) lpPipeInst,
         (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedWriteRoutine);
   }

// Disconnect if an error occurred.

   if (! fWrite)
      DisconnectAndClose(lpPipeInst);
}

// DisconnectAndClose(LPPIPEINST)
// This routine is called when an error occurs or the client closes
// its handle to the pipe.

VOID DisconnectAndClose(LPPIPEINST lpPipeInst)
{
// Disconnect the pipe instance.

   if (! DisconnectNamedPipe(lpPipeInst->hPipeInst) )
      MyErrExit("DisconnectNamedPipe");

// Close the handle to the pipe instance.

   CloseHandle(lpPipeInst->hPipeInst);

// Release the storage for the pipe instance.

   if (lpPipeInst != NULL)
      GlobalFree(lpPipeInst);
}

// CreateAndConnectInstance(LPOVERLAPPED)
// This function creates a pipe instance and connects to the client.
// It returns TRUE if the connect operation is pending, and FALSE if
// the connection has been completed.

BOOL CreateAndConnectInstance(LPOVERLAPPED lpoOverlap)
{
   LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe";

   hPipe = CreateNamedPipe(
      lpszPipename,             // pipe name
      PIPE_ACCESS_DUPLEX |      // read/write access
      FILE_FLAG_OVERLAPPED,     // overlapped mode
      PIPE_TYPE_MESSAGE |       // message-type pipe
      PIPE_READMODE_MESSAGE |   // message read mode
      PIPE_WAIT,                // blocking mode
      PIPE_UNLIMITED_INSTANCES, // unlimited instances
      BUFSIZE,                  // output buffer size
      BUFSIZE,                  // input buffer size
      PIPE_TIMEOUT,             // client time-out
      NULL);                    // no security attributes
  if (hPipe == INVALID_HANDLE_VALUE)
      MyErrExit("CreatePipe");

// Call a subroutine to connect to the new client.

   return ConnectToNewClient(hPipe, lpoOverlap);
}


Named Pipe Client

A named pipe client uses the CreateFile function to open a handle to a named pipe. If the pipe exists but all of its instances are busy, CreateFile returns zero and the GetLastError function returns ERROR_PIPE_BUSY. When this happens, the named pipe client uses the WaitNamedPipe function to wait for an instance of the named pipe to become available.

The CreateFile function fails if the access specified is incompatible with the access specified (duplex, outbound, or inbound) when the server created the pipe. For a duplex pipe, the client can specify read, write, or read/write access; for an outbound pipe (write-only server), the client must specify read-only access; and for an inbound pipe (read-only server), the client must specify write-only access.

The handle returned by CreateFile defaults to byte-read mode, blocking-wait mode, overlapped mode disabled, and write-through mode disabled. The pipe client can use CreateFile to enable overlapped mode by specifying FILE_FLAG_OVERLAPPED or to enable write-through mode by specifying FILE_FLAG_WRITE_THROUGH. The client can use the SetNamedPipeHandleState function to enable nonblocking mode by specifying PIPE_WAIT or to enable message-read mode by specifying PIPE_READMODE_MESSAGE.

The following example shows a pipe client that opens a named pipe, sets the pipe handle to message-read mode, uses the WriteFile function to send a request to the server, and uses the ReadFile function to read the server's reply. This pipe client can be used with any of the message-type servers shown in the previous examples. With a byte-type server, however, this pipe client fails when it calls SetNamedPipeHandleState to change to message-read mode. Because the client is reading from the pipe in message-read mode, it is possible for the ReadFile operation to return zero after reading a partial message. This happens when the message is larger than the read buffer. In this situation, GetLastError returns ERROR_MORE_DATA, and the client can read the remainder of the message using additional calls to ReadFile.

#include <windows.h>

DWORD main(int argc, char *argv[])
{
   HANDLE hPipe;
   LPVOID lpvMessage;
   CHAR chBuf[512];
   BOOL fSuccess;
   DWORD cbRead, cbWritten, dwMode;
   LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe";

// Try to open a named pipe; wait for it, if necessary.

   while (1)
   {
      hPipe = CreateFile(
         lpszPipename,   // pipe name
         GENERIC_READ |  // read and write access
         GENERIC_WRITE,
         0,              // no sharing
         NULL,           // no security attributes
         OPEN_EXISTING,  // opens existing pipe
         0,              // default attributes
         NULL);          // no template file

   // Break if the pipe handle is valid.

      if (hPipe != INVALID_HANDLE_VALUE)
         break;

      // Exit if an error other than ERROR_PIPE_BUSY occurs.

      if (GetLastError() != ERROR_PIPE_BUSY)
         MyErrExit("Could not open pipe");

      // All pipe instances are busy, so wait for 20 seconds.

      if (! WaitNamedPipe(lpszPipename, 20000) )
         MyErrExit("Could not open pipe");
   }

// The pipe connected; change to message-read mode.

   dwMode = PIPE_READMODE_MESSAGE;
   fSuccess = SetNamedPipeHandleState(
      hPipe,    // pipe handle
      &dwMode,  // new pipe mode
      NULL,     // don't set maximum bytes
      NULL);    // don't set maximum time
   if (!fSuccess)
      MyErrExit("SetNamedPipeHandleState");

// Send a message to the pipe server.

   lpvMessage = (argc > 1) ? argv[1] : "default message";

   fSuccess = WriteFile(
      hPipe,                  // pipe handle
      lpvMessage,             // message
      strlen(lpvMessage) + 1, // message length
      &cbWritten,             // bytes written
      NULL);                  // not overlapped
   if (! fSuccess)
      MyErrExit("WriteFile");

   do
   {
   // Read from the pipe.

      fSuccess = ReadFile(
         hPipe,    // pipe handle
         chBuf,    // buffer to receive reply
         512,      // size of buffer
         &cbRead,  // number of bytes read
         NULL);    // not overlapped

      if (! fSuccess && GetLastError() != ERROR_MORE_DATA)
         break;

      // Reply from the pipe is written to STDOUT.

      if (! WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
         chBuf, cbRead, &cbWritten, NULL))
      {
         break;
      }

   } while (! fSuccess);  // repeat loop if ERROR_MORE_DATA

   CloseHandle(hPipe);

   return 0;
}


Transactions on Named Pipes

A named pipe transaction is a client-server communication that combines a write operation and a read operation into a single network operation. A transaction can be used only on a duplex, message-type pipe. Transactions improve the performance of network communications between a client and a remote server. Processes can use the TransactNamedPipe and CallNamedPipe functions to perform named pipe transactions.

The TransactNamedPipe function is most commonly used by a pipe client to write a request message to the named pipe server and read the server's response message. The pipe client must specify GENERIC_READ | GENERIC_WRITE access when it opens its pipe handle by calling the CreateFile function. Then, the pipe client sets the pipe handle to message-read mode by calling the SetNamedPipeHandleState function. If the read buffer specified in the call to TransactNamedPipe is not large enough to hold the entire message written by the server, the function returns zero and GetLastError returns ERROR_MORE_DATA. The client can read the remainder of the message by calling either the ReadFile, ReadFileEx, or PeekNamedPipe function.

TransactNamedPipe is typically called by pipe clients, but can also be used by a pipe server.

The following example shows a pipe client using TransactNamedPipe. The example assumes that the pipe client has used CreateFile to connect to the pipe and SetNamedPipeHandleState to set the pipe handle's read mode, as shown in the pipe client example in the preceding topic.

fSuccess = TransactNamedPipe(
   hPipe,               // pipe handle
   lpszWrite,           // message to server
   strlen(lpszWrite)+1, // message length
   chReadBuf,           // buffer to receive reply
   512,                 // size of read buffer
   &cbRead,             // number of bytes read
   NULL);               // not overlapped

// Exit if an error occurs, unless the error indicates there is more
// data in the message.

if (!fSuccess && (GetLastError() != ERROR_MORE_DATA))
{
   MyErrExit("TransactNamedPipe");
}

while(1)
{
// Data from the pipe is written to STDOUT.

   if (! WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
      chReadBuf, cbRead, &cbWritten, NULL) )
      break;

// Break if TransactNamedPipe or ReadFile is successful.

   if (fSuccess)
      break;

// Read from the pipe if there is more data in the message.

   fSuccess = ReadFile(
      hPipe,      // pipe handle
      chReadBuf,  // buffer to receive reply
      512,        // size of buffer
      &cbRead,    // number of bytes read
      NULL);      // not overlapped

// Exit if an error other than ERROR_MORE_DATA occurs.

   if (! fSuccess && (GetLastError() != ERROR_MORE_DATA))
      break;
}

A pipe client uses CallNamedPipe to combine the CreateFile, WaitNamedPipe (if necessary), TransactNamedPipe, and CloseHandle function calls into a single call. Because the pipe handle is closed before the function returns, any additional bytes in the message are lost if the message is larger than the specified size of the read buffer. The following example shows the use of CallNamedPipe.

// Combines connect, wait, write, read, and close operations.

fSuccess = CallNamedPipe(
    lpszPipename,        // pipe name
    lpszWrite,           // message to server
    strlen(lpszWrite)+1, // message length
    chReadBuf,           // buffer to receive reply
    512,                 // size of read buffer
    &cbRead,             // number of bytes read
    20000);              // waits for 20 seconds

if (fSuccess || GetLastError() == ERROR_MORE_DATA)
{

// Data from the pipe is written to STDOUT.

   WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
      chReadBuf, cbRead, &cbWritten, NULL);

// The pipe is closed, so no more bytes can be read from the
// message.

   if (! fSuccess)
      printf("\n...extra data in message was lost\n");
}


Pipe Reference

The following elements are used with pipes.

  • Pipe Functions


Pipe Functions

The following functions are used with pipes.

CallNamedPipe
ConnectNamedPipe
CreateNamedPipe
CreatePipe
DisconnectNamedPipe
GetNamedPipeHandleState
GetNamedPipeInfo
PeekNamedPipe
SetNamedPipeHandleState
TransactNamedPipe
WaitNamedPipe


CallNamedPipe

The CallNamedPipe function connects to a message-type pipe (and waits if an instance of the pipe is not available), writes to and reads from the pipe, and then closes the pipe.

BOOL CallNamedPipe(
  LPCTSTR lpNamedPipeName,  // pointer to pipe name
  LPVOID lpInBuffer,        // pointer to write buffer
  DWORD nInBufferSize,      // size, in bytes, of write buffer
  LPVOID lpOutBuffer,       // pointer to read buffer
  DWORD nOutBufferSize,     // size, in bytes, of read buffer
  LPDWORD lpBytesRead,      // pointer to number of bytes read
  DWORD nTimeOut            // time-out value, in milliseconds
);

Parameters

lpNamedPipeName
Pointer to a null-terminated string specifying the pipe name.
lpInBuffer
Pointer to the buffer containing the data written to the pipe.
nInBufferSize
Specifies the size, in bytes, of the write buffer.
lpOutBuffer
Pointer to the buffer that receives the data read from the pipe.
nOutBufferSize
Specifies the size, in bytes, of the read buffer.
lpBytesRead
Pointer to a 32-bit variable that receives the number of bytes read from the pipe.
nTimeOut
Specifies the number of milliseconds to wait for the named pipe to be available. In addition to numeric values, the following special values can be specified:
Value | Meaning
NMPWAIT_NOWAIT | Does not wait for the named pipe. If the named pipe is not available, the function returns an error.
NMPWAIT_WAIT_FOREVER | Waits indefinitely.
NMPWAIT_USE_DEFAULT_WAIT | Uses the default time-out specified in a call to the CreateNamedPipe function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Calling CallNamedPipe is equivalent to calling the CreateFile (or WaitNamedPipe, if CreateFile cannot open the pipe immediately), TransactNamedPipe, and CloseHandle functions. CreateFile is called with an access flag of GENERIC_READ | GENERIC_WRITE, an inherit handle flag of FALSE, and a share mode of zero (indicating no sharing of this pipe instance).

If the message written to the pipe by the server process is longer than nOutBufferSize, CallNamedPipe returns FALSE, and GetLastError returns ERROR_MORE_DATA. The remainder of the message is discarded, because CallNamedPipe closes the handle to the pipe before returning.

CallNamedPipe fails if the pipe is a byte-type pipe.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Pipes Overview, Pipe Functions, CloseHandle, CreateFile, CreateNamedPipe, TransactNamedPipe, WaitNamedPipe


ConnectNamedPipe

The ConnectNamedPipe function enables a named pipe server process to wait for a client process to connect to an instance of a named pipe. A client process connects by calling either the CreateFile or CallNamedPipe function.

BOOL ConnectNamedPipe(
  HANDLE hNamedPipe,          // handle to named pipe to connect
  LPOVERLAPPED lpOverlapped   // pointer to overlapped structure
);

Parameters

hNamedPipe
Handle to the server end of a named pipe instance. This handle is returned by the CreateNamedPipe function.
lpOverlapped
Pointer to an OVERLAPPED structure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A named pipe server process can use ConnectNamedPipe with a newly created pipe instance. It can also be used with an instance that was previously connected to another client process; in this case, the server process must first call the DisconnectNamedPipe function to disconnect the handle from the previous client before the handle can be reconnected to a new client. Otherwise, ConnectNamedPipe returns zero, and GetLastError returns ERROR_NO_DATA if the previous client has closed its handle or ERROR_PIPE_CONNECTED if it has not closed its handle.

The behavior of ConnectNamedPipe depends on two conditions: whether the pipe handle's wait mode is set to blocking or nonblocking and whether the function is set to execute synchronously or in overlapped mode. A server initially specifies a pipe handle's wait mode in the CreateNamedPipe function, and it can be changed by using the SetNamedPipeHandleState function.

If hNamedPipe was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hNamedPipe was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the connect operation is complete.

If hNamedPipe was created with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the OVERLAPPED structure pointed to by lpOverlapped must contain a handle to a manual-reset event object (which the server can create by using the CreateEvent function).

If hNamedPipe was not opened with FILE_FLAG_OVERLAPPED, the function does not return until a client is connected or an error occurs. Successful synchronous operations result in the function returning a nonzero value if a client connects after the function is called. If a client connects before the function is called, the function returns zero and GetLastError returns ERROR_PIPE_CONNECTED. This can happen if a client connects in the interval between the call to CreateNamedPipe and the call to ConnectNamedPipe. In this situation, there is a good connection between client and server, even though the function returns zero.

The server process can use any of the wait functions or SleepEx — to determine when the state of the event object is signaled, and it can then use the GetOverlappedResult function to determine the results of the ConnectNamedPipe operation.

If the specified pipe handle is in nonblocking mode, ConnectNamedPipe always returns immediately. In nonblocking mode, ConnectNamedPipe returns a nonzero value the first time it is called for a pipe instance that is disconnected from a previous client. This indicates that the pipe is now available to be connected to a new client process. In all other situations when the pipe handle is in nonblocking mode, ConnectNamedPipe returns zero. In these situations, GetLastError returns ERROR_PIPE_LISTENING if no client is connected, ERROR_PIPE_CONNECTED if a client is connected, and ERROR_NO_DATA if a previous client has closed its pipe handle but the server has not disconnected. Note that a good connection between client and server exists only after the ERROR_PIPE_CONNECTED error is received.

Note Nonblocking mode is supported for compatibility with Microsoft LAN Manager version 2.0, and it should not be used to achieve asynchronous input and output (I/O) with named pipes.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Pipes Overview, Pipe Functions, CallNamedPipe, CreateEvent, CreateFile, CreateNamedPipe, DisconnectNamedPipe, GetOverlappedResult, SetNamedPipeHandleState, SleepEx, OVERLAPPED


CreateNamedPipe

The CreateNamedPipe function creates an instance of a named pipe and returns a handle for subsequent pipe operations. A named pipe server process uses this function either to create the first instance of a specific named pipe and establish its basic attributes or to create a new instance of an existing named pipe.

HANDLE CreateNamedPipe(
  LPCTSTR lpName,         // pointer to pipe name
  DWORD dwOpenMode,       // pipe open mode
  DWORD dwPipeMode,       // pipe-specific modes
  DWORD nMaxInstances,    // maximum number of instances
  DWORD nOutBufferSize,   // output buffer size, in bytes
  DWORD nInBufferSize,    // input buffer size, in bytes
  DWORD nDefaultTimeOut,  // time-out time, in milliseconds
  LPSECURITY_ATTRIBUTES lpSecurityAttributes  // pointer to security attributes
);

Parameters

lpName
Pointer to the null-terminated string that uniquely identifies the pipe. The string must have the following form:

\\.\pipe\pipename

The pipename part of the name can include any character other than a backslash, including numbers and special characters. The entire pipe name string can be up to 256 characters long. Pipe names are not case sensitive.

dwOpenMode
Specifies the pipe access mode, the overlapped mode, the write-through mode, and the security access mode of the pipe handle.

CreateNamedPipe fails if dwOpenMode specifies any flags other than those listed in the following tables.

This parameter must specify one of the following pipe access mode flags. The same mode must be specified for each instance of the pipe:
Mode | Description
PIPE_ACCESS_DUPLEX | The pipe is bidirectional; both server and client processes can read from and write to the pipe. This mode gives the server the equivalent of GENERIC_READ | GENERIC_WRITE access to the pipe. The client can specify GENERIC_READ or GENERIC_WRITE, or both, when it connects to the pipe using the CreateFile function.
PIPE_ACCESS_INBOUND | The flow of data in the pipe goes from client to server only. This mode gives the server the equivalent of GENERIC_READ access to the pipe. The client must specify GENERIC_WRITE access when connecting to the pipe.
PIPE_ACCESS_OUTBOUND | The flow of data in the pipe goes from server to client only. This mode gives the server the equivalent of GENERIC_WRITE access to the pipe. The client must specify GENERIC_READ access when connecting to the pipe.

This parameter can also include either or both of the following flags, which enable write-through mode and overlapped mode. These modes can be different for different instances of the same pipe.
Mode | Description
FILE_FLAG_WRITE_THROUGH | Write-through mode is enabled. This mode affects only write operations on byte-type pipes and, then, only when the client and server processes are on different computers. If this mode is enabled, functions writing to a named pipe do not return until the data written is transmitted across the network and is in the pipe's buffer on the remote computer. If this mode is not enabled, the system enhances the efficiency of network operations by buffering data until a minimum number of bytes accumulate or until a maximum time elapses.
FILE_FLAG_OVERLAPPED | Overlapped mode is enabled. If this mode is enabled, functions performing read, write, and connect operations that may take a significant time to be completed can return immediately. This mode enables the thread that started the operation to perform other operations while the time-consuming operation executes in the background. For example, in overlapped mode, a thread can handle simultaneous input and output (I/O) operations on multiple instances of a pipe or perform simultaneous read and write operations on the same pipe handle. If overlapped mode is not enabled, functions performing read, write, and connect operations on the pipe handle do not return until the operation is finished. The ReadFileEx and WriteFileEx functions can only be used with a pipe handle in overlapped mode. The ReadFile, WriteFile, ConnectNamedPipe, and TransactNamedPipe functions can execute either synchronously or as overlapped operations.

This parameter can include any combination of the following security access mode flags. These modes can be different for different instances of the same pipe. They can be specified without concern for what other dwOpenMode modes have been specified.
Mode | Description
WRITE_DAC | The caller will have write access to the named pipe's discretionary access control list (ACL).
WRITE_OWNER | The caller will have write access to the named pipe's owner.
ACCESS_SYSTEM_SECURITY | The caller will have write access to the named pipe's SACL. For more information, see Access-Control Lists (ACLs) and SACL Access Right.

dwPipeMode
Specifies the type, read, and wait modes of the pipe handle.

One of the following type mode flags can be specified. The same type mode must be specified for each instance of the pipe. If you specify zero, the parameter defaults to byte-type mode.
Mode | Description
PIPE_TYPE_BYTE | Data is written to the pipe as a stream of bytes. This mode cannot be used with PIPE_READMODE_MESSAGE.
PIPE_TYPE_MESSAGE | Data is written to the pipe as a stream of messages. This mode can be used with either PIPE_READMODE_MESSAGE or PIPE_READMODE_BYTE.

One of the following read mode flags can be specified. Different instances of the same pipe can specify different read modes. If you specify zero, the parameter defaults to byte-read mode.
Mode | Description
PIPE_READMODE_BYTE | Data is read from the pipe as a stream of bytes. This mode can be used with either PIPE_TYPE_MESSAGE or PIPE_TYPE_BYTE.
PIPE_READMODE_MESSAGE | Data is read from the pipe as a stream of messages. This mode can be only used if PIPE_TYPE_MESSAGE is also specified.

One of the following wait mode flags can be specified. Different instances of the same pipe can specify different wait modes. If you specify zero, the parameter defaults to blocking mode.
Mode | Description
PIPE_WAIT | Blocking mode is enabled. When the pipe handle is specified in the ReadFile, WriteFile, or ConnectNamedPipe function, the operations are not completed until there is data to read, all data is written, or a client is connected. Use of this mode can mean waiting indefinitely in some situations for a client process to perform an action.
PIPE_NOWAIT | Nonblocking mode is enabled. In this mode, ReadFile, WriteFile, and ConnectNamedPipe always return immediately. Note that nonblocking mode is supported for compatibility with Microsoft LAN Manager version 2.0 and should not be used to achieve asynchronous I/O with named pipes.

nMaxInstances
Specifies the maximum number of instances that can be created for this pipe. The same number must be specified for all instances. Acceptable values are in the range 1 through PIPE_UNLIMITED_INSTANCES. If this parameter is PIPE_UNLIMITED_INSTANCES, the number of pipe instances that can be created is limited only by the availability of system resources.
nOutBufferSize
Specifies the number of bytes to reserve for the output buffer. For a discussion on sizing named pipe buffers, see the following Remarks section.
nInBufferSize
Specifies the number of bytes to reserve for the input buffer. For a discussion on sizing named pipe buffers, see the following Remarks section.
nDefaultTimeOut
Specifies the default time-out value, in milliseconds, if the WaitNamedPipe function specifies NMPWAIT_USE_DEFAULT_WAIT. Each instance of a named pipe must specify the same value.
lpSecurityAttributes
Pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new named pipe and determines whether child processes can inherit the returned handle. If lpSecurityAttributes is NULL, the named pipe gets a default security descriptor and the handle cannot be inherited.

Return Values

If the function succeeds, the return value is a handle to the server end of a named pipe instance.

If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError. The return value is ERROR_INVALID_PARAMETER if nMaxInstances is greater than PIPE_UNLIMITED_INSTANCES.

Remarks

To create an instance of a named pipe by using CreateNamedPipe, the user must have FILE_CREATE_PIPE_INSTANCE access to the named pipe object. If a new named pipe is being created, the access control list (ACL) from the security attributes parameter defines the discretionary access control for the named pipe.

All instances of a named pipe must specify the same pipe type (byte-type or message-type), pipe access (duplex, inbound, or outbound), instance count, and time-out value. If different values are used, this function fails and GetLastError returns ERROR_ACCESS_DENIED.

The input and output buffer sizes are advisory. The actual buffer size reserved for each end of the named pipe is either the system default, the system minimum or maximum, or the specified size rounded up to the next allocation boundary.

The pipe server should not perform a blocking read operation until the pipe client has started. Otherwise, a race condition can occur. This typically occurs when initialization code, such as the C run-time, needs to lock and examine inherited handles.

An instance of a named pipe is always deleted when the last handle to the instance of the named pipe is closed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Pipes Overview, Pipe Functions, ConnectNamedPipe, CreateFile, ReadFile, ReadFileEx, SECURITY_ATTRIBUTES, TransactNamedPipe, WaitNamedPipe, WriteFile, WriteFileEx


CreatePipe

The CreatePipe function creates an anonymous pipe, and returns handles to the read and write ends of the pipe.

BOOL CreatePipe(
  PHANDLE hReadPipe,                       // pointer to read handle
  PHANDLE hWritePipe,                      // pointer to write handle
  LPSECURITY_ATTRIBUTES lpPipeAttributes,  // pointer to security attributes
  DWORD nSize                              // pipe size
);

Parameters

hReadPipe
Pointer to the variable that receives the read handle for the pipe.
hWritePipe
Pointer to the variable that receives the write handle for the pipe.
lpPipeAttributes
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpPipeAttributes is NULL, the handle cannot be inherited.

Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new pipe. If lpPipeAttributes is NULL, the pipe gets a default security descriptor.

nSize
Specifies the buffer size for the pipe. The size is only a suggestion; the system uses the value to calculate an appropriate buffering mechanism. If this parameter is zero, the system uses the default buffer size.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

CreatePipe creates the pipe, assigning the specified pipe size to the storage buffer. CreatePipe also creates handles that the process uses to read from and write to the buffer in subsequent calls to the ReadFile and WriteFile functions.

To read from the pipe, a process uses the read handle in a call to the ReadFile function. ReadFile returns when one of the following is true: a write operation completes on the write end of the pipe, the number of bytes requested has been read, or an error occurs.

When a process uses WriteFile to write to an anonymous pipe, the write operation is not completed until all bytes are written. If the pipe buffer is full before all bytes are written, WriteFile does not return until another process or thread uses ReadFile to make more buffer space available.

Windows NT: Anonymous pipes are implemented using a named pipe with a unique name. Therefore, you can often pass a handle to an anonymous pipe to a function that requires a handle to a named pipe.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Pipes Overview, Pipe Functions, ReadFile, SECURITY_ATTRIBUTES, WriteFile


DisconnectNamedPipe

The DisconnectNamedPipe function disconnects the server end of a named pipe instance from a client process.

BOOL DisconnectNamedPipe(
  HANDLE hNamedPipe   // handle to named pipe
);

Parameters

hNamedPipe
Handle to an instance of a named pipe. This handle must be created by the CreateNamedPipe function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the client end of the named pipe is open, the DisconnectNamedPipe function forces that end of the named pipe closed. The client receives an error the next time it attempts to access the pipe. A client that is forced off a pipe by DisconnectNamedPipe must still use the CloseHandle function to close its end of the pipe.

When the server process disconnects a pipe instance, any unread data in the pipe is discarded. Before disconnecting, the server can make sure data is not lost by calling the FlushFileBuffers function, which does not return until the client process has read all the data.

The server process must call DisconnectNamedPipe to disconnect a pipe handle from its previous client before the handle can be connected to another client by using the ConnectNamedPipe function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Pipes Overview, Pipe Functions, CloseHandle, ConnectNamedPipe, CreateNamedPipe, FlushFileBuffers


GetNamedPipeHandleState

The GetNamedPipeHandleState function retrieves information about a specified named pipe. The information returned can vary during the lifetime of an instance of the named pipe.

BOOL GetNamedPipeHandleState(
  HANDLE hNamedPipe,             // handle to named pipe
  LPDWORD lpState,               // pointer to pipe state flags state
  LPDWORD lpCurInstances,        // pointer to number of current pipe instances
  LPDWORD lpMaxCollectionCount,  // pointer to maximum collection count
  LPDWORD lpCollectDataTimeout,  // pointer to time before remote transmission
  LPTSTR lpUserName,             // pointer to user name of client process
  DWORD nMaxUserNameSize         // size, in characters, of user name buffer
);

Parameters

hNamedPipe
Handle to the named pipe for which information is wanted. The handle must have GENERIC_READ access to the named pipe.

Windows NT: This parameter can also be a handle to an anonymous pipe, as returned by the CreatePipe function.

lpState
Pointer to a 32-bit variable that indicates the current state of the handle. This parameter can be NULL if this information is not needed. Either or both of the following values can be specified:
Value | Meaning
PIPE_NOWAIT | The pipe handle is in nonblocking mode. If this flag is not specified, the pipe handle is in blocking mode.
PIPE_READMODE_MESSAGE | The pipe handle is in message-read mode. If this flag is not specified, the pipe handle is in byte-read mode.

lpCurInstances
Pointer to a 32-bit variable that receives the number of current pipe instances. This parameter can be NULL if this information is not required.
lpMaxCollectionCount
Pointer to a 32-bit variable that receives the maximum number of bytes to be collected on the client's computer before transmission to the server. This parameter must be NULL if the specified pipe handle is to the server end of a named pipe or if client and server processes are on the same computer. This parameter can be NULL if this information is not required.
lpCollectDataTimeout
Pointer to a 32-bit variable that receives the maximum time, in milliseconds, that can pass before a remote named pipe transfers information over the network. This parameter must be NULL if the specified pipe handle is to the server end of a named pipe or if client and server processes are on the same computer. This parameter can be NULL if this information is not required.
lpUserName
Pointer to a buffer that receives the null-terminated string containing the user name string of the client application. This parameter must be NULL if the specified pipe handle is to the client end of a named pipe. This parameter can be NULL if this information is not required.
nMaxUserNameSize
Specifies the size, in characters, of the buffer specified by the lpUserName parameter. This parameter is ignored if lpUserName is NULL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The GetNamedPipeHandleState function returns successfully even if all of the pointers passed to it are NULL.

To set the pipe handle state, use the SetNamedPipeHandleState function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Pipes Overview, Pipe Functions, SetNamedPipeHandleState


GetNamedPipeInfo

The GetNamedPipeInfo function retrieves information about the specified named pipe.

BOOL GetNamedPipeInfo(
  HANDLE hNamedPipe,        // handle to named pipe
  LPDWORD lpFlags,          // pointer to flags indicating the pipe type
  LPDWORD lpOutBufferSize,  // pointer to size of pipe's output buffer
  LPDWORD lpInBufferSize,   // pointer to size of pipe's input buffer
  LPDWORD lpMaxInstances    // pointer to the maximum number of pipe instances
);

Parameters

hNamedPipe
Handle to the named pipe instance. The handle must have GENERIC_READ access to the named pipe.

Windows NT: This parameter can also be a handle to an anonymous pipe, as returned by the CreatePipe function.

lpFlags
Pointer to a 32-bit variable that indicates the type of the named pipe. This parameter can be NULL if this information is not required. Otherwise, use the following values:
Value | Meaning
PIPE_CLIENT_END | The handle refers to the client end of a named pipe instance. This is the default.
PIPE_SERVER_END | The handle refers to the server end of a named pipe instance. If this value is not specified, the handle refers to the client end of a named pipe instance.
PIPE_TYPE_BYTE | The named pipe is a byte pipe. This is the default.
PIPE_TYPE_MESSAGE | The named pipe is a message pipe. If this value is not specified, the pipe is a byte pipe.

lpOutBufferSize
Pointer to a 32-bit variable that receives the size, in bytes, of the buffer for outgoing data. If the buffer size is zero, the buffer is allocated as needed. This parameter can be NULL if this information is not required.
lpInBufferSize
Pointer to a 32-bit variable that receives the size, in bytes, of the buffer for incoming data. If the buffer size is zero, the buffer is allocated as needed. This parameter can be NULL if this information is not required.
lpMaxInstances
Pointer to a 32-bit variable that receives the maximum number of pipe instances that can be created. If the variable is set to PIPE_UNLIMITED_INSTANCES, the number of pipe instances that can be created is limited only by the availability of system resources. This parameter can be NULL if this information is not required.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Pipes Overview, Pipe Functions, CreateNamedPipe, GetNamedPipeHandleState


PeekNamedPipe

The PeekNamedPipe function copies data from a named or anonymous pipe into a buffer without removing it from the pipe. It also returns information about data in the pipe.

BOOL PeekNamedPipe(
  HANDLE hNamedPipe,             // handle to pipe to copy from
  LPVOID lpBuffer,               // pointer to data buffer
  DWORD nBufferSize,             // size, in bytes, of data buffer
  LPDWORD lpBytesRead,           // pointer to number of bytes read
  LPDWORD lpTotalBytesAvail,     // pointer to total number of bytes available
  LPDWORD lpBytesLeftThisMessage // pointer to unread bytes in this message
);

Parameters

hNamedPipe
Handle to the pipe. This parameter can be a handle to a named pipe instance, as returned by the CreateNamedPipe or CreateFile function, or it can be a handle to the read end of an anonymous pipe, as returned by the CreatePipe function. The handle must have GENERIC_READ access to the pipe.
lpBuffer
Pointer to a buffer that receives data read from the pipe. This parameter can be NULL if no data is to be read.
nBufferSize
Specifies the size, in bytes, of the buffer specified by the lpBuffer parameter. This parameter is ignored if lpBuffer is NULL.
lpBytesRead
Pointer to a 32-bit variable that receives the number of bytes read from the pipe. This parameter can be NULL if no data is to be read.
lpTotalBytesAvail
Pointer to a 32-bit variable that receives the total number of bytes available to be read from the pipe. This parameter can be NULL if no data is to be read.
lpBytesLeftThisMessage
Pointer to a 32-bit variable that receives the number of bytes remaining in this message. This parameter will be zero for byte-type named pipes or for anonymous pipes. This parameter can be NULL if no data is to be read.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

PeekNamedPipe is similar to the ReadFile function with the following exceptions:

  • The data read from the pipe is not removed from the pipe's buffer.
  • The function always returns immediately, even if there is no data in the pipe. The wait mode of a named pipe handle (blocking or nonblocking) has no effect on the function.
  • The function can return additional information about the contents of the pipe.

If the specified handle is a named pipe handle in byte-read mode, the function reads all available bytes up to the size specified in nBufferSize. For a named pipe handle in message-read mode, the function reads the next message in the pipe. If the message is larger than nBufferSize, the function returns TRUE after reading the specified number of bytes. In this situation, lpBytesLeftThisMessage will receive the number of bytes remaining in the message.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Pipes Overview, Pipe Functions, CreateFile, CreateNamedPipe, CreatePipe, ReadFile, WriteFile


SetNamedPipeHandleState

The SetNamedPipeHandleState function sets the read mode and the blocking mode of the specified named pipe. If the specified handle is to the client end of a named pipe and if the named pipe server process is on a remote computer, the function can also be used to control local buffering.

BOOL SetNamedPipeHandleState(
  HANDLE hNamedPipe,             // handle to named pipe
  LPDWORD lpMode,                // pointer to new pipe mode
  LPDWORD lpMaxCollectionCount,  // pointer to maximum collection count
  LPDWORD lpCollectDataTimeout   // pointer to time-out value
);

Parameters

hNamedPipe
Handle to the named pipe instance. This parameter can be a handle to the server end of the pipe, as returned by the CreateNamedPipe function, or to the client end of the pipe, as returned by the CreateFile function. The handle must have GENERIC_WRITE access to the named pipe.

Windows NT: This parameter can also be a handle to an anonymous pipe, as returned by the CreatePipe function.

lpMode
Pointer to a 32-bit variable that supplies the new mode. The mode is a combination of a read-mode flag and a wait-mode flag. This parameter can be NULL if the mode is not being set. One of the following read modes can be specified:
Mode | Description
PIPE_READMODE_BYTE | Data is read from the pipe as a stream of bytes. This mode is the default if no read-mode flag is specified.
PIPE_READMODE_MESSAGE | Data is read from the pipe as a stream of messages. The function fails if this flag is specified for a byte-type pipe.

One of the following wait modes can be specified:
Mode | Description
PIPE_WAIT | Blocking mode is enabled. This mode is the default if no wait-mode flag is specified. When a blocking mode pipe handle is specified in the ReadFile, WriteFile, or ConnectNamedPipe function, operations are not finished until there is data to read, all data is written, or a client is connected. Use of this mode can mean waiting indefinitely in some situations for a client process to perform an action.
PIPE_NOWAIT | Nonblocking mode is enabled. In this mode, ReadFile, WriteFile, and ConnectNamedPipe always return immediately. Note that nonblocking mode is supported for compatibility with Microsoft® LAN Manager version 2.0 and should not be used to achieve asynchronous input and output (I/O) with named pipes.

lpMaxCollectionCount
Pointer to a 32-bit variable that specifies the maximum number of bytes collected on the client computer before transmission to the server. This parameter must be NULL if the specified pipe handle is to the server end of a named pipe or if client and server processes are on the same machine. This parameter is ignored if the client process specifies the FILE_FLAG_WRITE_THROUGH flag in the CreateFile function when the handle was created. This parameter can be NULL if the collection count is not being set.
lpCollectDataTimeout
Pointer to a 32-bit variable that specifies the maximum time, in milliseconds, that can pass before a remote named pipe transfers information over the network. This parameter must be NULL if the specified pipe handle is to the server end of a named pipe or if client and server processes are on the same computer. This parameter is ignored if the client process specified the FILE_FLAG_WRITE_THROUGH flag in the CreateFile function when the handle was created. This parameter can be NULL if the collection count is not being set.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Pipes Overview, Pipe Functions, ConnectNamedPipe, CreateFile, CreateNamedPipe, GetNamedPipeHandleState, ReadFile, WriteFile


TransactNamedPipe

The TransactNamedPipe function combines into a single network operation the functions that write a message to and read a message from the specified named pipe.

BOOL TransactNamedPipe(
  HANDLE hNamedPipe,          // handle to named pipe
  LPVOID lpInBuffer,          // pointer to write buffer
  DWORD nInBufferSize,        // size of the write buffer, in bytes
  LPVOID lpOutBuffer,         // pointer to read buffer
  DWORD nOutBufferSize,       // size of read buffer, in bytes
  LPDWORD lpBytesRead,        // pointer to variable for bytes read
  LPOVERLAPPED lpOverlapped   // pointer to overlapped structure
);

Parameters

hNamedPipe
Handle to the named pipe returned by the CreateNamedPipe or CreateFile function.

Windows NT: This parameter can also be a handle to an anonymous pipe, as returned by the CreatePipe function.

lpInBuffer
Pointer to the buffer containing the data written to the pipe.
nInBufferSize
Specifies the size, in bytes, of the write buffer.
lpOutBuffer
Pointer to the buffer that receives the data read from the pipe.
nOutBufferSize
Specifies the size, in bytes, of the read buffer.
lpBytesRead
Pointer to the variable that receives the number of bytes read from the pipe.

If lpOverlapped is NULL, lpBytesRead cannot be NULL.

If lpOverlapped is not NULL, lpBytesRead can be NULL. If this is an overlapped read operation, you can get the number of bytes read by calling GetOverlappedResult. If hNamedPipe is associated with an I/O completion port, you can get the number of bytes read by calling GetQueuedCompletionStatus.

lpOverlapped
Pointer to an OVERLAPPED structure. This structure is required if hNamedPipe was opened with FILE_FLAG_OVERLAPPED.

If hNamedPipe was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hNamedPipe was created with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the opeation is complete.

If hNamePipe was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, TransactNamedPipe is executed as an overlapped operation. The OVERLAPPED structure should contain a manual-reset event object (which can be created by using the CreateEvent function). If the operation cannot be completed immediately, TransactNamedPipe returns FALSE and GetLastError returns ERROR_IO_PENDING. In this situation, the event object is set to the nonsignaled state before TransactNamedPipe returns, and it is set to the signaled state when the transaction has finished. For more information about overlapped operations, see Pipes.

If hNamedPipe was not opened with FILE_FLAG_OVERLAPPED, TransactNamedPipe does not return until the operation is complete.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

TransactNamedPipe fails if the server did not create the pipe as a message-type pipe or if the pipe handle is not in message-read mode. For example, if a client is running on the same machine as the server and uses the \\.\pipe\pipename format to open the pipe, the pipe is opened in byte mode by the named pipe file system (NPFS). If the client uses the form \\server\pipe\pipename, the redirector opens the pipe in message mode. A byte mode pipe handle can be changed to message-read mode with the SetNamedPipeHandleState function.

The function cannot be completed successfully until data is written into the buffer specified by the lpOutBuffer parameter. The lpOverlapped parameter is available to enable the calling thread to perform other tasks while the operation is executing in the background.

If the message to be read is longer than the buffer specified by the nOutBufferSize parameter, TransactNamedPipe returns FALSE and the GetLastError function returns ERROR_MORE_DATA. The remainder of the message can be read by a subsequent call to ReadFile, ReadFileEx, or PeekNamedPipe.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Pipes Overview, Pipe Functions, CreateEvent, CreateFile, CreateNamedPipe, GetOverlappedResult, GetQueuedCompletionStatus, PeekNamedPipe, ReadFile, ReadFileEx, SetNamedPipeHandleState, OVERLAPPED


WaitNamedPipe

The WaitNamedPipe function waits until either a time-out interval elapses or an instance of the specified named pipe is available to be connected to (that is, the pipe's server process has a pending ConnectNamedPipe operation on the pipe).

BOOL WaitNamedPipe(
  LPCTSTR lpNamedPipeName,  // pointer to name of pipe for which to wait
  DWORD nTimeOut            // time-out interval, in milliseconds
);

Parameters

lpNamedPipeName
Pointer to a null-terminated string that specifies the name of the named pipe. The string must include the name of the computer on which the server process is executing. A period may be used for the servername if the pipe is local. The following pipe name format is used:

\\servername\pipe\pipename

nTimeOut
Specifies the number of milliseconds that the function will wait for an instance of the named pipe to be available. One of the following values can be used instead of specifying a number of milliseconds:
Value | Meaning
NMPWAIT_USE_DEFAULT_WAIT | The time-out interval is the default value specified by the server process in the CreateNamedPipe function.
NMPWAIT_WAIT_FOREVER | The function does not return until an instance of the named pipe is available.

Return Values

If an instance of the pipe is available before the time-out interval elapses, the return value is nonzero.

If an instance of the pipe is not available before the time-out interval elapses, the return value is zero. To get extended error information, call GetLastError.

Remarks

If no instances of the specified named pipe exist, the WaitNamedPipe function returns immediately, regardless of the time-out value.

If the function succeeds, the process should use the CreateFile function to open a handle to the named pipe. A return value of TRUE indicates that there is at least one instance of the pipe available. A subsequent CreateFile call to the pipe can fail, because the instance was closed by the server or opened by another client.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Pipes Overview, Pipe Functions, CallNamedPipe, ConnectNamedPipe, CreateFile, CreateNamedPipe


Synchronization

The Microsoft® Win32® API provides a variety of ways to coordinate multiple threads of execution. The functions described in this overview provide mechanisms that threads can use to synchronize access to a resource.


About Synchronization

To synchronize access to a resource, use one of the synchronization objects in one of the wait functions. The state of a synchronization object is either signaled or nonsignaled. The wait functions allow a thread to block its own execution until a specified nonsignaled object is set to the signaled state.

The following are other synchronization mechanisms:

  • overlapped input and output
  • asynchronous procedure calls
  • critical section objects
  • interlocked variable access


Wait Functions

The Win32® API provides a set of wait functions to allow a thread to block its own execution. There are three types of wait functions:

  • single-object
  • multiple-object
  • alertable

The wait functions do not return until the specified criteria have been met. The type of wait function determines the set of criteria used. When a wait function is called, it checks whether the wait criteria have been met. If the criteria have not been met, the calling thread enters an efficient wait state, consuming very little processor time while waiting for the criteria to be met.

Single-object Wait Functions

The SignalObjectAndWait, WaitForSingleObject, and WaitForSingleObjectEx functions require a handle to one synchronization object. These functions return when one of the following occurs:

  • The specified object is in the signaled state.
  • The time-out interval elapses. The time-out interval can be set to INFINITE to specify that the wait will not time out.

The SignalObjectAndWait function enables the calling thread to atomically set the state of an object to signaled and wait for the state of another object to be set to signaled.

Multiple-object Wait Functions

The WaitForMultipleObjects, WaitForMultipleObjectsEx, MsgWaitForMultipleObjects, and MsgWaitForMultipleObjectsEx functions enable the calling thread to specify an array containing one or more synchronization object handles. These functions return when one of the following occurs:

  • The state of any one of the specified objects is set to signaled or the states of all objects have been set to signaled. You control whether one or all of the states will be used in the function call.
  • The time-out interval elapses. The time-out interval can be set to INFINITE to specify that the wait will not time out.

The MsgWaitForMultipleObjects and MsgWaitForMultipleObjectsEx function allow you to specify input event objects in the object handle array. This is done when you specify the type of input to wait for in the thread's input queue.

For example, a thread could use MsgWaitForMultipleObjects to block its execution until the state of a specified object has been set to signaled and there is mouse input available in the thread's input queue. The thread can use the GetMessage or PeekMessage function to retrieve the input.

When waiting for the states of all objects to be set to signaled, these multiple-object functions do not modify the states of the specified objects until the states of all objects have been set signaled. For example, the state of a mutex object can be signaled, but the calling thread does not get ownership until the states of the other objects specified in the array have also been set to signaled. In the meantime, some other thread may get ownership of the mutex object, thereby setting its state to nonsignaled.

Alertable Wait Functions

The MsgWaitForMultipleObjectsEx, SignalObjectAndWait, WaitForMultipleObjectsEx , and WaitForSingleObjectEx functions differ from the other wait functions in that they can optionally perform an alertable wait operation. In an alertable wait operation, the function can return when the specified conditions are met, but it can also return if the system queues an I/O completion routine or an APC for execution by the waiting thread. For more information about alertable wait operations and I/O completion routines, see Synchronization and Overlapped Input and Output. For more information about APCs, see Asynchronous Procedure Calls.

Wait Functions and Synchronization Objects

Before returning, a wait function can modify the states of some types of synchronization objects. Modification occurs only for the object or objects whose signaled state caused the function to return. A wait function can modify the states of synchronization objects as follows:

  • The count of a semaphore object decreases by one, and the state of the semaphore is set to nonsignaled if its count is zero.
  • The states of mutex, auto-reset event, and change-notification objects are set to nonsignaled.
  • The state of a synchronization timer is set to nonsignaled.
  • The states of manual-reset event, manual-reset timer, process, thread, and console input objects are not affected by a wait function.
Wait Functions and Creating Windows

You have to be careful when using the wait functions and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. If you have a thread that uses a wait function with no time-out interval, the system will deadlock. Two examples of code that indirectly creates windows are DDE and COM CoInitialize. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than the other wait functions.


Synchronization Objects

A synchronization object is an object whose handle can be specified in one of the wait functions to coordinate the execution of multiple threads. More than one process can have a handle to the same synchronization object, making interprocess synchronization possible.

The following object types are provided exclusively for synchronization.

Type | Description
Event | Notifies one or more waiting threads that an event has occurred. For more information, see Event Objects.
Mutex | Can be owned by only one thread at a time, enabling threads to coordinate mutually exclusive access to a shared resource. For more information, see Mutex Objects.
Semaphore | Maintains a count between zero and some maximum value, limiting the number of threads that are simultaneously accessing a shared resource. For more information, see Semaphore Objects.
Waitable timer | Notifies one or more waiting threads that a specified time has arrived. For more information, see Waitable Timer Objects.

Though available for other uses, the following objects can also be used for synchronization.

Object | Description
Change notification | Created by the FindFirstChangeNotification function, its state is set to signaled when a specified type of change occurs within a specified directory or directory tree. For more information, see File I/O.
Console input | Created when a console is created. The handle to console input is returned by the CreateFile function when CONIN$ is specified, or by the GetStdHandle function. Its state is set to signaled when there is unread input in the console's input buffer, and set to nonsignaled when the input buffer is empty. For more information about consoles, see Consoles and Character-Mode Support.
Job | Created by calling the CreateJobObject function. The state of a job object is set to signaled when all its processes are terminated because the specified end-of-job time limit has been exceeded. For more information about job objects, see Job Objects.
Process | Created by calling the CreateProcess function. Its state is set to nonsignaled while the process is running, and set to signaled when the process terminates. For more information about processes, see Processes and Threads.
Thread | Created when a new thread is created by calling the CreateProcess, CreateThread, or CreateRemoteThread function. Its state is set to nonsignaled while the thread is running, and set to signaled when the thread terminates. For more information about threads, see Processes and Threads.

In some circumstances, you can also use a file, named pipe, or communications device as a synchronization object; however, their use for this purpose is discouraged. Instead, use asynchronous I/O and wait on the event object set in the OVERLAPPED structure. It is safer to use the event object because of the confusion that can occur when multiple simultaneous overlapped operations are performed on the same file, named pipe, or communications device. In this situation, there is no way to know which operation caused the object's state to be signaled.

For additional information about I/O operations on files, named pipes, or communications, see Synchronization and Overlapped Input and Output.


Event Objects

An event object is a synchronization object whose state can be explicitly set to signaled by use of the SetEvent or PulseEvent function. Following are the two types of event object.

Object | Description
Manual-reset event | An event object whose state remains signaled until it is explicitly reset to nonsignaled by the ResetEvent function. While it is signaled, any number of waiting threads, or threads that subsequently specify the same event object in one of the wait functions, can be released.
Auto-reset event | An event object whose state remains signaled until a single waiting thread is released, at which time the system automatically sets the state to nonsignaled. If no threads are waiting, the event object's state remains signaled.

The event object is useful in sending a signal to a thread indicating that a particular event has occurred. For example, in overlapped input and output, the system sets a specified event object to the signaled state when the overlapped operation has been completed. A single thread can specify different event objects in several simultaneous overlapped operations, then use one of the multiple-object wait functions to wait for the state of any one of the event objects to be signaled.

A thread uses the CreateEvent function to create an event object. The creating thread specifies the initial state of the object and whether it is a manual-reset or auto-reset event object. The creating thread can also specify a name for the event object. Threads in other processes can open a handle to an existing event object by specifying its name in a call to the OpenEvent function. For additional information about names for mutex, event, semaphore, and timer objects, see Interprocess Synchronization.

A thread can use the PulseEvent function to set the state of an event object to signaled and then reset it to nonsignaled after releasing the appropriate number of waiting threads. For a manual-reset event object, all waiting threads are released. For an auto-reset event object, the function releases only a single waiting thread, even if multiple threads are waiting. If no threads are waiting, PulseEvent simply sets the state of the event object to nonsignaled and returns.


Mutex Objects

A mutex object is a synchronization object whose state is set to signaled when it is not owned by any thread, and nonsignaled when it is owned. Only one thread at a time can own a mutex object, whose name comes from the fact that it is useful in coordinating mutually exclusive access to a shared resource. For example, to prevent two threads from writing to shared memory at the same time, each thread waits for ownership of a mutex object before executing the code that accesses the memory. After writing to the shared memory, the thread releases the mutex object.

A thread uses the CreateMutex function to create a mutex object. The creating thread can request immediate ownership of the mutex object and can also specify a name for the mutex object. Threads in other processes can open a handle to an existing mutex object by specifying its name in a call to the OpenMutex function. For additional information about names for mutex, event, semaphore, and timer objects, see Interprocess Synchronization.

Any thread with a handle to a mutex object can use one of the wait functions to request ownership of the mutex object. If the mutex object is owned by another thread, the wait function blocks the requesting thread until the owning thread releases the mutex object using the ReleaseMutex function. The return value of the wait function indicates whether the function returned for some reason other than the state of the mutex being set to signaled.

Threads that are waiting for ownership of a mutex are placed in a first in, first out (FIFO) queue. Therefore, the first thread to wait on the mutex will be the first to receive ownership of the mutex, regardless of thread priority. However, kernel-mode APCs and events that suspend a thread will cause the system to remove the thread from the queue. When the thread resumes its wait for the mutex, it is placed at the end of the queue.

After a thread obtains ownership of a mutex, it can specify the same mutex in repeated calls to the wait-functions without blocking its execution. This prevents a thread from deadlocking itself while waiting for a mutex that it already owns. To release its ownership under such circumstances, the thread must call ReleaseMutex once for each time that the mutex satisfied the conditions of a wait function.

If a thread terminates without releasing its ownership of a mutex object, the mutex object is considered to be abandoned. A waiting thread can acquire ownership of an abandoned mutex object, but the wait function's return value indicates that the mutex object is abandoned. It is best to assume that an abandoned mutex object indicates that an error has occurred and that any shared resource being protected by the mutex object is in an undefined state. If the thread proceeds as though the mutex object had not been abandoned, its "abandoned" flag is cleared when the thread releases its ownership. This restores normal behavior if a handle to the mutex object is subsequently specified in a wait function.


Semaphore Objects

A semaphore object is a synchronization object that maintains a count between zero and a specified maximum value. The count is decremented each time a thread completes a wait for the semaphore object and incremented each time a thread releases the semaphore. When the count reaches zero, no more threads can successfully wait for the semaphore object state to become signaled. The state of a semaphore is set to signaled when its count is greater than zero, and nonsignaled when its count is zero.

The semaphore object is useful in controlling a shared resource that can support a limited number of users. It acts as a gate that limits the number of threads sharing the resource to a specified maximum number. For example, an application might place a limit on the number of windows that it creates. It uses a semaphore with a maximum count equal to the window limit, decrementing the count whenever a window is created and incrementing it whenever a window is closed. The application specifies the semaphore object in call to one of the wait functions before each window is created. When the count is zero — indicating that the window limit has been reached — the wait function blocks execution of the window-creation code.

A thread uses the CreateSemaphore function to create a semaphore object. The creating thread specifies the initial count and the maximum value of the count for the object. The initial count must be neither less than zero nor greater than the maximum value. The creating thread can also specify a name for the semaphore object. Threads in other processes can open a handle to an existing semaphore object by specifying its name in a call to the OpenSemaphore function. For additional information about names for mutex, event, semaphore, and timer objects, see Interprocess Synchronization.

Threads that are waiting for a semaphore are placed in a first in, first out (FIFO) queue. Therefore, the first thread to wait on the semaphore will be the first to successfully complete the wait, regardless of thread priority. However, kernel-mode APCs and events that suspend a thread will cause the system to remove the thread from the queue. When the thread resumes its wait for the semaphore, it is placed at the end of the queue.

Each time one of the wait functions returns because the state of a semaphore was set to signaled, the count of the semaphore is decreased by one. The ReleaseSemaphore function increases a semaphore's count by a specified amount. The count can never be less than zero or greater than the maximum value.

The initial count of a semaphore is typically set to the maximum value. The count is then decremented from that level as the protected resource is consumed. Alternatively, you can create a semaphore with an initial count of zero to block access to the protected resource while the application is being initialized. After initialization, you can use ReleaseSemaphore to increment the count to the maximum value.

A thread that owns a mutex object can wait repeatedly for the same mutex object to become signaled without its execution becoming blocked. A thread that waits repeatedly for the same semaphore object, however, decrements the semaphore's count each time a wait operation is completed; the thread is blocked when the count gets to zero. Similarly, only the thread that owns a mutex can successfully call the ReleaseMutex function, though any thread can use ReleaseSemaphore to increase the count of a semaphore object.

A thread can decrement a semaphore's count more than once by repeatedly specifying the same semaphore object in calls to any of the wait functions. However, calling one of the multiple-object wait functions with an array that contains multiple handles of the same semaphore does not result in multiple decrements.


Waitable Timer Objects

A "waitable" timer object is a synchronization object whose state is set to signaled when the specified due time arrives. There are two types of waitable timers that can be created: manual-reset and synchronization. A timer of either type can also be a periodic timer.

Object | Description
manual-reset timer | A timer whose state remains signaled until SetWaitableTimer is called to establish a new due time.
synchronization timer | A timer whose state remains signaled until a thread completes a wait operation on the timer object.
periodic timer | A timer that is reactivated each time the specified period expires, until the timer is reset or canceled. A periodic timer is either a periodic manual-reset timer or a periodic synchronization timer.

A thread uses the CreateWaitableTimer function to create a timer object. Specify TRUE for the bManualReset parameter to create a manual-reset timer and FALSE to create a synchronization timer. The creating thread can specify a name for the timer object in the lpTimerName parameter. Threads in other processes can open a handle to an existing timer by specifying its name in a call to the OpenWaitableTimer function. Any thread with a handle to a timer object can use one of the wait functions to wait for the timer state to be set to signaled.

  • The thread calls the SetWaitableTimer function to activate the timer. Note the use of the following parameters for SetWaitableTimer:
  • Use the lpDueTime parameter to specify the time at which the timer is to be set to the signaled state. When a manual-reset timer is set to the signaled state, it remains in this state until SetWaitableTimer establishes a new due time. When a synchronization timer is set to the signaled state, it remains in this state until a thread completes a wait operation on the timer object.
  • Use the lPeriod parameter of the SetWaitableTimer function to specify the timer period. If the period is not zero, the timer is a periodic timer; it is reactivated each time the period expires, until the timer is reset or canceled. If the period is zero, the timer is not a periodic timer; it is signaled once and then deactivated.

A thread can use the CancelWaitableTimer function to set the timer to the inactive state. To reset the timer, call SetWaitableTimer. When you are finished with the timer object, call CloseHandle to close the handle to the timer object.


Interprocess Synchronization

Multiple processes can have handles to the same event, mutex, semaphore, or timer object, so these objects can be used to accomplish interprocess synchronization. The process that creates an object can use the handle returned by the creation function (CreateEvent, CreateMutex, CreateSemaphore, or CreateWaitableTimer). Other processes can open a handle to the object by using its name, or through inheritance or duplication.


Object Names

Named objects provide an easy way for processes to share object handles. The name specified by the creating process is limited to MAX_PATH characters, and can include any character except the backslash path-separator character (\). Once a process has created a named event, mutex, semaphore, or timer object, other processes can use the name to call the appropriate function (OpenEvent, OpenMutex, OpenSemaphore, or OpenWaitableTimer) to open a handle to the object. Name comparison is case sensitive.

The names of event, mutex, semaphore, timer, and file-mapping objects share the same name space. If you specify a name that is in use by an object of another type when creating an object, the function succeeds, but GetLastError returns ERROR_ALREADY_EXISTS. Therefore, when creating named objects, use unique names and be sure to check function return values for duplicate-name errors.

For example, if the name specified in a call to the CreateMutex function matches the name of an existing mutex object, the function returns a handle to the existing object. In this case, the call to CreateMutex is equivalent to a call to the OpenMutex function. Having multiple processes use CreateMutex for the same mutex is therefore equivalent to having one process that calls CreateMutex while the other processes call OpenMutex, except that it eliminates the need to ensure that the creating process is started first. When using this technique for mutex objects, however, none of the calling processes should request immediate ownership of the mutex. If multiple processes do request immediate ownership, it can be difficult to predict which process actually gets the initial ownership.


Object Inheritance

When you create a process with the CreateProcess function, you can specify that the process inherit handles to mutex, event, semaphore, or timer objects using the SECURITY_ATTRIBUTES structure. The handle inherited by the process has the same access to the object as the original handle. The inherited handle appears in the handle table of the created process, but you must communicate the handle value to the created process. You can do this by specifying the value as a command-line argument when you call CreateProcess. The created process then uses the GetCommandLine function to retrieve the command-line string and convert the handle argument into a usable handle. For more information, see Inheritance.


Object Duplication

The DuplicateHandle function creates a duplicate handle that can be used by another specified process. This method of sharing object handles is more complex than using named objects or inheritance. It requires communication between the creating process and the process into which the handle is duplicated. The necessary information (the handle value and process identifier) can be communicated by any of the interprocess communication methods, such as named pipes or named shared memory.


Synchronization and Overlapped Input and Output

The Win32 API supports both synchronous and asynchronous (or overlapped) I/O operations on files, named pipes, and serial communications devices. The WriteFile, ReadFile, DeviceIoControl, WaitCommEvent, ConnectNamedPipe, and TransactNamedPipe functions can be performed either synchronously or asynchronously. The ReadFileEx and WriteFileEx functions can be performed asynchronously only.

When a function is executed synchronously, it does not return until the operation has been completed. This means that the execution of the calling thread can be blocked for an indefinite period while it waits for a time-consuming operation to finish. Functions called for overlapped operation can return immediately, even though the operation has not been completed. This enables a time-consuming I/O operation to be executed in the background while the calling thread is free to perform other tasks. For example, a single thread can perform simultaneous I/O operations on different handles, or even simultaneous read and write operations on the same handle.

To synchronize its execution with the completion of the overlapped operation, the calling thread uses the GetOverlappedResult function or one of the wait functions to determine when the overlapped operation has been completed. You can also use the HasOverlappedIoCompleted macro to poll for completion.

To cancel all pending asynchronous I/O operations, use the CancelIo function. This function only cancels operations issued by the calling thread for the specified file handle.

Overlapped operations require a file, named pipe, or communications device that was created with the FILE_FLAG_OVERLAPPED flag. To call a function to perform an overlapped operation, the calling thread must specify a pointer to an OVERLAPPED structure. If this pointer is NULL, the function return value may incorrectly indicate that the operation completed. The OVERLAPPED structure must contain a handle to a manual-reset — not an auto-reset — event object. The system sets the state of the event object to nonsignaled when a call to the I/O function returns before the operation has been completed. The system sets the state of the event object to signaled when the operation has been completed.

When a function is called to perform an overlapped operation, it is possible that the operation will be completed before the function returns. When this happens, the results are handled as if the operation had been performed synchronously. If the operation was not completed, however, the function's return value is FALSE, and the GetLastError function returns ERROR_IO_PENDING.

A thread can manage overlapped operations by either of two methods:

  • Use the GetOverlappedResult function to wait for the overlapped operation to be completed.
  • Specify a handle to the OVERLAPPED structure's manual-reset event object in one of the wait functions and then call GetOverlappedResult after the wait function returns. The GetOverlappedResult function returns the results of the completed overlapped operation, and for functions in which such information is appropriate, it reports the actual number of bytes that were transferred.

When performing multiple simultaneous overlapped operations, the calling thread must specify an OVERLAPPED structure with a different manual-reset event object for each operation. To wait for any one of the overlapped operations to be completed, the thread specifies all the manual-reset event handles as wait criteria in one of the multiple-object wait functions. The return value of the multiple-object wait function indicates which manual-reset event object was signaled, so the thread can determine which overlapped operation caused the wait operation to be completed.

If no event object is specified in the OVERLAPPED structure, the system signals the state of the file, named pipe, or communications device when the overlapped operation has been completed. Thus, you can specify these handles as synchronization objects in a wait function, though their use for this purpose can be difficult to manage. When performing simultaneous overlapped operations on the same file, named pipe, or communications device, there is no way to know which operation caused the object's state to be signaled. It is safer to use a separate event object for each overlapped operation.

For examples that illustrate the use of overlapped operations, completion routines, and the GetOverlappedResult function, see Using Pipes.


Asynchronous Procedure Calls

An asynchronous procedure call (APC) is a function that executes asynchronously in the context of a particular thread. When an APC is queued to a thread, the system issues a software interrupt. The next time the thread is scheduled, it will run the APC function. APCs made by the system are called "kernel-mode APCs." APCs made by an application are called "user-mode APCs." A thread must be in an alertable state to run a user-mode APC.

Each thread has its own APC queue. An application queues an APC to a thread by calling the QueueUserAPC function. The calling thread specifies the address of an APC function in the call to QueueUserAPC. The queuing of an APC is a request for the thread to call the APC function.

When a user-mode APC is queued, the thread to which it is queued is not directed to call the APC function unless it is in an alertable state. A thread enters an alertable state when it calls the SleepEx, SignalObjectAndWait, MsgWaitForMultipleObjectsEx, WaitForMultipleObjectsEx, or WaitForSingleObjectEx function. Note that you can not use WaitForSingleObjectEx to wait on the handle to the object for which the APC is queued. Otherwise, when the asynchronous operation is completed, the handle is set to the signaled state and the thread is no longer in an alertable wait state, so the APC function will not be executed. However, the APC is still queued, so the APC function will be executed if you call another alertable wait function.

Note that the ReadFileEx, SetWaitableTimer, and WriteFileEx functions are implemented using an APC as the completion notification callback mechanism.


Critical Section Objects

Critical section objects provide synchronization similar to that provided by mutex objects, except that critical section objects can be used only by the threads of a single process. Event, mutex, and semaphore objects can also be used in a single-process application, but critical section objects provide a slightly faster, more efficient mechanism for mutual-exclusion synchronization. Like a mutex object, a critical section object can be owned by only one thread at a time, which makes it useful for protecting a shared resource from simultaneous access. There is no guarantee about the order in which threads will obtain ownership of the critical section, however, the system will be fair to all threads.

The process is responsible for allocating the memory used by a critical section. Typically, this is done by simply declaring a variable of type CRITICAL_SECTION. Before the threads of the process can use it, initialize the critical section by using the InitializeCriticalSection or InitializeCriticalSectionAndSpinCount function.

A thread uses the EnterCriticalSection or TryEnterCriticalSection function to request ownership of a critical section. It uses the LeaveCriticalSection function to release ownership of a critical section. If the critical section object is currently owned by another thread, EnterCriticalSection waits indefinitely for ownership. In contrast, when a mutex object is used for mutual exclusion, the wait functions accept a specified time-out interval. The TryEnterCriticalSection function attempts to enter a critical section without blocking the calling thread.

Once a thread owns a critical section, it can make additional calls to EnterCriticalSection or TryEnterCriticalSection without blocking its execution. This prevents a thread from deadlocking itself while waiting for a critical section that it already owns. To release its ownership, the thread must call LeaveCriticalSection once for each time that it entered the critical section.

A thread uses the InitializeCriticalSectionAndSpinCount or SetCriticalSectionSpinCount function to specify a spin count for the critical section object. On single-processor systems, the spin count is ignored and the critical section spin count is set to 0. On multiprocessor systems, if the critical section is unavailable, the calling thread will spin dwSpinCount times before performing a wait operation on a semaphore associated with the critical section. If the critical section becomes free during the spin operation, the calling thread avoids the wait operation.

Any thread of the process can use the DeleteCriticalSection function to release the system resources that were allocated when the critical section object was initialized. After this function has been called, the critical section object can no longer be used for synchronization.

When a critical section object is owned, the only other threads affected are those waiting for ownership in a call to EnterCriticalSection. Threads that are not waiting are free to continue running.


Interlocked Variable Access

The functions InterlockedCompareExchange, InterlockedExchangeAdd, InterlockedDecrement, InterlockedExchange, and InterlockedIncrement provide a simple mechanism for synchronizing access to a variable that is shared by multiple threads. The threads of different processes can use this mechanism if the variable is in shared memory.

The InterlockedIncrement and InterlockedDecrement functions combine the operations of incrementing or decrementing the variable and checking the resulting value. This atomic operation is useful in a multitasking operating system, in which the system can interrupt one thread's execution to grant a slice of processor time to another thread. Without such synchronization, one thread could increment a variable but be interrupted by the system before it can check the resulting value of the variable. A second thread could then increment the same variable. When the first thread receives its next timeslice, it will check the value of the variable, which has now been incremented not once but twice. The interlocked variable-access functions protect against this kind of error.

The InterlockedExchange function atomically exchanges the values of the specified variables. The InterlockedExchangeAdd function combines two operations: adding two variables together and storing the result in one of the variables.

The InterlockedCompareExchange function combines two operations: comparing two values and storing a third value in one of the variables, based on the outcome of the comparison.


Using Synchronization

  • Using named objects
  • Waiting for multiple objects
  • Waiting in a message loop
  • Using mutex objects
  • Using semaphore objects
  • Using event objects
  • Using critical section objects


Using Named Objects

The following examples illustrate the use of object names by creating and opening named objects.

Mutex

The first process uses the CreateMutex function to create the mutex object. Note that the function succeeds even if there is an existing object with the same name.

// One process creates the mutex object.

HANDLE hMutex;
DWORD dwErr;

hMutex = CreateMutex(
    NULL,                  // no security descriptor
    FALSE,                 // mutex not owned
    "NameOfMutexObject");  // object name

if (hMutex == NULL)
    printf("CreateMutex error: %d\n", GetLastError() );
else
    if ( GetLastError() == ERROR_ALREADY_EXISTS )
        printf("CreateMutex opened existing mutex\n");
    else
        printf("CreateMutex created new mutex\n");

The second process uses the OpenMutex function to open a handle to the existing mutex. This function fails if a mutex object with the specified name does not exist. The access parameter requests full access to the mutex object, which is necessary for the handle to be used in any of the wait functions.

// Another process opens a handle to the existing mutex.

HANDLE hMutex;

hMutex = OpenMutex(
    MUTEX_ALL_ACCESS,      // request full access
    FALSE,                 // handle not inheritable
    "NameOfMutexObject");  // object name

if (hMutex == NULL)
    printf("OpenMutex error: %d\n", GetLastError() );
Semaphore

The following example uses the CreateSemaphore function to illustrate a named-object creation operation that fails if the object already exists.

HANDLE CreateNewSemaphore(LPSECURITY_ATTRIBUTES lpsa,
    LONG cInitial, LONG cMax, LPTSTR lpszName)
{
    HANDLE hSem;

// Create or open a named semaphore.

    hSem = CreateSemaphore(
        lpsa,         // security attributes
        cInitial,     // initial count
        cMax,         // maximum count
        lpszName);    // semaphore name

// Close handle, and return NULL if existing semaphore opened.

    if (hSem != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
    {
        CloseHandle(hSem);
        return NULL;
    }

// If new semaphore was created, return the handle.

    return hSem;
}


Waiting for Multiple Objects

The following example uses the CreateEvent function to create two event objects. It then uses the WaitForMultipleObjects function to wait for the state of one of the objects to be set to signaled.

HANDLE hEvents[2];
DWORD i, dwEvent;

// Create two event objects.

for (i = 0; i < 2; i++)
{
    hEvents[i] = CreateEvent(
        NULL,   // no security attributes
        FALSE,  // auto-reset event object
        FALSE,  // initial state is nonsignaled
        NULL);  // unnamed object
    if (hEvents[i] == NULL) {
        printf("CreateEvent error: %d\n", GetLastError() );
        ExitProcess(0);
    }
}

// The creating thread waits for other threads or processes
// to signal the event objects.

dwEvent = WaitForMultipleObjects(
    2,           // number of objects in array
    hEvents,     // array of objects
    FALSE,       // wait for any
    INFINITE);   // indefinite wait

// Return value indicates which event is signaled.

switch (dwEvent) {

    // hEvent[0] was signaled.
    case WAIT_OBJECT_0 + 0:
        // Perform tasks required by this event.
        break;

    // hEvent[1] was signaled.
    case WAIT_OBJECT_0 + 1:
        // Perform tasks required by this event.
        break;

    // Return value is invalid.
    default:
        printf("Wait error: %d\n", GetLastError());
        ExitProcess(0);
}


Waiting in a Message Loop

The following code fragment illustrates the use of the MsgWaitForMultipleObjects function in a message loop.

int MessageLoop (
    HANDLE* lphObjects,  // handles that need to be waited on
    int     cObjects     // number of handles to wait on
  )
{
    // The message loop lasts until we get a WM_QUIT message,
    // upon which we shall return from the function.
    while (TRUE)
    {
        // block-local variable
        DWORD result ;
        MSG msg ;

        // Read all of the messages in this next loop,
        // removing each message as we read it.
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            // If it's a quit message, we're out of here.
            if (msg.message == WM_QUIT)
                return 1;
            // Otherwise, dispatch the message.
            DispatchMessage(&msg);
        } // End of PeekMessage while loop.

        // Wait for any message sent or posted to this queue
        // or for one of the passed handles be set to signaled.
        result = MsgWaitForMultipleObjects(cObjects, lphObjects,
                 FALSE, INFINITE, QS_ALLINPUT);

        // The result tells us the type of event we have.
        if (result == (WAIT_OBJECT_0 + cObjects))
        {
            // New messages have arrived.
            // Continue to the top of the always while loop to
            // dispatch them and resume waiting.
            continue;
        }
        else
        {
            // One of the handles became signaled.
            DoStuff (result - WAIT_OBJECT_0) ;
        } // End of else clause.
    } // End of the always while loop.
} // End of function.


Using Mutex Objects

You can use a mutex object to protect a shared resource from simultaneous access by multiple threads or processes. Each thread must wait for ownership of the mutex before it can execute the code that accesses the shared resource. For example, if several threads share access to a database, the threads can use a mutex object to permit only one thread at a time to write to the database.

In the following example, a process uses the CreateMutex function to create a named mutex object or open a handle to an existing mutex object.

HANDLE hMutex;

// Create a mutex with no initial owner.

hMutex = CreateMutex(
    NULL,                       // no security attributes
    FALSE,                      // initially not owned
    "MutexToProtectDatabase");  // name of mutex

if (hMutex == NULL)
{
    // Check for error.
}

When a thread of this process writes to the database, as in the next example, it first requests ownership of the mutex. If it gets ownership, the thread writes to the database and then releases its ownership.

The example uses the try-finally structured exception-handling syntax to ensure that the thread properly releases the mutex object. The finally block of code is executed no matter how the try block terminates (unless the try block includes a call to the TerminateThread function). This prevents the mutex object from being abandoned inadvertently.

BOOL FunctionToWriteToDatabase(HANDLE hMutex)
{
    DWORD dwWaitResult;

    // Request ownership of mutex.

    dwWaitResult = WaitForSingleObject(
        hMutex,   // handle to mutex
        5000L);   // five-second time-out interval

    switch (dwWaitResult)
    {
        // The thread got mutex ownership.
        case WAIT_OBJECT_0:
            try {
                // Write to the database.
            }

            finally {
                // Release ownership of the mutex object.
                if (! ReleaseMutex(hMutex)) {
                    // Deal with error.
                }

            break;
        }

        // Cannot get mutex ownership due to time-out.
        case WAIT_TIMEOUT:
            return FALSE;

        // Got ownership of the abandoned mutex object.
        case WAIT_ABANDONED:
            return FALSE;
    }

    return TRUE;
}


Using Semaphore Objects

In the following example, a process uses a semaphore object to limit the number of windows it creates. First, it uses the CreateSemaphore function to create the semaphore and to specify initial and maximum counts.

HANDLE hSemaphore;
LONG cMax = 10;
LONG cPreviousCount;

// Create a semaphore with initial and max. counts of 10.

hSemaphore = CreateSemaphore(
    NULL,   // no security attributes
    cMax,   // initial count
    cMax,   // maximum count
    NULL);  // unnamed semaphore

if (hSemaphore == NULL)
{
    // Check for error.
}

Before any thread of the process creates a new window, it uses the WaitForSingleObject function to determine whether the semaphore's current count permits the creation of additional windows. The wait function's time-out parameter is set to zero, so the function returns immediately if the semaphore is nonsignaled.

DWORD dwWaitResult;

// Try to enter the semaphore gate.

dwWaitResult = WaitForSingleObject(
        hSemaphore,   // handle to semaphore
        0L);          // zero-second time-out interval

switch (dwWaitResult) {

    // The semaphore object was signaled.
    case WAIT_OBJECT_0:
        // OK to open another window.
        break;

    // Semaphore was nonsignaled, so a time-out occurred.
    case WAIT_TIMEOUT:
        // Cannot open another window.
        break;
}

When a thread closes a window, it uses the ReleaseSemaphore function to increment the semaphore's count.

// Increment the count of the semaphore.

if (!ReleaseSemaphore(
        hSemaphore,  // handle to semaphore
        1,           // increase count by one
        NULL) )      // not interested in previous count
{
    // Deal with the error.
}


Using Event Objects

Win32-based applications use event objects in a number of situations to notify a waiting thread of the occurrence of an event. For example, overlapped I/O operations on files, named pipes, and communications devices use an event object to signal their completion. For more information about the use of event objects in overlapped I/O operations, see Synchronization and Overlapped Input and Output.

In the following example, an application uses event objects to prevent several threads from reading from a shared memory buffer while a master thread is writing to that buffer. First, the master thread uses the CreateEvent function to create a manual-reset event object. The master thread sets the event object to nonsignaled when it is writing to the buffer and then resets the object to signaled when it has finished writing. Then it creates several reader threads and an auto-reset event object for each thread. Each reader thread sets its event object to signaled when it is not reading from the buffer.

#define NUMTHREADS 4

HANDLE hGlobalWriteEvent;

void CreateEventsAndThreads(void)
{
    HANDLE hReadEvents[NUMTHREADS], hThread;
    DWORD i, IDThread;

    // Create a manual-reset event object. The master thread sets
    // this to nonsignaled when it writes to the shared buffer.

    hGlobalWriteEvent = CreateEvent(
        NULL,         // no security attributes
        TRUE,         // manual-reset event
        TRUE,         // initial state is signaled
        "WriteEvent"  // object name
        );

    if (hGlobalWriteEvent == NULL) {
        // error exit
    }

    // Create multiple threads and an auto-reset event object
    // for each thread. Each thread sets its event object to
    // signaled when it is not reading from the shared buffer.

    for(i = 1; i <= NUMTHREADS; i++)
    {
        // Create the auto-reset event.
        hReadEvents[i] = CreateEvent(
            NULL,     // no security attributes
            FALSE,    // auto-reset event
            TRUE,     // initial state is signaled
            NULL);    // object not named

        if (hReadEvents[i] == NULL)
        {
            // Error exit.
        }

        hThread = CreateThread(NULL, 0,
            (LPTHREAD_START_ROUTINE) ThreadFunction,
            &hReadEvents[i],  // pass event handle
            0, &IDThread);
        if (hThread == NULL)
        {
            // Error exit.
        }
    }
}

Before the master thread writes to the shared buffer, it uses the ResetEvent function to set the state of hGlobalWriteEvent (an application-defined global variable) to nonsignaled. This blocks the reader threads from starting a read operation. The master then uses the WaitForMultipleObjects function to wait for all reader threads to finish any current read operations. When WaitForMultipleObjects returns, the master thread can safely write to the buffer. After it has finished, it sets hGlobalWriteEvent and all the reader-thread events to signaled, enabling the reader threads to resume their read operations.

VOID WriteToBuffer(VOID)
{
    DWORD dwWaitResult, i;

    // Reset hGlobalWriteEvent to nonsignaled, to block readers.

    if (! ResetEvent(hGlobalWriteEvent) )
    {
        // Error exit.
    }

    // Wait for all reading threads to finish reading.

    dwWaitResult = WaitForMultipleObjects(
        NUMTHREADS,   // number of handles in array
        hReadEvents,  // array of read-event handles
        TRUE,         // wait until all are signaled
        INFINITE);    // indefinite wait

    switch (dwWaitResult)
    {
        // All read-event objects were signaled.
        case WAIT_OBJECT_0:
            // Write to the shared buffer.
            break;

        // An error occurred.
        default:
            printf("Wait error: %d\n", GetLastError());
            ExitProcess(0);
    }

    // Set hGlobalWriteEvent to signaled.

    if (! SetEvent(hGlobalWriteEvent) )
    {
        // Error exit.
    }

    // Set all read events to signaled.
    for(i = 1; i <= NUMTHREADS; i++)
        if (! SetEvent(hReadEvents[i]) ) {
            // Error exit.
        }
}

Before starting a read operation, each reader thread uses WaitForMultipleObjects to wait for the application-defined global variable hGlobalWriteEvent and its own read event to be signaled. When WaitForMultipleObjects returns, the reader thread's auto-reset event has been reset to nonsignaled. This blocks the master thread from writing to the buffer until the reader thread uses the SetEvent function to set the event's state back to signaled.

VOID ThreadFunction(LPVOID lpParam)
{
    DWORD dwWaitResult, i;
    HANDLE hEvents[2];

    hEvents[0] = (HANDLE) *lpParam;  // thread's read event
    hEvents[1] = hGlobalWriteEvent;

    dwWaitResult = WaitForMultipleObjects(
        2,            // number of handles in array
        hEvents,      // array of event handles
        TRUE,         // wait till all are signaled
        INFINITE);    // indefinite wait

    switch (dwWaitResult)
    {

        // Both event objects were signaled.
        case WAIT_OBJECT_0:
            // Read from the shared buffer.
            break;

        // An error occurred.
        default:
            printf("Wait error: %d\n", GetLastError());
            ExitThread(0);
    }

    // Set the read event to signaled.

    if (! SetEvent(hEvents[0]) )
    {
        // Error exit.
    }
}


Using Critical Section Objects

The following example shows how a thread initializes, enters, and leaves a critical section. As with the mutex example (see Using Mutex Objects), this example uses the try-finally structured exception-handling syntax to ensure that the thread calls the LeaveCriticalSection function to release its ownership of the critical section object.

CRITICAL_SECTION GlobalCriticalSection;

// Initialize the critical section.
InitializeCriticalSection(&GlobalCriticalSection);

// Request ownership of the critical section.
try
{
    EnterCriticalSection(&GlobalCriticalSection);
    // Access the shared resource.
}
finally
{
    // Release ownership of the critical section.
    LeaveCriticalSection(&GlobalCriticalSection);
}


Synchronization Reference

The following elements are used with synchronization.

  • Synchronization Functions
  • Synchronization Structures
  • Synchronization Macros


Synchronization Functions

The following functions are used in synchronization.

CancelWaitableTimer
CreateEvent
CreateMutex
CreateSemaphore
CreateWaitableTimer
DeleteCriticalSection
EnterCriticalSection
GetOverlappedResult
InitializeCriticalSection
InitializeCriticalSectionAndSpinCount
InterlockedCompareExchange
InterlockedDecrement
InterlockedExchange
InterlockedExchangeAdd
InterlockedIncrement
LeaveCriticalSection
MsgWaitForMultipleObjects
MsgWaitForMultipleObjectsEx
OpenEvent
OpenMutex
OpenSemaphore
OpenWaitableTimer
PulseEvent
QueueUserAPC
ReleaseMutex
ReleaseSemaphore
ResetEvent
SetCriticalSectionSpinCount
SetEvent
SetWaitableTimer
SignalObjectAndWait
TimerAPCProc
TryEnterCriticalSection
WaitForMultipleObjects
WaitForMultipleObjectsEx
WaitForSingleObject
WaitForSingleObjectEx


CancelWaitableTimer

The CancelWaitableTimer function sets the specified "waitable" timer to the inactive state.

BOOL CancelWaitableTimer(
  HANDLE hTimer  // handle to a timer object
);

Parameters

hTimer
Handle to the timer object. The CreateWaitableTimer or OpenWaitableTimer function returns this handle.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The CancelWaitableTimer function does not change the signaled state of the timer. It stops the timer before it can be set to the signaled state and cancels outstanding APCs. Therefore, threads performing a wait operation on the timer remain waiting until they time out or the timer is reactivated and its state is set to signaled. If the timer is already in the signaled state, it remains in that state.

To reactivate the timer, call the SetWaitableTimer function.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, CreateWaitableTimer, OpenWaitableTimer, SetWaitableTimer


CreateEvent

The CreateEvent function creates a named or unnamed event object.

HANDLE CreateEvent(
  LPSECURITY_ATTRIBUTES lpEventAttributes,
                      // pointer to security attributes
  BOOL bManualReset,  // flag for manual-reset event
  BOOL bInitialState, // flag for initial state
  LPCTSTR lpName      // pointer to event-object name
);

Parameters

lpEventAttributes
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpEventAttributes is NULL, the handle cannot be inherited.

Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new event. If lpEventAttributes is NULL, the event gets a default security descriptor.

bManualReset
Specifies whether a manual-reset or auto-reset event object is created. If TRUE, then you must use the ResetEvent function to manually reset the state to nonsignaled. If FALSE, the system automatically resets the state to nonsignaled after a single waiting thread has been released.
bInitialState
Specifies the initial state of the event object. If TRUE, the initial state is signaled; otherwise, it is nonsignaled.
lpName
Pointer to a null-terminated string specifying the name of the event object. The name is limited to MAX_PATH characters and can contain any character except the backslash path-separator character (\). Name comparison is case sensitive.

If lpName matches the name of an existing named event object, this function requests EVENT_ALL_ACCESS access to the existing object. In this case, the bManualReset and bInitialState parameters are ignored because they have already been set by the creating process. If the lpEventAttributes parameter is not NULL, it determines whether the handle can be inherited, but its security-descriptor member is ignored.

If lpName is NULL, the event object is created without a name.

If lpName matches the name of an existing semaphore, mutex, waitable timer, job, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space.

Return Values

If the function succeeds, the return value is a handle to the event object. If the named event object existed before the function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The handle returned by CreateEvent has EVENT_ALL_ACCESS access to the new event object and can be used in any function that requires a handle to an event object.

Any thread of the calling process can specify the event-object handle in a call to one of the wait functions. The single-object wait functions return when the state of the specified object is signaled. The multiple-object wait functions can be instructed to return either when any one or when all of the specified objects are signaled. When a wait function returns, the waiting thread is released to continue its execution.

The initial state of the event object is specified by the bInitialState parameter. Use the SetEvent function to set the state of an event object to signaled. Use the ResetEvent function to reset the state of an event object to nonsignaled.

When the state of a manual-reset event object is signaled, it remains signaled until it is explicitly reset to nonsignaled by the ResetEvent function. Any number of waiting threads, or threads that subsequently begin wait operations for the specified event object, can be released while the object's state is signaled.

When the state of an auto-reset event object is signaled, it remains signaled until a single waiting thread is released; the system then automatically resets the state to nonsignaled. If no threads are waiting, the event object's state remains signaled.

Multiple processes can have handles of the same event object, enabling use of the object for interprocess synchronization. The following object-sharing mechanisms are available:

  • A child process created by the CreateProcess function can inherit a handle to an event object if the lpEventAttributes parameter of CreateEvent enabled inheritance.
  • A process can specify the event-object handle in a call to the DuplicateHandle function to create a duplicate handle that can be used by another process.
  • A process can specify the name of an event object in a call to the OpenEvent or CreateEvent function.

Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The event object is destroyed when its last handle has been closed.

Windows CE: Windows CE does not support security attributes, so the lpEventAttributes parameter must be set to NULL.

Windows CE does not support named events, so the lpname parameter must be set to NULL.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Synchronization Overview, Synchronization Functions, CloseHandle, CreateProcess, DuplicateHandle, OpenEvent, ResetEvent, SECURITY_ATTRIBUTES, SetEvent


CreateMutex

The CreateMutex function creates a named or unnamed mutex object.

HANDLE CreateMutex(
  LPSECURITY_ATTRIBUTES lpMutexAttributes,
                       // pointer to security attributes
  BOOL bInitialOwner,  // flag for initial ownership
  LPCTSTR lpName       // pointer to mutex-object name
);

Parameters

lpMutexAttributes
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpMutexAttributes is NULL, the handle cannot be inherited.

Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new mutex. If lpMutexAttributes is NULL, the mutex gets a default security descriptor.

bInitialOwner
Specifies the initial owner of the mutex object. If this value is TRUE and the caller created the mutex, the calling thread obtains ownership of the mutex object. Otherwise, the calling thread does not obtain ownership of the mutex. To determine if the caller created the mutex, see the Return Values section.
lpName
Pointer to a null-terminated string specifying the name of the mutex object. The name is limited to MAX_PATH characters and can contain any character except the backslash path-separator character (\). Name comparison is case sensitive.

If lpName matches the name of an existing named mutex object, this function requests MUTEX_ALL_ACCESS access to the existing object. In this case, the bInitialOwner parameter is ignored because it has already been set by the creating process. If the lpMutexAttributes parameter is not NULL, it determines whether the handle can be inherited, but its security-descriptor member is ignored.

If lpName is NULL, the mutex object is created without a name.

If lpName matches the name of an existing event, semaphore, waitable timer, job, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space.

Return Values

If the function succeeds, the return value is a handle to the mutex object. If the named mutex object existed before the function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS. Otherwise, the caller created the mutex.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The handle returned by CreateMutex has MUTEX_ALL_ACCESS access to the new mutex object and can be used in any function that requires a handle to a mutex object.

Any thread of the calling process can specify the mutex-object handle in a call to one of the wait functions. The single-object wait functions return when the state of the specified object is signaled. The multiple-object wait functions can be instructed to return either when any one or when all of the specified objects are signaled. When a wait function returns, the waiting thread is released to continue its execution.

The state of a mutex object is signaled when it is not owned by any thread. The creating thread can use the bInitialOwner flag to request immediate ownership of the mutex. Otherwise, a thread must use one of the wait functions to request ownership. When the mutex's state is signaled, one waiting thread is granted ownership, the mutex's state changes to nonsignaled, and the wait function returns. Only one thread can own a mutex at any given time. The owning thread uses the ReleaseMutex function to release its ownership.

The thread that owns a mutex can specify the same mutex in repeated wait function calls without blocking its execution. Typically, you would not wait repeatedly for the same mutex, but this mechanism prevents a thread from deadlocking itself while waiting for a mutex that it already owns. However, to release its ownership, the thread must call ReleaseMutex once for each time that the mutex satisfied a wait.

Two or more processes can call CreateMutex to create the same named mutex. The first process actually creates the mutex, and subsequent processes open a handle to the existing mutex. This enables multiple processes to get handles of the same mutex, while relieving the user of the responsibility of ensuring that the creating process is started first. When using this technique, you should set the bInitialOwner flag to FALSE; otherwise, it can be difficult to be certain which process has initial ownership.

Multiple processes can have handles of the same mutex object, enabling use of the object for interprocess synchronization. The following object-sharing mechanisms are available:

  • A child process created by the CreateProcess function can inherit a handle to a mutex object if the lpMutexAttributes parameter of CreateMutex enabled inheritance.
  • A process can specify the mutex-object handle in a call to the DuplicateHandle function to create a duplicate handle that can be used by another process.
  • A process can specify the name of a mutex object in a call to the OpenMutex or CreateMutex function.

Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The mutex object is destroyed when its last handle has been closed.

Windows CE: The lpMutexAttributes parameter must be set to NULL.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Synchronization Overview, Synchronization Functions, CloseHandle, CreateProcess, DuplicateHandle, OpenMutex, ReleaseMutex, SECURITY_ATTRIBUTES


CreateSemaphore

The CreateSemaphore function creates a named or unnamed semaphore object.

HANDLE CreateSemaphore(
  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
                       // pointer to security attributes
  LONG lInitialCount,  // initial count
  LONG lMaximumCount,  // maximum count
  LPCTSTR lpName       // pointer to semaphore-object name
);

Parameters

lpSemaphoreAttributes
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpSemaphoreAttributes is NULL, the handle cannot be inherited.

Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new semaphore. If lpSemaphoreAttributes is NULL, the semaphore gets a default security descriptor.

lInitialCount
Specifies an initial count for the semaphore object. This value must be greater than or equal to zero and less than or equal to lMaximumCount. The state of a semaphore is signaled when its count is greater than zero and nonsignaled when it is zero. The count is decreased by one whenever a wait function releases a thread that was waiting for the semaphore. The count is increased by a specified amount by calling the ReleaseSemaphore function.
lMaximumCount
Specifies the maximum count for the semaphore object. This value must be greater than zero.
lpName
Pointer to a null-terminated string specifying the name of the semaphore object. The name is limited to MAX_PATH characters, and can contain any character except the backslash path-separator character (\). Name comparison is case sensitive.

If lpName matches the name of an existing named semaphore object, this function requests SEMAPHORE_ALL_ACCESS access to the existing object. In this case, the lInitialCount and lMaximumCount parameters are ignored because they have already been set by the creating process. If the lpSemaphoreAttributes parameter is not NULL, it determines whether the handle can be inherited, but its security-descriptor member is ignored.

If lpName is NULL, the semaphore object is created without a name.

If lpName matches the name of an existing event, mutex, waitable timer, job, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space.

Return Values

If the function succeeds, the return value is a handle to the semaphore object. If the named semaphore object existed before the function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The handle returned by CreateSemaphore has SEMAPHORE_ALL_ACCESS access to the new semaphore object and can be used in any function that requires a handle to a semaphore object.

Any thread of the calling process can specify the semaphore-object handle in a call to one of the wait functions. The single-object wait functions return when the state of the specified object is signaled. The multiple-object wait functions can be instructed to return either when any one or when all of the specified objects are signaled. When a wait function returns, the waiting thread is released to continue its execution.

The state of a semaphore object is signaled when its count is greater than zero, and nonsignaled when its count is equal to zero. The lInitialCount parameter specifies the initial count. Each time a waiting thread is released because of the semaphore's signaled state, the count of the semaphore is decreased by one. Use the ReleaseSemaphore function to increment a semaphore's count by a specified amount. The count can never be less than zero or greater than the value specified in the lMaximumCount parameter.

Multiple processes can have handles of the same semaphore object, enabling use of the object for interprocess synchronization. The following object-sharing mechanisms are available:

  • A child process created by the CreateProcess function can inherit a handle to a semaphore object if the lpSemaphoreAttributes parameter of CreateSemaphore enabled inheritance.
  • A process can specify the semaphore-object handle in a call to the DuplicateHandle function to create a duplicate handle that can be used by another process.
  • A process can specify the name of a semaphore object in a call to the OpenSemaphore or CreateSemaphore function.

Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The semaphore object is destroyed when its last handle has been closed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Synchronization Overview, Synchronization Functions, CloseHandle, CreateProcess, DuplicateHandle, OpenSemaphore, ReleaseSemaphore, SECURITY_ATTRIBUTES


CreateWaitableTimer

The CreateWaitableTimer function creates a "waitable" timer object.

HANDLE CreateWaitableTimer(
  LPSECURITY_ATTRIBUTES lpTimerAttributes,
                      // pointer to security attributes
  BOOL bManualReset,  // flag for manual reset state
  LPCTSTR lpTimerName // pointer to timer object name
);

Parameters

lpTimerAttributes
Pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new timer object and determines whether child processes can inherit the returned handle. If lpTimerAttributes is NULL, the timer object gets a default security descriptor and the handle cannot be inherited.
bManualReset
Specifies the timer type. If bManualReset is TRUE, the timer is a manual-reset notification timer. Otherwise, the timer is a synchronization timer.
lpTimerName
Pointer to a null-terminated string specifying the name of the timer object. The name is limited to MAX_PATH characters and can contain any character except the backslash path-separator character (\). Name comparison is case sensitive.

If the string specified in the lpTimerName parameter matches the name of an existing named timer object, the call returns successfully and the GetLastError function returns ERROR_ALREADY_EXISTS.

If lpTimerName is NULL, the timer object is created without a name.

If lpTimerName matches the name of an existing event, semaphore, mutex, job, or file-mapping object, the function fails and GetLastError returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space.

Return Values

If the function succeeds, the return value is a handle to the timer object. If the named timer object exists before the function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The handle returned by CreateWaitableTimer is created with the TIMER_ALL_ACCESS access right. This handle can be used in any function that requires a handle to a timer object.

Any thread of the calling process can specify the timer object handle in a call to one of the wait functions.

Multiple processes can have handles to the same timer object, enabling use of the object for interprocess synchronization.

  • A process created by the CreateProcess function can inherit a handle to a timer object if the lpTimerAttributes parameter of CreateWaitableTimer enables inheritance.
  • A process can specify the timer object handle in a call to the DuplicateHandle function. The resulting handle can be used by another process.
  • A process can specify the name of a timer object in a call to the OpenWaitableTimer or CreateWaitableTimer function.

Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The timer object is destroyed when its last handle has been closed.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Synchronization Overview, Synchronization Functions, CancelWaitableTimer, CloseHandle, CreateProcess, DuplicateHandle, FILETIME, OpenWaitableTimer, SECURITY_ATTRIBUTES, SetWaitableTimer


DeleteCriticalSection

The DeleteCriticalSection function releases all resources used by an unowned critical section object.

VOID DeleteCriticalSection(
  LPCRITICAL_SECTION lpCriticalSection   // pointer to critical
                                         // section object
);

Parameters

lpCriticalSection
Pointer to the critical section object.

Return Values

This function does not return a value.

Remarks

Deleting a critical section object releases all system resources used by the object. Once deleted, the critical section object cannot be specified in the EnterCriticalSection, TryEnterCriticalSection, or LeaveCriticalSection function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, EnterCriticalSection, InitializeCriticalSection, LeaveCriticalSection TryEnterCriticalSection


EnterCriticalSection

The EnterCriticalSection function waits for ownership of the specified critical section object. The function returns when the calling thread is granted ownership.

VOID EnterCriticalSection(
  LPCRITICAL_SECTION lpCriticalSection   // pointer to critical
                                         // section object
);

Parameters

lpCriticalSection
Pointer to the critical section object.

Return Values

This function does not return a value.

Remarks

The threads of a single process can use a critical section object for mutual-exclusion synchronization. The process is responsible for allocating the memory used by a critical section object, which it can do by declaring a variable of type CRITICAL_SECTION. Before using a critical section, some thread of the process must call the InitializeCriticalSection or InitializeCriticalSectionAndSpinCount function to initialize the object.

To enable mutually exclusive access to a shared resource, each thread calls the EnterCriticalSection or TryEnterCriticalSection function to request ownership of the critical section before executing any section of code that accesses the protected resource. The difference is that TryEnterCriticalSection returns immediately, regardless of whether it obtained ownership of the critical section, while EnterCriticalSection blocks until the thread can take ownership of the critical section. When it has finished executing the protected code, the thread uses the LeaveCriticalSection function to relinquish ownership, enabling another thread to become owner and access the protected resource. The thread must call LeaveCriticalSection once for each time that it entered the critical section. The thread enters the critical section each time EnterCriticalSection and TryEnterCriticalSection succeed.

Once a thread has ownership of a critical section, it can make additional calls to EnterCriticalSection or TryEnterCriticalSection without blocking its execution. This prevents a thread from deadlocking itself while waiting for a critical section that it already owns.

Any thread of the process can use the DeleteCriticalSection function to release the system resources that were allocated when the critical section object was initialized. After this function has been called, the critical section object can no longer be used for synchronization.

If a thread terminates while it has ownership of a critical section, the state of the critical section is undefined.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, DeleteCriticalSection, InitializeCriticalSection, InitializeCriticalSectionAndSpinCount, LeaveCriticalSection TryEnterCriticalSection


GetOverlappedResult

The GetOverlappedResult function returns the results of an overlapped operation on the specified file, named pipe, or communications device.

Windows 95: This function works only on communications devices or on files opened by using the DeviceIoControl function.

BOOL GetOverlappedResult(
  HANDLE hFile,                       // handle to file, pipe, or comm device
  LPOVERLAPPED lpOverlapped,          // pointer to overlapped structure
  LPDWORD lpNumberOfBytesTransferred, // pointer to actual bytes count
  BOOL bWait                          // wait flag
);

Parameters

hFile
Handle to the file, named pipe, or communications device. This is the same handle that was specified when the overlapped operation was started by a call to the ReadFile, WriteFile, ConnectNamedPipe, TransactNamedPipe, DeviceIoControl, or WaitCommEvent function.
lpOverlapped
Pointer to an OVERLAPPED structure that was specified when the overlapped operation was started.
lpNumberOfBytesTransferred
Pointer to a 32-bit variable that receives the number of bytes that were actually transferred by a read or write operation. For a TransactNamedPipe operation, this is the number of bytes that were read from the pipe. For a DeviceIoControl operation, this is the number of bytes of output data returned by the device driver. For a ConnectNamedPipe or WaitCommEvent operation, this value is undefined.
bWait
Specifies whether the function should wait for the pending overlapped operation to be completed. If TRUE, the function does not return until the operation has been completed. If FALSE and the operation is still pending, the function returns FALSE and the GetLastError function returns ERROR_IO_INCOMPLETE.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The results reported by the GetOverlappedResult function are those of the specified handle's last overlapped operation to which the specified OVERLAPPED structure was provided, and for which the operation's results were pending. A pending operation is indicated when the function that started the operation returns FALSE, and the GetLastError function returns ERROR_IO_PENDING. When an I/O operation is pending, the function that started the operation resets the hEvent member of the OVERLAPPED structure to the nonsignaled state. Then when the pending operation has been completed, the system sets the event object to the signaled state.

Specify a manual-reset event object in the OVERLAPPED structure. If an auto-reset event object is used, the event handle must not be specified in any other wait operation in the interval between starting the overlapped operation and the call to GetOverlappedResult. For example, the event object is sometimes specified in one of the wait functions to wait for the operation's completion. When the wait function returns, the system sets an auto-reset event's state to nonsignaled, and a subsequent call to GetOverlappedResult with the bWait parameter set to TRUE causes the function to be blocked indefinitely.

If the bWait parameter is TRUE, GetOverlappedResult determines whether the pending operation has been completed by waiting for the event object to be in the signaled state.

Windows 95 and Windows 98: If bWait is TRUE, the hEvent member of the OVERLAPPED structure must not be NULL.

Windows NT: If the hEvent member of the OVERLAPPED structure is NULL, the system uses the state of the hFile handle to signal when the operation has been completed. Use of file, named pipe, or communications-device handles for this purpose is discouraged. It is safer to use an event object because of the confusion that can occur when multiple simultaneous overlapped operations are performed on the same file, named pipe, or communications device. In this situation, there is no way to know which operation caused the object's state to be signaled.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, CancelIo, ConnectNamedPipe, CreateEvent, DeviceIoControl, GetLastError, OVERLAPPED, ReadFile, TransactNamedPipe, WaitCommEvent, WriteFile


InitializeCriticalSection

The InitializeCriticalSection function initializes a critical section object.

VOID InitializeCriticalSection(
  LPCRITICAL_SECTION lpCriticalSection   // address of critical
                                         // section object
);

Parameters

lpCriticalSection
Pointer to the critical section object.

Return Values

This function does not return a value.

Remarks

The threads of a single process can use a critical section object for mutual-exclusion synchronization. There is no guarantee about the order in which threads will obtain ownership of the critical section, however, the system will be fair to all threads.

The process is responsible for allocating the memory used by a critical section object, which it can do by declaring a variable of type CRITICAL_SECTION. Before using a critical section, some thread of the process must call the InitializeCriticalSection or InitializeCriticalSectionAndSpinCount function to initialize the object.

Once a critical section object has been initialized, the threads of the process can specify the object in the EnterCriticalSection, TryEnterCriticalSection, or LeaveCriticalSection function to provide mutually exclusive access to a shared resource. For similar synchronization between the threads of different processes, use a mutex object.

A critical section object cannot be moved or copied. The process must also not modify the object, but must treat it as logically opaque. Use only the critical section functions provided by the Win32 API to manage critical section objects.

In low memory situations, InitializeCriticalSection can raise a STATUS_NO_MEMORY exception.

Windows CE: Use only the functions provided in the Windows CE application programming interface to manage critical section objects.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, CreateMutex, DeleteCriticalSection, EnterCriticalSection, InitializeCriticalSectionAndSpinCount, LeaveCriticalSection, TryEnterCriticalSection


InitializeCriticalSectionAndSpinCount

The InitializeCriticalSectionAndSpinCount function initializes a critical section object and sets the spin count for the critical section.

BOOL InitializeCriticalSectionAndSpinCount(
  LPCRITICAL_SECTION lpCriticalSection,
                      // pointer to critical section
  DWORD dwSpinCount   // spin count for critical section
);

Parameters

lpCriticalSection
Pointer to the critical section object.
dwSpinCount
Specifies the spin count for the critical section object. On single-processor systems, the spin count is ignored and the critical section spin count is set to 0. On multiprocessor systems, if the critical section is unavailable, the calling thread will spin dwSpinCount times before performing a wait operation on a semaphore associated with the critical section. If the critical section becomes free during the spin operation, the calling thread avoids the wait operation.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The threads of a single process can use a critical section object for mutual-exclusion synchronization. There is no guarantee about the order in which threads will obtain ownership of the critical section, however, the system will be fair to all threads.

The process is responsible for allocating the memory used by a critical section object, which it can do by declaring a variable of type CRITICAL_SECTION. Before using a critical section, some thread of the process must call the InitializeCriticalSection or InitializeCriticalSectionAndSpinCount function to initialize the object. You can subsequently modify the spin count by calling the SetCriticalSectionSpinCount function.

Once a critical section object has been initialized, the threads of the process can specify the object in the EnterCriticalSection, TryEnterCriticalSection, or LeaveCriticalSection function to provide mutually exclusive access to a shared resource. For similar synchronization between the threads of different processes, use a mutex object.

A critical section object cannot be moved or copied. The process must also not modify the object, but must treat it as logically opaque. Use only the critical section functions provided by the Win32 API to manage critical section objects.

The spin count is useful for critical sections of short duration that can experience high levels of contention. Consider a worst-case scenario, in which an application on an SMP system has two or three threads constantly allocating and releasing memory from the heap. The application serializes the heap with a critical section. In the worst-case scenario, contention for the critical section is constant, and each thread makes an expensive call to the WaitForSingleObject function. However, if the spin count is set properly, the calling thread will not immediately call WaitForSingleObject when contention occurs. Instead, the calling thread can acquire ownership of the critical section if it is released during the spin operation.

You can improve performance significantly by choosing a small spin count for a critical section of short duration. The heap manager uses a spin count of roughly 4000 for its per-heap critical sections. This gives great performance and scalability in almost all worst-case scenarios.

In low memory situations, InitializeCriticalSectionAndSpinCount can raise a STATUS_NO_MEMORY exception.

QuickInfo

Windows NT: Requires version 4.0 SP3 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, InitializeCriticalSection, SetCriticalSectionSpinCount, WaitForSingleObject


InterlockedCompareExchange

The InterlockedCompareExchange function performs an atomic comparison of the values specified in the Destination and Comperand parameters and exchange of the values, based on the outcome of the comparison. The function prevents more than one thread from using the same variable simultaneously.

PVOID InterlockedCompareExchange(
  PVOID *Destination,  // pointer to the destination pointer
  PVOID Exchange,      // the exchange value
  PVOID Comperand      // the value to compare
);

Parameters

Destination
Specifies the address of the destination value. This is a 32-bit value. The sign is ignored.
Exchange
Specifies the exchange value. This is a 32-bit value. The sign is ignored.
Comperand
Specifies the value to compare to Destination. This is a 32-bit value. The sign is ignored.

Return Values

The return value is the initial value of the destination.

Remarks

The functions InterlockedCompareExchange, InterlockedDecrement, InterlockedExchange, InterlockedExchangeAdd, and InterlockedIncrement provide a simple mechanism for synchronizing access to a variable that is shared by multiple threads. The threads of different processes can use this mechanism if the variable is in shared memory.

The InterlockedCompareExchange function performs an atomic comparison of the Destination value with the Comperand value. If the Destination value is equal to the Comperand value, the Exchange value is stored in the address specified by Destination. Otherwise, no operation is performed.

The variables for InterlockedCompareExchange must be aligned on a 32-bit boundary; otherwise, this function will fail on multiprocessor x86 systems.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, InterlockedDecrement, InterlockedExchange, InterlockedExchangeAdd, InterlockedIncrement


InterlockedDecrement

The InterlockedDecrement function both decrements (decreases by one) the value of the specified 32-bit variable and checks the resulting value. The function prevents more than one thread from using the same variable simultaneously.

LONG InterlockedDecrement(
  LPLONG lpAddend   // address of the variable to decrement
);

Parameters

lpAddend
Pointer to the 32-bit variable to decrement.

Return Values

Windows 98, Windows NT 4.0 and later: The return value is the resulting decremented value.

Windows 95, Windows NT 3.51 and earlier: If the result of the operation is zero, the return value is zero. If the result of the operation is less than zero, the return value is negative, but it is not necessarily equal to the result. If the result of the operation is greater than zero, the return value is positive, but it is not necessarily equal to the result.

Remarks

The functions InterlockedDecrement, InterlockedCompareExchange, InterlockedExchange, InterlockedExchangeAdd, and InterlockedIncrement provide a simple mechanism for synchronizing access to a variable that is shared by multiple threads. The threads of different processes can use this mechanism if the variable is in shared memory.

The variable pointed to by the lpAddend parameter must be aligned on a 32-bit boundary; otherwise, this function will fail on multiprocessor x86 systems.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, InterlockedCompareExchange, InterlockedExchange, InterlockedExchangeAdd, InterlockedIncrement


InterlockedExchange

The InterlockedExchange function atomically exchanges a pair of 32-bit values. The function prevents more than one thread from using the same variable simultaneously.

LONG InterlockedExchange(
  LPLONG Target,
               // pointer to the 32-bit value to exchange
  LONG Value   // new value for the LONG value pointed to by Target
);

Parameters

Target
Pointer to the LONG value to exchange. The function sets this LONG value to Value, and returns its prior value.
Value
Specifies a new value for the LONG value pointed to by Target.

Return Values

The function returns the prior value of the LONG value pointed to by Target.

Remarks

The functions InterlockedExchange, InterlockedCompareExchange, InterlockedDecrement, InterlockedExchangeAdd, and InterlockedIncrement provide a simple mechanism for synchronizing access to a variable that is shared by multiple threads. The threads of different processes can use this mechanism if the variable is in shared memory.

The variable pointed to by the Target parameter must be aligned on a 32-bit boundary; otherwise, this function will fail on multiprocessor x86 systems.

QuickInfo

Windows NT: Requires version 3.5 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, InterlockedCompareExchange, InterlockedDecrement, InterlockedExchangeAdd, InterlockedIncrement


InterlockedExchangeAdd

The InterlockExchangeAdd function performs an atomic addition of an increment value to an addend variable. The function prevents more than one thread from using the same variable simultaneously.

LONG InterlockedExchangeAdd (
  PLONG Addend,  // pointer to the addend
  LONG Increment // increment value
);

Parameters

Addend
Pointer to the number that will have the Increment number added to it.
Increment
Specifies the number to be added to the variable pointed to by the Addend parameter.

Return Values

The return value is the initial value of the variable pointed to by the Addend parameter.

Remarks

The functions InterlockedExchangeAdd, InterlockedCompareExchange, InterlockedDecrement, InterlockedExchange, and InterlockedIncrement provide a simple mechanism for synchronizing access to a variable that is shared by multiple threads. The threads of different processes can use this mechanism if the variable is in shared memory.

The InterlockedExchangeAdd function performs an atomic addition of the Increment value to the value pointed to by Addend. The result is stored in the address specified by Addend. The initial value of the variable pointed to by Addend is returned as the function value.

The variables for InterlockedExchangeAdd must be aligned on a 32-bit boundary; otherwise, this function will fail on multiprocessor x86 systems.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, InterlockedCompareExchange, InterlockedDecrement, InterlockedExchange, InterlockedIncrement


InterlockedIncrement

The InterlockedIncrement function both increments (increases by one) the value of the specified 32-bit variable and checks the resulting value. The function prevents more than one thread from using the same variable simultaneously.

LONG InterlockedIncrement(
  LPLONG lpAddend   // pointer to the variable to increment
);

Parameters

lpAddend
Pointer to the LONG variable to increment.

Return Values

Windows 98, Windows NT 4.0 and later: The return value is the resulting incremented value.

Windows 95, Windows NT 3.51 and earlier: If the result of the operation is zero, the return value is zero. If the result of the operation is less than zero, the return value is negative, but it is not necessarily equal to the result. If the result of the operation is greater than zero, the return value is positive, but it is not necessarily equal to the result.

Remarks

The functions InterlockedIncrement, InterlockedCompareExchange, InterlockedDecrement, InterlockedExchange, and InterlockedExchangeAdd provide a simple mechanism for synchronizing access to a variable that is shared by multiple threads. The threads of different processes can use this mechanism if the variable is in shared memory.

The variable pointed to by the lpAddend parameter must be aligned on a 32-bit boundary; otherwise, this function will fail on multiprocessor x86 systems.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, InterlockedCompareExchange, InterlockedDecrement, InterlockedExchange, InterlockedExchangeAdd


LeaveCriticalSection

The LeaveCriticalSection function releases ownership of the specified critical section object.

VOID LeaveCriticalSection(
  LPCRITICAL_SECTION lpCriticalSection   // address of critical
                                         // section object
);

Parameters

lpCriticalSection
Pointer to the critical section object.

Return Values

This function does not return a value.

Remarks

The threads of a single process can use a critical-section object for mutual-exclusion synchronization. The process is responsible for allocating the memory used by a critical-section object, which it can do by declaring a variable of type CRITICAL_SECTION. Before using a critical section, some thread of the process must call the InitializeCriticalSection or InitializeCriticalSectionAndSpinCount function to initialize the object.

A thread uses the EnterCriticalSection or TryEnterCriticalSection function to acquire ownership of a critical section object. To release its ownership, the thread must call LeaveCriticalSection once for each time that it entered the critical section.

If a thread calls LeaveCriticalSection when it does not have ownership of the specified critical section object, an error occurs that may cause another thread using EnterCriticalSection to wait indefinitely.

Any thread of the process can use the DeleteCriticalSection function to release the system resources that were allocated when the critical section object was initialized. After this function has been called, the critical section object can no longer be used for synchronization.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, DeleteCriticalSection, EnterCriticalSection, InitializeCriticalSection, InitializeCriticalSectionAndSpinCount, TryEnterCriticalSection


MsgWaitForMultipleObjects

The MsgWaitForMultipleObjects function returns when one of the following occurs:

  • Either any one or all of the specified objects are in the signaled state. The objects can include input event objects, which you specify using the dwWakeMask parameter.
  • The time-out interval elapses.

Note that MsgWaitForMultipleObjects does not return if there is unread input of the specified type in the message queue after the thread has called a function to check the queue. This is because functions such as PeekMessage, GetMessage, GetQueueStatus, and WaitMessage check the queue and then change the state information for the queue so that the input is no longer considered new. A subsequent call to MsgWaitForMultipleObjects will not return until new input of the specified type arrives. The existing unread input (received prior to the last time the thread checked the queue) is ignored.

DWORD MsgWaitForMultipleObjects(
  DWORD nCount,          // number of handles in the handle array
  LPHANDLE pHandles,     // pointer to the object-handle array
  BOOL fWaitAll,         // wait for all or wait for one
  DWORD dwMilliseconds,  // time-out interval in milliseconds
  DWORD dwWakeMask       // type of input events to wait for
);

Parameters

nCount
Specifies the number of object handles in the array pointed to by pHandles. The maximum number of object handles is MAXIMUM_WAIT_OBJECTS minus one.
pHandles
Pointer to an array of object handles. For a list of the object types whose handles can be specified, see the following Remarks section. The array can contain handles of objects of different types.

Windows NT: The handles must have SYNCHRONIZE access. For more information, see Standard Access Rights.

Windows 95: No handle may be a duplicate of another handle created using DuplicateHandle.

fWaitAll
Specifies the wait type. If TRUE, the function returns when the states of all objects in the pHandles array, including input events, have been set to signaled. If FALSE, the function returns when the state of any one of the objects is set to signaled. In the latter case, the return value indicates the object whose state caused the function to return.
dwMilliseconds
Specifies the time-out interval, in milliseconds. The function returns if the interval elapses, even if the criteria specified by the fWaitAll or dwWakeMask parameter have not been met. If dwMilliseconds is zero, the function tests the states of the specified objects and returns immediately. If dwMilliseconds is INFINITE, the function's time-out interval never elapses.
dwWakeMask
Specifies input types for which an input event object handle will be added to the array of object handles. This parameter can be any combination of the following values:
Value | Meaning
QS_ALLEVENTS | An input, WM_TIMER, WM_PAINT, WM_HOTKEY, or posted message is in the queue.
QS_ALLINPUT | Any message is in the queue.
QS_ALLPOSTMESSAGE | A posted message (other than those listed here) is in the queue.
QS_HOTKEY | A WM_HOTKEY message is in the queue.
QS_INPUT | An input message is in the queue.
QS_KEY | A WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, or WM_SYSKEYDOWN message is in the queue.
QS_MOUSE | A WM_MOUSEMOVE message or mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on).
QS_MOUSEBUTTON | A mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on).
QS_MOUSEMOVE | A WM_MOUSEMOVE message is in the queue.
QS_PAINT | A WM_PAINT message is in the queue.
QS_POSTMESSAGE | A posted message (other than those just listed) is in the queue.
QS_SENDMESSAGE | A message sent by another thread or application is in the queue.
QS_TIMER | A WM_TIMER message is in the queue.

Return Values

If the function succeeds, the return value indicates the event that caused the function to return. The successful return value is one of the following:

Value | Meaning
WAIT_OBJECT_0 to
(WAIT_OBJECT_0 + nCount – 1) 		If fWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled. If fWaitAll is FALSE, the return value minus WAIT_OBJECT_0 indicates the pHandles array index of the object that satisfied the wait.
WAIT_OBJECT_0 + nCount New input of the type specified in the dwWakeMask parameter is available in the thread's input queue. Functions such as PeekMessage, GetMessage, and WaitMessage mark messages in the queue as old messages. Therefore, after you call one of these functions, a subsequent call to MsgWaitForMultipleObjects will not return until new input of the specified type arrives.

This value is also returned upon the occurrence of a system event that requires the thread's action, such as foreground activation. Therefore, MsgWaitForMultipleObjects can return even though no appropriate input is available and even if dwWaitMask is set to 0. If this occurs, call PeekMessage or GetMessage to process the system event before trying the call to MsgWaitForMultipleObjects again.

WAIT_ABANDONED_0 to
(WAIT_ABANDONED_0 + nCount – 1) 		If fWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled and at least one of the objects is an abandoned mutex object. If fWaitAll is FALSE, the return value minus WAIT_ABANDONED_0 indicates the pHandles array index of an abandoned mutex object that satisfied the wait.
WAIT_TIMEOUT | The time-out interval elapsed and the conditions specified by the fWaitAll and dwWakeMask parameters were not satisfied.

If the function fails, the return valueis 0xFFFFFFFF. To get extended error information, call GetLastError.

Remarks

The MsgWaitForMultipleObjects function determines whether the wait criteria have been met. If the criteria have not been met, the calling thread enters an efficient wait state, using very little processor time while waiting for the conditions of the wait criteria to be met.

When fWaitAll is TRUE, the function does not modify the states of the specified objects until the states of all objects have been set to signaled. For example, a mutex can be signaled, but the thread does not get ownership until the states of the other objects have also been set to signaled. In the meantime, some other thread may get ownership of the mutex, thereby setting its state to nonsignaled.

When fWaitAll is TRUE, the function's wait is completed only when the states of all objects have been set to signaled, including the input events specified by dwWaskMask. Therefore, setting fWaitAll to TRUE prevents input from being processed until the state of all objects in the pHandles array have been set to signaled. For this reason, if you set fWaitAll to TRUE, you should use a short timeout value in dwMilliseconds. If you have a thread that creates windows waiting for all objects in the pHandles array, including input events specified by dwWakeMask, with no timeout interval, the system will deadlock. This is because threads that create windows must process messages. DDE sends message to all windows in the system. Therefore, if a thread creates windows, do not set the fWaitAll parameter to TRUE in calls to MsgWaitForMultipleObjects made from that thread.

Before returning, a wait function modifies the state of some types of synchronization objects. Modification occurs only for the object or objects whose signaled state caused the function to return. For example, the count of a semaphore object is decreased by one. When fWaitAll is FALSE, and multiple objects are in the signaled state, the function chooses one of the objects to satisfy the wait; the states of the objects not selected are unaffected.

The MsgWaitForMultipleObjects function can specify handles of any of the following object types in the pHandles array:

  • Change notification
  • Console input
  • Event
  • Job
  • Mutex
  • Process
  • Semaphore
  • Thread
  • Waitable timer

For more information, see Synchronization Objects.

The QS_ALLPOSTMESSAGE and QS_POSTMESSAGE flags differ in when they are cleared. QS_POSTMESSAGE is cleared when you call GetMessage or PeekMessage, whether or not you are filtering messages. QS_ALLPOSTMESSAGE is cleared when you call GetMessage or PeekMessage without filtering messages (wMsgFilterMin and wMsgFilterMax are 0). This can be useful when you call PeekMessage multiple times to get messages in different ranges.

Windows CE: The MsgWaitForMultipleObjects function is implemented as a macro that calls MsgWaitForMultipleObjectsEx, passing 0 in the dwFlags parameter.

Windows CE does not support the QS_HOTKEY value for the dwWakeMask parameter.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Synchronization Overview, Synchronization Functions, CancelWaitableTimer, CreateEvent, CreateFile, CreateMutex, CreateProcess, CreateRemoteThread, CreateSemaphore, CreateThread, FindFirstChangeNotification, GetQueueStatus, GetStdHandle, MsgWaitForMultipleObjectsEx OpenEvent, OpenMutex, OpenProcess, OpenSemaphore, OpenWaitableTimer, PulseEvent, ResetEvent, SetEvent


MsgWaitForMultipleObjectsEx

The MsgWaitForMultipleObjectsEx function returns when one of the following occurs:

  • Either any one or all of the specified objects are in the signaled state. The array of objects can include input event objects, which you specify using the dwWakeMask parameter.
  • An I/O completion routine or asynchronous procedure call (APC) is queued to the thread.
  • The time-out interval elapses.

Note MsgWaitForMultipleObjectsEx does not return if there is unread input of the specified type in the message queue after the thread has called a function to check the queue, unless you use the MWMO_INPUTAVAILABLE flag. This is because functions such as PeekMessage, GetMessage, GetQueueStatus, and WaitMessage check the queue and then change the state information for the queue so that the input is no longer considered new. A subsequent call to MsgWaitForMultipleObjectsEx will not return until new input of the specified type arrives, unless you use the MWMO_INPUTAVAILABLE flag. If this flag is not used, the existing unread input (received prior to the last time the thread checked the queue) is ignored.

DWORD MsgWaitForMultipleObjectsEx(
  DWORD nCount,          // number of handles in handle array
  LPHANDLE pHandles,     // pointer to an object-handle array
  DWORD dwMilliseconds,  // time-out interval in milliseconds
  DWORD dwWakeMask,      // type of input events to wait for
  DWORD dwFlags          // wait flags
);

Parameters

nCount
Specifies the number of object handles in the array pointed to by pHandles. The maximum number of object handles is MAXIMUM_WAIT_OBJECTS minus one.
pHandles
Pointer to an array of object handles. For a list of the object types whose handles you can specify, see the Remarks section later in this topic. The array can contain handles to multiple types of objects.

Windows NT: The handles must have SYNCHRONIZE access. For more information, see Standard Access Rights.

dwMilliseconds
Specifies the time-out interval, in milliseconds. The function returns if the interval elapses, even if the conditions specified by the dwWakeMask and dwFlags parameters are not met. If dwMilliseconds is zero, the function tests the states of the specified objects and returns immediately. If dwMilliseconds is INFINITE, the function's time-out interval never elapses.
dwWakeMask
Specifies input types for which an input event object handle will be added to the array of object handles. This parameter can be any combination of the following values:
Value | Meaning
QS_ALLEVENTS | An input, WM_TIMER, WM_PAINT, WM_HOTKEY, or posted message is in the queue.
QS_ALLINPUT | Any message is in the queue.
QS_ALLPOSTMESSAGE | A posted message (other than those listed here) is in the queue.
QS_HOTKEY | A WM_HOTKEY message is in the queue.
QS_INPUT | An input message is in the queue.
QS_KEY | A WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, or WM_SYSKEYDOWN message is in the queue.
QS_MOUSE | A WM_MOUSEMOVE message or mouse-button message ( WM_LBUTTONUP, WM_RBUTTONDOWN, and so on) is in the queue.
QS_MOUSEBUTTON | A mouse-button message ( WM_LBUTTONUP, WM_RBUTTONDOWN, and so on) is in the queue.
QS_MOUSEMOVE | A WM_MOUSEMOVE message is in the queue.
QS_PAINT | A WM_PAINT message is in the queue.
QS_POSTMESSAGE | A posted message (other than those just listed) is in the queue.
QS_SENDMESSAGE | A message sent by another thread or application is in the queue.
QS_TIMER | A WM_TIMER message is in the queue.

dwFlags
Specifies the wait type. This parameter can be any combination of the following values:
Value | Meaning
0 | The function returns when any one of the objects is signaled. The return value indicates the object whose state caused the function to return.
MWMO_WAITALL | The function returns when all objects in the pHandles array are signaled at the same time.
MWMO_ALERTABLE | The function also returns if an APC has been queued to the thread with QueueUserAPC.
MWMO_INPUTAVAILABLE | Windows 98, Windows NT 5.0 and later: The function returns if input exists for the queue, even if the input has been seen (but not removed) using a call to another function, such as PeekMessage.

Return Values

If the function succeeds, the return value indicates the event that caused the function to return. The successful return value is one of the following:

Value | Meaning
WAIT_OBJECT_0 to
(WAIT_OBJECT_0 + nCount - 1) 		If the MWMO_WAITALL flag is used, the return value indicates that the state of all specified objects is signaled. Otherwise, the return value minus WAIT_OBJECT_0 indicates the pHandles array index of the object that caused the function to return.
WAIT_OBJECT_0 + nCount New input of the type specified in the dwWakeMask parameter is available in the thread's input queue. Functions such as PeekMessage, GetMessage, GetQueueStatus, and WaitMessage mark messages in the queue as old messages. Therefore, after you call one of these functions, a subsequent call to MsgWaitForMultipleObjectsEx will not return until new input of the specified type arrives.

This value is also returned upon the occurrence of a system event that requires the thread's action, such as foreground activation. Therefore, MsgWaitForMultipleObjectsEx can return even though no appropriate input is available and even if dwWaitMask is set to 0. If this occurs, call PeekMessage or GetMessage to process the system event before trying the call to MsgWaitForMultipleObjectsEx again.

WAIT_ABANDONED_0 to
(WAIT_ABANDONED_0 + nCount - 1) 		If the MWMO_WAITALL flag is used, the return value indicates that the state of all specified objects is signaled and at least one of the objects is an abandoned mutex object. Otherwise, the return value minus WAIT_ABANDONED_0 indicates the pHandles array index of an abandoned mutex object that caused the function to return.
WAIT_IO_COMPLETION | The wait was ended by a user-mode asynchronous procedure call (APC) queued to the thread.
WAIT_TIMEOUT | The time-out interval elapsed, but the conditions specified by the dwFlags and dwWakeMask parameters were not met.

If the function fails, the return value is 0xFFFFFFFF. To get extended error information, call GetLastError.

Remarks

The MsgWaitForMultipleObjectsEx function determines whether the conditions specified by dwWakeMask and dwFlags have been met. If the conditions have not been met, the calling thread enters an efficient wait state. The thread uses very little processor time while waiting for one of the conditions to be met or for the time-out interval to elapse.

Before returning, a wait function modifies the state of some types of synchronization objects. Modification occurs only for the object or objects whose signaled state caused the function to return. For example, the system decreases the count of a semaphore object by one. When dwFlags is zero, and multiple objects are in the signaled state, the function chooses one of the objects to satisfy the wait; the states of the objects not selected are unaffected.

The MsgWaitForMultipleObjectsEx function can specify handles of any of the following object types in the pHandles array:

  • Change notification
  • Console input
  • Event
  • Job
  • Mutex
  • Process
  • Semaphore
  • Thread
  • Waitable timer

For more information, see Synchronization Objects.

The QS_ALLPOSTMESSAGE and QS_POSTMESSAGE flags differ in when they are cleared. QS_POSTMESSAGE is cleared when you call GetMessage or PeekMessage, whether or not you are filtering messages. QS_ALLPOSTMESSAGE is cleared when you call GetMessage or PeekMessage without filtering messages (wMsgFilterMin and wMsgFilterMax are 0). This can be useful when you call PeekMessage multiple times to get messages in different ranges.

Windows CE: Windows CE does not support the QS_HOTKEY value for the dwWakeMask parameter or the MWMO_WAITALL and MWMO_ALERTABLE flags for the dwFlags parameter.

The MsgWaitForMultipleObjectsEx function copies the handle table, adds to it the message queue event, and calls WaitForMultipleObjects.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Requires version 2.0 or later.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Synchronization Overview, Synchronization Functions, CancelWaitableTimer, CreateEvent, CreateFile, CreateMutex, CreateProcess, CreateRemoteThread, CreateSemaphore, CreateThread, CreateWaitableTimer, FindFirstChangeNotification, GetQueueStatus, GetStdHandle, MsgWaitForMultipleObjects, OpenEvent, OpenMutex, OpenProcess, OpenSemaphore, OpenWaitableTimer, PulseEvent, QueueUserAPC, ResetEvent, SetEvent, SetWaitableTimer


OpenEvent

The OpenEvent function returns a handle to an existing named event object.

HANDLE OpenEvent(
  DWORD dwDesiredAccess,  // access flag
  BOOL bInheritHandle,    // inherit flag
  LPCTSTR lpName          // pointer to event-object name
);

Parameters

dwDesiredAccess
Specifies the requested access to the event object. For systems that support object security, the function fails if the security descriptor of the specified object does not permit the requested access for the calling process.

This parameter can be any combination of the following values:
Access | Description
EVENT_ALL_ACCESS | Specifies all possible access flags for the event object.
EVENT_MODIFY_STATE | Enables use of the event handle in the SetEvent and ResetEvent functions to modify the event's state.
SYNCHRONIZE | Windows NT: Enables use of the event handle in any of the wait functions to wait for the event's state to be signaled.

bInheritHandle
Specifies whether the returned handle is inheritable. If TRUE, a process created by the CreateProcess function can inherit the handle; otherwise, the handle cannot be inherited.
lpName
Pointer to a null-terminated string that names the event to be opened. Name comparisons are case sensitive.

Return Values

If the function succeeds, the return value is a handle to the event object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The OpenEvent function enables multiple processes to open handles of the same event object. The function succeeds only if some process has already created the event by using the CreateEvent function. The calling process can use the returned handle in any function that requires a handle to an event object, subject to the limitations of the access specified in the dwDesiredAccess parameter.

The handle can be duplicated by using the DuplicateHandle function. Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The event object is destroyed when its last handle has been closed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Synchronization Overview, Synchronization Functions, CloseHandle, CreateEvent, CreateProcess, DuplicateHandle, PulseEvent, ResetEvent, SetEvent


OpenMutex

The OpenMutex function returns a handle to an existing named mutex object.

HANDLE OpenMutex(
  DWORD dwDesiredAccess,  // access flag
  BOOL bInheritHandle,    // inherit flag
  LPCTSTR lpName          // pointer to mutex-object name
);

Parameters

dwDesiredAccess
Specifies the requested access to the mutex object. For systems that support object security, the function fails if the security descriptor of the specified object does not permit the requested access for the calling process.

This parameter can be any combination of the following values:
Access | Description
MUTEX_ALL_ACCESS | Specifies all possible access flags for the mutex object.
SYNCHRONIZE | Windows NT: Enables use of the mutex handle in any of the wait functions to acquire ownership of the mutex, or in the ReleaseMutex function to release ownership.

bInheritHandle
Specifies whether the returned handle is inheritable. If TRUE, a process created by the CreateProcess function can inherit the handle; otherwise, the handle cannot be inherited.
lpName
Pointer to a null-terminated string that names the mutex to be opened. Name comparisons are case sensitive.

Return Values

If the function succeeds, the return value is a handle to the mutex object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The OpenMutex function enables multiple processes to open handles of the same mutex object. The function succeeds only if some process has already created the mutex by using the CreateMutex function. The calling process can use the returned handle in any function that requires a handle to a mutex object, such as the wait functions, subject to the limitations of the access specified in the dwDesiredAccess parameter.

The handle can be duplicated by using the DuplicateHandle function. Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The mutex object is destroyed when its last handle has been closed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Synchronization Overview, Synchronization Functions, CloseHandle, CreateMutex, CreateProcess, DuplicateHandle, ReleaseMutex


OpenSemaphore

The OpenSemaphore function returns a handle to an existing named semaphore object.

HANDLE OpenSemaphore(
  DWORD dwDesiredAccess,  // access flag
  BOOL bInheritHandle,    // inherit flag
  LPCTSTR lpName          // pointer to semaphore-object name
);

Parameters

dwDesiredAccess
Specifies the requested access to the semaphore object. For systems that support object security, the function fails if the security descriptor of the specified object does not permit the requested access for the calling process.

This parameter can be any combination of the following values:
Access | Description
SEMAPHORE_ALL_ACCESS | Specifies all possible access flags for the semaphore object.
SEMAPHORE_MODIFY_STATE | Enables use of the semaphore handle in the ReleaseSemaphore function to modify the semaphore's count.
SYNCHRONIZE | Windows NT: Enables use of the semaphore handle in any of the wait functions to wait for the semaphore's state to be signaled.

bInheritHandle
Specifies whether the returned handle is inheritable. If TRUE, a process created by the CreateProcess function can inherit the handle; otherwise, the handle cannot be inherited.
lpName
Pointer to a null-terminated string that names the semaphore to be opened. Name comparisons are case sensitive.

Return Values

If the function succeeds, the return value is a handle to the semaphore object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The OpenSemaphore function enables multiple processes to open handles of the same semaphore object. The function succeeds only if some process has already created the semaphore by using the CreateSemaphore function. The calling process can use the returned handle in any function that requires a handle to a semaphore object, such as the wait functions, subject to the limitations of the access specified in the dwDesiredAccess parameter.

The handle can be duplicated by using the DuplicateHandle function. Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The semaphore object is destroyed when its last handle has been closed.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Synchronization Overview, Synchronization Functions, CloseHandle, CreateSemaphore, DuplicateHandle, ReleaseSemaphore


OpenWaitableTimer

The OpenWaitableTimer function returns a handle to an existing named "waitable" timer object.

HANDLE OpenWaitableTimer(
  DWORD dwDesiredAccess,  // access flag
  BOOL bInheritHandle,    // inherit flag
  LPCTSTR lpTimerName     // pointer to timer object name
);

Parameters

dwDesiredAccess
Specifies the requested access to the timer object. For systems that support object security, the function fails if the security descriptor of the specified object does not permit the requested access for the calling process.

This parameter can be any combination of the following values:
Value | Meaning
TIMER_ALL_ACCESS | Specifies all possible access rights for the timer object.
TIMER_MODIFY_STATE | Enables use of the timer handle in the SetWaitableTimer and CancelWaitableTimer functions to modify the timer's state.
SYNCHRONIZE | Windows NT: Enables use of the timer handle in any of the wait functions to wait for the timer's state to be signaled.

bInheritHandle
Specifies whether the returned handle is inheritable. If TRUE, a process created by the CreateProcess function can inherit the handle; otherwise, the handle cannot be inherited.
lpTimerName
Pointer to a null-terminated string specifying the name of the timer object. The name is limited to MAX_PATH characters and can contain any character except the backslash path-separator character (\). Name comparison is case sensitive.

Return Values

If the function succeeds, the return value is a handle to the timer object.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The OpenWaitableTimer function enables multiple processes to open handles to the same timer object. The function succeeds only if some process has already created the timer using the CreateWaitableTimer function. The calling process can use the returned handle in any function that requires the handle to a timer object, such as the wait functions, subject to the limitations of the access specified in the dwDesiredAccess parameter.

The returned handle can be duplicated by using the DuplicateHandle function. Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The timer object is destroyed when its last handle has been closed.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Synchronization Overview, Synchronization Functions, CancelWaitableTimer, CloseHandle, CreateProcess, CreateWaitableTimer, DuplicateHandle, SetWaitableTimer


PulseEvent

The PulseEvent function provides a single operation that sets (to signaled) the state of the specified event object and then resets it (to nonsignaled) after releasing the appropriate number of waiting threads.

BOOL PulseEvent(
  HANDLE hEvent   // handle to event object
);

Parameters

hEvent
Handle to the event object. The CreateEvent or OpenEvent function returns this handle.

Windows NT: The handle must have EVENT_MODIFY_STATE access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

For a manual-reset event object, all waiting threads that can be released immediately are released. The function then resets the event object's state to nonsignaled and returns.

For an auto-reset event object, the function resets the state to nonsignaled and returns after releasing a single waiting thread, even if multiple threads are waiting.

If no threads are waiting, or if no thread can be released immediately, PulseEvent simply sets the event object's state to nonsignaled and returns.

Note that for a thread using the multiple-object wait functions to wait for all specified objects to be signaled, PulseEvent can set the event object's state to signaled and reset it to nonsignaled without causing the wait function to return. This happens if not all of the specified objects are simultaneously signaled.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, CreateEvent, OpenEvent, ResetEvent, SetEvent


QueueUserAPC

The QueueUserAPC function adds a user-mode asynchronous procedure call (APC) object to the APC queue of the specified thread.

DWORD QueueUserAPC(
  PAPCFUNC pfnAPC, // pointer to APC function
  HANDLE hThread,  // handle to the thread
  DWORD dwData     // argument for the APC function
);

Parameters

pfnAPC
Pointer to the application-supplied APC function to be called when the specified thread performs an alertable wait operation.
hThread
Specifies the handle to the thread. The handle must have THREAD_SET_CONTEXT access.
dwData
Specifies a single DWORD argument that is passed to the APC function pointed to by the pfnAPC parameter.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. There are no error values defined for this function that can be retrieved by calling GetLastError.

Remarks

The APC support provided in the operating system allows an application to queue an APC object to a thread. Each thread has its own APC queue. The queuing of an APC is a request for the thread to call the APC function. The operating system issues a software interrupt to direct the thread to call the APC function.

When a user-mode APC is queued, the thread is not directed to call the APC function unless it is in an alertable state. After the thread is in an alertable state, the thread handles all pending APCs in first in, first out (FIFO) order, and the wait operation returns WAIT_IO_COMPLETION. A thread enters an alertable state by using SleepEx, SignalObjectAndWait, WaitForSingleObjectEx, WaitForMultipleObjectsEx, or MsgWaitForMultipleObjectsEx to perform an alertable wait operation. Note that you can not use WaitForSingleObjectEx to wait on the handle to the object for which the APC is queued. Otherwise, when the asynchronous operation is completed, the handle is set to the signaled state and the thread is no longer in an alertable wait state, so the APC function will not be executed. However, the APC is still queued, so the APC function will be executed if you call another alertable wait function.

If an application queues an APC before the thread begins running, the thread begins by calling the APC function. Once the thread calls an APC function, it calls the APC functions for all APCs in its APC queue.

When the thread is terminated using the ExitThread or TerminateThread function, the APCs in its APC queue are lost. The APC functions are not called.

Note that the ReadFileEx, SetWaitableTimer, and WriteFileEx functions are implemented using an APC as the completion notification callback mechanism.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, MsgWaitForMultipleObjectsEx, ReadFileEx, SetWaitableTimer, SleepEx, WaitForMultipleObjectsEx, WaitForSingleObjectEx, WriteFileEx


ReleaseMutex

The ReleaseMutex function releases ownership of the specified mutex object.

BOOL ReleaseMutex(
  HANDLE hMutex   // handle to mutex object
);

Parameters

hMutex
Handle to the mutex object. The CreateMutex or OpenMutex function returns this handle.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ReleaseMutex function fails if the calling thread does not own the mutex object.

A thread gets ownership of a mutex by specifying a handle to the mutex in one of the wait functions. The thread that creates a mutex object can also get immediate ownership without using one of the wait functions. When the owning thread no longer needs to own the mutex object, it calls the ReleaseMutex function.

While a thread has ownership of a mutex, it can specify the same mutex in additional wait-function calls without blocking its execution. This prevents a thread from deadlocking itself while waiting for a mutex that it already owns. However, to release its ownership, the thread must call ReleaseMutex once for each time that the mutex satisfied a wait.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, CreateMutex


ReleaseSemaphore

The ReleaseSemaphore function increases the count of the specified semaphore object by a specified amount.

BOOL ReleaseSemaphore(
  HANDLE hSemaphore,   // handle to the semaphore object
  LONG lReleaseCount,  // amount to add to current count
  LPLONG lpPreviousCount   // address of previous count
);

Parameters

hSemaphore
Handle to the semaphore object. The CreateSemaphore or OpenSemaphore function returns this handle.

Windows NT: This handle must have SEMAPHORE_MODIFY_STATE access.

lReleaseCount
Specifies the amount by which the semaphore object's current count is to be increased. The value must be greater than zero. If the specified amount would cause the semaphore's count to exceed the maximum count that was specified when the semaphore was created, the count is not changed and the function returns FALSE.
lpPreviousCount
Pointer to a 32-bit variable to receive the previous count for the semaphore. This parameter can be NULL if the previous count is not required.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The state of a semaphore object is signaled when its count is greater than zero and nonsignaled when its count is equal to zero. The process that calls the CreateSemaphore function specifies the semaphore's initial count. Each time a waiting thread is released because of the semaphore's signaled state, the count of the semaphore is decreased by one.

Typically, an application uses a semaphore to limit the number of threads using a resource. Before a thread uses the resource, it specifies the semaphore handle in a call to one of the wait functions. When the wait function returns, it decreases the semaphore's count by one. When the thread has finished using the resource, it calls ReleaseSemaphore to increase the semaphore's count by one.

Another use of ReleaseSemaphore is during an application's initialization. The application can create a semaphore with an initial count of zero. This sets the semaphore's state to nonsignaled and blocks all threads from accessing the protected resource. When the application finishes its initialization, it uses ReleaseSemaphore to increase the count to its maximum value, to permit normal access to the protected resource.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, CreateSemaphore, OpenSemaphore


ResetEvent

The ResetEvent function sets the state of the specified event object to nonsignaled.

BOOL ResetEvent(
  HANDLE hEvent   // handle to event object
);

Parameters

hEvent
Handle to the event object. The CreateEvent or OpenEvent function returns this handle.

Windows NT: The handle must have EVENT_MODIFY_STATE access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The state of an event object remains nonsignaled until it is explicitly set to signaled by the SetEvent or PulseEvent function. This nonsignaled state blocks the execution of any threads that have specified the event object in a call to one of the wait functions.

The ResetEvent function is used primarily for manual-reset event objects, which must be set explicitly to the nonsignaled state. Auto-reset event objects automatically change from signaled to nonsignaled after a single waiting thread is released.

Windows CE: Windows CE does not support waiting for processes or threads.

ResetEvent returns FALSE if the handle to the event object is invalid.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, CreateEvent, OpenEvent, PulseEvent, SetEvent


SetCriticalSectionSpinCount

The SetCriticalSectionSpinCount function sets the spin count for the specified critical section.

DWORD SetCriticalSectionSpinCount(
  LPCRITICAL_SECTION lpCriticalSection,
                      // pointer to critical section
  DWORD dwSpinCount   // spin count for critical section
);

Parameters

lpCriticalSection
Pointer to the critical section object.
dwSpinCount
Specifies the spin count for the critical section object. On uniprocessor systems, the spin count is ignored and the critical section spin count is set to 0. On multiprocessor systems, if contention for the critical section occurs, the calling thread will spin dwSpinCount times before waiting on a semaphore associated with the critical section. If the critical section becomes free during the spin operation, the wait is avoided.

Return Values

The function returns the previous spin count for the critical section.

Remarks

The threads of a single process can use a critical section object for mutual-exclusion synchronization. The process is responsible for allocating the memory used by a critical section object, which it can do by declaring a variable of type CRITICAL_SECTION. Before using a critical section, some thread of the process must call the InitializeCriticalSection or InitializeCriticalSectionAndSpinCount function to initialize the object. You can subsequently modify the spin count by calling the SetCriticalSectionSpinCount function.

The spin count is useful for critical sections of short duration that can experience high levels of contention. Consider a worst-case scenario, in which an application on an SMP system has two or three threads constantly allocating and releasing memory from the heap. The application serializes the heap with a critical section. In the worst-case scenario, contention for the critical section is constant, and each thread makes an expensive call to the WaitForSingleObject function. However, if the spin count is set properly, the calling thread will not immediately call WaitForSingleObject when contention occurs. Instead, the calling thread can acquire ownership of the critical section if it is released during the spin operation.

You can improve performance significantly by choosing a small spin count for a critical section of short duration. The heap manager uses a spin count of roughly 4000 for its per-heap critical sections. This gives great performance and scalability in almost all worst-case scenarios.

QuickInfo

Windows NT: Requires version 4.0 SP3 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, InitializeCriticalSection, InitializeCriticalSectionAndSpinCount, WaitForSingleObject


SetEvent

The SetEvent function sets the state of the specified event object to signaled.

BOOL SetEvent(
  HANDLE hEvent   // handle to event object
);

Parameters

hEvent
Handle to the event object. The CreateEvent or OpenEvent function returns this handle.

Windows NT: The handle must have EVENT_MODIFY_STATE access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The state of a manual-reset event object remains signaled until it is set explicitly to the nonsignaled state by the ResetEvent function. Any number of waiting threads, or threads that subsequently begin wait operations for the specified event object by calling one of the wait functions, can be released while the object's state is signaled.

The state of an auto-reset event object remains signaled until a single waiting thread is released, at which time the system automatically sets the state to nonsignaled. If no threads are waiting, the event object's state remains signaled.

Windows CE: Windows CE does not support waiting for a process or thread. Waiting on an invalid handle will return FALSE.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, CreateEvent, OpenEvent, PulseEvent, ResetEvent


SetWaitableTimer

The SetWaitableTimer function activates the specified "waitable" timer. When the due time arrives, the timer is signaled and the thread that set the timer calls the optional completion routine.

BOOL SetWaitableTimer(
  HANDLE hTimer,                          // handle to a timer object
  const LARGE_INTEGER *pDueTime,          // when timer will become signaled
  LONG lPeriod,                           // periodic timer interval
  PTIMERAPCROUTINE pfnCompletionRoutine,  // completion routine
  LPVOID lpArgToCompletionRoutine,        // data for completion routine
  BOOL fResume                            // flag for resume state
);

Parameters

hTimer
Handle to the timer object. The CreateWaitableTimer or OpenWaitableTimer function returns this handle.
pDueTime
Specifies when the state of the timer is to be set to signaled, in 100 nanosecond intervals. Use the format described by the FILETIME structure. Positive values indicate absolute time. Be sure to use a UTC-based absolute time, as the system uses UTC-based time internally. Negative values indicate relative time. The actual timer accuracy depends on the capability of your hardware. For more information about UTC-based time, see System Time.
lPeriod
Specifies the period of the timer, in milliseconds. If lPeriod is zero, the timer is signaled once. If lPeriod is greater than zero, the timer is periodic. A periodic timer automatically reactivates each time the period elapses, until the timer is canceled using the CancelWaitableTimer function or reset using SetWaitableTimer. If lPeriod is less than zero, the function fails.
pfnCompletionRoutine
Pointer to an optional completion routine. The completion routine is application-defined function of type PTIMERAPCROUTINE to be executed when the timer is signaled. For more information on the timer callback function, see TimerAPCProc.
lpArgToCompletionRoutine
Pointer to the structure that is passed to the optional completion routine.
fResume
Specifies whether to restore a system in suspended power conservation mode when the timer state is set to signaled. If fResume is TRUE on a platform that does not support a restore, the call will succeed, but GetLastError returns ERROR_NOT_SUPPORTED.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Timers are initially inactive. To activate a timer, call SetWaitableTimer. If the timer is already active when you call SetWaitableTimer, the timer is stopped, then it is reactivated. Stopping the timer in this manner does not set the timer state to signaled, so threads blocked in a wait operation on the timer remain blocked.

When the specified due time arrives, the timer becomes inactive and the APC is queued to the thread that set the timer. The state of the timer is set to signaled, the timer is reactivated using the specified period, and the thread that set the timer calls the completion routine when it enters an alertable wait state. For more information, see QueueUserAPC.

If the thread that set the timer exits before the timer elapses, the timer is cancelled. If you call SetWaitableTimer on a timer that has been set by another thread and that thread is not in an alertable state, the completion routine is cancelled.

When a manual-reset timer is set to the signaled state, it remains in this state until SetWaitableTimer is called to reset the timer. As a result, a periodic manual-reset timer is set to the signaled state when the initial due time arrives and remains signaled until it is reset. When a synchronization timer is set to the signaled state, it remains in this state until a thread completes a wait operation on the timer object.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, CancelWaitableTimer, CreateWaitableTimer, FILETIME, OpenWaitableTimer, TimerAPCProc


SignalObjectAndWait

The SignalObjectAndWait function allows the caller to atomically signal an object and wait on another object.

DWORD SignalObjectAndWait(
  HANDLE hObjectToSignal,  // handle to object to signal
  HANDLE hObjectToWaitOn,  // handle to object to wait for
  DWORD dwMilliseconds,    // time-out interval in milliseconds
  BOOL bAlertable          // alertable flag
);

Parameters

hObjectToSignal
Specifies the handle to the object to signal. This object can be a semaphore, a mutex, or an event.

Windows NT: If the handle is a semaphore, SEMAPHORE_MODIFY_STATE access is required. If the handle is an event, EVENT_MODIFY_STATE access is required. If the handle is a mutex, SYNCHRONIZE access is assumed, because only the owner of a mutex may release it. For more information, see Standard Access Rights.

hObjectToWaitOn
Specifies the handle to the object to wait for. For a list of the object types whose handles you can specify, see the Remarks section.
dwMilliseconds
Specifies the time-out interval, in milliseconds. The function returns if the interval elapses, even if the object's state is nonsignaled and no completion or asynchronous procedure call (APC) objects are queued. If dwMilliseconds is zero, the function tests the object's state, checks for queued completion routines or APCs, and returns immediately. If dwMilliseconds is INFINITE, the function's time-out interval never elapses.
bAlertable
Specifies whether the function returns when the system queues an I/O completion routine or an APC for the calling thread. If TRUE, the function returns and the thread calls the completion routine or APC function. If FALSE, the function does not return, and the thread does not call the completion routine or APC function.

A completion routine is queued when the ReadFileEx or WriteFileEx function in which it was specified has completed. The wait function returns and the completion routine is called only if bAlertable is TRUE, and the calling thread is the thread that initiated the read or write operation. An APC is queued when you call QueueUserAPC.

Return Values

If the function succeeds, the return value indicates the event that caused the function to return. This value can be one of the following:

Value | Meaning
WAIT_ABANDONED | The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread terminated. Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.
WAIT_IO_COMPLETION | One or more I/O completion routines or user-mode APCs are queued for execution.
WAIT_OBJECT_0 | The state of the specified object is signaled.
WAIT_TIMEOUT | The time-out interval elapsed, and the object's state is nonsignaled.

If the function fails, the return value is 0xFFFFFFFF. To get extended error information, call GetLastError.

Remarks

A completion routine is queued for execution when the ReadFileEx or WriteFileEx function in which it was specified has been completed. The wait function returns and the completion routine is executed only if bAlertable is TRUE, and the calling thread is the thread that initiated the read or write operation.

The SignalObjectAndWait function can wait for the following objects:

  • Change notification
  • Console input
  • Event
  • Job
  • Mutex
  • Process
  • Semaphore
  • Thread
  • Waitable timer

For more information, see Synchronization Objects.

Use caution when using the wait functions and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. A thread that uses a wait function with no time-out interval may cause the system to become deadlocked. Two examples of code that indirectly creates windows are DDE and COM CoInitialize. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than SignalObjectAndWait.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, CancelWaitableTimer, CreateEvent, CreateMutex, CreateProcess, CreateThread, CreateRemoteThread, CreateSemaphore, CreateWaitableTimer, FindFirstChangeNotification, MsgWaitForMultipleObjects, MsgWaitForMultipleObjectsEx, OpenEvent, OpenMutex, OpenProcess, OpenSemaphore, OpenWaitableTimer, PulseEvent, QueueUserAPC, ReadFileEx, ResetEvent, SetEvent, SetWaitableTimer, WriteFileEx


TimerAPCProc

The TimerAPCProc function is an application-defined timer completion routine. Specify this address when calling the SetWaitableTimer function. The PTIMERAPCROUTINE type defines a pointer to this callback function. TimerAPCProc is a placeholder for the application-defined function name.

VOID CALLBACK TimerAPCProc(
  LPVOID lpArgToCompletionRoutine   // data value
  DWORD dwTimerLowValue             // timer low value
  DWORD dwTimerHighValue            // timer high value
);

Parameters

lpArgToCompletionRoutine
Specifies the value passed to the function using the lpArgToCompletionRoutine parameter of the SetWaitableTimer function.
dwTimerLowValue
Specifies the low-order 32-bits of the UTC-based time at which the timer was signaled. This value corresponds to the dwLowDateTime member of the FILETIME structure. For more information about UTC-based time, see System Time.
dwTimerHighValue
Specifies the high-order 32-bits of the UTC-based time at which the timer was signaled. This value corresponds to the dwHighDateTime member of the FILETIME structure.

Return Values

This function does not return a value.

Remarks

The completion routine is executed by the thread that activates the timer using SetWaitableTimer. However, the thread must be in an alertable state. For more information, see Asynchronous Procedure Calls.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: User-defined.

See Also

Synchronization Overview, Synchronization Functions, FILETIME, SetWaitableTimer


TryEnterCriticalSection

The TryEnterCriticalSection function attempts to enter a critical section without blocking. If the call is successful, the calling thread takes ownership of the critical section.

BOOL TryEnterCriticalSection(
  LPCRITICAL_SECTION lpCriticalSection  // pointer to critical
                                        // section object
);

Parameters

lpCriticalSection
Specifies the critical section object.

Return Values

If the critical section is successfully entered or the current thread already owns the critical section, the return value is nonzero.

If another thread already owns the critical section, the return value is zero.

Remarks

The threads of a single process can use a critical section object for mutual-exclusion synchronization. The process is responsible for allocating the memory used by a critical section object, which it can do by declaring a variable of type CRITICAL_SECTION. Before using a critical section, some thread of the process must call the InitializeCriticalSection or InitializeCriticalSectionAndSpinCount function to initialize the object.

To enable mutually exclusive use of a shared resource, each thread calls the EnterCriticalSection or TryEnterCriticalSection function to request ownership of the critical section before executing any section of code that uses the protected resource. The difference is that TryEnterCriticalSection returns immediately, regardless of whether it obtained ownership of the critical section, while EnterCriticalSection blocks until the thread can take ownership of the critical section. When it has finished executing the protected code, the thread uses the LeaveCriticalSection function to relinquish ownership, enabling another thread to become the owner and gain access to the protected resource. The thread must call LeaveCriticalSection once for each time that it entered the critical section.

Any thread of the process can use the DeleteCriticalSection function to release the system resources that were allocated when the critical section object was initialized. After this function has been called, the critical section object can no longer be used for synchronization.

If a thread terminates while it has ownership of a critical section, the state of the critical section is undefined.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, DeleteCriticalSection, EnterCriticalSection, InitializeCriticalSection, InitializeCriticalSectionAndSpinCount, LeaveCriticalSection


WaitForMultipleObjects

The WaitForMultipleObjects function returns when one of the following occurs:

  • Either any one or all of the specified objects are in the signaled state.
  • The time-out interval elapses.
DWORD WaitForMultipleObjects(
  DWORD nCount,             // number of handles in the handle array
  CONST HANDLE *lpHandles,  // pointer to the object-handle array
  BOOL fWaitAll,            // wait flag
  DWORD dwMilliseconds      // time-out interval in milliseconds
);

Parameters

nCount
Specifies the number of object handles in the array pointed to by lpHandles. The maximum number of object handles is MAXIMUM_WAIT_OBJECTS.
lpHandles
Pointer to an array of object handles. For a list of the object types whose handles can be specified, see the following Remarks section. The array can contain handles of objects of different types.

Windows NT: The handles must have SYNCHRONIZE access. For more information, see Standard Access Rights.

Windows 95: No handle may be a duplicate of another handle created using DuplicateHandle.

fWaitAll
Specifies the wait type. If TRUE, the function returns when the state all objects in the lpHandles array is signaled. If FALSE, the function returns when the state of any one of the objects set to is signaled. In the latter case, the return value indicates the object whose state caused the function to return.
dwMilliseconds
Specifies the time-out interval, in milliseconds. The function returns if the interval elapses, even if the conditions specified by the bWaitAll parameter are not met. If dwMilliseconds is zero, the function tests the states of the specified objects and returns immediately. If dwMilliseconds is INFINITE, the function's time-out interval never elapses.

Return Values

If the function succeeds, the return value indicates the event that caused the function to return. This value can be one of the following.

Value | Meaning
WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount – 1) | If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled. If bWaitAll is FALSE, the return value minus WAIT_OBJECT_0 indicates the lpHandles array index of the object that satisfied the wait. If more than one object became signalled during the call, this is the array index of the signalled object with the smallest index value of all the signalled objects.
WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount – 1) | If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled and at least one of the objects is an abandoned mutex object. If bWaitAll is FALSE, the return value minus WAIT_ABANDONED_0 indicates the lpHandles array index of an abandoned mutex object that satisfied the wait.
WAIT_TIMEOUT | The time-out interval elapsed and the conditions specified by the bWaitAll parameter are not satisfied.

If the function fails, the return value is WAIT_FAILED. To get extended error information, call GetLastError.

Remarks

The WaitForMultipleObjects function determines whether the wait criteria have been met. If the criteria have not been met, the calling thread enters an efficient wait state, consuming very little processor time while waiting for the criteria to be met.

When fWaitAll is TRUE, the function's wait operation is completed only when the states of all objects have been set to signaled. The function does not modify the states of the specified objects until the states of all objects have been set to signaled. For example, a mutex can be signaled, but the thread does not get ownership until the states of the other objects are also set to signaled. In the meantime, some other thread may get ownership of the mutex, thereby setting its state to nonsignaled.

Before returning, a wait function modifies the state of some types of synchronization objects. Modification occurs only for the object or objects whose signaled state caused the function to return. For example, the count of a semaphore object is decreased by one. When fWaitAll is FALSE, and multiple objects are in the signaled state, the function chooses one of the objects to satisfy the wait; the states of the objects not selected are unaffected.

The WaitForMultipleObjects function can specify handles of any of the following object types in the lpHandles array:

  • Change notification
  • Console input
  • Event
  • Job
  • Mutex
  • Process
  • Semaphore
  • Thread
  • Waitable timer

For more information, see Synchronization Objects.

Use caution when calling the wait functions and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. A thread that uses a wait function with no time-out interval may cause the system to become deadlocked. Two examples of code that indirectly creates windows are DDE and COM CoInitialize. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than WaitForMultipleObjects.

Windows CE: Windows CE does not support waiting for semaphores, change notification objects, console input, and timers.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, CancelWaitableTimer, CreateEvent, CreateFile, CreateMutex, CreateProcess, CreateRemoteThread, CreateSemaphore, CreateThread, CreateWaitableTimer, FindFirstChangeNotification, GetStdHandle, MsgWaitForMultipleObjects, MsgWaitForMultipleObjectsEx, OpenEvent, OpenMutex, OpenProcess, OpenSemaphore, OpenWaitableTimer, PulseEvent, QueueUserAPC, ResetEvent, SetEvent, SetWaitableTimer


WaitForMultipleObjectsEx

The WaitForMultipleObjectsEx function returns when one of the following occurs:

  • Either any one or all of the specified objects are in the signaled state.
  • An I/O completion routine or asynchronous procedure call (APC) is queued to the thread.
  • The time-out interval elapses.
DWORD WaitForMultipleObjectsEx(
  DWORD nCount,             // number of handles in handle array
  CONST HANDLE *lpHandles,  // points to the object-handle array
  BOOL fWaitAll,            // wait flag
  DWORD dwMilliseconds,     // time-out interval in milliseconds
  BOOL bAlertable           // alertable wait flag
);

Parameters

nCount
Specifies the number of object handles to wait for in the array pointed to by lpHandles. The maximum number of object handles is MAXIMUM_WAIT_OBJECTS.
lpHandles
Pointer to an array of object handles. For a list of the object types whose handles can be specified, see the following Remarks section. The array can contain handles of objects of different types.

Windows NT: The handles must have SYNCHRONIZE access. For more information, see Standard Access Rights.

Windows 95: No handle may be a duplicate of another handle created using DuplicateHandle.

fWaitAll
Specifies the wait type. If TRUE, the function returns when the states all objects in the lpHandles array are set to signaled. If FALSE, the function returns when the state of any one of the objects is set to signaled. In the latter case, the return value indicates the object whose state caused the function to return.
dwMilliseconds
Specifies the time-out interval, in milliseconds. The function returns if the interval elapses, even if the criteria specified by the bWaitAll parameter are not met and no completion routines or APCs are queued. If dwMilliseconds is zero, the function tests the states of the specified objects and checks for queued completion routines or APCs and then returns immediately. If dwMilliseconds is INFINITE, the function's time-out interval never elapses.
bAlertable
Specifies whether the function returns when the system queues an I/O completion routine or APC. If TRUE, the function returns and the completion routine or APC function is executed. If FALSE, the function does not return and the completion routine or APC function is not executed.

A completion routine is queued when the ReadFileEx or WriteFileEx function in which it was specified has completed. The wait function returns and the completion routine is called only if bAlertable is TRUE and the calling thread is the thread that initiated the read or write operation. An APC is queued when you call QueueUserAPC.

Return Values

If the function succeeds, the return value indicates the event that caused the function to return. This value can be one of the following.

Value | Meaning
WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount – 1) | If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled. If bWaitAll is FALSE, the return value minus WAIT_OBJECT_0 indicates the lpHandles array index of the object that satisfied the wait. If more than one object became signalled during the call, this is the array index of the signalled object with the smallest index value of all the signalled objects.
WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount – 1) | If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled, and at least one of the objects is an abandoned mutex object. If bWaitAll is FALSE, the return value minus WAIT_ABANDONED_0 indicates the lpHandles array index of an abandoned mutex object that satisfied the wait.
WAIT_IO_COMPLETION | One or more I/O completion routines are queued for execution.
WAIT_TIMEOUT | The time-out interval elapsed, the conditions specified by the bWaitAll parameter were not satisfied, and no completion routines are queued.

If the function fails, the return value is 0xFFFFFFFF. To get extended error information, call GetLastError.

Remarks

The WaitForMultipleObjectsEx function determines whether the wait criteria have been met. If the criteria have not been met, the calling thread enters an efficient wait state, using very little processor time while waiting for the criteria to be met.

When fWaitAll is TRUE, the function's wait operation is completed only when the states of all objects have been set to signaled. The function does not modify the states of the specified objects until the states of all objects have been set to signaled. For example, a mutex can be signaled, but the thread does not get ownership until the states of the other objects are also set to signaled. In the meantime, some other thread may get ownership of the mutex, thereby setting its state to nonsignaled.

Before returning, a wait function modifies the state of some types of synchronization objects. Modification occurs only for the object or objects whose signaled state caused the function to return. For example, the count of a semaphore object is decreased by one. When fWaitAll is FALSE, and multiple objects are in the signaled state, the function chooses one of the objects to satisfy the wait; the states of the objects not selected are unaffected.

The WaitForMultipleObjectsEx function can specify handles of any of the following object types in the lpHandles array:

  • Change notification
  • Console input
  • Event
  • Job
  • Mutex
  • Process
  • Semaphore
  • Thread
  • Waitable timer

For more information, see Synchronization Objects.

Use caution when calling the wait functions and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. A thread that uses a wait function with no time-out interval may cause the system to become deadlocked. Two examples of code that indirectly creates windows are DDE and COM CoInitialize. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than WaitForMultipleObjectsEx.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, CancelWaitableTimer, CreateEvent, CreateFile, CreateMutex, CreateProcess, CreateRemoteThread, CreateSemaphore, CreateWaitableTimer, CreateThread, FindFirstChangeNotification, GetStdHandle, MsgWaitForMultipleObjects, MsgWaitForMultipleObjectsEx, OpenEvent, OpenMutex, OpenProcess, OpenSemaphore, OpenWaitableTimer, PulseEvent, QueueUserAPC, ReadFileEx, ResetEvent, SetEvent, SetWaitableTimer, WriteFileEx


WaitForSingleObject

The WaitForSingleObject function returns when one of the following occurs:

  • The specified object is in the signaled state.
  • The time-out interval elapses.
DWORD WaitForSingleObject(
  HANDLE hHandle,        // handle to object to wait for
  DWORD dwMilliseconds   // time-out interval in milliseconds
);

Parameters

hHandle
Handle to the object. For a list of the object types whose handles can be specified, see the following Remarks section.

Windows NT: The handle must have SYNCHRONIZE access. For more information, see Standard Access Rights.

dwMilliseconds
Specifies the time-out interval, in milliseconds. The function returns if the interval elapses, even if the object's state is nonsignaled. If dwMilliseconds is zero, the function tests the object's state and returns immediately. If dwMilliseconds is INFINITE, the function's time-out interval never elapses.

Return Values

If the function succeeds, the return value indicates the event that caused the function to return. This value can be one of the following.

Value | Meaning
WAIT_ABANDONED | The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread terminated. Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.
WAIT_OBJECT_0 | The state of the specified object is signaled.
WAIT_TIMEOUT | The time-out interval elapsed, and the object's state is nonsignaled.

If the function fails, the return value is WAIT_FAILED. To get extended error information, call GetLastError.

Remarks

The WaitForSingleObject function checks the current state of the specified object. If the object's state is nonsignaled, the calling thread enters an efficient wait state. The thread consumes very little processor time while waiting for the object state to become signaled or the time-out interval to elapse.

Before returning, a wait function modifies the state of some types of synchronization objects. Modification occurs only for the object whose signaled state caused the function to return. For example, the count of a semaphore object is decreased by one.

The WaitForSingleObject function can wait for the following objects:

  • Change notification
  • Console input
  • Event
  • Job
  • Mutex
  • Process
  • Semaphore
  • Thread
  • Waitable timer

For more information, see Synchronization Objects.

Use caution when calling the wait functions and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. A thread that uses a wait function with no time-out interval may cause the system to become deadlocked. Two examples of code that indirectly creates windows are DDE and COM CoInitialize. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than WaitForSingleObject.

Windows CE: Windows CE does not support waiting for semaphores, change notification objects, console input, and timers.

Waiting on an invalid handle causes WaitForSingleObject to return WAIT_FAILED.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Requires version 1.0 or later.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, CancelWaitableTimer, CreateEvent, CreateFile, CreateMutex, CreateProcess, CreateRemoteThread, CreateSemaphore, CreateThread, CreateWaitableTimer, FindFirstChangeNotification, GetStdHandle, MsgWaitForMultipleObjects, MsgWaitForMultipleObjectsEx, OpenEvent, OpenMutex, OpenProcess, OpenSemaphore, OpenWaitableTimer, PulseEvent, ResetEvent, SetEvent, SetWaitableTimer


WaitForSingleObjectEx

The WaitForSingleObjectEx function returns when one of the following occurs:

  • The specified object is in the signaled state.
  • An I/O completion routine or asynchronous procedure call (APC) is queued to the thread.
  • The time-out interval elapses.
DWORD WaitForSingleObjectEx(
  HANDLE hHandle,        // handle to object to wait for
  DWORD dwMilliseconds,  // time-out interval, in milliseconds
  BOOL bAlertable        // return to execute I/O completion routine if TRUE
);

Parameters

hHandle
Handle to the object. For a list of the object types whose handles can be specified, see the following Remarks section.

Windows NT: The handle must have SYNCHRONIZE access. For more information, see Standard Access Rights.

dwMilliseconds
Specifies the time-out interval, in milliseconds. The function returns if the interval elapses, even if the object's state is nonsignaled and no completion routines or APCs are queued. If dwMilliseconds is zero, the function tests the object's state and checks for queued completion routines or APCs and then returns immediately. If dwMilliseconds is INFINITE, the function's time-out interval never elapses.
bAlertable
Specifies whether the function returns when the system queues an I/O completion routine or APC. If TRUE, the function returns and the completion routine or APC function is executed. If FALSE, the function does not return, and the completion routine or APC function is not executed.

A completion routine is queued when the ReadFileEx or WriteFileEx function in which it was specified has completed. The wait function returns and the completion routine is called only if bAlertable is TRUE, and the calling thread is the thread that initiated the read or write operation. An APC is queued when you call QueueUserAPC.

Return Values

If the function succeeds, the return value indicates the event that caused the function to return. This value can be one of the following.

Value | Meaning
WAIT_OBJECT_0 | The state of the specified object is signaled.
WAIT_ABANDONED | The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread terminated. Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.
WAIT_IO_COMPLETION | One or more I/O completion routines are queued for execution.
WAIT_TIMEOUT | The time-out interval elapsed, and the object's state is nonsignaled.

If the function fails, the return value is 0xFFFFFFFF. To get extended error information, call GetLastError.

Remarks

The WaitForSingleObjectEx function determines whether the wait criteria have been met. If the criteria have not been met, the calling thread enters an efficient wait state, consuming very little processor time while waiting for the criteria to be met.

Before returning, a wait function modifies the state of some types of synchronization objects. Modification occurs only for the object whose signaled state caused the function to return. For example, the count of a semaphore object is decreased by one.

The WaitForSingleObjectEx function can wait for the following objects:

  • Change notification
  • Console input
  • Event
  • Job
  • Mutex
  • Process
  • Semaphore
  • Thread
  • Waitable timer

For more information, see Synchronization Objects.

Use caution when calling the wait functions and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. A thread that uses a wait function with no time-out interval may cause the system to become deadlocked. Two examples of code that indirectly creates windows are DDE and COM CoInitialize. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than WaitForSingleObjectEx.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Synchronization Overview, Synchronization Functions, CancelWaitableTimer, CreateEvent, CreateFile, CreateMutex, CreateProcess, CreateRemoteThread, CreateSemaphore, CreateThread, CreateWaitableTimer, FindFirstChangeNotification, GetStdHandle, MsgWaitForMultipleObjects, MsgWaitForMultipleObjectsEx, OpenEvent, OpenMutex, OpenProcess, OpenSemaphore, OpenWaitableTimer, PulseEvent, QueueUserAPC, ReadFileEx, ResetEvent, SetEvent, SetWaitableTimer, WriteFileEx


Synchronization Structures

The following structure is used with synchronization.

OVERLAPPED


OVERLAPPED

The OVERLAPPED structure contains information used in asynchronous input and output (I/O).

typedef struct _OVERLAPPED { // o
    DWORD  Internal;
    DWORD  InternalHigh;
    DWORD  Offset;
    DWORD  OffsetHigh;
    HANDLE hEvent;
} OVERLAPPED;

Members

Internal
Reserved for operating system use. This member, which specifies a system-dependent status, is valid when the GetOverlappedResult function returns without setting the extended error information to ERROR_IO_PENDING.
InternalHigh
Reserved for operating system use. This member, which specifies the length of the data transferred, is valid when the GetOverlappedResult function returns TRUE.
Offset
Specifies a file position at which to start the transfer. The file position is a byte offset from the start of the file. The calling process sets this member before calling the ReadFile or WriteFile function. This member is ignored when reading from or writing to named pipes and communications devices.
OffsetHigh
Specifies the high word of the byte offset at which to start the transfer. This member is ignored when reading from or writing to named pipes and communications devices.
hEvent
Handle to an event set to the signaled state when the transfer has been completed. The calling process sets this member before calling the ReadFile, WriteFile, ConnectNamedPipe, or TransactNamedPipe function.

Remarks

You can use the HasOverlappedIoCompleted macro to determine whether an asynchronous I/O operation has completed. You can use the CancelIo function to cancel an asynchronous I/O operation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Synchronization Overview, Synchronization Structures, CancelIo, ConnectNamedPipe, CreateFile, GetOverlappedResult, HasOverlappedIoCompleted, ReadFile, ReadFileEx, TransactNamedPipe, WriteFile, WriteFileEx


Synchronization Macros

The following macro is used with synchronization.

HasOverlappedIoCompleted


HasOverlappedIoCompleted

The HasOverlappedIoCompleted macro provides a high performance test operation that can be used to poll for the completion of an outstanding I/O operation.

BOOL HasOverlappedIoCompleted(
  LPOVERLAPPED lpOverlapped
);

Parameters

lpOverlapped
Pointer to an OVERLAPPED structure that was specified when the overlapped I/O operation was started.

Return Values

Returns TRUE if the I/O operation has completed, and FALSE otherwise.

Remarks

To cancel all pending asynchronous I/O operations, use the CancelIo function. This function only cancels operations issued by the calling thread for the specified file handle. I/O operations that are canceled complete with the error ERROR_OPERATION_ABORTED.

To get more details about a completed I/O operation, call the GetOverlappedResult or GetQueuedCompletionStatus function.

The HasOverlappedIoCompleted macro is defined as follows:

#define HasOverlappedIoCompleted(lpOverlapped) \
    ((lpOverlapped)->Internal != STATUS_PENDING)

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 98 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

Synchronization Overview, Synchronization Macros, CancelIo, ConnectNamedPipe, DeviceIoControl, OVERLAPPED, ReadFile, TransactNamedPipe, WaitCommEvent, WriteFile


Legal Information

[This is preliminary documentation and subject to change.]

Removable Storage Manager Programmer's Reference

This is a preliminary document and may be changed substantially prior to final commercial release. This document is provided for informational purposes only and Microsoft makes no warranties, either express or implied, in this document. Information in this document is subject to change without notice. The entire risk of the use or the results of the use of this document remains with the user. The names of companies, products, people, characters, and/or data mentioned herein are fictitious and are in no way intended to represent any real individual, company, product, or event, unless otherwise noted. Complying with all applicable copyright laws is the responsibility of the user. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without the express written permission of Microsoft Corporation.

Portions of this document specify and accompany software that is still in development. Some of the information in this documentation may be inaccurate or may not be an accurate representation of the functionality of final documentation or software. Microsoft assumes no responsibility for any damages that might occur directly or indirectly from these inaccuracies.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

© 1985-1998 Microsoft Corporation. All rights reserved.

Portions © 1998 HighGround Systems, Inc. All rights reserved.

ActiveX, BackOffice, DirectX, JScript, Microsoft, Microsoft Press, MS, MS-DOS, Visual Basic, Visual C++, Windows, Win32, Win32s, and Windows NT are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. OS/2 is a registered trademark licensed to Microsoft Corporation.

Other product and company names mentioned herein may be the trademarks of their respective owners.


Roadmap to Removable Storage Manager Documentation

[This is preliminary documentation and subject to change.]

The Removable Storage Manager (RSM) for Microsoft® Windows NT® documentation covers the following functional areas:

  • Removable Storage Manager Overview

    Contains high-level information about RSM and the features it provides, as well as information about designing your own RSM application.

  • Developing a Media Label Library

    Contains a sample media label library and information on how to test and install a media label library.

  • RSM Media Handling

    Contains information on how RSM handles media, including information about allocating, deallocating, and importing media.

  • Removable Storage Manager Function Reference

    Contains RSM function reference pages.

  • Media Label Library Function Reference

    Contains media label library function reference pages.

  • Removable Storage Manager Structure Reference

    Contains RSM structure reference pages.

  • Glossary

    Contains RSM glossary terms and definitions.


Removable Storage Manager Overview

[This is preliminary documentation and subject to change.]

The Removable Storage Manager (RSM) for Microsoft® Windows NT® consists of functions and a set of management tools for bulk media and robotic libraries. RSM is part of Microsoft® Windows NT® Server version 5.0 and Microsoft Windows NT Workstation version 5.0. It works on top of the tape, optical, library, and other class drivers that exist in Windows NT.

The Removable Storage Manager:

  • Provides a uniform end-user interface for managing bulk-media storage resources.
  • Presents bulk-media storage resources as shareable network resources.
  • Provides a media management API for application developers to uniformly and easily incorporate bulk-media storage resources into applications.

Applications use the RSM functions to:

  • Share local changers.
  • Share drives in local changers.
  • Track online and offline media.
  • Make operator requests.
  • Clean drives.
  • Allocate, deallocate, and decommission media.
  • Perform library inventories.


About RSM

[This is preliminary documentation and subject to change.]

RSM is a service included with Windows NT that facilitates communication among applications, robotic changers, and media libraries. It enables multiple applications to share local robotic media libraries and tape or disk drives, and manage removable media within a single-server system. A group of libraries, drives, and media that are managed by RSM is called an RSM system. RSM can help you create an application that makes effective use of the media resources in an RSM system.

RSM includes the following components:

  • The RSM application programming interface (API)
  • The RSM database
  • The RSM MMC snap-in

The following figure illustrates the relationships among the components of RSM, devices, and Windows NT. RSM components are shown in solid white.

The RSM MMC snap-in includes a Mount menu command. This command uses the MountNtmsMedia function to issue a mount request for the specified medium. RSM reads the database for location and identification information of the medium. If the medium is offline, RSM generates an operator request to insert it. If the medium is online, RSM mounts it and updates the database.


RSM API

[This is preliminary documentation and subject to change.]

The RSM API is the interface that applications use to access the services and media in an RSM system. It is a dynamic-link library (DLL) that contains a group of functions you can use to build your media management application. These functions perform the following operations:

  • Mount and dismount media
  • Clean drives
  • Insert and eject media
  • Inventory libraries
  • Enable and disable libraries, drives, and media
  • Access information in the RSM database

When you develop your media management application using the RSM API, you gain the following benefits:

  • Multiple applications can share the same library, drive, and media resources
  • A single computer can track multiple types of media
  • A single computer can track media that are inside or outside a media library unit


RSM Database

[This is preliminary documentation and subject to change.]

The RSM database contains information about the objects in an RSM system. RSM maintains the data in the database and updates it whenever the administrator or an application makes a change in an RSM system. For example, if the administrator wants to mount a piece of media in an online library, RSM mounts the media and updates the database to reflect the change.

The database is the mechanism used by RSM to track media-related system components. The database stores the status of these system components and maintains media inventories. The database includes the following information:

  • Library, drive, and media configuration and state
  • Media pool configuration and contents
  • Library work list
  • Operator requests


RSM MMC Snap-in

[This is preliminary documentation and subject to change.]

The RSM MMC snap-in is a user interface to RSM that is a snap-in for the Microsoft Management Console (MMC) for Windows NT. Administrators can use the snap-in to add RSM objects, view and modify properties of objects, insert and eject media, perform inventories, mount and dismount media, and check status information. RSM objects can be physical objects (such as libraries, drives, and media) or groups of media (called media pools).

The MMC snap-in can help administrators perform the following tasks:

  • Handle operator requests
  • Point and click operations such as inserting media, ejecting media, drive cleaning, and dismounting media
  • Report status
  • Manage media pools manually


Storage Media

[This is preliminary documentation and subject to change.]

This section describes how RSM uses media and groups of media.

RSM uses the following media concepts to manage media:

  • Physical media
  • Partitions
  • Logical media


Physical Media

[This is preliminary documentation and subject to change.]

Physical media are the tangible RSM media objects. Optical disks and magnetic tapes are examples of physical media.

Physical media are referenced by physical media IDs (PMIDs). RSM applications use PMIDs to perform operations normally associated with tangible media, such as eject, enable, disable, and delete media. RSM uses PMIDs to perform these operations because the operations affect all partitions of a piece of media.

In libraries that include a bar-code reader, physical media might have bar codes as well as sequence numbers.


Partitions

[This is preliminary documentation and subject to change.]

RSM uses the concept of partitions to manage physical media. A partition is a portion of a piece of physical media. Physical media can have more than one partition. For example, RSM reads one side of a two-sided optical disk in a drive with one head as a single partition. Most media (such as CD-ROM and magnetic tape) have one partition.

Partitions are referenced by partition IDs (PARTIDs).

Note RSM partitions are not the equivalent of FAT/NTFS disk partitions or tape partitions.


Logical Media

[This is preliminary documentation and subject to change.]

Logical media are abstract representations of partitions of physical media. All media that are currently in use in RSM are represented as logical media. You can use logical media to change a piece of physical media without changing the logical representation of the media. For example, you can replace media that is worn out by removing the old media and assigning the same logical media ID (LMID) to the new media.

Each logical medium maps to one partition of a physical medium. For example, a two-sided optical disk contains two partitions; each partition is represented by a different LMID. RSM applications can use LMIDs to mount, dismount, allocate, and deallocate media.

When a partition is allocated by an application, RSM changes its state from Available to Allocated and assigns LMID. Applications can only use allocated partitions. When media is deallocated, RSM disassociates the LMIDs from the logical media.


Groups of Media

[This is preliminary documentation and subject to change.]

RSM media belongs to the following two groups:

  • Libraries that represent physical media grouping
  • Media pools that represent logical media grouping

Libraries

Libraries are physical media storage locations. RSM media always belong to a library.

There are three types of libraries in an RSM system: online, stand-alone drives, and offline.

  • Online libraries are robotic library units. Online libraries are sometimes referred to as jukeboxes.
  • Stand-alone drives are operator-mounted drives, such as single-slot CD-ROM or tape drives. RSM treats stand-alone drives as online libraries with one drive and an insert/eject port.
  • Offline libraries hold all media that are known by RSM but not in an online library or stand-alone drive. A set of shelves is an example of an offline library. There is only one offline library in an RSM system. The offline library is the only library that can hold more than one type of media.

    Media can be moved from an offline library to an online library or stand-alone drive only when the administrator physically inserts the media into a library unit or stand-alone drive.

In addition to media, libraries contain devices that are also managed by RSM. Drives and robotic changers are devices. RSM maintains information about devices in the database.

Media Pools

All RSM media also belong to a media pool. Media pools are logical collections of media that have the same media management policies. Media pools are used by applications to control access to media within an RSM system. A single media pool can contain media from more than one library. Each medium can belong to only one media pool.

The purpose of media pools is to provide a mechanism by which policies and properties can be defined for logical groupings of media. In the past, media policies and properties were typically defined for all the media in a library.

With RSM media pools, media in a single library can be shared among multiple applications. Therefore:

  • Media in the same library can have different policies and properties
  • Media policies and properties can span multiple libraries.

RSM supports two classes of media pools:

  • System media pools include scratch, foreign, and import media pools. RSM creates one scratch, one foreign, and one import media pool for each media type in an RSM system.
  • Application media pools are created by applications. There can be any number of application media pools in an RSM system.

You can logically group media pools by creating hierarchies of media pools. However, a media pool cannot contain both media and other media pools.

Administrators can move media among pools through the RSM MMC snap-in, or you can use the RSM API to do this in your application.

The different types of media pools are described next.

Scratch Media Pools

Scratch media pools contain media that are not allocated by an application and do not contain useful data. RSM creates one scratch media pool for each media type in an RSM system.

Scratch media pools are media buffers for application media pools. An application can draw media from a scratch media pool when it is necessary for the application to allocate media. An application can deallocate media to send the media to a scratch pool. Only media that are not allocated by an application can be moved between media pools.

An application media pool can be configured so that it never automatically draws media from or returns media to scratch pools. When a media pool uses this configuration, the administrator must explicitly move media in or out of that pool.

Foreign Media Pools

Foreign media pools contain blank media and media that have unrecognized on-media identifiers (OMIDs).

Foreign media pools also contain media that are new to an RSM system. Administrators should immediately move new media from the foreign media pool to a scratch media pool so that RSM can assign and record OMIDs to the media for tracking.

Media in foreign media pools can be inserted, ejected, mounted, dismounted, and moved to a scratch media pool. Foreign media are automatically deleted from the RSM database when they are ejected from an online library or stand-alone drive.

Import Media Pools

RSM puts media in an import media pool when RSM recognizes the on-media identifier, but the piece of media is not cataloged in the current RSM database. For example, media in an import media pool can be from one office location that is introduced into an RSM system at another office location. RSM recognizes the OMIDs, but does not have information about the media in the current RSM database.

Media in import media pools can be moved into a scratch pool or application pool for reuse. Such media must be explicitly moved using the RSM API or the RSM MMC snap-in.

Application Media Pools

Application media pools are used by applications to determine which media can be accessed by which applications and to set the policies for that media. Media in an application media pool are owned by an application or group of applications.

Application media pools can be created by an application using the RSM API or by the administrator in the RSM MMC snap-in.

An application can use more than one media pool. For example, a backup application might use one media pool for full backup media and one for incremental backup media, each containing a different media type. More than one application can also share one media pool.

Media Pool Configuration Model

This section describes an example system and how the media pools might be configured. The example system contains one optical library and one tape library, and the administrator wants to use a backup application and a document management application on the system.

The following table shows the intersections among the libraries and applications in this system. The backup application uses tape media to store full and incremental backups, and optical disk for catalog storage. The document management application uses tape media to store engineering archive documents, and optical disk media to store accounting and engineering documents.

 | Backup Application | Document Management Application
Tape Media | Full backup Incremental backup | Engineering archive documents
Optical Disk Media | Catalog storage | Accounting documents Engineering documents

The following image depicts a model media pool configuration for this system. This configuration uses nesting to create a useful media pool configuration. Notice that each media pool contains other media pools or media; no media pool contains both.

In this media pool configuration, each media pool contains one type of media and serves a single purpose.


Media Identification

[This is preliminary documentation and subject to change.]

RSM uses the following concepts to gather information about and identify media.

  • Media identifiers
  • Media states


Media Identifiers

[This is preliminary documentation and subject to change.]

RSM uses the following media identification methods to gather information about media.

  • On-media identifiers
  • Sequence numbers
  • Bar codes

On-media Identifiers

[This is preliminary documentation and subject to change.]

On-media identifiers (OMIDs) are labels that are electronically recorded on each piece of new media in an RSM system. RSM uses OMIDs to track media in the RSM database. When media is moved from a foreign media pool to a scratch media pool, RSM assigns a scratch OMID and electronically records it at the beginning of the media. When the media is moved to an application media pool and allocated by an application, the application overwrites the scratch OMID with a media label. RSM uses a subset of the information in the media label to create the application OMID, which RSM uses to track the piece of media.

After the first time a piece of media is inserted into a media library unit in an RSM system, RSM uses the OMID to recognize the piece of media. RSM stores and maintains information about OMIDs in the RSM database. All media managed by RSM have OMIDs.

OMIDs have two important parts: a label type and a label ID. The label type identifies a media format, such as Microsoft tape format (MTF). The label ID is a unique identifier for the medium. If RSM does not recognize the medium's label type, RSM puts the medium in the foreign media pool. If RSM recognizes the label type but does not recognize the label ID, RSM puts the medium in the import media pool. If RSM recognizes the label type and the label ID, RSM updates the database to show that the medium is online and does not alter its current media state.

RSM does not record OMIDs on read-only or write-once media. RSM uses volume and serial number information that is already associated with the media.

Sequence Numbers

RSM assigns sequence numbers to media so that the administrator can visually identify media during insertion, ejection, and offline tracking. The sole purpose of sequence numbers is to help the administrator visually identify physical media. When a library does not support bar codes, the administrator must label all the media in that library with the sequence numbers assigned by RSM when the media are ejected for the first time.

Bar Codes

In online libraries that support bar codes, RSM uses bar codes to accelerate media inventories and as visual identification for the administrator. Media that have a bar code also have OMIDs and sequence numbers.

Bar codes are most useful to RSM when they are unique.


Media States

[This is preliminary documentation and subject to change.]

Media states identify the condition of each partition of the media in an RSM system and define which applications have access to partitions. When media is introduced to RSM, RSM reads the OMID or bar code of the media to determine the state of the partition. This process is known as classification.

The following table describes the RSM media states.

Media State | Description
Allocated | Media that are in use and assigned to application media pools.
Available | Media that can be allocated for use by applications.
Completed | Media that are in use but can no longer be used for write operations.
Decommissioned | Media that have reached their allocation maximum (specified by the administrator or an application) and cannot be used again.
Foreign | Media whose label types and label IDs are not recognized by RSM, and media that are new to RSM.
Imported | Media whose label types are recognized by RSM, but whose label IDs are not recognized by RSM.
Incompatible | Media that are not compatible with the library in which they were classified. This media should be immediately ejected from the media library unit. RSM puts Incompatible media in the foreign media pool.
Reserved | Media that are being held by an application.
Unprepared | Media that are in a scratch media pool but have not been assigned scratch labels by RSM. This is a temporary state; applications cannot allocate Unprepared media.

How Media Moves Among States

The following figure illustrates what happens when media is inserted into an RSM library.

When media is inserted into a library unit in an RSM system, RSM classifies the medium by reading its bar code (if unique) or OMID. If the RSM database contains information about the medium, RSM does not alter the current states of its partitions and relies on the information in the RSM database.

If RSM does not recognize the label type of an OMID or if the medium is new to RSM, RSM sets the medium's state to Foreign. If RSM recognizes the label type but not the label ID, RSM sets the medium's state to Imported.

If the medium is not compatible with the current library, RSM sets the medium's state to Incompatible. Media in the Incompatible state cannot be changed to another state, and it should be ejected from the media library unit.

Foreign and Incompatible media do not have a recognized OMID and are not managed by RSM. They are deleted from the database when they are ejected.

RSM never sets the state of inserted media to Reserved. This state can only be set by an application.

Foreign State

The following figure shows movement out of the Foreign state.

When media that RSM cannot identify is inserted into a RSM library, RSM sets the medium's state to Foreign and moves the medium to the foreign media pool.

Foreign media can only be changed to the Available state by moving it to the scratch pool. Foreign media must be explicitly changed by an administrator or an application.

Available State

The following figure shows movement in and out of the Available state.

RSM moves media from the Available to the Allocated state when an application allocates it using the AllocateNtmsMedia function.

When an application deallocates media, RSM checks the database for the number of times the specified medium has been allocated. If the medium has reached its allocation maximum, RSM changes the state of the medium to Decommissioned. Only media in the Available state can be changed to the Decommissioned state.

When an application deallocates one partition of a piece of media that contains Reserved partitions, RSM changes the state of all Reserved partitions to Available.

Available and Decommissioned media can be in scratch or application media pools.

Allocated State

The following figure shows movement in and out of the Allocated state.

Media in the Allocated state can be changed to the Available and Completed states. The process of changing the state of media from Allocated to Available is called deallocation. The process of changing the state of a piece of media from Allocated to Completed is called completion.

You can allocate and deallocate media without moving it out of an application media pool.

When you use the _ALLOCATE_NEW option of the AllocateNtmsMedia function, RSM allocates one partition of the specified medium and sets the state of all other partitions to Reserved. You can specify the _ALLOCATE_NEXT option of the AllocateNtmsMedia function to allocate the next Reserved partition of the specified media. When there are no more Reserved partitions, RSM returns an error message.

Imported State

The following figure shows movement in and out of the Imported state.

The state of Imported media must be explicitly changed to Available or Allocated.

When media are moved from the import media pool to a scratch media pool, RSM sets the state of the media to Available.

RSM initially sets the state of CD-ROM media to Imported and places it in the import media pool.

How Media Pools and Media States Are Related

Many changes in media state are accompanied by movement between media pools. For example, you can configure application media pools to automatically allocate media from scratch pools when there are no Available media in the application media pool; this is the Draw from Scratch option. You can also configure application media pools to automatically return Available media to scratch pools; this is the Return to Scratch option.. These options can be set using the RSM API or the RSM MMC snap-in.

When RSM deallocates media and changes the state to Available, RSM checks the allocation count. If the specified medium has been allocated the maximum number of times, it is decommissioned by RSM. If the specified medium has not been allocated the maximum number of times, RSM checks the Return to Scratch option. If the Return to Scratch option for that application media pool is set to True, RSM returns the specified medium to the appropriate scratch media pool. If the Return to Scratch option is set to False, the media remains in the application media pool.

The administrator can also set the Draw from Scratch option for an application media pool. If this option is set to True, RSM automatically allocates media from the appropriate scratch media pool when the application media pool does not contain any Available media. If this option is set to False, RSM generates an error message when there are no Available media in the application media pool.


RSM Database Object Relationships

[This is preliminary documentation and subject to change.]

All RSM objects are represented in the RSM database. The relationships among these objects are important for enumeration. When you use the EnumerateNtmsObject function, you specify the object ID of the appropriate container object. For example, specify a library ID to enumerate the drives in that library.

The following table lists the database relationships among RSM objects. The NULL container represents the RSM system and enumerates top-level objects.

Container Object | Object
Library | Changer
 | Door
 | Drive
 | Library request
 | Media type
 | Physical media
 | Port
 | Slot
Logical media | Partition
Media pool | Logical media
 | Media pool
 | Physical media
NULL | Changer
 | Changer type
 | Door
 | Drive
 | Drive type
 | Library
 | Library request
 | Logical media
 | Media pools (scratch, foreign, import and application root)
 | Media type
 | Operator request
 | Port
 | Physical media
 | Partition
Physical Media | Partition


RSM Security

[This is preliminary documentation and subject to change.]

RSM provides security for media pool and library objects. Media pool security controls access to media, including physical media, partitions, and logical media. Library security controls access to physical library units, including drives, changers, slots, and insert/eject ports.

Administrators can use the RSM MMC snap-in to set and check object security. Applications can use the SetNtmsObjectSecurity and GetNtmsObjectSecurity functions to set and check security for an RSM object.

When you use nested media pools, the security of the lowest-level media pool determines the security of the media objects.

The following table lists RSM functions and the RSM security descriptors required to successfully perform each operation. This table uses the following key.

  • U = NTMS_USE_ACCESS
  • M = NTMS_MODIFY_ACCESS
  • C = NTMS_CONTROL_ACCESS
 |  | Media Pool | Library |  | Computer
OpenNtmsSession |  |  |  |  | U
AllocateNtmsMedia |  | M |  |  |
CompleteNtmsMedia |  | M |  |  |
CreateNtmsMediaPool |  | M |  |  |
DeallocateNtmsMedia |  | M |  |  |
DecommissionNtmsMedia |  | M |  |  |
DeleteNtmsMedia |  | M |  |  |
DeleteNtmsMediaPool |  | C |  |  |
DismountNtmsMedia |  | U | U |  |
MountNtmsMedia |  | U | U |  |
MoveToNtmsMediaPool |  | M |  |  |
SwapNtmsMedia |  | M |  |  |
AccessNtmsLibraryDoor |  |  | C |  |
CancelNtmsLibraryRequest |  |  | C |  |
DeleteNtmsLibrary |  |  | M |  |
DismountNtmsDrive |  |  | C |  |
EjectNtmsMedia |  |  | C |  |
InjectNtmsMedia |  |  | C |  |
InventoryNtmsLibrary |  |  | C |  |
UpdateNtmsOmidInfo |  |  | C |  |
CancelNtmsOperatorRequest |  |  |  |  |
SatisfyNtmsOperatorRequest |  |  |  |  | C
SubmitNtmsOperatorRequest |  |  |  |  |
WaitForNtmsOperatorRequest |  |  |  |  | C
CleanNtmsDrive |  |  | C |  |
EjectNtmsCleaner |  |  | C |  |
InjectNtmsCleaner |  |  | C |  |
ReleaseNtmsCleanerSlot |  |  | C |  |
ReserveNtmsCleanerSlot |  |  | C |  |
GetNtmsObjectInformation |  |  |  |  |
NTMS_DRIVE |  |  | C |  |
NTMS_LIBRARY |  |  | C |  |
NTMS_CHANGER |  |  | C |  |
NTMS_STORAGESLOT |  |  | C |  |
NTMS_IEDOOR |  |  | C |  |
NTMS_IEPORT |  |  | C |  |
NTMS_PHYSICAL_MEDIA |  | C |  |  |
NTMS_MEDIA_POOL |  | C |  |  |
NTMS_PARTITION |  | C |  |  |
NTMS_LOGICAL_MEDIA |  | C |  |  |
NTMS_OPREQUEST |  |  |  |  | M
NTMS_MEDIA_TYPE |  |  |  |  | M
NTMS_DRIVE_TYPE |  |  |  |  | M
NTMS_CHANGER_TYPE |  |  |  |  | M
NTMS_LIBREQUEST |  |  | M |  |
GetNtmsObjectSecurity | READ_CONTROL for the object
SetNtmsObjectSecurity | To set discretionary access rights |  |  | WRITE_DAC or ownership of the object
 | To change owner and group information |  |  | WRITE_OWNER or ownership of the object
 | To set system access rights |  |  | SE_SECURITY_NAME for the process


Designing an RSM Application

[This is preliminary documentation and subject to change.]

This section describes how to design an RSM application. You should read it before you make decisions about how to use RSM in your application.


Before You Start

[This is preliminary documentation and subject to change.]

Before you begin developing your RSM application, you must complete the following tasks:

  • Building a media label library
  • Creating and configuring media pools
  • Allocating and using media
  • Cleaning up after a disaster


Building a Media Label Library

[This is preliminary documentation and subject to change.]

A media label library is a DLL that can interpret the format of a media label written by an RSM application. Before you develop your application, you must develop a media label library so that RSM can read media labels written by your application.

For more information about building a media label library, see Developing a Media Label Library.


Creating and Configuring Media Pools

[This is preliminary documentation and subject to change.]

After you build your media label library, you can begin developing your RSM application. The first task your application should perform is to create and configure media pools. You can use the CreateNtmsMediaPool function to create media pools.

The following points should be considered when you set the parameters for this function and configure the media pool:

  • Available media types

    You can enumerate the media pools in the scratch media pool folder to generate a list of the media types in an RSM system. You can enumerate the media type object to list all the media types supported by RSM. You can also enumerate the media type object of each library in the system.

  • Automatic media draw

    Decide whether RSM will automatically draw media from the scratch pool when there are no media set to the Available state in the media pool.

  • Automatic media return

    Decide whether RSM will automatically return media to the scratch pool when the media are no longer needed.

  • Media pool security

    Decide what level of security you want to assign to the media pool.


Allocating and Using Media

[This is preliminary documentation and subject to change.]

After you create and configure media pools, you can allocate media using the AllocateNtmsMedia function. This function returns a logical media identifier (LMID) that you can use to mount the media with the MountNtmsMedia function. You can also use this LMID to control the media.

After you mount and use media with standard Microsoft® Win32® I/O functions, you should use the DismountNtmsMedia function to dismount it. You can open and close media many times before dismount.

The following list follows the path of functions you should use to access media in a RSM system.

  • OpenNtmsSession
  • AllocateNtmsMedia
  • MountNtmsMedia
  • CreateFile
  • CloseFile
  • DismountNtmsMedia
  • DeallocateNtmsMedia
  • CloseNtmsSession

You can use the DeallocateNtmsMedia function to deallocate media. You can mount and dismount media many times before deallocation.


Cleaning up After a Disaster

[This is preliminary documentation and subject to change.]

RSM might reset deallocated media to allocated when the RSM database is restored with an older copy during a disaster recovery. You can prepare for this by designing your application to periodically enumerate the LMIDs in each media pool and deallocate any media that you no longer need.

For more information about disaster recovery see Disaster Recovery.


Using Basic RSM Functions

[This is preliminary documentation and subject to change.]

This section describes the typical life cycle of RSM media. Most media in RSM follows the same path; variations from this path are provoked by unusual situations. An example of an unusual situation is introducing media from one RSM system into another.

The following figure illustrates the typical media pool cycle of RSM media.

When an unrecognized medium is inserted into an online library, RSM typically puts the medium in the foreign media pool. The administrator or your application can move the medium to the appropriate scratch media pool using the MoveToNtmsMediaPool function.

The following figure illustrates the typical media state cycle of RSM media.

When a new medium is inserted into an online library, RSM typically sets the medium's state to Foreign. When the administrator or your application moves the medium to a scratch media pool, RSM sets the medium's state to Available. You can use the AllocateNtmsMedia function to allocate Available media in the application media pool. If there are no Available media in the application media pool and the Draw from Scratch option is set to True, RSM allocates media from a scratch media pool. After you allocate media, you can use the MountNtmsMedia function to mount and write to the medium.

Note When you use the MountNtmsMedia function to mount tape media, remember that your application must specifically set the drive to fixed or variable block mode. Your application cannot assume that the device is in the default mode. You can use the Microsoft® Win32® function, SetTapeParameters to set the drive mode.

When you do not want to record any more information on the medium, you can set the medium's state to Completed using the SetNtmsMediaComplete function. Typically, Completed media will not be written to again. Placing a medium in the Completed state allows a management application to replicate or refresh the media.

Media that hold less vital information and are recorded on many times are typically decommissioned after the maximum number of allocations. Only Available media can be decommissioned, so you must use the DeallocateNtmsMedia function before you can decommission a piece of media. You can use the DecommissionNtmsMedia function to decommission Available media.

After you deallocate media, you can leave the media in the application media pool or move it to a scratch media pool so that it can be used by other applications. Your application can reallocate Available media that remains in the application media pool until it has reached its allocation maximum (determined by the administrator or an application).


Using Operator Requests in RSM

[This is preliminary documentation and subject to change.]

An RSM operator request is a request for a human operator to perform a task. Operator requests can be issued by RSM or by RSM applications. RSM generates operator requests in the following situations:

  • Media must be moved online because an application has initiated a mount request for media that is offline.
  • There are no Available media online in the specified application media pool or in the appropriate scratch media pool when an application requests media allocation. The operator can supply new media or Available media that is offline to satisfy the request.
  • A device failed and requires service.
  • A drive needs to be cleaned and there is no usable cleaner cartridge available in the library unit.

Operator requests are displayed in the RSM MMC snap-in. Operators can satisfy or cancel operator requests. When an operator satisfies an operator request, the operator must acknowledge the request in the RSM MMC snap-in. When an operator cancels an operator request, RSM notifies the application that generated the request. RSM saves operator requests for less than one hour after they have been satisfied or canceled.

The RSM API includes the following functions to manage operator requests.

  • SubmitNtmsOperatorRequest

    This function submits an operator request and returns the status of the request (Satisfied or Cancelled) or times out (if the operator does not act upon the request). The dwRequest parameter of this function specifies the request type. Use the NTMS_OPREQ_MESSAGE type for your application messages.

  • WaitForNtmsOperatorRequest

    Typically, applications use the SubmitNtmsOperatorRequest function to submit operator requests and use the WaitForNtmsOperatorRequest function to wait for their resolution.

  • CancelNtmsOperatorRequest

    This function cancels an existing operator request.

  • SatisfyNtmsOperatorRequest

    If an application detects that the operator did not acknowledge a satisfied operator request, the application can use this function to remove the request.


Cleaning Drives in RSM

[This is preliminary documentation and subject to change.]

Unless you are developing an application that is intended to manage device maintenance, your application does not have to address drive cleaning. RSM is designed to manage device maintenance.

In the RSM model of device maintenance, each library unit can contain one cleaner cartridge. Administrators can use the RSM MMC snap-in to clean a drive, reserve or release a cleaner slot, and insert or eject a cleaner cartridge.

RSM maintains a usage count for each cleaner cartridge. When a cleaner reaches its maximum usage count, RSM generates an operator request. If the administrator ejects a cleaner cartridge before it has reached its maximum usage count, RSM releases the usage count information.

If you are developing an application that manages device maintenance, you can use the following RSM functions to implement drive cleaning functionality.

  • CleanNtmsDrive
  • EjectNtmsCleaner
  • InjectNtmsCleaner
  • ReleaseNtmsCleanerSlot
  • ReserveNtmsCleanerSlot


RSM Configuration

[This is preliminary documentation and subject to change.]

When configuring RSM applications, administrators and application developers should remember the following issues:

  • For performance reasons, administrators should not manage more than 1,000 media in a single RSM system.
  • RSM includes an autoconfiguration feature that maps each drive in a library unit to a changer. To avoid manual configuration, administrators should install changers and their drives on the same SCSI bus.
  • RSM does not support every existing piece of hardware. Before adding new hardware to an RSM system, administrators must check http://www.microsoft.com/isapi/hwtest/hcl.idc on the Microsoft Web site for the Microsoft® Windows NT® Hardware Compatibility List (HCL) that lists all the libraries and stand-alone drives supported by RSM.


Disaster Recovery

[This is preliminary documentation and subject to change.]

This section addresses the backup and recovery of a RSM database. The following are tasks that the administrator must complete to prepare for and execute the recovery process:

  1. Backing up the RSM database
  2. Tracking the RSM database backup media
  3. Mounting the media
  4. Recovering the database
  5. Updating the restored database

Note The information in this section assumes that there has been no change to the system configuration that affects RSM.


Backing Up the RSM Database

[This is preliminary documentation and subject to change.]

To back up the RSM database, a backup application must open an RSM session and use the ExportNtmsDatabase function. This function creates a replica of the current database so that the recovery application can back up the database without stopping RSM. RSM creates the replica in the %SYSTEMROOT%\System32\NTMSData\Export subdirectory of the RSM database directory.


Tracking the RSM Database Backup Media

[This is preliminary documentation and subject to change.]

The administrator must always know the location of the most recent RSM database backup. To help identify the backup during disaster recovery, the administrator should record and maintain the following information about the latest database backup in a safe place (such as a notebook or a spreadsheet):

  • Sequence number
  • Bar code

    The administrator can look for the appropriate sequence number and bar code (if available).

  • On-media identifier (OMID)

    The administrator can use the RSM MMC snap-in to look up the OMID. The RSM MMC snap-in displays the OMID of media in the import pool on the media property page. However, a recovery application that is fully integrated with RSM can select the right media for disaster recovery based on this reconstructed OMID information.

During disaster recovery, the administrator typically reinstalls the operating system and generates an empty RSM database. When the system is started with a new RSM database, RSM places all online media in the import media pool. The sequence number, bar code, and OMID can help the administrator identify the media with the most recent database backup during disaster recovery.


Mounting the Media

[This is preliminary documentation and subject to change.]

To allow the recovery application to access media, the media must be mounted in a drive. Most libraries have doors that allow the administrator to mount the media. If there is no door, the administrator can mount media from the import media pool in the RSM MMC snap-in or from the front panel of the library.

Recovery applications should use the RSM API to select and mount the appropriate media as part of their disaster recovery procedures.


Recovering the Database

[This is preliminary documentation and subject to change.]

When the RSM database has been restored, the recovery application can use the ImportNtmsDatabase function. This function makes the changes necessary for RSM to import the restored database and inventory the online libraries on the next restart. Recovery applications should offer the administrator the option to restart RSM or the system.

Typically, recovery applications also restore the registry and reboot the system after it has been restored. Applications can restore the registry and import the RSM database in any order.


Updating the Restored Database

[This is preliminary documentation and subject to change.]

The restored database might not be synchronized with the current state of media. The following table describes some reasons that the RSM database might not be synchronized and how your application can resolve each problem.

Problem | Solution
A specified medium is deallocated by an application after the backup but before the disaster and remains in the application media pool. RSM recognizes this medium as allocated and puts it in the application media pool. | The application can deallocate this medium.
A specified medium is allocated by an application after the backup but before the disaster. RSM puts the medium in the import media pool. | The application can import the medium to the scratch media pool.

When the restored database is updated, you can use the RSM system to complete the recovery process.


Recovery with Non-RSM Applications

[This is preliminary documentation and subject to change.]

RSM opens the RSM database when it needs it and closes the database immediately after usage. This allows a non-RSM recovery application to back up the RSM database. To recover the database using a non-RSM application, restore the database to a temporary location, shut down RSM, copy the restored database files to the %SYSTEMROOT%\System32\ntmsdata directory, and restart RSM.


Restoring the RSM Database in the Absence of a Backup

[This is preliminary documentation and subject to change.]

This section describes a strategy for an application to recover the RSM database when the database has been lost and there is no backup copy, but the application has not lost the database that refers to the lost RSM database. For this example it is assumed that the application has kept both the RSM LMID and its own OMID information in its database. An application can take the following steps to recover the RSM database:

  1. All the media in the library will appear in the import pool.
  2. The application must have a mechanism that scans the Import media pool for its media. This can be accomplished by reading the OMID information of the partitions of the physical media and finding all media with the szOmidLabelType parameter that is the application's type. As an additional check the application can verify that the szOmidLabelInfo parameter is correct for the media.
  3. For all partitions found, the application must call the AllocateNtmsMedia function, specifying the partition and media pool, to allocate the target media pool.
  4. The application database must be updated with the new LMID that is assigned to the media. The application should search through its database for all cases of the OMID it has found and replace the corresponding LMID with the new one.
  5. After the operation is complete, both the RSM database and the application's database should be in a usable state again.
  6. Media that is not in the library must be inserted to fully reconstruct the RSM database.


Developing a Media Label Library

[This is preliminary documentation and subject to change.]

A media label library is a DLL that can interpret the format of a media label written by an RSM application. RSM uses media label libraries to read application media labels and translate the medium's label type and label ID to create an application on-media identifier (OMID). You must develop a media label library for any application that uses a media format that is not supported by RSM. (RSM supports FAT, NTFS, and CDFS for disk media and includes a media label library that identifies NTBackup media.)

To use RSM, your media labels must:

  • Be recorded at the beginning of the specified media.
  • Include a label type that is the same across all media.
  • Include a label ID that is unique across all media of that label type.

RSM includes two media label libraries: Mll_scr.dll interprets scratch media labels, and Mll_ntbk.dll interprets NTBackup media labels. When RSM reads a media label, it communicates with each registered media label library to find out which application wrote the media label.


Sample Media Label Library

[This is preliminary documentation and subject to change.]

The following section contains the source code for an example media label library that identifies a fictitious media label. If you use industry-standard media formats, such as Microsoft tape format (MTF) and System Independent Data Format (SIDF), keep in mind that other companies use these formats. Your media label library should not recognize all MTF or SIDF media labels; it should recognize only those written by your application.

DWORD ClaimMediaLabel (const BYTE * const pBuffer,
                 const DWORD nBufferSize,
                 MediaLabelInfo *pLabelInfo)
{
    #include <ntmsmli.h>
    // local variables
    NTMS_FictLabel   *pLabel ;
    // see if this is our format ...
    pLabel = (NTMS_FictLabel *) pBuffer ;
    // if this is the NTMS Fictitious Media Label ... get the
    // appropriate info out of it ...
    if (wcsncmp (pLabel->LabelType, L"NTMS Fictitious Media
             Label", NTMS_FictLabelTypeSize)  == 0)
    {
        // use Unicode string copy functions ... if the
        // strings in the media label are not in Unicode then
        // they must first be converted to Unicode by using
        // mbstowcs() routine and then copied into the
        // MediaLabelInfo structure ...
        wcscpy (pLabelInfo->LabelType, pLabel->LabelType)
        pLabelInfo->LabelIDSize = pLabel->LabelIDSize ;
        memcpy (pLabelInfo->LabelID, pLabel->LabelID,
              pLabelInfo->LabelIDSize) ;
        wcscpy (pLabelInfo->LabelAppDescr,
              pLabel->LabelAppDescr) ;
        return NO_ERROR ;
    }
    // not an NTMS fictitious media label ...
    return ERROR_BAD_FORMAT ;
}
DWORD MaxMediaLabel (DWORD * const pMaxSize)
{
    // set the max size for the NTMS fictitious media label ...
    *pMaxSize = 1024 ;
    return NO_ERROR ;
}


Testing Your Media Label Library

[This is preliminary documentation and subject to change.]

RSM includes a sample test utility that reads media and uses the media label library functions to verify that the information added to the MediaLabelInfo data structure is correct. RSM displays the information added to the data structure. The utility is hard-coded to read \\.\tape0 and uses the media label library, YourMediaLabelLibraryHere.dll. Replace YourMediaLabelLibraryHere.dll with the name of your media label library, including the absolute path, before using the test utility.


Installing A Media Label Library

[This is preliminary documentation and subject to change.]

You must install or provide instructions for installing your media label library in the installation program for your application. Your installation program must create the appropriate registry entries and copy your media label library to the appropriate directory. The following figure illustrates the registry hierarchy that your application must create. YourCompanyName represents your company or product name and must be unique.

Under the key for your media label library, the installation program must create two registry values: Description and Path. The previous figure displays these values in the right window pane. The Description registry value contains a description of the media label library. The Path registry value contains the absolute path of the media label library.

Remember the following rules when you develop the installation program for your application:

  • Installations of new media label libraries are restricted to members of the Administrator group.
  • The registry entries that contain the list of media label libraries are accessible only by members of the Administrator group.
  • The ExtMLL key is optional.
  • The directory that contains all the media label library DLLs is typically accessible only by members of the Administrator group. The default directory for RSM media label libraries is winnt\system32.

Note If you distribute an update, users can install the new media label library through the RSM MMC snap-in.


Using MTF Media Labels

[This is preliminary documentation and subject to change.]

RSM provides a generic media label library for Microsoft Tape Format (MTF). An application that uses MTF as a media format for tape may not be required to provide a media label library.

RSM has the following requirements for applications that use MTF:

  • RSM uses the MTF Common Block Header for tape identification. RSM verifies that the label is MTF format by checking that BlockHeader.BlockType is equal to MTF_TAPE and that the checksum of the header is correct.
  • RSM uses the TapeName/Media Name as the Label Application Description and the Software Name as the Label Type
  • If the Tape Media Label Bit is set in the Tape Attribute field, the label library verifies the media label field of the MTF label and checks the description/label field for a GUID (UUID) of the form
    12345678-1234-1234-1234-123456789012
  • If found, RSM uses the UUID as the LabelID of the medium. If a GUID is not found in the field, then an MD5 algorithm is used to generate a unique ID from the MTF block and it is returned as the LabelID.


RSM Startup

[This is preliminary documentation and subject to change.]

RSM performs several tasks at startup time. During some of the tasks, RSM is unavailable for commands. At other times during startup, RSM may accept commands, however, the execution of the command may be delayed while RSM completes initialization. The following steps outline the process followed by RSM during startup. It is important to note that the process is the same when the service is restarted or the computer has been restarted.

  1. Build or reconfigure the RSM database based on the current device configuration.
  2. Remove all work-items from the work queue.
  3. Start a thread to process requests for each online library in the system.
  4. Each thread checks it configuration and performs a default inventory for its library. The inventory may result work items being placed on the library's work queue.
  5. Start accepting requests.
  6. Complete the default inventory work.

Note that inventory will empty the drives if possible. If the drives are currently in use, RSM leaves the media in the drive and examines the media in the drive at a later time. Also, note that the inventory performed is the default inventory for the specified device which can be set to FULL, FAST, or NONE.


Deploying an RSM Application

[This is preliminary documentation and subject to change.]

This section describes issues associated with deploying an RSM application.


Installation Issues

[This is preliminary documentation and subject to change.]

This section describes issues that affect the installation of an RSM application.

  • During installation, instruct the user to insert a tape into each library that will be under RSM control before you create your media pools. If the libraries are empty, RSM cannot detect the media type.


Device Configuration

[This is preliminary documentation and subject to change.]

RSM supports two types of device configuration: autoconfiguration and manual configuration. Administrators can use the autoconfiguration feature of RSM only if the following statements are true:

  • All drives are installed on the same SCSI bus as the associated changer.
  • All library hardware units currently in use in the system support drive element address reporting with the ReadElementStatus SCSI command.

Because not all library hardware units and system configurations support the RSM autoconfiguration feature, RSM provides a method for manually configuring library hardware units. However, administrators should not use this method unless it is absolutely necessary because manually configured devices do not recognize system configuration changes. Each time a change is made to a device in an RSM system that contains one or more manually configured devices, the administrator must repeat the manual configuration process.


RSM Media Handling

[This is preliminary documentation and subject to change.]

This section explains media handling in RSM. Media handling is defined as the actions and reactions that RSM makes in response to operations performed by both administrators and applications. In particular, the label semantics of RSM are defined as media, entered into the system, moved between media pools, and allocated and deallocated for use by applications. Because the behavior of RSM in some circumstances varies by media type, the description of its behavior has been divided by media type and presented in tables.

The second part of this section describes importing media into an RSM system. This is the case where an application has been integrated with RSM and has media that was written without RSM (for example, in a previous version of the application) that it is moving under RSM control.


RSM Media Type Support

[This is preliminary documentation and subject to change.]

RSM manages all removable media and drive types. RSM supports media types differently based on their read and write characteristics. The following topics describe the specific types of removable media and drives.


READ_ONLY

[This is preliminary documentation and subject to change.]

CD-ROMs that support the CD-ROM file system (CDFS) are treated as imported media when first identified by RSM. These imported media can be moved to other user-defined application media pools for further organization and cataloging. A user-defined string can be created in the database to allow users to more easily locate their specific volumes. For CD-ROM, duplicate OMIDs are likely (because the OMIDs are on the same CD-ROM), and these are tracked. During inventory, two identical CD-ROMs can get their user-defined descriptions exchanged, but this is not a problem because they are identical.

RSM accesses the disk drive at the driver level. After an RSM mount, the application can view the volume as a mapped drive (for example, E:\). As part of updating drive configuration, both the volume name and the mapped name are available in the RSM database so the application can access the medium with either handle.

DVD-ROM and UDF support are not available in Windows NT 5.0.


WRITE_ONCE

[This is preliminary documentation and subject to change.]

Write once, read many (WORM) media is not supported by RSM in Windows NT 5.0.


Rewritable Tape Media

[This is preliminary documentation and subject to change.]

RSM manages many tape media types. RSM depends on the ability of media to mark itself as scratch when the media is committed to the scratch pool. Tape OMID formats such as MTF are supported by default in RSM. Applications that employ proprietary label formats can extend the OMID label recognition package so that their media formats are recognized by RSM during media classification.

RSM accesses the tape drive at the raw driver level. Since tape drives are not mapped to drive letters, the application uses the raw path of the tape device (for example, \\.\Tapex) to open and access the tape device.


Rewritable Disk Media

[This is preliminary documentation and subject to change.]

There are two classes of rewritable removable disk: rewritable optical disk (3.5", 5.25") and rewritable magnetic disk (floppy, ZIP, JAZ, and so forth). In Windows NT 5.0, RSM supports rewritable optical disks, but does not support the management of rewritable magnetic disk..

RSM accesses the disk drive at the raw driver level. On an RSM mount completion, the application can view the volume as a mapped drive (for example, E:\). As part of updating drive configuration, both the raw path and the mapped path are available in the RSM database so the application can access the drive with either handle.


RSM Media Pools

[This is preliminary documentation and subject to change.]

There are four types of media pools in RSM:

  • Foreign

    Media that is new or unrecognized

  • Import

    Media that have labels that are recognized by the system but are not in the RSM catalog

  • Scratch

    Media available for writing

  • Application

    Media used by a particular application on the system

All media in an application media pool are in the RSM catalog by default. Media in the available state can reside in both the scratch media pools and application pools. Note that there are individual Import, Foreign, and Scratch media pools for each media type detected on the system.

Media in Scratch, Import, or Foreign media pools are deleted from the RSM catalog when they are ejected from the library or drive.


RSM Labels and Application Label Requirements

[This is preliminary documentation and subject to change.]

RSM requires that all media be labeled so that it can be identified when it is inserted into a drive. Applications are required to identify media they are using by providing a Media label library that identifies the media it has labeled.

By providing this flexibility, RSM can support multiple labeling methods simultaneously, and allow proprietary labels to be used as well. RSM requires that an application relabel media assigned to it using the AllocateNtmsMedia function. After the application relabels the media it should use the UpdateNtmsOmidInfo function to notify RSM of the identification change.

RSM supports a default or Scratch label for both sequential and optical rewritable media. Writing a Scratch label destroys all data on the media. For sequential media, RSM uses a Microsoft tape format (MTF) label that is applied as media enters the Scratch pool. RSM does not update the media description when writing a Scratch label. RSM currently uses a binary label to identify optical media that are placed in the scratch pool.

RSM supports CD-ROM that cannot be relabeled. For CD-ROM media, RSM recognizes CDFS as a valid label. Since duplicated CD-ROMs are a common occurrence, RSM handles a CD-ROM quite differently from writable media.


Importing RSM Media

[This is preliminary documentation and subject to change.]

Applications that are upgrading to RSM must transition already written media into RSM. Moving legacy media that was created before RSM under the control of RSM is called importing the media. To import media that is currently in use, the application must allocate the media to acquire a logical media identifier (LMID) so that the media can be mounted and managed by RSM.

When media that has a recognized label but does not exist in the RSM catalog is inserted into an RSM drive or library, RSM places the media in the Import pool for that media type. The application can move the media from the Import pool and acquire an LMID by using the AllocateNtmsMedia function and specifying the partition to import and the destination application pool. RSM moves the media to the pool and returns an LMID for use with the media. If the media is two-sided, both sides must be imported into the same application pool. The reverse side remains in the import state until it is imported by the application. If the application user does not want to import the reverse side of the media, the application should import the media and deallocate it to make it available for reuse if desired.


Handling CD-ROMs in RSM

[This is preliminary documentation and subject to change.]


Inserting a CD-ROM into a library

[This is preliminary documentation and subject to change.]

When a CD-ROM is introduced into a library by an insert command or door access command, the CD-ROM is examined to determine its destination media pool. The identification process uses the CDFS label as identification. The following diagram shows the process and resulting media pool for the medium. Because CD-ROMs are not writable media, CD-ROMs never appear in a scratch pool.


Moving a CD-ROM Among Media Pools

[This is preliminary documentation and subject to change.]

Compact discs in general appear in the import pool. A user or application can create an application pool and move media to that pool, allowing RSM to continue to track the media. If the media is in the import pool and is ejected from the library or drive without moving it to an application pool, the media is deleted from the RSM catalog.

Also, because the media is read-only, RSM does not allow it to be placed in the Scratch pool, and does not attempt to label the media as it moves between pools. The following table shows what happens when media is moved from or to different media pools.

From/To | Import | Foreign | Application
Import |  | Not allowed | Allowed – no action
Foreign | Not allowed |  | Not allowed
Application | Not allowed | Not allowed | Allowed – no action


Allocating and Deallocating a CD-ROM

[This is preliminary documentation and subject to change.]

Compact discs cannot be allocated or deallocated because they are not writable.


Using a CD-ROM

[This is preliminary documentation and subject to change.]

An application using a CD-ROM should specify the physical media identifier (PMID) and use the MountNtmsMedia function provided with RSM.


Duplicate copies of a CD-ROM

[This is preliminary documentation and subject to change.]

RSM tracks duplicate copies of media only if they are all in an online library at the same time. Each medium is given a unique PMID and can be accessed by an application. For example, if a user has two copies of the Microsoft® Windows NT® Server installation CD-ROM and places both in a changer, RSM creates two PMIDs and tracks both media. When the CD-ROMs are ejected from the library, RSM continues to track both CD-ROMs. When one is inserted again, RSM will pick one of the PMIDs to use as the one that has been inserted.


Handling Tapes in RSM

[This is preliminary documentation and subject to change.]

Inserting media into a library

When a medium is introduced into a library, either by an insert command or a door access command, it is examined to determine its destination media pool. The identification process involves two IDs: a bar code if available or an on-media identifier (OMID). The following diagram shows the process and resulting destination media pool for the medium.

The following table shows what happens when media is moved from or to different media pools.

From/To | Scratch | Import | Foreign | Application
Scratch |  | Not allowed | Not allowed | Retains Scratch label until allocated.
Import | Write MTF scratch label |  | Not allowed | Not allowed
Foreign | Write MTF scratch label | Not allowed |  | Not allowed
Application | Write MTF scratch label | Not allowed | Not allowed | Retains current label. Allocated media may not be moved from a pool.


Allocating Tape Media

[This is preliminary documentation and subject to change.]

To obtain media to use, an application uses the AllocateNtmsMedia function specifying a media pool from which to obtain the medium. The AllocateNtmsMedia function assigns media to the application and returns a logical media identifier (LMID) to the application. Only media in online libraries can be allocated to the application.

The media pool can be set up to automatically draw from the Scratch pool upon allocation. If no media are available in its media pool, RSM automatically moves online media from the Scratch pool and assigns it to the application. If no media are available, RSM generates an operator request for new media, or the applications are notified of the problem.

Because the application is not guaranteed the type of label on the specified medium, the application is required to write its own label on the medium and use the UpdateNtmsOmidInfo function to notify RSM of the new label identifier. This does not have to be done immediately after the allocate command, because RSM can use the current label identifier until the current owner overwrites the label. After the application overwrites the label, the application must notify RSM of the change as soon as possible to prevent a mismatch between the RSM version of the label and the actual label. If the application does not notify RSM of the label change, the medium is moved to the Import pool, and the application must import the medium to access it again.


Deallocating Tape Media

[This is preliminary documentation and subject to change.]

When an application has finished using media, the application can make the media available for use by deallocating the media using the DeallocateNtmsMedia function. If the application's media pool has the Return to Scratch property set when the media is deallocated, the media is returned to the Scratch pool, and a new scratch label is assigned.


Handling Optical/Rewritable Random-access Media in RSM

[This is preliminary documentation and subject to change.]

Media such as rewritable optical (EO), JAZ, and ZIP cartridges are example of media types that are members of this category. However, RSM supports only Optical EO media. RSM requires that these media have a file system written on the medium. RSM currently supports both FAT and NTFS file systems.


Inserting Media into a Library

[This is preliminary documentation and subject to change.]

When media is introduced into a library, either by an insert command or a door access command, it is examined to determine its destination media pool. The identification process involves RSM identifying an NTFS, FAT, or scratch label. The following diagram shows the process and resulting destination media pool for the medium.


Moving Optical/Rewritable Among Media Pools

[This is preliminary documentation and subject to change.]

The following table shows what happens when media is moved from or to different media pools.

From/To | Scratch | Import | Foreign | Application
Scratch |  | Not allowed | Not allowed | Retains Scratch label until allocated.
Import | Write NTFS Scratch label |  | Not allowed | Not allowed
Foreign | Write NTFS Scratch label | Not allowed |  | Not allowed
Application | Write NTFS Scratch label | Not allowed | Not allowed | Retains current label. Allocated media may not be moved from a pool. Both sides must be Available.


Allocating Optical/Rewritable Random Access Media

[This is preliminary documentation and subject to change.]

To obtain media to use, an application uses the AllocateNtmsMedia function, specifying a media pool from which to obtain the medium. The AllocateNtmsMedia function assigns media to the application and returns a logical media identifier (LMID) to the application. Only media in online libraries can be allocated to the application. To allocate both sides of the specified medium, the application can use the New and Next options to allocate. New returns media that has both sides available and reserves the reverse side. Using the Next option and specifying the LMID of a side already allocated, the application can obtain an LMID for the reverseside of the medium

The media pool can be set up to automatically draw from the Scratch pool upon allocation. If no media are available in its media pool, RSM automatically moves online media from the Scratch pool and assigns it to the application. If no media are available, RSM generates an operator request for new media.

Because the application is not guaranteed the type of label on a medium, the application is required to write its own label on the medium and use the UpdateNtmsOmidInfo function to notify RSM of the new label identifier. This does not have to be done immediately after the allocate command, because RSM can use the current label identifier until the current owner overwrites the label. After the application overwrites the label, it must notify RSM of the change as soon as possible to prevent a mismatch between the RSM version of the label and the actual label. If the application does not notify RSM of the label change, the media is moved to the Import pool, and the application must import the media to be able to access it again.


Deallocating Optical/Rewritable Media

[This is preliminary documentation and subject to change.]

When an application finishes using media, the application can make the media available again by deallocating the media using the DeallocateNtmsMedia function. If the application's media pool has the Return to Scratch property set when the medium is deallocated, the medium is returned to the Scratch pool and a new scratch label is assigned.


Appendix A

[This is preliminary documentation and subject to change.]

Device Configuration

The following sections describe autoconfiguration and manual device configuration. These are the same processes used by administrators to configure their RSM devices.


Autoconfiguration Feature

[This is preliminary documentation and subject to change.]

You can use the autoconfiguration feature of RSM if you follow these steps:

  • Install all drives on the same SCSI bus as the associated changer
  • Use only library hardware units that support drive element address reporting with the ReadElementStatus SCSI command. Consult the manufacturer to find out if your library hardware unit supports this feature.


Manual Device Configuration

[This is preliminary documentation and subject to change.]

Because not all library hardware units and system configurations support the RSM autoconfiguration feature, RSM provides a method for manually configuring library hardware units. However, you should not use this method unless it is absolutely necessary, because manually configured devices do not recognize system configuration changes. Always let RSM autoconfigure all devices when you add, move, or remove a device in an RSM system. If the autoconfiguration fails, you can complete the configuration manually.

To perform a manual configuration
  1. After installing, moving, or removing hardware, let RSM start the process of autoconfiguration. This process adds incomplete registry entries and generates an operator request to manually configure each changer it cannot autoconfigure.

Note If you manually configured a changer when it was installed, RSM does not recognize changes made to that changer or its associated drives, and RSM does not start the autoconfiguration process.

  2. After RSM generates an operator request for each changer that it cannot autoconfigure, stop RSM.
  3. Back up the RSM database by copying %SYSTEMROOT%\System32\ntmsdata\* to a secure temporary directory.
  4. Open the Windows NT registry in Regedt32 or RegEdit.
  5. Go to the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\
    MediaService\Config     key. There is a subkey for each changer in the system and a subkey for the stand-alone drives. The following figure illustrates a registry configuration that contains one changer (Changer0) and at least one stand-alone drive.

    The following table describes the registry entries in the preceding figure.

Registry Entry | Description
AutoCfg | Determines whether the current changer is automatically or manually configured. A value of zero (0) represents manual configuration, and a non-zero value represents autoconfiguration.
CurrentConfigPassed | Represents the success of the current configuration. A non-zero value indicates that RSM did not find a conflict with the configuration the last time RSM was started.
DriveBayX | Represents the drive bays associated with the changer (where X is a numeric value). Changers can be associated with any number of drive bays. The values of these entries map the drive bays to the drive inside them. Triple question marks (???) represent unrecognized drives that must be manually configured. Note When RSM cannot establish communication with the changer, RSM does not create any drive bay entries. Manual configuration cannot solve this problem; you might have to replace the changer driver.

  6. Go to the subkey for the changer that RSM did not configure and note the name of each unrecognized drive bay. Unrecognized drive bays have a value of ??? instead of a drive device name.
  7. Open MMC and access the RSM Administration Tool.
  8. Insert media in a drive that RSM does not recognize. RSM typically categorizes unrecognized drives as stand-alone drives. Check each of the stand-alone drives listed until RSM updates the right pane with the inserted media. Note the name of the drive that contains the media you inserted. You must associate this drive name with the appropriate drive bay by replacing the ??? in the registry entry for that drive bay later in this procedure.

    If this identification process is unsuccessful, move to the next step. Otherwise, complete this step for each drive that RSM does not recognize and skip to step 12.

  9. Go to the HKEY_LOCAL_MACHINE\Hardware\DeviceMap\SCSI key in the Windows NT registry and look for the port, bus, target, and logical unit ID of an unrecognized drive. Use the SCSI ID of the drive to ensure that you are looking at the correct drive.
  10. Note the value of the DeviceName entry in the right window pane. This is the name of the current drive that replaces the ??? in the registry entry for the current drive bay.
  11. Repeat steps 8 through 10 for each drive that RSM does not recognize.
  12. Stop all processes that are accessing RSM drives.
  13. Stop RSM.

    Warning Do not continue until you are sure RSM is not running. It is very important not to edit the RSM entries in the registry while RSM is running.

  14. When all drive activity stops, go to the RSM configuration information in the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\
    MediaService\Config     key of the Windows NT registry.
  15. Go to the first drive bay entry with a value of ???. This represents a drive that RSM does not recognize.
  16. Replace the ??? with the appropriate drive name for that drive bay.
  17. Set the AutoCfg flag to 0.
  18. Repeat steps 16 and 17 for each drive that is not configured.
  19. Close the Windows NT registry.
  20. Restart RSM. It will read the new configuration information and initialize the devices.
  21. Mount media in each drive in the library after RSM is initialized. If any of the configurations are incorrect, RSM generates an error message (during either initialization or mounting).
  22. If the manual configuration was unsuccessful, stop RSM. Copy your backup version of the RSM database files back to the %SYSTEMROOT%\System32\ntmsdata\ directory to restore the database and restart the manual configuration process.

    If RSM does not generate any error messages, the manual configuration was successful and you have completed the manual configuration process.


Appendix B

[This is preliminary documentation and subject to change.]


RSM Database Internals

[This is preliminary documentation and subject to change.]

This section describes the components and files of the RSM database and how they are used to overcome system and application failures.


Database Files

[This is preliminary documentation and subject to change.]

The RSM database consists of five distinct files. All files are stored by default in the \WINNT\SYSTEM32\ NTMSDATA directory.

  • NTMSDATA
  • NTMSREG
  • NTMSIDX
  • NTMSJRNL
  • NTMSDATA.BAK


NTMSDATA

[This is preliminary documentation and subject to change.]

The NTMSDATA (data) file contains all the database records and properties. This is the in-place copy of all the RSMobject data. This file provides the latest copy instance of all data committed to the database.


NTMSREG

[This is preliminary documentation and subject to change.]

The NTMSREG (registration) file stores record types available in the database. Rather than configuring certain static type codes using a C/C++ enumerator, the RSM database allows its application to register types by name and dynamically assigning codes. This enables easier upgrades of the database by using registration. When the RSM service starts, it searches for or registers all the necessary types and builds an array of record types in memory. A database record type exists for each of the RSM object types such as NTMS_OBJECT, NTMS_DRIVE, NTMS_PHYSICAL_MEDIA, and others. This registration file is also used to register new custom record types such as RSM object attributes using the SetNtmsObjectAttribute GetNtmsObjectAttribute functions.

The registration file is built when the service is started and basically remains unchanged.


NTMSIDX

[This is preliminary documentation and subject to change.]

The NTMSIDX (index) file stores the indexes for looking up records in the database. The following two distinct indexes are stored within this file:

  • An index of records organized by type, for finding records by type.
  • An index using a globally unique identifier (GUID) hash, for locating records by their IDs.

The index file can be fully recreated from the NTMSDATA file and is therefore not critical to integrity. In fact, RSM rebuilds the index on startup if an integrity problem exists.


NTMSJRNL

[This is preliminary documentation and subject to change.]

The NTMSJRNL (journal) file contains records that are being modified but have not been committed yet. The RSM database uses this file to help implement its transaction-based model. Like the index file, the journal is not critical with respect to database integrity except when an incomplete transaction update has occurred.


NTMSDATA.BAK

[This is preliminary documentation and subject to change.]

The NTMSDATA.BAK (replica) file contains a interlocked replica of the database's data file. The purpose of this file is not to create a backup, but to provide a consistent replica of the database file while updates are in progress. An update to the main data file occurs only during a transaction commit operation, at which time the data file becomes inconsistent. The replica is guaranteed to remain consistent across the update and until the main data file is consistent again, at which point the replica is updated slowly. Although the database uses the slow update model for the backup, the database employs an interlock that prevents the main data file from beginning another update until the replica is completely up to date. This provides the benefit of improved performance for the thread performing the commit operation while ensuring integrity. Although this means that any thread performing back-to-back commit operations incurs a performance penalty for the replica, in practice very few RSM operations use back-to-back transaction commits.


Database Transactions

[This is preliminary documentation and subject to change.]

The RSM database uses write transactions to perform updates using the journal file. To begin an update, the application (RSM system code transactions are not externalized) begins a transaction. All database records that are updated, inserted, or deleted are written into a journal file. When database updates are complete, the application issues a commit or a rollback command.

The commit command flushes the journal file, then sets a commit state in the journal file indicating that this journal has been committed. The commit command then flushes the commit state and begins the in-place update of the database data file (NTMSDATA). The journal file is removed when the update of NTMSDATA and its replica is complete. If RSM is terminated during the commit operation, the journal file is replayed when the service is restarted and all database consistency reconstruction is complete. This occurs only if the commit state is indicated in the journal file. If the journal has not been committed, it is discarded, since it is part of an incomplete transaction.

The rollback command deletes the journal file. The NTMSDATA file remains unchanged.


Index File Recovery

[This is preliminary documentation and subject to change.]

Since abnormal termination can occur during a data file update, the possibility exists that the RSM database data file and index file will become inconsistent. The database uses a rolling incarnation number in each of these files to verify that they are consistent. When the update begins, the incarnation number in the data file rolls forward and the data file is flushed to disk. When the update is complete, the data file and index file are flushed to disk and the index file incarnation number rolls forward and is subsequently flushed to disk. If the service is terminated for any reason during the update, the incarnation numbers are mismatched, indicating that they are inconsistent. The RSM database is designed to rebuild the index file from the data file and does so on startup if an inconsistency is detected.

In addition to using the normal mechanism for verifying the integrity of the index and data files, RSM also sets a registry value to force a recovery when a disk full or disk I/O error has occurred.


Data File Recovery

[This is preliminary documentation and subject to change.]

The RSM database handles an additional inconsistency problem. It is possible that a system failure can cause an incomplete write operation of the RSM data file. This occurs when some sectors are written to disk and some are not at the time of the system failure. This causes the RSM data file to be inconsistent within itself. The lost data might not be available in the data file or in the journal, since it includes records that might have been moved due to space allocation and so forth. Also, the RSM database cannot determine which data might be lost. To prevent inconsistency in this case, RSM uses a data file replica (NTMSDATA.BAK). The database keeps the replica up to date using a slow update of all modified data file clusters. It does not do immediate updates, because it this would increase the latency of a database commit operation. However, it synchronizes subsequent updates to the database with the completion of the slow update of the replica. Therefore, either the data file or the replica is consistent at all times. The database determines which is consistent by comparing the incarnation number to the index file's incarnation number. This is possible since the incarnation number of the index file is flushed to disk after the successful completion of the data file and index file update flush. This ensures that the data file and index file is on disk prior to rolling the incarnation number of the index file, indicating a completed update.

The database recovers using the replica as follows:

  1. If the data file and the index file are inconsistent, RSM checks if the replica is consistent with the index and moves the replica to the main data file (that is, renames NTMSDATA.BAK to NTMSDATA). Either file is always consistent due to the synchronized updates of each.
  2. The database rebuilds the index file, making the data file and index consistent.
  3. The RSM database updates from the journal file if one exists and its state indicates that it is committed. Using this model, data that has been committed is never lost.


Run-Time I/O Error Handling

[This is preliminary documentation and subject to change.]

The RSM database is designed to handle a variety of I/O error conditions from the file system. The most common error is a full disk. In this case, the RSM database restricts further write access to the database and uses either the main data file or the replica to support further read requests. The replica is used if the disk full error occurred during a data file update. Since write access is restricted, the replica data file is guaranteed to be consistent and is used to rebuild the database to a consistent state when RSM is restarted. Partial reconstruction of the index file might occur on-the-fly to repair any indexes that might have been in mid-update.

If the database experiences I/O errors other than disk full, the database shuts down. The intent is to prevent damaging the database files further.


Database Import and Export

[This is preliminary documentation and subject to change.]

Database backup and restore is another feature of RSM. RSM provides database import and export functions that create a copy of the database files in an export directory. RSM guarantees that the files are consistent (not in mid-update) on export. Since the index file and the replica can be recreated, RSM exports only the record type registration file and the data file. The import operation also imports only the data file and the registration file. The import API only schedules database import. The actual import operation occurs when the service is started. When the database is imported, the index file and the replica are always recreated and are therefore consistent.


Database File Relocation

[This is preliminary documentation and subject to change.]

The database files can be relocated by creating the registry key REG_SZ (NtmsData) in the registry hierarchy at HKEY_LOCAL_SYSTEM\SYSTEM\CurrentControlSet\Control\NTMS. This allows the database to be relocated to a different local disk or a remote file service. In some cases, the RSM administrator might want to relocate the RSM database to a more reliable file server using RAID or mirroring technology.


Database Security

[This is preliminary documentation and subject to change.]

All RSM database files are protected when stored on NTFS file volumes using an access control list that denies access to everyone except the system administrator and the local system. The access control prevents unauthorized access to the database as well as preventing accidental removal of the database files by the Windows NT user.


Optional Replica Synchronization

[This is preliminary documentation and subject to change.]

The RSM database can add an option to provide for immediate replica synchronization on commit completion. This option allows the replica to be up-to-date prior to commit completion and therefore available as an exact duplicate of the main data file. Although this does not provide additional integrity, it can help failure one or more sectors within the data file are bad and the one or more files within the journal are bad.


Removable Storage Manager Function Reference

[This is preliminary documentation and subject to change.]

This section includes Removable Storage Manager (RSM) functions.

Cleaner Management Functions

You can use the following functions to control and manage drive cleaning:

CleanNtmsDrive

EjectNtmsCleaner

InjectNtmsCleaner

ReleaseNtmsCleanerSlot

ReserveNtmsCleanerSlot

Database Backup and Recovery Functions

You can use the following functions for database backup and recovery:

ExportNtmsDatabase

ImportNtmsDatabase

Database Notification Functions

You can use the following functions for database notification:

CloseNtmsNotification

OpenNtmsNotification

WaitForNtmsNotification

Session Management Functions

You can use the following session management functions to open and close RSM sessions:

CloseNtmsSession

OpenNtmsSession

Library Control Functions

Library control functions control:

  • Injecting and ejecting media
  • Moving media between libraries
  • Enabling and disabling drive and changer resources
  • Taking library inventory

You can use the following library control functions:

AccessNtmsLibraryDoor

CancelNtmsLibraryRequest

DeleteNtmsDrive

DeleteNtmsLibrary

DismountNtmsDrive

EjectNtmsMedia

GetNtmsRequestOrder

InjectNtmsMedia

InventoryNtmsLibrary

SetNtmsRequestOrder

Media Services Functions

[This is preliminary documentation and subject to change.]

Media services functions are used for:

  • Mounting and dismounting media
  • Allocating and deallocating media for an application
  • Managing media pools

You can use the following media services functions:

AddNtmsMediaType

AllocateNtmsMedia

ChangeNtmsMediaType

CreateNtmsMediaPool

DeallocateNtmsMedia

DecommissionNtmsMedia

DeleteNtmsMedia

DeleteNtmsMediaPool

DeleteNtmsMediaType

DismountNtmsMedia

GetNtmsMediaPoolName

MountNtmsMedia

MoveToNtmsMediaPool

SetNtmsMediaComplete

SwapNtmsMedia

Object Management Functions

[This is preliminary documentation and subject to change.]

You can use the following functions to enumerate, get, and set information about RSM objects.

DisableNtmsObject

EnableNtmsObject

EnumerateNtmsObject

GetNtmsObjectAttribute

GetNtmsObjectInformation

GetNtmsObjectSecurity

SetNtmsObjectAttribute

SetNtmsObjectInformation

SetNtmsObjectSecurity

On-Media-Identifier Management Functions

[This is preliminary documentation and subject to change.]

You can use the following function to control the use of OMIDs in an RSM system:

UpdateNtmsOmidInfo

Operator Request Functions

[This is preliminary documentation and subject to change.]

You can use the following functions to manage and control requests to system operators:

CancelNtmsOperatorRequest

SatisfyNtmsOperatorRequest

SubmitNtmsOperatorRequest

WaitForNtmsOperatorRequest


AccessNtmsLibraryDoor

[This is preliminary documentation and subject to change.]

The AccessNtmsLibraryDoor function unlocks the door of the specified online library. If the library is busy, RSM queues the request and returns successfully.

DWORD WINAPI AccessNtmsLibraryDoor(
  HANDLE hSession,
  LPNTMS_GUID lpLibraryId,
  DWORD dwAction
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpLibraryId
Specifies the unique identifier of a library object. This library must support door access.
dwAction
This parameter can be one of the following values.
Value | Meaning
NTMS_INVENTORY_NONE | After the user closes the door, no inventory is performed. However, if a mount-label check fails, an inventory will be performed.
NTMS_INVENTORY_OMID | After the user closes the door, a full on-media inventory is performed. This can be time consuming because each partition of each medium must be mounted.
NTMS_INVENTORY_FAST | If the library has a bar-code reader installed, this flag causes bar-code inventory to be performed. If the library does not have a bar-code reader, this flag causes a differential inventory to be performed.
NTMS_INVENTORY_DEFAULT | Use the InventoryMethod specified in the library object.

Return Values

ERROR_ACCESS_DENIED
NTMS_CONTROL_ACCESS to the library is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_DEVICE_NOT_AVAILABLE
The library is disabled.
ERROR_INVALID_HANDLE
The session ID is invalid or missing.
ERROR_INVALID_PARAMETER
The library ID is missing.
ERROR_LIBRARY_OFFLINE
The library ID references an offline library without a door.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_RESOURCE_NOT_PRESENT
The library does not have a door.
ERROR_SUCCESS
Door access is queued.

Remarks

The AccessNtmsLibraryDoor function is valid only for online libraries.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Library Control Functions, EjectNtmsMedia, InjectNtmsMedia


AddNtmsMediaType

[This is preliminary documentation and subject to change.]

The AddNtmsMediaType function adds the specified media type to the specified library if there is not currently a relation in the library object. The function then creates the system media pools (SCRATCH/IMPORT/FOREIGN) if they do not exist. This call requires the caller to have NTMS_CONTROL_ACCESS rights to the library object.

DWORD AddNtmsMediaType(
  HANDLE hSession,
  LPNTMS_GUID lpMediaTypeId,
  LPNTMS_GUID lpLibId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpMediaTypeId
Specifies the unique identifier of a media type to add to the library.
lpLibId
Specifies the unique identifier of the library to which to add the media type.

Return Values

ERROR_ACCESS_DENIED
NTMS_MODIFY_ACCESS to media's media pool is denied.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_LIBRARY
The library ID is invalid.
ERROR_INVALID_PARAMETER
The media type or library ID is missing.
ERROR_NOT_ENOUGH_MEMORY
There was an allocation failure during processing.
ERROR_SUCCESS
The function was successful.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions, DeleteNtmsMediaType


AllocateNtmsMedia

[This is preliminary documentation and subject to change.]

The AllocateNtmsMedia function allocates a piece of available media.

DWORD WINAPI AllocateNtmsMedia(
  HANDLE hSession,
  LPNTMS_GUID lpMediaPool,
  LPNTMS_GUID lpPartition,
  LPNTMS_GUID lpMediaId,
  DWORD dwOptions,
  DWORD dwTimeout
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpMediaPool
Specifies the unique identifier of a media pool from which the media is to be allocated.
lpPartition
Specifies the part ID of a partition to use for LMID. The partition must be in the Available or Import state. This feature can be used to allocate a particular partition or to import media. This parameter is optional. A NULL pointer is normally used.
lpMediaId
Used to return the media ID of the allocated medium. The returned logical media ID is NULL if the medium cannot be allocated.
dwOptions
This parameter must be one or more of the following values.
Value | Meaning
NTMS_ALLOCATE_ERROR_IF_UNAVAILABLE | Prevents the submission of an operator request for new media if none can be allocated with the specified constraints.
NTMS_ALLOCATE_NEW | Allocates a partition of the specified medium that cannot be shared with another application's logical media. For example, this value reserves the second side of two-sided optical media.
NTMS_ALLOCATE_NEXT Allocate the next partition of the multipartitioned medium previously allocated with the NTMS_ALLOCATE_NEW value. This allows a single application to use both partitions of a piece of two-sided media and ensure that the application owns all the data on the piece of physical media.

If all the partitions of the medium are already allocated, the allocation request fails.

dwTimeout
Specifies the maximum time allowed, in milliseconds, to allocate the specified media. Set this parameter to INFINITE so the function will not time out. Set this parameter to zero to not wait for media. Note that this function does not queue a request for more media if the NTMS_ALLOCATE_ERROR_IF_UNAVAILABLE value is specified.

Return Values

ERROR_ACCESS_DENIED
NTMS_MODIFY_ACCESS to media's media pool is denied.
ERROR_CANCELLED
The operator canceled the request for new media.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_DEVICE_NOT_AVAILABLE
An intermediate resource is not available; for example, the scratch media pool is not available.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_MEDIA
The partition ID or logical media ID was invalid upon input when using the NTMS_ALLOCATE_NEXT flag.
ERROR_INVALID_MEDIA_POOL
The media pool ID is invalid.
ERROR_INVALID_PARAMETER
The media or media pool ID is missing.
ERROR_MEDIA_OFFLINE
The specified media is offline and cannot be allocated.
ERROR_MEDIA_UNAVAILABLE
No media has been allocated within the specified time-out event.
ERROR_NOT_ENOUGH_MEMORY
There was an allocation failure during processing.
ERROR_SUCCESS
The function was successful.
ERROR_TIMEOUT
The time-out event expired before media was available.

Remarks

Only application pools may be specified for allocation using the AllocateNtmsMedia function.

The AllocateNtmsMedia function returns an LMID. Depending upon the media pool's policy, if the specified media pool does not contain any online Available media, AllocateNtmsMedia might search the scratch media pool for the specified medium to move to the specified media pool. Media from the designated media pool is allocated first, and then the scratch media is moved and allocated.

If the media pool contains any online Available media, a medium from the pool is allocated.

If the media pool is configured to allocate media from the scratch pool automatically, and the scratch pool contains online Available media, a medium is moved to the specified pool and allocated.

When the NTMS_ALLOCATE_NEXT value is specified, the lpMediaId parameter must point to a valid media ID at the time of invocation. In this case, lpMediaId is used as an IN and OUT parameter. The next partition of the multiple partitioned (sided) medium specified by lpMediaId is allocated, and the new partition ID is returned through lpMediaId (overwriting the original media ID passed in).

If NTMS_ALLOCATE_ERROR_IF_UNAVAILABLE is specified, ERROR_MEDIA_ UNAVAILABLE is returned if no media is available.

When necessary, RSM generates an operator request to insert new or Available media. If the time specified in the dwTimeout parameter elapses before the operator request is handled, RSM returns ERROR_TIMEOUT and deletes the operator request.

If the user cancels the allocation request, RSM returns ERROR_CANCELLED.

If a user indicates that the operator request has been satisfied, the request is deleted and RSM retries the process. The following steps describe how to allow media to be imported into RSM:

To allow media to be imported into RSM
  1. The AllocateNtmsMedia function specifies a partition in the Import Media pool or in the Import state.
  2. RSM moves the medium to the specified media pool.
  3. RSM changes the media's state to allocated.
  4. RSM returns an LMID.

Note For two-sided media the flip side remains in the Import state and is not available for use until imported.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions, DeallocateNtmsMedia


CancelNtmsLibraryRequest

[This is preliminary documentation and subject to change.]

The CancelNtmsLibraryRequest function cancels outstanding RSM requests, such as calls to the CleanNtmsDrive function. If the library is busy, RSM queues the CancelNtmsLibraryRequest function and returns success.

DWORD WINAPI CancelNtmsLibraryRequest(
  HANDLE hSession,
  LPNTMS_GUID lpRequestId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpRequestId
Specifies the RSM request object ID. To get a list of the existing library requests (or work items) to cancel, see the EnumerateNtmsObject function.

Return Values

ERROR_ACCESS_DENIED
Only an administrator of the RSM server can cancel library requests.
ERROR_OBJECT_NOT_FOUND
The library request object ID was not found. This error occurs if the request is completed prior to issuing the cancel or when an invalid request ID is specified.
ERROR_SUCCESS
The library request has been queued for cancelation.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Library Control Functions, EnumerateNtmsObject


CancelNtmsOperatorRequest

[This is preliminary documentation and subject to change.]

The CancelNtmsOperatorRequest function cancels the specified RSM operator request.

DWORD WINAPI CancelNtmsOperatorRequest(
  HANDLE hSession,
  LPNTMS_GUID lpRequestId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpRequestId
Specifies the operator request object ID

Return Values

ERROR_ACCESS_DENIED
The user that tried to execute this function does not have administrator privileges. Only an administrator of the RSM server can cancel operator requests.
ERROR_OBJECT_NOT_FOUND
The operator request object ID was not found. This error occurs if the request is completed prior to cancelation of the operation or when an invalid request ID is supplied.
ERROR_SUCCESS
The operator request has been canceled.

Remarks

For a list of the existing requests to cancel with the CancelNtmsOperatorRequest function, see the EnumerateNtmsObject function or use the ID passed back by the SubmitNtmsOperatorRequest function.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Operator Request Functions, SatisfyNtmsOperatorRequest, SubmitNtmsOperatorRequest


ChangeNtmsMediaType

[This is preliminary documentation and subject to change.]

The ChangeNtmsMediaType function moves the specified PMID to the specified target media pool and sets the PMID's MediaType GUID to the MediaType of the target media pool.

DWORD ChangeNtmsMediaType(
  HANDLE hSession,
  LPNTMS_GUID lpMediaId,
  LPNTMS_GUID lpPoolId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpMediaId
Specifies the unique identifier of the physical media to be moved.
lppoolId
Specifies the unique identifier of a media pool to which the media is to be allocated.

Return Values

ERROR_ACCESS_DENIED
NTMS_MODIFY_ACCESS to media's media pool is denied.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_MEDIA_POOL
The media pool ID is invalid.
ERROR_INVALID_PARAMETER
The media pool or media ID is missing.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_SUCCESS
The function was successful.

Remarks

The ChangeNtmsMediaType function requires the caller to have NTMS_MODIFY_ACCESS rights on the target media pool. The ChangeNtmsMediaType function uses the same policy for moving media as the MoveToNtmsMediaPool function (FOREIGN media can only be moved to the SCRATCH Pool).

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions, AddNtmsMediaType, DeleteNtmsMediaType


CleanNtmsDrive

[This is preliminary documentation and subject to change.]

The CleanNtmsDrive function queues a cleaning request for the specified drive for cleaning.

DWORD WINAPI CleanNtmsDrive(
  HANDLE hSession,
  LPNTMS_GUID lpDriveId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpDriveId
Specifies the unique identifier of the drive to be cleaned.

Return Values

ERROR_ACCESS_DENIED
NTMS_CONTROL_ACCESS to the library is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_DEVICE_NOT AVAILABLE
The drive or the library is not enabled.
ERROR_INVALID_DRIVE
The drive ID is invalid.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_LIBRARY
The library for the drive is invalid.
ERROR_INVALID_PARAMETER
The drive ID is missing.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_SUCCESS
The cleaning was queued successfully.

Remarks

If the drive you selected in the CleanNtmsDrive function is a stand-alone drive, the drive is marked as cleaned and the time is noted in the RSM Database.

Queued cleaning requests are deleted when the service is restarted.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Cleaner Management Functions, EjectNtmsCleaner, InjectNtmsCleaner, ReleaseNtmsCleanerSlot, ReserveNtmsCleanerSlot


CloseNtmsNotification

[This is preliminary documentation and subject to change.]

The CloseNtmsNotification function closes the specified notification channel.

DWORD WINAPI CloseNtmsNotification(
  HANDLE hSession,
  HANDLE hNotification
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
hNotification
Notification handle generated by the OpenNtmsNotification function.

Return Values

ERROR_DATABASE_FAILURE
The database query or update failed.
ERROR_INVALID_HANDLE
The value specified in the hNotification parameter is invalid or NULL.
ERROR_NOT_CONNECTED
Unable to connect to the RSM service.
ERROR_SUCCESS
The function was successful.

Remarks

If the CloseNtmsNotification function is called while there is an outstanding call to the WaitForNtmsNotification function, an error returns.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Database Notification Functions, OpenNtmsNotification, WaitForNtmsNotification


CloseNtmsSession

[This is preliminary documentation and subject to change.]

The CloseNtmsSession function closes the specified RSM session.

DWORD WINAPI CloseNtmsSession(
  HANDLE hSession
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.

Return Values

ERROR_CONNECTION_UNAVAIL
Connection to the RSM server or domain is not available.
ERROR_INVALID_HANDLE
The value specified in the hSession parameter is invalid or NULL.

Remarks

The CloseNtmsSession function releases all resources. Use of a closed session handle returns an error code.

If a call to the CloseNtmsSession function occurs while an application has an outstanding synchronous request (for example, a mount or dismount request), the request is unwound and canceled.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Session Management Functions, OpenNtmsSession


CreateNtmsMediaPool

[This is preliminary documentation and subject to change.]

The CreateNtmsMediaPool function creates a new application media pool.

DWORD WINAPI CreateNtmsMediaPool(
  HANDLE hSession,
  LPCTSTR lpPoolName,
  LPNTMS_GUID lpMediaType,
  DWORD dwAction,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  LPNTMS_GUID lpPoolId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpPoolName
Specifies the name of the new media pool. Media pool names must be unique within the scope of a single RSM database.
lpMediaType
Specifies the type of media in this media pool. Use the EnumerateNtmsObject function to get a list of available media types and their attributes. The application can pass a NULL pointer to create a media pool that only contains other media pools.
dwAction
This parameter must be one of the following values.
Value | Meaning
NTMS_OPEN_EXISTING | Opens an existing media pool by name. Returns ERROR_INVALID_PARAMETER if the pool does not exist.
NTMS_OPEN_ALWAYS | Opens an existing media pool or creates the pool if it does not exist.
NTMS_CREATE_NEW | Creates a new media pool. Returns ERROR_ALREADY_EXISTS if the pool exists.

lpSecurityAttributes
Optional. Specifies the security descriptor used to restrict access to the pool.
lpPoolId
Pointer to the unique identifier where the media pool ID is returned after the media pool is successfully created or opened.

Return Values

ERROR_ACCESS_DENIED
NTMS_MODIFY_ACCESS to the parent media pool is denied while trying to create a new media pool.
ERROR_ALREADY_EXISTS
Unable to create a new media pool because one already exists with this name.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_MEDIA
The selected media type is not valid.
ERROR_INVALID_NAME
The pool name syntax is invalid. (The name is too long.)
ERROR_INVALID_PARAMETER
The media pool name or media pool ID pointer is missing.
ERROR_OBJECT_NOT_FOUND
Unable to open existing media pool.
ERROR_SUCCESS
The function was successful.

Remarks

Scratch, Foreign, and Import media pools are created by RSM and cannot be created with the CreateNtmsMediaPool function.

RSM media pools are organized as a hierarchy separated by the "\" character. The Application, Scratch, Foreign, and Import media pools exist at the root of the hierarchy. RSM creates and manages the Scratch, Foreign, and Import pools. RSM creates a Scratch media pool for each media type available.

Application-specific media pools are created by applications. Applications create media pools for their own use under the root application pool. These media pools have file system-like names. Only the end-point of the name contains media and policy. An application can define pools such as \MyApp\Pool1 and \MyApp\Pool2. This conveys the hierarchy to the user interface and avoids duplicate names. Each pool level must be created individually; first MyApp and then Pool1 and Pool2, much like folders and files.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions, AllocateNtmsMedia , DeleteNtmsMediaPool, GetNtmsObjectSecurity, SetNtmsObjectSecurity


DeallocateNtmsMedia

[This is preliminary documentation and subject to change.]

The DeallocateNtmsMedia function deallocates the partition associated with the specified logical media.

DWORD WINAPI DeallocateNtmsMedia(
  HANDLE hSession,
  LPNTMS_GUID lpMediaId,
  DWORD dwOptions
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpMediaId
Specifies the unique identifier of logical media.
dwOptions
Reserved; must be zero.

Return Values

ERROR_ACCESS_DENIED
NTMS_MODIFY_ACCESS to media's media pool is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_MEDIA
The LMID is invalid.
ERROR_INVALID_PARAMETER
The media or media pool ID is missing.
ERROR_INVALID_PARTITION
The LMID partition is invalid.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_SUCCESS
The function was successful.

Remarks

When a logical medium is deallocated with the DeallocateNtmsMedia function, RSM puts the partition associated with the logical media in the Available or Decommissioned media state. The logical media is deleted from the system when the logical media is deallocated.

Partitions are decommissioned upon deallocation if the partition has been allocated the maximum number of times specified in the media pool. After media is in the Decommissioned state, it cannot be allocated again.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions, AllocateNtmsMedia


DecommissionNtmsMedia

[This is preliminary documentation and subject to change.]

The DecommissionNtmsMedia function moves a partition from the Available state to the Decommissioned state.

DWORD WINAPI DecommissionNtmsMedia(
   HANDLE hSession,
  LPNTMS_GUID lpMedia
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpMedia
Specifies the unique identifier of a partition of a piece of physical media.

Return Values

ERROR_ACCESS_DENIED
NTMS_MODIFY_ACCESS to either media's media pool is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_MEDIA
The media identifier is invalid.
ERROR_INVALID_MEDIA_POOL
The media pool for media is invalid.
ERROR_INVALID_PARAMETER
The media identifier is missing.
ERROR_INVALID_STATE
The media is not in the Available state.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_SUCCESS
The function was successful.

Remarks

Media decommissioned by the DecommissionNtmsMedia function is recognized by RSM but the decommissioned media does not contain any data and is never again used.

Only media that is in the Available state can be decommissioned.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions, AllocateNtmsMedia


DeleteNtmsDrive

[This is preliminary documentation and subject to change.]

The DeleteNtmsDrive function deletes a drive from the RSM database. The drive must have a dwOperationalState of NTMS_NOT_PRESENT.

DWORD WINAPI DeleteNtmsDrive(
  HANDLE hSession,
  LPNTMS_GUID lpDriveId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpDriveId
Specifies the unique identifier of a drive.

Return Values

ERROR_ACCESS_DENIED
NTMS_MODIFY_ACCESS to the library is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_INVALID_DRIVE
The drive identifier is invalid.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_LIBRARY
The drive library identifier is invalid.
ERROR_INVALID_PARAMETER
The media identifier is missing.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_SUCCESS
The function was successful.

Remarks

You can use this function to remove drives that are no longer connected to the NTMS server.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Library Control Functions


DeleteNtmsLibrary

[This is preliminary documentation and subject to change.]

The DeleteNtmsLibrary function deletes a library, and all the devices contained in the library, from the RSM database. All media in the library is moved to the offline library.

DWORD WINAPI DeleteNtmsLibrary(
  HANDLE hSession,
  LPNTMS_GUID lpLibraryId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpLibraryId
Specifies the unique identifier of a library.

Return Values

ERROR_ACCESS_DENIED
NTMS_MODIFY_ACCESS to the library is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_INVALID_HANDLE
There is an invalid or missing session handle.
ERROR_INVALID_LIBRARY
There is an invalid library identifier.
ERROR_INVALID_PARAMETER
There is a missing media identifier.
ERROR_NOT_ENOUGH_MEMORY
There was an allocation failure during processing.
ERROR_SUCCESS
The function was successful.

Remarks

If the library referenced by the DeleteNtmsLibrary function contains media, the media is moved to the offline library.

You can use DeleteNtmsLibrary to remove libraries that are no longer connected to the RSM server.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Library Control Functions


DeleteNtmsMedia

[This is preliminary documentation and subject to change.]

The DeleteNtmsMedia function deletes a physical piece of offline media from RSM by removing all references to the specified media from the database.

DWORD WINAPI DeleteNtmsMedia(
  HANDLE hSession,
  LPNTMS_GUID lpMediaId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpMediaId
Specifies the unique identifier of a piece of physical media.

Return Values

ERROR_ACCESS_DENIED
NTMS_MODIFY_ACCESS to either media's media pool is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_MEDIA
The media identifier is invalid.
ERROR_INVALID_MEDIA_POOL
The media pool for the media is invalid.
ERROR_INVALID_PARAMETER
The media identifier is missing.
ERROR_INVALID_STATE
The media is not offline.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_SUCCESS
The function was successful.

Remarks

Media specified by the DeleteNtmsMedia function must be located in an offline library and not have a partition in the Allocated, Completed, or Reserved states.

You can use DeleteNtmsMedia to remove lost or destroyed media.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions


DeleteNtmsMediaPool

[This is preliminary documentation and subject to change.]

The DeleteNtmsMediaPool function deletes the specified application media pool.

DWORD WINAPI DeleteNtmsMediaPool(
  HANDLE hSession,
  LPNTMS_GUID lpPoolId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpPoolId
Specifies the unique identifier of the media pool.

Return Values

ERROR_ACCESS_DENIED
NTMS_CONTROL_ACCESS to the media pool is denied. Other security errors are also possible, but they indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_MEDIA_POOL
Unable to open existing media pool, or attempting to delete scratch, import, or foreign media pools.
ERROR_INVALID_PARAMETER
The media pool ID is missing.
ERROR_NOT_EMPTY
The media pool must be empty to be deleted.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_SUCCESS
The function was successful.

Remarks

Only empty media pools can be deleted with the DeleteNtmsMediaPool function.

Scratch, foreign, and import media pools are managed by RSM and cannot be deleted with DeleteNtmsMediaPool.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions, CreateNtmsMediaPool, MoveToNtmsMediaPool


DeleteNtmsMediaType

[This is preliminary documentation and subject to change.]

The DeleteNtmsMediaType function deletes the specified media type relation from the specified library provided that the library does not contain any physical media objects of the specified media type (offline included).

DWORD DeleteNtmsMediaType(
  HANDLE hSession,
  LPNTMS_GUID lpMediaTypeId,
  LPNTMS_GUID lpLibId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpMediaTypeId
Specifies the unique identifier of a media type to delete from a library.
lpLibId
Specifies the unique identifier of the library from which to delete the media type.

Return Values

ERROR_ACCESS_DENIED
NTMS_MODIFY_ACCESS to media's media pool is denied.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_INVALID_HANDLE
The session handle is bad or missing.
ERROR_INVALID_LIBRARY
The library ID is invalid.
ERROR_INVALID_PARAMETER
The media type or library ID is missing.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_SUCCESS
The function was successful.

Remarks

If there are no physical media objects of the specified media type in the RSM system and there are no library objects that contain the specified media type relation in the RSM system, the system media pools for that media type will be deleted. Inability to delete the system media pools does not cause the DeleteNtmsMediaType function to fail. This call requires the caller to have NTMS_CONTROL_ACCESS rights to the library object.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions, AddNtmsMediaType


DisableNtmsObject

[This is preliminary documentation and subject to change.]

The DisableNtmsObject function disables the specified RSM object.

DWORD WINAPI DisableNtmsObject(
  HANDLE hSession,
  DWORD dwType,
  LPNTMS_GUID lpObjectId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
dwType
Specifies the RSM object type. This parameter can be one of the following values.
Value | Meaning
NTMS_DRIVE | An RSM drive.
NTMS_LIBRARY | An RSM library unit.
NTMS_PHYSICAL_MEDIA | A physical media object (a tape, optical disk, CD, or magnetic cartridge).

lpObjectId
Specifies the unique identifier of the RSM object.

Return Values

ERROR_ACCESS_DENIED
NTMS_CONTROL_ACCESS to the library containing the object is denied.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_PARAMETER
An object ID is missing or the object type is invalid. (The object type is invalid if it is not NTMS_LIBRARY, NTMS_DRIVE, or NTMS_PHYSICAL_MEDIA.)
ERROR_INVALID_STATE
The object is already disabled.
ERROR_OBJECT_NOT_FOUND
The object is not valid.
ERROR_SUCCESS
The disable is queued.

Remarks

The DisableNtmsObject function queues a disable command with the specified object. If RSM is busy, the command can take some time to complete. The application can wait for the command to complete by examining the enabled field of the object.

When the medium is disabled, RSM renders all of the media's partitions and associated logical media unavailable. All requests to disabled media returns an error.

To remove a drive or media changer from service the drive or media changer must first be disabled.

All objects contained by a disabled object are also disabled. For example, disabling a piece of physical media disables all partitions. However, RSM does not set the disabled bit of the partition, and functions such as GetNtmsObjectInformation continue to work.

Whenever possible, when a drive is disabled, the medium in the drive is removed and placed in its slot.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Object Management Functions, EnableNtmsObject


DismountNtmsDrive

[This is preliminary documentation and subject to change.]

The DismountNtmsDrive function moves the media in the specified drive to its storage slot. If the library is busy, RSM queues DismountNtmsDrive and returns success. This function should be paired with the MountNtmsMedia function.

DWORD WINAPI DismountNtmsDrive(
  HANDLE hSession,
  LPNTMS_GUID lpDriveId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpDriveId
Specifies the unique identifier of a drive object.

Return Values

ERROR_ACCESS_DENIED
NTMS_CONTROL_ACCESS to the library is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_DEVICE_NOT_AVAILABLE
The drive or library is not enabled.
ERROR_INVALID_DRIVE
There is an invalid drive ID.
ERROR_INVALID_HANDLE
There is an invalid or missing session handle.
ERROR_INVALID_LIBRARY
There is an invalid library for the drive.
ERROR_INVALID_PARAMETER
There is a missing drive ID.
ERROR_INVALID_STATE
The drive does not contain media.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_SUCCESS
The function was successful.

Remarks

If the drive specified by the DismountNtmsDrive function is empty or if the media is opened, an error is returned. Otherwise, the media is returned to its slot.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Library Control Functions


DismountNtmsMedia

[This is preliminary documentation and subject to change.]

The DismountNtmsMedia function releases the specified medium from a drive.

DWORD WINAPI DismountNtmsMedia(
  HANDLE hSession,
  LPNTMS_GUID lpMediaId,
  DWORD dwCount,
  DWORD dwOptions
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpMediaId
Specifies an array of at least one logical medium or partition.
dwCount
Specifies the number of media identifiers in the lpMediaId parameter.
dwOptions
This parameter can be the following value.
Value | Meaning
NTMS_DISMOUNT_DEFERRED | Marks media state as Dismountable, and keeps the medium in the drive. Subsequent mount requests are satisfied using dismounted or dismountable drives. The default is to dismount immediately.

Return Values

ERROR_ACCESS_DENIED
NTMS_USE_ACCESS to the media pool or library that contains the media is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_DEVICE_NOT_AVAILABLE
One or more resources required to perform the dismount are not currently available (probably disabled).
ERROR_INVALID_LIBRARY
The library that contains the media is not valid.
ERROR_INVALID_MEDIA
At least one of the specified media is not valid.
ERROR_INVALID_STATE
An unexpected media or device state occurred during dismount.
ERROR_MEDIA_OFFLINE
The specified media is offline.
ERROR_MEDIA_NOT_AVAILABLE
One or more media resources required to perform the mount are not currently available (probably disabled).
ERROR_NOT_ENOUGH_MEMORY
A memory allocation failure occurred during processing.
ERROR_SUCCESS
The media dismount has been queued.
ERROR_TIMEOUT
The time-out event expired while the application attempted to acquire one or more resources.

Remarks

An application must use the DismountNtmsMedia function to release the drive resource after the application has used the specified medium. Unreleased media cannot be used by other RSM sessions.

If the session closes, RSM eventually dismounts the media.

The DismountNtmsMedia function returns as soon as the operation is queued with RSM. The application can wait for the partition state to become idle.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions, MountNtmsMedia


EjectNtmsCleaner

[This is preliminary documentation and subject to change.]

The EjectNtmsCleaner function ejects the cleaning cartridge from the currently reserved cleaner slot.

DWORD WINAPI EjectNtmsCleaner(
  HANDLE hSession,
  LPNTMS_GUID lpLibrary,
  LPNTMS_GUID lpEjectOperation,
  DWORD dwAction
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpLibrary
Specifies the unique identifier of a library object.
lpEjectOperation
Specifies the GUID of the eject process. This value is returned for use with a Stop action code.
dwAction
Specifies the action to take. This parameter can be either one of the following values.
Value | Meaning
NTMS_EJECT_START | Starts the eject operation with a port. The specified medium is ejected until the time-out event occurs or the EjectNtmsCleaner function is called again with the NTMS_EJECT_STOP flag set for this parameter. The time-out value is specified in the library object and is applied to all ejections in the library.
NTMS_EJECT_STOP | For libraries with NTMS_IEPORTobjects only. Terminates the ejection process prior to the time-out event lapsing.

Return Values

ERROR_ACCESS_DENIED
Access to one or more RSM objects is denied.
ERROR_INVALID_HANDLE
The value supplied in the hSession parameter is invalid.
ERROR_INVALID_LIBRARY
Unable to retrieve the library definition from the database.
ERROR_NO_SLOT_RESERVED
This library does not have a cleaner slot reserved.
ERROR_NOT_CONNECTED
Unable to connect to the RSM service.
ERROR_SLOT_EMPTY
A cleaner slot is reserved but is already empty.
ERROR_SLOT_NOT_PRESENT
A cleaner slot is reserved but the slot is currently not installed in the library. This error occurs when at least one magazine is missing from the library.
ERROR_SUCCESS
The function was successful.

Remarks

If the library specified in the EjectNtmsCleaner function has an NTMS_IEPORT object, RSM uses the NTMS_IEPORT object to eject the cleaner. If there is no NTMS_IEPORT object, the NTMS_IEDOOR object is used to allow the operator to gain access to the cleaner slot.

Ejected cleaner cartridges are not tracked in an offline library.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Cleaner Management Functions, CleanNtmsDrive, InjectNtmsCleaner, ReleaseNtmsCleanerSlot, ReserveNtmsCleanerSlot


EjectNtmsMedia

[This is preliminary documentation and subject to change.]

The EjectNtmsMedia function ejects the specified medium from the port of the current library. If the library is busy, RSM queues EjectNtmsMedia and returns success.

DWORD WINAPI EjectNtmsMedia(
  HANDLE hSession,
  LPNTMS_GUID lpMediaId,
  LPNTMS_GUID lpEjectOperation,
  DWORD dwAction
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpMediaId
Specifies the unique identifier of a piece of physical media (PMID).
lpEjectOperation
Specifies the GUID of the eject process. This must be used with the dwAction parameter set to the NTMS_EJECT_STOP flag.
dwAction
This parameter can be one of the following values.
Value | Meaning
NTMS_EJECT_START | Start the eject operation with a port. The specified medium is ejected until the time-out event occurs or until NTMS_EJECT_STOP is issued. The time-out value is specified in the library object and is applied to all ejects in the library.
NTMS_EJECT_STOP | Terminate the ejection process before the time-out event lapses.
NTMS_EJECT_QUEUE | Queue the specified media for ejection. Used to group media for multi-slot NTMS_IEPORT objects.

Return Values

ERROR_ACCESS_DENIED
NTMS_CONTROL_ACCESS to the library is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_BUSY
More media was queued than slots available in the NTMS_IEPORT object.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_DEVICE_NOT_AVAILABLE
The library is disabled.
ERROR_INVALID_HANDLE
The session ID is invalid or missing.
ERROR_INVALID_OPERATION
A stop was performed on an invalid operation ID.
ERROR_INVALID_PARAMETER
A library ID or operation ID pointer is missing.
ERROR_LIBRARY_OFFLINE
The library ID refers to an offline library that cannot eject media.
ERROR_MEDIA_NOT_AVAILABLE
The media is disabled.
ERROR_NOT_ENOUGH_MEMORY
There was an allocation failure during processing.
ERROR_SUCCESS
The eject is queued.

Remarks

Media ejected using the EjectNtmsMedia function is moved to the offline library or deleted from the database. Cleaner cartridges, foreign media, and incompatible media are deleted when ejected.

If the NTMS_EJECT_STOP flag is specified for dwAction, the EjectNtmsMedia function stops the eject operation specified by the lpEjectOperation parameter. The lpEjectOperation GUID is returned when the NTMS_EJECT_START flag is used.

The NTMS_EJECT_QUEUE flag is used to bundle or batch media marked for ejection into a multi-slot library. You can queue media for ejection using the queue action when the application has queued all the necessary media. The application uses the start command to begin the physical eject operation. If more media is queued than slots in the NTMS_IEPORT object, EjectNtmsMedia returns ERROR_BUSY. To begin the physical eject operation, the application can use the START action on the last media or use a NULL media ID with the Start Operation

The QUEUE action does not return a GUID that can be used for the STOP action. However, when the queued requests are started with the START action, a GUID returns that can be used to cancel the entire operation with the STOP action.

If the media is currently in use (mounted or opened), this function returns an error.

If the library does not have a port, use the AccessNtmsLibraryDoor function to insert and eject media.

Eject works only with online libraries.

The EjectNtmsMedia function returns to the application as soon as the eject request is queued.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Library Control Functions, InjectNtmsMedia


EnableNtmsObject

[This is preliminary documentation and subject to change.]

The EnableNtmsObject function enables the specified object.

DWORD WINAPI EnableNtmsObject(
  HANDLE hSession,
  DWORD dwType,
  LPNTMS_GUID lpObjectId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
dwType
Specifies the RSM object type. This parameter can be one of the following values.
Value | Meaning
NTMS_DRIVE | An RSM drive.
NTMS_LIBRARY | An RSM library unit.
NTMS_PHYSICAL_MEDIA | A physical media object (a tape, optical disk, CD, or magnetic disk cartridge).

lpObjectId
The unique identifier of the RSM object.

Return Values

ERROR_ACCESS_DENIED
NTMS_CONTROL_ACCESS to the library containing the object is denied.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_PARAMETER
The object ID is missing or the object type is invalid. (The object type is invalid if it is not NTMS_LIBRARY, NTMS_DRIVE, or NTMS_PHYSICAL_MEDIA.)
ERROR_INVALID_STATE
The object is already enabled.
ERROR_OBJECT_NOT_FOUND
The object is not valid.
ERROR_SUCCESS
The enable is queued.

Remarks

The EnableNtmsObject function queues a disable command with RSM. If RSM is busy, the command can take some time to complete. The application can wait for the command to complete by examining the enabled field of the object.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Object Management Functions, DisableNtmsObject


EnumerateNtmsObject

[This is preliminary documentation and subject to change.]

The EnumerateNtmsObject function enumerates the RSM objects contained in the lpContainerId parameter.

DWORD WINAPI EnumerateNtmsObject(
  HANDLE hSession,
  LPNTMS_GUID lpContainerId,
  LPNTMS_GUID lpList,
  LPDWORD lpdwListSize,
  DWORD dwType,
  DWORD dwOptions
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpContainerId
Specifies the unique identifier of the RSM object container. The type of object identified depends on the type of object being requested. Can be set to Library, Media Pool, Partition ID, Physical Media, Logical Media, or NULL. Set this parameter to NULL to enumerate all objects of the type specified by the dwType parameter.
lpList
Buffer for the array of libraries, drives, media or other RSM object IDs.
lLpdwListSize
Pointer to a DWORD that specifies the maximum number of IDs the function can return through the lpList parameter. At return time, the number of IDs in lpList is returned in lpdwListSizeA
dwType
Specifies the type of objects that you are enumerating in the container. This parameter can be one of the following values.
Value | Meaning
NTMS_CHANGER | Lists changers contained in the library specified by the lpContainerId parameter or all the changers supported by RSM if a NULL container ID is supplied. Available when lpContainerID is set to NULL or Library.
NTMS_DRIVE | Lists drives contained in a specific library specified by the lpContainerId parameter or all the drives supported by RSM if a NULL container ID is supplied. Available when lpContainerID is set to NULL or Library.
NTMS_CHANGER_TYPE | Lists changer types supported by RSM. The lpContainerId parameter must be NULL.
NTMS_COMPUTER | Specifies the current computer object. The lpContainerId parameter must be NULL.
NTMS_DRIVE_TYPE | Lists drive types supported by RSM. The lpContainerId parameter must be NULL.
NTMS_IEDOOR | Lists access doors contained in a library specified by the lpContainerId parameter or all the doors supported by RSM if a NULL container ID is specified. Available when lpContainerID is set to NULL or Library.
NTMS_IEPORT | Lists insert/eject ports contained in a library specified by the lpContainerId parameter or all the insert/eject ports supported by RSM if a NULL container ID is supplied. Available when lpContainerID is set to NULL or Library.
NTMS_LIBRARY | Lists the library objects. These include the physical library units and the offline library. The lpContainerId parameter must be NULL.
NTMS_LIBREQUEST | Lists library active requests (or work items) queued to the library specified by the lpContainerId parameter or all the library work items queued within RSM if a NULL container ID is supplied. Available when lpContainerID is set to NULL or Library.
NTMS_LOGICAL_MEDIA | Specifies a logical media object. This is a medium allocated to an application that might contain more than one partition or piece of physical media. Available when lpContainerID is set to NULL, Media Pool, or Partition ID.
NTMS_MEDIA_POOL | Specifies a media pool object that contains logical and/or physical media, and configuration parameters to manage them. If NULL is specified as a container ID, only the top-level names are returned. Available when lpContainerID is set to NULL or Media Pool.
NTMS_MEDIA_TYPE | Specifies a media type object that contains the attributes of a type of medium that is supported by RSM. Enumerating with a NULL will give all possible media types, not just those available on the current server. Available when lpContainerID is set to NULL or Library.
NTMS_OPREQUEST | Lists operator requests that are on this RSM server. The lpContainerId parameter must be NULL.
NTMS_PARTITION | Specifies a partition on a piece of physical media. The piece of physical media can contain multiple physical partitions (for example, an optical disk contains two sides). Available when lpContainerID is set to NULL, Physical Media, Logical Media, or Media Pool.
NTMS_PHYSICAL_MEDIA Specifies a piece of physical media (a tape, optical disk, CD-ROM, or magnetic cartridge). A piece of physical media can contain multiple physical partitions (for example, sides of an optical disk).

The container ID contains NULL to get all the physical media, a media pool, logical media, or a library. Available when lpContainerID is set to NULL, Media Pool, or Library
NTMS_STORAGESLOT | Lists media slots contained in a library specified by the lpContainerId parameter or all the storage slots supported by RSM if a NULL container ID is supplied. Available when lpContainerID is set to NULL or Library.

dwOptions
Option flags. Reserved and must be set to 0.

Return Values

ERROR_INVALID_PARAMETER
The list-size pointer is missing or the object type is invalid.
ERROR_INSUFFICIENT_BUFFER
The buffer provided is too small to return all the entries available. The list is truncated and the actual size is returned in lpdwListSize.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_OBJECT_NOT_FOUND
No objects match the search criteria.
ERROR_SUCCESS
The function was successful.

Remarks

Security functions are also available to get and set specific access rights on RSM objects.

If the available number of IDs specified in the lpdwListSize parameter is greater than the current buffer size, lpdwListSize returns the number of IDs required. The application should then allocate a larger buffer and try again.

Since it is possible for IDs to be added by another process, it is possible for a subsequent function with a resized list to get an error indicating that the list is too small. To avoid this, specify a list in the lpdwListSize parameter that is slightly larger than the required length.

If the lpContainerId parameter is set to NULL, RSM enumerates top-level objects (such as libraries).

If more than one object is listed, the object may be enumerated from more than one container. The NULL container is the highest-level container and enumerates all objects in a system. For example, you can enumerate media in a particular library or all media in the system.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Object Management Functions, CreateNtmsMediaPool, GetNtmsObjectInformation, SetNtmsObjectInformation


ExportNtmsDatabase

[This is preliminary documentation and subject to change.]

The ExportNtmsDatabase function creates a consistent set of database files in the RSM database directory, %SystemRoot%\System32\NtmsData\Export.

DWORD WINAPI ExportNtmsDatabase(
  HANDLE hSession
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.

Return Values

ERROR_ACCESS_DENIED
Access to one or more RSM objects is denied.
ERROR_DATABASE_FAILURE
The database query or update failed.
ERROR_INVALID_HANDLE
The value specified in the hSession parameter is invalid.
ERROR_NOT_CONNECTED
Unable to connect to the RSM service.
ERROR_SUCCESS
The function was successful.

Remarks

The ExportNtmsDatabase function is used by backup applications to create a copy of the RSM database. The existing files in the %SystemRoot%\System32\NtmsData\Export directory are overwritten by this function.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Database Backup and Recovery Functions, ImportNtmsDatabase


GetNtmsMediaPoolName

[This is preliminary documentation and subject to change.]

The GetNtmsMediaPoolName function returns the specified media pool's full name hierarchy into the output buffer.

DWORD WINAPI GetNtmsMediaPoolName(
  HANDLE hSession,
  LPNTMS_GUID lpPoolId,
  LPTSTR lpBufName,
  LPDWORD lpdwBufSize
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpPoolId
Specifies the GUID of the media pool to retrieve the name.
lpBufName
Specifies the name of the output buffer.
lpdwBufSize
Specifies the size of the name data buffer on input. Returns the number of characters (string length) of the full name.

Return Values

ERROR_INSUFFICIENT_BUFFER
The buffer size was not correctly specified. The correct size is returned in lpdwBufSize.
ERROR_INVALID_HANDLE
The value specified in the hSession parameter is NULL or invalid.
ERROR_INVALID_MEDIA_POOL
The media pool ID is missing or invalid.
ERROR_INVALID_PARAMETER
The parameter is missing or invalid.
ERROR_NOT_ENOUGH_MEMORY
The memory allocation failed.
ERROR_SUCCESS
The function was successful.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions, CreateNtmsMediaPool


GetNtmsObjectAttribute

[This is preliminary documentation and subject to change.]

The GetNtmsObjectAttribute function gets private data from the specified RSM object.

DWORD WINAPI GetNtmsObjectAttribute(
  HANDLE hSession,
  LPNTMS_GUID lpObjectId,
  DWORD dwType,
  LPCTSTR lpAttributeName,
  LPVOID lpAttributeData,
  LPDWORD lpAttributeSize
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpObjectId
Specifies the GUID of the object from which to retrieve the attribute.
dwType
Specifies the RSM object type. (See EnumerateNtmsObject for object types.)
lpAttributeName
Specifies the name for the extended attribute to get from the RSM objects.
lpAttributeData
Specifies the buffer in which to store the attribute.
lpAttributeSize
Specifies the size of the attribute data buffer on input and returns the actual size of the attribute data on return.

Return Values

ERROR_DATABASE_FAILURE
The database query or update failed.
ERROR_INSUFFICIENT_BUFFER
The buffer size is not correctly specified. The correct size is returned in the lpAttributeSize parameter.
ERROR_INVALID_HANDLE
The value specified in the hSession parameter is NULL or invalid.
ERROR_INVALID_PARAMETER
The pointer is NULL or invalid.
ERROR_NO_DATA
The attribute specified is greater than or equal to NTMS_MAXATTR_LENGTH.
ERROR_NOT_CONNECTED
Unable to connect to the RSM service.
ERROR_OBJECT_NOT_FOUND
The specified attribute was not found.
ERROR_SUCCESS
The function was successful.

Remarks

The GetNtmsObjectAttribute function must be executed on the RSM server. Because the buffer of bytes is unmarshaled between systems of different architectures, remote execution of this function may result in unpredictable results.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Object Management Functions, EnumerateNtmsObject, SetNtmsObjectAttribute


GetNtmsObjectInformation

[This is preliminary documentation and subject to change.]

The GetNtmsObjectInformation function returns an object's information structure for the specified object.

DWORD WINAPI GetNtmsObjectInformation(
  HANDLE hSession,
  LPNTMS_GUID lpObjectId,
  LPNTMS_OBJECTINFORMATION lpInfo
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpObjectId
Specifies a unique identifier of the RSM object.
lpInfo
Pointer to the NTMS_OBJECTINFORMATION structure.

Return values

ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_PARAMETER
The object ID or information structure is missing, or the object information size or object type is invalid.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_OBJECT_NOT_FOUND
The object ID is invalid.
ERROR_SUCCESS
The function was successful.

Remarks

The information size and type of the information structure must be set correctly in the lpInfo parameter before you use the GetNtmsObjectInformation function.

To avoid unpredictable results, applications must call the GetNtmsObjectInformation function before calling the SetNtmsObjectInformation function. The SetNtmsObjectInformation function updates all writable members of the NTMS_OBJECTINFORMATION structure, therefore the application is responsible for providing a value for all writable members.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Object Management Functions, GetNtmsObjectSecurity, NTMS_OBJECTINFORMATION, SetNtmsObjectInformation


GetNtmsObjectSecurity

[This is preliminary documentation and subject to change.]

The GetNtmsObjectSecurity function reads the security descriptor for the specified RSM object.

DWORD WINAPI GetNtmsObjectSecurity(
  HANDLE hSession,
  LPNTMS_GUID lpObjectId,
  DWORD dwType,
  SECURITY_INFORMATION RequestedInformation,
  PSECURITY_DESCRIPTOR lpSecurityDescriptor,
  DWORD nLength,
  LPDWORD lpnLengthNeeded
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpObjectId
Specifies the unique identifier of the RSM object.
dwType
Specifies the object type. (See the EnumerateNtmsObject function for object types.)
RequestedInformation
Specifies the Windows NT security data.
lpSecurityDescriptor
Specifies the Windows NT security descriptor.
nlength
Specifies the length of the descriptor.
lpnLengthNeeded
Specifies the required length if the supplied buffer is not large enough for the security descriptor.

Return Values

ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_PARAMETER
The object ID is missing.
ERROR_NO_SECURITY_ON_OBJECT
There is no security information for this object.
ERROR_OBJECT_NOT_FOUND
The object ID is invalid.
ERROR_SUCCESS
The function was successful.

Remarks

RSM security uses the same security descriptors and information members that Windows NT security uses. This allows the standard security dialog boxes to be used to select RSM security.

For more information on Windows NT security, see the SetPrivateObjectSecurity function and the security section in the Platform SDK. For more information on RSM security, see RSM Security.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Object Management Functions, EnumerateNtmsObject, SetNtmsObjectSecurity


GetNtmsRequestOrder

[This is preliminary documentation and subject to change.]

The GetNtmsRequestOrder function gets the order that the specified request will be processed in the library queue.

DWORD WINAPI GetNtmsRequestOrder(
  HANDLE hSession,
  LPNTMS_GUID lpRequestId,
  LPDWORD lpdwOrderNumber
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpRequestId
Specifies the unique identifier of a library request.
lpdwOrderNumber
Specifies the order in which this request will be processed in the queue.

Return Values

ERROR_ACCESS_DENIED
NTMS_CONTROL_ACCESS to the library is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_INVALID_HANDLE
The request ID is invalid or missing.
ERROR_INVALID_PARAMETER
The library ID or operation ID pointer is missing.
ERROR_SUCCESS
The insert is queued.

Remarks

If the GetNtmsRequestOrder function returns zero, ordering is not available for this request. The order number is specific to the type of request because the types are processed in a predetermined order.

For example, the NTMS_LM_DISMOUNT request is processed prior to an NTMS_LM_MOUNT request. Within a specific class of requests the queue can be ordered, however. The lower-ordered requests are processed first, for example, 1 is the first request processed, 2 is the next request processed, and so forth.

You can use this order number, the request type, the submission time, and the submission date to help view the queue in sorted order. Request type, order number, and submission time should perform sorting.

Currently on NTMS_LM_MOUNT, requests are sorted using the order number.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Library Control Functions, SetNtmsRequestOrder


ImportNtmsDatabase

[This is preliminary documentation and subject to change.]

The ImportNtmsDatabase function causes RSM to import the database files from the %SystemRoot%\System32\NtmsData\Export directory at the next restart of the RSM.

DWORD WINAPI ImportNtmsDatabase(
  HANDLE hSession
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.

Return Values

ERROR_ACCESS_DENIED
Access to at least one RSM object is denied.
ERROR_DATABASE_FAILURE
The database query or update failed.
ERROR_INVALID_HANDLE
The value specified in the hSession parameter is invalid.
ERROR_NOT_CONNECTED
Unable to connect to the RSM.
ERROR_SUCCESS
The function was successful.

Remarks

The ImportNtmsDatabase function is used by backup applications during disaster recovery.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Database Backup and Recovery Functions, ExportNtmsDatabase


InjectNtmsCleaner

[This is preliminary documentation and subject to change.]

The InjectNtmsCleaner function allows a cleaner cartridge to be inserted into the specified online library unit.

DWORD WINAPI InjectNtmsCleaner(
  HANDLE hSession,
  LPNTMS_GUID lpLibrary,
  LPNTMS_GUID lpInjectOperation,
  WORD dwNumberOfCleansLeft,
  DWORD dwAction
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpLibrary
Specifies the unique identifier of a library object.
lpInjectOperation
Specifies the GUID of the insert process. This is returned for use of with Stop action code.
dwNumberOfCleansLeft
Represents the number of cleaning cycles left on the inserted cleaning cartridge
dwAction
This parameter can be one of the following values.
Value | Meaning
NTMS_INJECT_START | Start the insertion with either the NTMS_IEPORT or the NTMS_IEDOOR object. A single cleaner cartridge should be inserted. If the NTMS_IEDOOR object is used, no inventory will be performed on the library.
NTMS_INJECT_STOP | For libraries with PORTs only: Terminates the insertion prior to the time-out event lapsing.

Return Values

ERROR_ACCESS_DENIED
Access to at least one RSM object is denied.
ERROR_DEVICE_NOT_AVAILABLE
The library is not currently connected.
ERROR_INVALID_HANDLE
The value specified in the hSession parameter is invalid.
ERROR_INVALID_LIBRARY
Unable to retrieve the library definition from the database.
ERROR_LIBRARY_OFFLINE
The library must be online for a cleaner cartridge to be inserted.
ERROR_NO_SLOT_RESERVED
This library has no slot reserved as a cleaner slot.
ERROR_SLOT_FULL
A cleaner slot is reserved but already has a cleaner cartridge. The cleaner cartridge must be ejected first, using the EjectNtmsCleaner function.
ERROR_SLOT_NOT_PRESENT
A cleaner slot is reserved but the slot specified is currently not installed in the library. This error occurs if at least one magazine is missing from the library.
ERROR_SUCCESS
The function was successful.

Remarks

To use the InjectNtmsCleaner function, the number of cleaning cycles that remain on the cleaner cartridge must be specified so that RSM can keep track of it.

If an NTMS_IEPORT object is available, the NTMS_IEPORT object directs the cartridge to the currently reserved cleaner slot.

If there is no NTMS_IEPORT object, a door access is performed. In this case, the operator is directed to place the media into the reserved slot.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Cleaner Management Functions, CleanNtmsDrive, EjectNtmsCleaner, ReleaseNtmsCleanerSlot, ReserveNtmsCleanerSlot


InjectNtmsMedia

[This is preliminary documentation and subject to change.]

The InjectNtmsMedia function allows media to be inserted into the port of the specified online library. If the library is busy, RSM queues InjectNtmsMedia and returns success.

DWORD WINAPI InjectNtmsMedia(
  HANDLE hSession,
  LPNTMS_GUID lpLibraryId,
  LPNTMS_GUID lpInjectOperation,
  DWORD dwAction
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpLibraryId
Specifies the unique identifier of a library object.
lpInjectOperation
Specifies the GUID of the insert Libraryworkitem. This is returned for use with the Stop action code.
dwAction
This parameter can be one of the following values.
Value | Meaning
NTMS_INJECT_START | Start the insert operation with a port. Media is repeatedly inserted until the time-out event occurs or the NTMS_INJECT_STOP flag is issued.
NTMS_INJECT_STOP | Terminate the insertion process prior to the time-out event lapsing.

Return Values

ERROR_ACCESS_DENIED
NTMS_CONTROL_ACCESS to the library is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_DEVICE_NOT_AVAILABLE
The library is disabled.
ERROR_INVALID_HANDLE
The session ID is invalid or missing.
ERROR_INVALID_OPERATION
There was a Stop action performed on an invalid operation ID.
ERROR_INVALID_PARAMETER
The library ID or operation ID pointer is missing.
ERROR_LIBRARY_OFFLINE
The library ID refers to an offline library that cannot eject media.
ERROR_NOT_ENOUGH_MEMORY
There was an allocation failure during processing.
ERROR_SUCCESS
The insert is queued.

Remarks

If the library specified by the InjectNtmsMedia function does not have a port, use the AccessNtmsLibraryDoor function to insert and eject media.

This function is valid only for online libraries.

This function returns to the application as soon as the insert request is queued.

Insert begins the process of inserting media into an online library. Because libraries vary on the functionality of the NTMS_IEPORT object, each device may operate slightly differently. The following steps describe how to insert media into a library:

To insert media into a library
  1. Allow/unlock/extend the NTMS_IEPORT object.
  2. Poll for a full NTMS_IEPORT object, a retracted NTMS_IEPORT object, a Stop Inject command, or a time-out value. If none of these have occurred, continue to wait. (Multi-cartridge IEports are not scanned for full status.)
  3. When one of the preceding events occurs, the NTMS_IEPORT object is locked, each medium in the NTMS_IEPORT object is moved to a slot, and an identify medium command is queued for each medium.

If there are not enough slots for the media in the NTMS_IEPORT object, the media remains in the NTMS_IEPORT object and an Operator Request is posted to have media removed from the library.

If there are no free slots, the InjectNtmsMedia function receives an error.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Library Control Functions, EjectNtmsMedia


InventoryNtmsLibrary

[This is preliminary documentation and subject to change.]

The InventoryNtmsLibrary function queues an inventory of the specified online library. If the library is busy, RSM queues InventoryNtmsLibrary and returns success.

DWORD WINAPI InventoryNtmsLibrary(
  HANDLE hSession,
  LPNTMS_GUID lpLibraryId,
  DWORD dwAction
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpLibraryId
Specifies the unique identifier of an online library object.
dwAction
This parameter can be one of the following values.
Value | Meaning
NTMS_INVENTORY_OMID | A full on-media inventory is performed. Each partition of each medium must be mounted into a drive. This is a time consuming process.
NTMS_INVENTORY_FAST | If the library has a bar-code reader installed, this flag causes a bar-code inventory to be performed. If the library does not have a bar-code reader, this flag causes a differential inventory to be performed (slots are classified).
NTMS_INVENTORY_DEFAULT | Use the InventoryMethod specified in the library object.
NTMS_INVENTORY_NONE | Perform no inventory. Operation is a non-operation.

Return Values

ERROR_ACCESS_DENIED
Access to one or more RSM objects is denied.
ERROR_DEVICE_NOT_AVAILABLE
The library is not currently connected.
ERROR_INVALID_HANDLE
The value specified in the hSession parameter is invalid.
ERROR_INVALID_LIBRARY
The library specified is not an online library.
ERROR_INVALID_PARAMETER
The library ID or session ID is invalid.
ERROR_NOT_CONNECTED
Unable to connect to the RSM service.
ERROR_SUCCESS
The function was successful.

Remarks

Only online libraries can be inventoried.

The InventoryNtmsLibrary function marks all the slots that currently contain a medium in the library for classification/identification. The InventoryNtmsLibrary function returns when all the media is marked.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Library Control Functions, AccessNtmsLibraryDoor


MountNtmsMedia

[This is preliminary documentation and subject to change.]

The MountNtmsMedia function synchronously mounts one or more pieces of media.

DWORD WINAPI MountNtmsMedia(
  HANDLE hSession,
  LPNTMS_GUID lpMediaId,
  LPNTMS_GUID lpDriveId,
  DWORD dwCount,
  DWORD dwOptions,
  DWORD dwPriority,
  DWORD dwTimeout
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpMediaId
Specifies an array of unique identifiers of logical media or partitions.
lpDriveId
Specifies an array of drive identifiers that corresponds to the list of media in the IpMediaId parameter. This array either supplies a list of drives to mount media into or returns the list of drives that media is mounted into on operation completion. See the NTMS_MOUNT_SPECIFIC_DRIVE value below. If the MountNtmsMedia function times out prior to the completion of the mount, RSM does not return the list of drives.
dwCount
Specifies the number of media identifiers and drive identifiers passed in the lpMediaId and lpDriveId parameters. Note that lpMediaId and lpDriveId must point to the first element of equal-length arrays.
dwOptions
This parameter can be one or more of the following values.
Value | Meaning
NTMS_MOUNT_SPECIFIC_DRIVE | Mount the media into the specific drives provided in the lpDriveId parameter.
NTMS_MOUNT_READ | Mount the media for read access. Use this value to mount read-only media.
NTMS_MOUNT_WRITE Mount the media for write access. Use this flag to prevent RSM from mounting Completed media. This value can be combined with NTMS_MOUNT_READ for read/write access.

RSM cannot mount Completed media if this flag is selected.
NTMS_MOUNT_ERROR_NOT_AVAILABLE | This value returns an error if the media or a drive is not available.
NTMS_MOUNT_ERROR_OFFLINE | Do not issue an operator request to mount offline media. Return an error if the media specified is not currently in an online library.

dwPriority
Specifies the priority of the mount used by RSM to allow access to drives. Priorities range from -15 to 15, with 15 the highest priority and 0 is the default. This parameter can also take one of the following constants. An application should pass NTMS_PRIORITY_NORMAL unless a special mount priority is required.
Value | Meaning
NTMS_PRIORITY_NORMAL | Mounts that are not time critical.
NTMS_PRIORITY_LOW | Mounts performed as a background activity.
NTMS_PRIORITY_HIGH | Mounts that are time critical.
NTMS_PRIORITY_LOWEST | Lowest priority mount.
NTMS_PRIORITY_HIGHEST | Highest priority mount.

dwTimeout
Specifies the maximum time, in milliseconds, allowed to mount the specified media. Set this parameter to INFINITE to wait as long as the mount takes.

Return Values

ERROR_ACCESS_DENIED
NTMS_USE_ACCESS to the media pool or library that contains the media is denied; other security errors are also possible but they would indicate a security subsystem error.
ERROR_BUSY
The media or drives are busy.
ERROR_CANCELED
The request was canceled by the CloseNtmsSession function.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_DRIVE_MEDIA_MISMATCH
The media and drive specified are not in the same library.
ERROR_INVALID_DRIVE
At least one of the specified drives is not valid.
ERROR_INVALID_LIBRARY
The library that contains the drives or media is not valid.
ERROR_INVALID_MEDIA
One or more of the media specified is not valid, or there are duplicate media IDs in list of media.
ERROR_INVALID_STATE
An unexpected media or device state occurred during mount.
ERROR_MEDIA_OFFLINE
The media is offline and cannot be mounted.
ERROR_NOT_ENOUGH_MEMORY
A memory allocation failure occurred during processing.
ERROR_REQUEST_REFUSED
The user canceled the request through the user interface.
ERROR_RESOURCE_DISABLED
One or more resources required to perform the mount are disabled.
ERROR_SUCCESS
The media has been mounted and is ready for use.
ERROR_TIMEOUT
The time-out event expired while attempting to acquire one or more required resources. The mount request has been canceled.
ERROR_WRITE_PROTECT
The media state is set to Completed and the NTMS_MOUNT_WRITE value was specified.

Remarks

The MountNtmsMedia function queues a request to mount the specified media, then waits for the number of milliseconds specified in the dwTimeout parameter for the mount to complete or for an error to be detected. If RSM cannot complete the mount operation before dwTimeout expires, NTMS cancels the request and returns an errorIf the specified media is in an offline library, the application might be blocked for an extended period of time. You can use the GetNtmsObjectInformation function to determine the current location of the specified medium. You can also use the NTMS_MOUNT_ERROR_OFFLINE value to generate an immediate error instead of an operator request when the media is offline.

If the specified medium is in use or a drive is not available, the process blocks up to the time-out value and returns ERROR_BUSY. If the NTMS_MOUNT_ERROR_NOT_AVAILABLE value is specified, the function returns an immediate error when a resource (media or drive) is not available.

The time-out value of INFINITE can be used to make the function synchronous. When a non-zero time-out value is specified in the dwTimeout parameter, RSM waits for all the media specified in lpMediaId to become available. If the specified time elapses before all the media is available, the MountNtmsMedia function returns an error and cancels the request. The application can examine the status returned and resubmit the request if desired.

When multiple media to be mounted are specified with a single call, all the specified media must be in a single library. If any of the specified media are offline, none of the media will be mounted until all the media are online.

At the completion of the mount the drive state (for example, fix or variable mode) is not defined. The application must set up the drive.

The CloseNtmsSession function can be used to cancel a mount that is pending. The default behavior is:

If the specified medium is offline, RSM posts an operator request to mount the media and the MountNtmsMedia function waits for the period of time specified in the dwTimeout parameter.

If a the specified medium is online, RSM requests the mount.

If a drive or media is not available, RSM pends the request and the MountNtmsMedia function waits for the period of time specified in the dwTimeout parameter.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions


MoveToNtmsMediaPool

[This is preliminary documentation and subject to change.]

The MoveToNtmsMediaPool function moves the specified medium from its current media pool to the specified media pool.

DWORD WINAPI MoveToNtmsMediaPool(
  HANDLE hSession,
  LPNTMS_GUID lpMediaId,
  LPNTMS_GUID lpPoolId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpMediaId
Specifies the unique identifier of a piece of physical media. A medium must not have a partition in the Completed, Allocated, or Reserved state to be moved to another media pool.
lpPoolId
Specifies the unique identifier of the destination media pool.

Return Values

ERROR_ACCESS_DENIED
NTMS_MODIFY_ACCESS to source media's media pool or the destination media pool is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_BUSY
At least one partition of the media is in use or currently unavailable.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_MEDIA_POOL
The destination media pool is invalid. The media pool is nonexistent. The media in the foreign or import pool may only be moved to the scratch pool.
ERROR_INVALID_MEDIA
The source media or implied source media pool is invalid.
ERROR_INVALID_PARAMETER
The media ID or media pool ID is missing.
ERROR_MEDIA_INCOMPATIBLE
The source media type differs from the destination media pool's media type.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_SUCCESS
The function was successful.

Remarks

The destination pool specified in the MoveToNtmsMediaPool function must be of the same media type and have compatible security.

RSM writes an on-media identifier to media before moving the media into the scratch media pool from the foreign media pool.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions, AllocateNtmsMedia, CreateNtmsMediaPool


OpenNtmsNotification

[This is preliminary documentation and subject to change.]

The OpenNtmsNotification function opens a channel to receive RSM object change notifications for objects of the specified type.

HANDLE WINAPI OpenNtmsNotification(
  HANDLE hSession,
  DWORD dwType
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
dwType
Specifies the RSM object type for notification.

Return Values

ERROR_DATABASE_FAILURE
The database query or update failed.
ERROR_INVALID_HANDLE
The value specified in the hSession parameter is invalid or NULL.
ERROR_NOT_CONNECTED
Unable to connect to the RSM service.
ERROR_SUCCESS
The function was successful.
INVALID_HANDLE_VALUE
The function failed.

Remarks

The OpenNtmsNotification function returns a notification handle that you pass to the WaitForNtmsNotification or CloseNtmsNotification functions.

For extended error information, call the Win32 GetLastError function.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Database Notification Functions, CloseNtmsNotification, WaitForNtmsNotification


OpenNtmsSession

[This is preliminary documentation and subject to change.]

The OpenNtmsSession function sets up a session with a RSM server.

HANDLE WINAPI OpenNtmsSession(
  LPCTSTR lpServer,
  LPCTSTR lpApplication,
  DWORD dwOptions
);

Parameters

lpServer
Specifies a character string that points to the RSM server name. If this parameter is NULL, the current computer is used.
lpApplication
Specifies a unique character string that identifies the application. This name identifies resources and operator requests.
dwOptions
Reserved. The application should pass 0.

Return Values

ERROR_INVALID_COMPUTERNAME
An invalid computer name format was supplied.
ERROR_INVALID_PARAMETER
Invalid parameters were supplied.
ERROR_NO_NETWORK
The network is not started or not available.
ERROR_NOT_CONNECTED
Unable to connect to the RSM service.
ERROR_NOT_READY
RSM service has not started.
ERROR_SUCCESS
The function was successful.
INVALID_HANDLE_VALUE
RSM cannot open a session.
RPC_S_NO_INTERFACES
If you build your application on a newer version of RSM than the service is using

Remarks

The OpenNtmsSession function returns a session handle used with other RSM functions, establishes a connection with the RSM database, and initializes the RSM subsystem for the application.

The OpenNtmsSession function returns a handle that uniquely identifies this session, or it returns INVALID_HANDLE_VALUE if RSM cannot open a session. Other RSM functions use this session handle to perform operations.

If INVALID_HANDLE_VALUE returns, you can call the Win32 GetLastError function to retrieve the error code.

When OpenNtmsSession returns, the application can perform RSM operations.

Sessions are thread-safe but cannot be passed among processes.

If you build your application on a newer version of RSM than the service is using, RPC_S_NO_INTERFACES returns when you call OpenNtmsSession.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Session Management Functions, CloseNtmsSession


ReleaseNtmsCleanerSlot

[This is preliminary documentation and subject to change.]

The ReleaseNtmsCleanerSlot function removes an existing slot reservation for a cleaning cartridge. The slot can then be used for data cartridges.

DWORD WINAPI ReleaseNtmsCleanerSlot(
  HANDLE hSession,
  LPNTMS_GUID lpLibrary
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpLibrary
Specifies the unique identifier of the library to set the cleaner slot.

Return Values

ERROR_ DEVICE_NOT_AVAILABLE
The library is not currently connected.
ERROR_INVALID_HANDLE
The value specified in the hSession parameter is invalid.
ERROR_NOT_CONNECTED
Unable to connect to the RSM service.
ERROR_NO_SLOT_RESERVED
This library has no slot reserved for a cleaner cartridge.
ERROR_SLOT_FULL
The library has a reserved cleaner cartridge slot but the slot contains a cleaner cartridge (the slot must be empty). Use the EjectNtmsCleaner function to eject a cleaner cartridge.
ERROR_SLOT_NOT_PRESENT
The library has a reserved cleaner cartridge slot, but the specified slot is currently not installed in the library. This error can occur if at least one magazine is missing from the library.
ERROR_SUCCESS
The function was successful.

Remarks

For the ReleaseNtmsCleanerSlot function to succeed, the slot must be present and empty. The library must also have a slot reserved for cleaning.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Cleaner Management Functions, CleanNtmsDrive, EjectNtmsCleaner, InjectNtmsCleaner, ReserveNtmsCleanerSlot


ReserveNtmsCleanerSlot

[This is preliminary documentation and subject to change.]

The ReserveNtmsCleanerSlot function reserves a single slot in an online library unit for a drive cleaner cartridge.

DWORD WINAPI ReserveNtmsCleanerSlot(
  HANDLE hSession,
  LPNTMS_GUID lpLibrary,
  LPNTMS_GUID lpSlot
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpLibrary
Specifies the unique identifier of the library to set the cleaner slot.
lpSlot
Specifies the unique identifier of the slot that is to be reserved for a cleaner cartridge.

Return Values

ERROR_ALREADY_RESERVED
Either this slot or another slot in the library has already been reserved for cleaning. To change the cleaner cartridge slot, the currently reserved cleaner slot must be released first, using the ReleaseNtmsCleanerSlot function.
ERROR_ DEVICE_NOT_AVAILABLE
The library is not currently connected.
ERROR_INVALID_HANDLE
The value specified in the hSession parameter is invalid.
ERROR_INVALID_SLOT
Unable to retrieve the slot definition from the database.
ERROR_NOT_CONNECTED
Unable to connect to the RSM service.
ERROR_SLOT_FULL
A cleaner slot is not reserved. The slot specified has media in it. Reservation can only be performed on an empty slot.
ERROR_SLOT_NOT_PRESENT
A cleaner slot is not reserved. The slot specified is currently not installed in the library. This error occurs if at least one cartridge magazine is missing from the library.
ERROR_SUCCESS
The function was successful.

Remarks

The slot reserved with the ReserveNtmsCleanerSlot function must be present and empty. The library must not already have a slot reserved for a cleaner cartridge.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Cleaner Management Functions, CleanNtmsDrive, EjectNtmsCleaner, InjectNtmsCleaner, ReleaseNtmsCleanerSlot


SatisfyNtmsOperatorRequest

[This is preliminary documentation and subject to change.]

The SatisfyNtmsOperatorRequest function completes the specified RSM operator request.

DWORD WINAPI SatisfyNtmsOperatorRequest(
  HANDLE hSession,
  LPNTMS_GUID lpRequestId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpRequestId
The operator request object ID.

Return Values

ERROR_ACCESS_DENIED
The user that tried to execute this function does not have administrator privileges. Only an administrator of the RSM server can satisfy operator requests.
ERROR_OBJECT_NOT_FOUND
The operator request object ID was not found. This error occurs if the request is completed before the operation has been satisfied or when an invalid request ID is supplied.
ERROR_SUCCESS
The operator request has been satisfied.

Remarks

For a list of the existing operator requests to cancel with the SatisfyNtmsOperatorRequest function, see the EnumerateNtmsObject function.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Operator Request Functions, CancelNtmsOperatorRequest, SubmitNtmsOperatorRequest, WaitforNtmsOperatorRequest


SetNtmsMediaComplete

[This is preliminary documentation and subject to change.]

The SetNtmsMediaComplete function marks a piece of logical media as complete.

DWORD WINAPI SetNtmsMediaComplete(
  HANDLE hSession,
  LPNTMS_GUID lpMediaId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpMediaId
Specifies the unique identifier of a piece of logical media.

Return Values

ERROR_ACCESS_DENIED
NTMS_MODIFY_ACCESS to either media's media pool is denied Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_MEDIA
The media identifier is invalid.
ERROR_INVALID_MEDIA_POOL
The media pool for the media is invalid.
ERROR_INVALID_PARAMETER
The media identifier is missing.
ERROR_INVALID_STATE
The media is not in the allocated state or is currently mounted.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_SUCCESS
The function was successful.

Remarks

The SetNtmsMediaComplete function marks the specified medium as Complete. An application marks the medium as Complete when the application is no longer going to write to the medium. Complete media cannot be mounted with the NTMS_MOUNT_WRITE flag. For many applications, the date and time when the medium is marked Complete indicates which media can be safely removed from a library.

The SetNtmsMediaComplete function is typically used when an application reaches the end of media. Media that is mounted or in use cannot be marked as complete.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions, MountNtmsMedia


SetNtmsObjectAttribute

[This is preliminary documentation and subject to change.]

The SetNtmsObjectAttribute function creates private data in the specified RSM object.

DWORD WINAPI SetNtmsObjectAttribute(
  HANDLE hSession,
  LPNTMS_GUID lpObjectId,
  DWORD dwType,
  LPCTSTR lpAttributeName,
  LPVOID lpAttributeData,
  DWORD dwAttributeSize
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpObjectId
Specifies the GUID of the object for which to set the attribute.
dwType
Specifies the RSM object type. (See EnumerateNtmsObject for object types.)
lpAttributeName
Specifies the name that the extended attribute writes to one of the RSM objects.
lpAttributeData
Specifies the data to save as the RSM object attribute.
dwAttributeSize
Specifies the size of the attribute data.

Return Values

ERROR_DATABASE_FAILURE
The database update failed.
ERROR_INSUFFICIENT_BUFFER
The buffer size is not correctly specified. The correct size is returned in the lpAttributeSize parameter.
ERROR_INVALID_HANDLE
The value specified in the hSession parameter is NULL or invalid.
ERROR_INVALID_NAME
The name or attribute is invalid. The NTMS_MAXATTR_NAMELEN value defines the maximum attribute name length. The length includes a NULL.
ERROR_INVALID_PARAMETER
The pointer is NULL or invalid.
ERROR_NO_DATA
The attribute specified is greater than or equal to NTMS_MAXATTR_LENGTH.
ERROR_NOT_CONNECTED
Unable to connect to the RSM service.
ERROR_OBJECT_NOT_FOUND
The GUID is invalid.
ERROR_SUCCESS
The function was successful.

Remarks

The SetNtmsObjectAttribute function must be executed on the specified RSM server. Because the buffer of bytes is unmarshaled between systems of different architectures, remote execution of this function can result in unpredictable results.

To delete an attribute, perform a set of the attribute with a length of zero.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Object Management Functions, EnumerateNtmsObject, GetNtmsObjectAttribute


SetNtmsObjectInformation

[This is preliminary documentation and subject to change.]

The SetNtmsObjectInformation function changes the information structure of the specified object.

DWORD WINAPI SetNtmsObjectInformation(
  HANDLE hSession,
  LPNTMS_GUID lpObjectId,
  LPNTMS_OBJECTINFORMATION lpInfo
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpObjectId
Specifies the unique identifier of the RSM object.
lpInfo
Pointer to the NTMS_OBJECTINFORMATION structure.

Return Values

ERROR_ACCESS_DENIED
NTMS_MODIFY_ACCESS or NTMS_CONTROL_ACCESS is denied to the object being written or no modifications are allowed to the object type specified. Access required is as follows:
NTMS_MEDIA_POOL
NTMS_CONTROL_ACCESS to the media pool.
NTMS_LOGICAL_MEDIA
NTMS_MODIFY_ACCESS to the media pool of the logical media.
NTMS_LIBRARY
NTMS_CONTROL_ACCESS to the library.
NTMS_CHANGER
No write fields.
NTMS_DRIVE
No write fields.
NTMS_CHANGER_TYPE
No write fields.
NTMS_DRIVE_TYPE
No write fields.
NTMS_STORAGESLOT
No write fields.
NTMS_IEDOOR
No write fields.
NTMS_IEPORT
No write fields.
NTMS_PHYSICAL_MEDIA
No write fields.
NTMS_PARTITION
NTMS_MODIFY_ACCESS to the media pool of the partition.
NTMS_MEDIA_TYPE
No write fields.
NTMS_OPREQUEST
No write fields.
NTMS_LIBREQUEST
No write fields.
ERROR_SUCCESS
The function was successful.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_PARAMETER
The object ID or information structure is missing, or the object information size or object type is invalid.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_OBJECT_NOT_FOUND
The object ID is invalid.

Remarks

Not all information in an object can be set using the SetNtmsObjectInformation function. For writable fields, see object definitions.

The information size and type must be set before you can use SetNtmsObjectInformation.

All writable properties for the object are read from the NTMS_OBJECTINFORMATION structure and written to the database without regard for any write operations that have occurred between the time this application called the GetNtmsObjectInformation function and the SetNtmsObjectInformation function. Because of this you can lose changes.

To avoid unpredictable results, applications must call GetNtmsObjectInformation before calling SetNtmsObjectInformation. As noted above, SetNtmsObjectInformation updates all writable fields, therefore the application is responsible for providing a value for all writable fields.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Object Management Functions, GetNtmsObjectInformation, GetNtmsObjectSecurity, NTMS_OBJECTINFORMATION


SetNtmsObjectSecurity

[This is preliminary documentation and subject to change.]

The SetNtmsObjectSecurity function writes the security descriptor for the specified RSM object.

DWORD WINAPI SetNtmsObjectSecurity(
  HANDLE hSession,
  LPNTMS_GUID lpObjectId,
  DWORD dwType,
  SECURITY_INFORMATION SecurityInformation,
  PSECURITY_DESCRIPTOR pSecurityDescriptor
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpObjectId
Specifies the unique identifier of the RSM object.
dwType
Specifies the RSM object type. (See the EnumerateNtmsObject function for object types.)
SecurityInformation
Specifies the security information to write to the RSM object.
IpSecurityDescriptor
Specifies the security descriptor to write to the RSM object: NTMS_USE_ACCESS, NTMS_CONTROL_ACCESS, or NTMS_MODIFY_ACCESS.

Return Values

ERROR_ACCESS_DENIED
The privileges required to modify the security descriptor are denied.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_PARAMETER
The object ID is missing.
ERROR_NO_SECURITY_ON_OBJECT
There is no security information for this object.
ERROR_OBJECT_NOT_FOUND
The object ID is invalid.
ERROR_SUCCESS
The function was successful.

Remarks

If an application uses the SetNtmsObjectSecurity function to set the owner of an object, the application must have WRITE_OWNER permission or be the owner of the object.

If an application uses SetNtmsObjectSecurity to set the discretionary access-control list (ACL) of an object, the application must have WRITE_DAC permission or be the owner of the object.

If an application uses SetNtmsObjectSecurity to set the system ACL of an object, the SE_SECURITY_NAME privilege must be enabled for the application.

For more information on Windows NT security, see the SetPrivateObjectSecurity function and the security section in the Platform SDK. For more information on RSM security, see RSM Security.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Object Management Functions, EnumerateNtmsObject, GetNtmsObjectSecurity


SetNtmsRequestOrder

[This is preliminary documentation and subject to change.]

The SetNtmsRequestOrder function sets the order that the specified request will be processed in the library queue.

DWORD WINAPI SetNtmsRequestOrder(
  HANDLE hSession,
  LPNTMS_GUID lpRequestId,
  DWORD dwOrderNumber
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpRequestId
Specifies the unique identifier of a library request.
dwOrderNumber
Specifies the order that the request will be processed in the queue.

Return Values

ERROR_ACCESS_DENIED
NTMS_CONTROL_ACCESS to the library is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_INVALID_HANDLE
The request ID is invalid or missing.
ERROR_INVALID_PARAMETER
The library ID or operation ID pointer is missing.
ERROR_SUCCESS
An insert is queued.

Remarks

Currently NTMS_LM_MOUNT requests are sorted using the order number.

The order number set by the SetNtmsRequestOrder function is specific to the type of request because the types are processed in a predetermined order. For example, an NTMS_LM_DISMOUNT request is processed prior to an NTMS_LM_MOUNT request. Within a specific class of requests the queue can be ordered, however. The lower ordered requests are processed first; for example, 1 is the first request processed, 2 is the next request processed, and so forth.

To process a request immediately, an application can set the order number to 1. To defer processing, an application should set the order number to a very large number or 0xFFFFFFFF. The order number of a request, which currently has an order number of 0, cannot be changed.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Library Control Functions, SetNtmsRequestOrder


SubmitNtmsOperatorRequest

[This is preliminary documentation and subject to change.]

The SubmitNtmsOperatorRequest function submits an RSM operator request.

DWORD WINAPI SubmitNtmsOperatorRequest(
  HANDLE hSession,
  DWORD dwRequest,
  LPCTSTR lpMessage,
  LPNTMS_GUID lpArg1Id,
  LPNTMS_GUID lpArg2Id,
  LPNTMS_GUID lpRequestId
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
dwRequest
Specifies the type of operator request. This parameter can be one of the following values.
Value | Meaning
NTMS_OPREQ_CLEANER | RSM sends an operator request to insert a cleaner when a clean operation is queued and no cleaner is available to the drive.
NTMS_OPREQ_DEVICESERVICE | An application or RSM sends an operator request for drive service when a changer device or drive is experiencing problems. The lpArg1Id parameter specifies the device that needs service.
NTMS_OPREQ_MESSAGE | Application message only.
NTMS_OPREQ_MOVEMEDIA | An application or RSM sends an operator request to move media from one library to another for a mount of offline media or to eject existing media to the offline library. The lpArg1Id parameter specifies the piece of physical media that must be moved and the lpArg2Id parameter specifies the target library.
NTMS_OPREQ_NEWMEDIA | An application or RSM sends an operator request for new media when no media is available. The lpArg1Id parameter specifies the media pool object and the lpArg2Id parameter is the optional library identifier to which to add the new medium.

lpMessage
Specifies an optional message string sent to the user.
lpArg1Id
Specifies an object identifier for the operator request. Refer to the descriptions of the values in the dwRequest parameter for a description of what type of object must be passed for this argument.
lpArg2Id
Specifies an object identifier for the operator request. Refer to the descriptions of the values in the dwRequest parameter for details on what type of object must be passed for this argument.
lpRequestId
Pointer to an NTMS_GUID to receive the identifier of the operator request that was created.

Return Values

ERROR_ACCESS_DENIED
Access to one or more RSM objects is denied.
ERROR_DATABASE_FAILURE
The database query or update failed.
ERROR_INVALID_HANDLE
The value specified in the hSession parameter is NULL or invalid.
ERROR_INVALID_PARAMETER
Invalid parameters were passed to the function.
ERROR_NOT_CONNECTED
Unable to connect to the RSM service.
ERROR_OBJECT_NOT_FOUND
Unable to find the source or destination object.
ERROR_SUCCESS
The function was successful.

Remarks

Operator requests specified in the SubmitNtmsOperatorRequest function are used to request media, to request that the specified medium be moved from one library to another, or to request RSM device service.

The NTMS_OPEREQ_MESSAGE value is the request type most often used by applications. RSM cannot use NTMS_OPEREQ_MESSAGE. RSM uses the other request types as needed.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Operator Request Functions, AllocateNtmsMedia, MountNtmsMedia, CancelNtmsOperatorRequest, SatisfyNtmsOperatorRequest, WaitForNtmsOperatorRequest


SwapNtmsMedia

[This is preliminary documentation and subject to change.]

The SwapNtmsMedia function swaps the partitions associated with the two specified LMIDs. The specified LMID's must be in the same media pool.

DWORD WINAPI SwapNtmsMedia(
  HANDLE hSession,
  LPNTMS_GUID lpMediaId1,
  LPNTMS_GUID lpMediaId2
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpMediaId1
Specifies the unique identifier of a piece of logical media.
lpMediaId2
Specifies the unique identifier of a piece of logical media.

Return Values

ERROR_ACCESS_DENIED
NTMS_MODIFY_ACCESS to either media's media pool is denied. Other security errors are also possible, but they would indicate a security subsystem error.
ERROR_DATABASE_FAILURE
The database is inaccessible or damaged.
ERROR_DATABASE_FULL
The database is full.
ERROR_INVALID_HANDLE
The session handle is invalid or missing.
ERROR_INVALID_MEDIA
At least one of the media IDs is invalid.
ERROR_INVALID_MEDIA_POOL
One or more media pools for the logical media are invalid.
ERROR_INVALID_PARAMETER
At least one media identifier is missing.
ERROR_NOT_ENOUGH_MEMORY
An allocation failure occurred during processing.
ERROR_SUCCESS
The function was successful.

Remarks

The SwapNtmsMedia function is used to update physical media without affecting the application.

The media for both LMIDs must not be in use for this function to succeed.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Media Services Functions, AllocateNtmsMedia


UpdateNtmsOmidInfo

[This is preliminary documentation and subject to change.]

The UpdateNtmsOmidInfo function updates the RSM database with label information immediately after writing to the newly allocated medium.

DWORD WINAPI UpdateNtmsOmidInfo(
  HANDLE hSession,
  LPNTMS_GUID lpMediaId,
  DWORD labelType,
  DWORD numberOfBytes,
  LPVOID lpBuffer
);

typedef struct
  {
    WCHAR   FileSystemType[64];
    WCHAR   VolumeName[256];
    DWORD   SerialNumber;
} FILESYSTEM_INFO;

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpMediaId
Specifies the unique identifier of a piece of logical media.
labelType
Specifies whether the label is a string contained in lpBuffer, or is a FILESTSYSTEM_INFO structure contained in lpBuffer. This parameter can be set to one of the following values.
Value | Meaning
NTMS_OMID_TYPE_FILESYSTEM_INFO | The lpBuffer argument contains the raw bytes of the application label. This flag is used for Erasable/Optical and CD-ROM media that are labeled with file systems.
NTMS_OMID_TYPE_RAW_LABEL | The lpBuffer argument contains the FILESYSTEM_INFO structure. This flag is used for tape media.

numberOfBytes
Specifies the number of bytes sent in the lpBuffer parameter.
lpBuffer
Contains the actual label information, either raw bytes or a FILESYSTEM_INFO structure, depending on the setting of the labelType argument.

Return Values

ERROR_ACCESS_DENIED
Access to one or more RSM objects is denied.
ERROR_DATABASE_FAILURE
The database query or update failed.
ERROR_INVALID_HANDLE
The value specified in the hSession parameter is invalid.
ERROR_INVALID_MEDIA
Unable to retrieve the logical media definition from the database.
ERROR_INVALID_PARTITION
Unable to retrieve the partition definition from the database.
ERROR_INVALID_PARAMETER
The lpMediaId parameter is NULL.
ERROR_NOT_CONNECTED
Unable to connect to the RSM service.
ERROR_SUCCESS
The function was successful.

Remarks

The application updates RSM with the information supplied by the UpdateNtmsOmidInfo function and RSM verifies the information in the database. The label information is stored in the RSM database with the partition associated with this LMID.

The UpdateNtmsOmidInfofunction must be executed on the RSM server. Remote execution of this function results in an error.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

On-Media-Identifier Management Functions


WaitForNtmsNotification

[This is preliminary documentation and subject to change.]

The WaitForNtmsNotification function waits for the next object change notification.

DWORD WINAPI WaitForNtmsNotification(
  HANDLE hSession,
  HANDLE hNotification,
  LPNTMS_NOTIFICATIONINFORMATION lpNotificationInformation,
  DWORD dwTimeout
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
hNotification
Notification handle generated by the OpenNtmsNotification function.
lpNotificationInformation
Specifies notification information. For more information, see the NTMS_NOTIFICATIONINFORMATION data structure.
dwTimeout
Specifies the maximum number of milliseconds to wait. If you specify a value of INFINITE, this function will not time-out.

Return Values

ERROR_DATABASE_FAILURE
The database query or update failed.
ERROR_INVALID_HANDLE
The value specified in the hNotification parameter is invalid or NULL.
ERROR_NO_DATA
Notification pipe failed. Attempt to set up notification again.
ERROR_NOT_CONNECTED
Unable to connect to the RSM.
ERROR_TIMEOUT
The time-out event expired.
ERROR_SUCCESS
The function was successful.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Database Notification Functions, CloseNtmsNotification, OpenNtmsNotification


WaitForNtmsOperatorRequest

[This is preliminary documentation and subject to change.]

The WaitForNtmsOperatorRequest function waits for the specified RSM operator request.

DWORD WINAPI WaitForNtmsOperatorRequest(
  HANDLE hSession,
  LPNTMS_GUID lpRequestId,
  DWORD dwTimeout
);

Parameters

hSession
Handle to the session returned by the OpenNtmsSession function.
lpRequestId
Specifies the operator request identifier created by the SubmitNtmsOperatorRequest function.
dwTimeout
Specifies the number of milliseconds to wait. To check for an operator request, pass a time-out value of zero. If you specify a value of INFINITE, this function does not time-out.

Return Values

ERROR_ACCESS_DENIED
Access to one or more RSM objects is denied.
ERROR_CANCELLED
The operator request was canceled by an administrator.
ERROR_INVALID_HANDLE
The value specified in the hSession parameter is NULL or invalid.
ERROR_INVALID_PARAMETER
Invalid parameters were passed to the function.
ERROR_NOT_CONNECTED
Unable to connect to the RSM service.
ERROR_OBJECT_NOT_FOUND
Unable to find the operator request object. Object requests are flushed from the database. Application should call a function like AllocateNtmsMedia if RSM returns this error.
ERROR_SUCCESS
The function was successful.
ERROR_TIMEOUT
The time specified in the dwTimeout parameter elapsed before the completion of the operator request.

Remarks

Operator requests specified with the WaitForNtmsOperatorRequest function are used to request media, to request that the medium be moved from one library to another, or to request RSM device service.

An application uses WaitForNtmsOperatorRequest to wait for resolution of an operator request. The request can be satisfied, rejected, deleted, or timed out.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

See Also

Operator Request Functions, CancelNtmsOperatorRequest, SatisfyNtmsOperatorRequest, SubmitNtmsOperatorRequest


Media Label Library Function Reference

[This is preliminary documentation and subject to change.]

Your media label library must support the following functions. RSM uses these functions to communicate with media label libraries.


ClaimMediaLabel

[This is preliminary documentation and subject to change.]

The ClaimMediaLabel function determines whether a specified media label was created by the media's associated application.

DWORD ClaimMediaLabel(
  const BYTE *const pBuffer,
  const DWORD nBufferSize,
  MediaLabelInfo *const pLabelInfo
);

Parameters

pBuffer
Pointer to a buffer that contains the media label.
nBufferSize
Specifies the size of the buffer. Must be equal to the size of pBuffer.
pLabelInfo
Pointer to the MediaLabelInfo data structure. The media label library fills in this structure if the library recognizes the media label.

Return Values

NO_ERROR
The media label library filled in the MediaLabelInfo structure.
ERROR_BAD_FORMAT
The media label library does not recognize the media label.

Remarks

When a media label library uses the ClaimMediaLabel function to identify the media label as one created by its associated application, the media label library must fill in the MediaLabelInfo structure and return NO_ERROR. If the media label library does not recognize the media label, it returns ERROR_BAD_FORMAT.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Import Library: User-defined.


MaxMediaLabel

[This is preliminary documentation and subject to change.]

The MaxMediaLabel function determines the maximum size of the media label for the applications supported by the media label library.

DWORD MaxMediaLabel(
  DWORD *const pMaxSize
);

Parameters

pMaxSize
Pointer to the maximum size of the buffer that is sent to the ClaimMediaLabel function.

Return Values

NO_ERROR
The function was successful.

Remarks

When the media format of the media specified in the MaxMediaLabel function does not have a theoretical size limit, the application should return the size of the largest media label the application can possibly generate.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Import Library: User-defined.


RegisterMediaLabel

[This is preliminary documentation and subject to change.]

The RegisterMediaLabel function is passed a logical media ID, a buffer containing a media label, and the size of the buffer. There are no guidelines for processing this information.

DWORD RegisterMediaLabel(
  const LPNTMS_GUID pMediaID,
  const BYTE *const pBuffer,
  const DWORD nBufferSize
);

Parameters

pMediaID
Pointer to the ID of the media.
pBuffer
Pointer to a buffer of data.
nBufferSize
Specifies the size of the buffer.

Return Values

NO_ERROR
The function was successful.

Remarks

An extended media label library enables an application to associate an LMID with a media label and process the media label for extended attributes, specified in the RegisterMediaLabel function. You are not required to provide an extended media label library; this functionality is completely optional.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Import Library: User-defined.


MediaLabelInfo Data Structure

[This is preliminary documentation and subject to change.]

The MediaLabelInfo data structure adds information to the RSM database. The media label library fills in this data structure for all media labels the library recognizes.

struct MediaLabelInfo
    WCHAR    LabelType[64];
    DWORD    LabelIDSize;
    BYTE     LabelID[256];
    WCHAR    LabelAppDescr[256];
}

Members

LabelType
Unicode string that identifies the source of the media label. For example, the LabelType for a Windows NT backup media label is "Microsoft Windows NTBackup".
LabelIDSize
Number of bytes that are used in the LabelID field.
LabelID
Unique identifier for the media label.
LabelAppDescr
Unicode string that describes the media. For example, the LabelAppDescr for a Windows NT backup media label is something like "Tape created on 04/14/97".


Removable Storage Manager Structure Reference

[This is preliminary documentation and subject to change.]

The following topics contain reference material for RSM structures.


NTMS_OBJECTINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_OBJECTINFORMATION data structure defines the properties that an application can get and set for RSM devices, media and system controls (such as libraries, drives, media, operator requests). This structure defines the common structure of objects in the RSM database.

typedef struct _NTMS_OBJECTINFORMATION
{
    DWORD        dwSize;
    DWORD        dwType;
    SYSTEMTIME   Created;
    SYSTEMTIME   Modified;
    NTMS_GUID    ObjectGuid;
    BOOL         Enabled;
    DWORD        dwOperationalState;
    TCHAR        szName[NTMS_OBJECTNAME_LENGTH];
    TCHAR        szDescription[NTMS_DESCRIPTION_LENGTH];
    union {
    NTMS_LIBRARYINFORMATION Library;
    NTMS_CHANGERINFORMATION Changer;
    NTMS_CHANGERTYPEINFORMATION ChangerType;
    NTMS_DRIVEINFORMATION Drive;
    NTMS_DRIVETYPEINFORMATION DriveType;
    NTMS_STORAGESLOTINFORMATION StorageSlot;
    NTMS_IEDOORINFORMATION IEDoor;
    NTMS_IEPORTINFORMATION IEPort;
    NTMS_LMIDINFORMATION LogicalMedia;
    NTMS_PARTITIONINFORMATION Partition;
    NTMS_PMIDINFORMATION PhysicalMedia;
    NTMS_MEDIAPOOLINFORMATION MediaPool;
    NTMS_MEDIATYPEINFORMATION MediaType;
    NTMS_OPREQUESTINFORMATION OpRequest;
    NTMS_LIBREQUESTINFORMATION LibRequest;
} Info;
} NTMS_OBJECTINFORMATION, *LPNTMS_OBJECTINFORMATION;

Members

dwSize
Size of the information structure. This member must be set to the correct size of the structure prior to using either the GetNtmsObjectInformation function or the SetNtmsObjectInformation function.
dwType
The type of device or system control for which to get/set information. This member must be set to one of the following values.
Value | Meaning
NTMS_CHANGER | A changer object represents the robotic element of an online library unit.
NTMS_CHANGER_TYPE | A changer type object is created for each unique changer device type attached to a system.
NTMS_COMPUTER | The current computer object. There is no structure for the computer object.
NTMS_DRIVE | A drive object represents a tape drive or disk drive.
NTMS_DRIVE_TYPE | A drive type object is created for each unique drive device type attached to a system.
NTMS_IEDOOR | An NTMS_IEDOOR object represents the door-access mechanism of an online library unit.
NTMS_IEPORT | An NTMS_IEPORT object represents the insert/eject port of an online library unit.
NTMS_LIBRARY | A library object represents an online or offline library.
NTMS_LIBREQUEST | A library request object is created for each request for an online library to perform an action. A list of library requests is maintained by RSM as a queue of work to be performed.
NTMS_LOGICAL_MEDIA | The primary handle used by applications to access the specified medium. In the case of multipartitioned media, each partition is treated as an individual piece of physical media.
NTMS_MEDIA_POOL | A media pool is a logical grouping of media. All media in a media pool must be the same media type.
NTMS_MEDIA_TYPE | A media type object is created for each unique media type in a system.
NTMS_OPREQUEST | An operator request object represents an RSM request for a user to get the information.
NTMS_PARTITION | A partition object represents a side of a piece of physical media.
NTMS_PHYSICAL_MEDIA | A physical media object represents a magnetic tape or removable disk. A piece of physical media can contain one or more partitions.
NTMS_STORAGESLOT | A storage slot object represents one of the slots that can hold the specified medium in an online library.

Created
A date/time stamp when the object was created.
Modified
A date/time stamp when the object was modified.
ObjectGuid
The GUID of the object.
Enabled
Indicates whether the device or system control object is enabled.
dwOperationalState
Defines the current operational state of the object. This can be one of the following values.
Value | Meaning
NTMS_NOT_PRESENT | This device or object is not currently present.
NTMS_READY | This device or object is available and ready.
NTMS_NEEDS_SERVICE | This device or object has failed and needs service.

szName
The name of the media, device, or system control object. Media pool and logical media names can be changed using the SetNtmsObjectInformation function. All other object names are read-only.
szDescription
A description of the device or system control object. The description of device and system control objects can be changed using the SetNtmsObjectInformation function. (Writable for all objects)
Info
Device or system control object-specific information.

Remarks

All members of the NTMS_OBJECTINFORMATION data structure are read-only at the RSM function-level unless specified as WRITABLE in the definition of the member.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.

NTMS_ALLOCATION_INFORMATION


NTMS_CHANGERINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_CHANGERINFORMATION data structure defines properties specific to a robotic changer object.

typedef struct _NTMS_CHANGERINFORMATION {
    DWORD       Number
    NTMS_GUID   ChangerType;
    TCHAR       szSerialNumber[NTMS_SERIALNUMBER_LENGTH];
    TCHAR       szRevision[NTMS_REVISION_LENGTH];
    TCHAR       szDeviceName[NTMS_DEVICENAME_LENGTH];
    WORD        ScsiPort;
    WORD        ScsiBus;
    WORD        ScsiTarget;
    WORD        ScsiLun;
    NTMS_GUID   Library;
} NTMS_CHANGERINFORMATION;

Members

Number
Number of the changer within the online library.
ChangerType
The changer type that matches the instance of the changer.
szSerialNumber
A serial number for the changer represented as a string.
szRevision
A revision for the changer represented as a string.
szDeviceName
The name of the device used to access the changer. This contains the device name.
ScsiPort
SCSI host adapter to which the changer is connected.
ScsiBus
SCSI bus to which the changer is connected.
ScsiTarget
SCSI target ID for the changer.
ScsiLun
SCSI logical unit ID for the changer.
Library
Unique ID of the library that contains the changer.

Remarks

The NTMS_CHANGERINFORMATION data structure is included in the NTMS_OBJECTINFORMATION structure used for the GetNtmsObjectInformation and SetNtmsObjectInformation functions.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_CHANGERTYPEINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_CHANGERTYPEINFORMATION data structure defines the properties specific to a type of robotic changer supported by RSM.

typedef struct _NTMS_CHANGERTYPEINFORMATION {
    TCHAR    szVendor[NTMS_VENDORNAME_LENGTH];
    TCHAR    szProduct[NTMS_PRODUCTNAME_LENGTH];
    DWORD    DeviceType;
} NTMS_CHANGERTYPEINFORMATION;

Members

szVendor
Name of the vendor of the changer. This is acquired directly from the device inquiry data.
SzProduct
Product name of the changer. This is acquired directly from the device inquiry data.
DeviceType
SCSI device type as reported from device inquiry data. From Winioctl.h. This can be the following value.
Value | Meaning
FILE_DEVICE_CHANGER | Changer device.

Remarks

The NTMS_CHANGERTYPEINFORMATION data structure is part of the NTMS_OBJECTINFORMATION structure and is read-only.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_DRIVEINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_DRIVEINFORMATION data structure defines properties specific to a drive object.

typedef struct _NTMS_DRIVEINFORMATION {
    DWORD        Number;
    DWORD        State;
    NTMS_GUID    DriveType;
    TCHAR        szSerialNumber[NTMS_SERIALNUMBER_LENGTH];
    TCHAR        szRevision[NTMS_REVISION_LENGTH];
    TCHAR        szDeviceName[NTMS_DEVICENAME_LENGTH];
    WORD         ScsiPort;
    WORD         ScsiBus;
    WORD         ScsiTarget;
    WORD         ScsiLun;
    SYSTEMTIME   LastCleanedTs;
    DWORD        dwMountCount;
    NTMS_GUID    SavedPartitionId;
    NTMS_GUID    Library;
    GUID         Reserved;
    DWORD        dwDeferDismountDelay;
} NTMS_DRIVEINFORMATION;

Members

Number
Number of the drive in the library. This is set zero or one relative the value based on the drive numbering system of the device. Some changers number drives beginning with zero, and some changers begin with one.
State
State of the drive. This can be one of the following values.
Value | Meaning
NTMS_DRIVESTATE_BEING_CLEANED | The drive is being cleaned and is unavailable.
NTMS_DRIVESTATE_DISMOUNTABLE | If a library is set for lazy dismounts, the medium might be left in the library's drive on a dismount. RSM can satisfy mount requests for loaded and dismounted drives.
NTMS_DRIVESTATE_DISMOUNTED | No medium in the drive.
NTMS_DRIVESTATE_LOADED | The medium is mounted in the drive and is loaded for read and write access.
NTMS_DRIVESTATE_MOUNTED | The medium is mounted in the drive but is not ready for read and write access. This is a temporary state that is used while a drive is waiting for spindle synchronization or loading tape media into the head mechanism.
NTMS_DRIVESTATE_UNLOADED | The medium has been dismounted by the drive and is ready to be opened. This state indicates that the spindle has stopped or a tape media has been returned to the tape cartridge.

DriveType
The drive type object containing the attributes for the drive.
szSerialNumber
A serial number for the drive represented as a string. Devices that do not support serial numbers report NULL for this member.
szRevision
A revision for the drive represented as a string.
szDeviceName
Name of the device used to access the drive. For a tape drive this contains the device name \\.\tape0 or \\.\tape1. Other devices provide the name of a SCSI disk drive or the root of a file system that currently has the device mounted (raw, NTFS, FAT and so forth.).
ScsiPort
SCSI host adapter to which the drive is connected.
ScsiBus
SCSI bus to which the drive is connected.
ScsiTarget
SCSI target ID for the drive.
ScsiLun
SCSI logical unit ID for the drive.
LastCleanedTs
Last time the drive was cleaned.
dwMountCount
Number of times the drive has had a medium mounted to it. If the drive supports the reporting of a unique serial number, this value is the number of times the drive has been mounted since it was installed. If the drive does not support the reporting of serial numbers, this member reflects the number of mounts to all of the drives at that location.
SavedPartitionId
Partition ID of the medium that is in the drive. If this value is NULL and the drive is found to be full, the media was loaded by a user and needs to be classified.
Library
Unique ID of the library that contains the drive.
Reserved
Reserved.
dwDeferDismountDelay
Minimum number of seconds a medium will remain in a drive of an online library after a deferred dismount has been performed. The default is 5 minutes. This member does not apply to standalone libraries. This member is writable.

Remarks

The NTMS_DRIVEINFORMATION data structure is part of the NTMS_OBJECTINFORMATION structure used for the GetNtmsObjectInformation and SetNtmsObjectInformation functions.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_DRIVETYPEINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_DRIVETYPEINFORMATION data structure defines the properties specific to a type of drive supported by RSM.

typedef struct _NTMS_DRIVETYPEINFORMATION {
    TCHAR    szVendor[NTMS_VENDORNAME_LENGTH];
    TCHAR    szProduct[NTMS_PRODUCTNAME_LENGTH];
    DWORD    NumberOfHeads;
    DWORD    DeviceType;
} NTMS_DRIVETYPEINFORMATION;

Members

szVendor
Name of the vendor of the drive. This is acquired directly from the device inquiry data.
szProduct
Name of the product of the drive. This is acquired directly from the device inquiry data.
NumberOfHeads
This field is reserved for future use and should be ignored.
DeviceType
The SCSI device type as reported from device inquiry data. From Winioctl.h. This can be one of the following values.
Value | Meaning
FILE_DEVICE_CD_ROM | CD-ROM device.
FILE_DEVICE_DISK | Direct access device.
FILE_DEVICE_TAPE | Sequential access device.

Remarks

The NTMS_DRIVETYPEINFORMATION data structure is part of the NTMS_OBJECTINFORMATION structure and is not used separately.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_IEDOORINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_IEDOORINFORMATION data structure defines properties specific to an insert/eject door object.

typedef struct _NTMS_IEDOORINFORMATION {
    WORD         Number;
    WORD         State;
    WORD         MaxOpenSecs;
    NTMS_GUID    Library
} NTMS_IEDOORINFORMATION;

Members

Number
Number of the door in the library. Typically, libraries have one door.
State
State of the door. This can be one of the following values.
Value | Meaning
NTMS_DOORSTATE_CLOSED | Library door is closed.
NTMS_DOORSTATE_OPEN | Library door is open.
NTMS_DOORSTATE_UNKNOWN | State of the library is unknown.

MaxOpenSecs
Maximum number of seconds the door is to remain open. Valid values are between 0-65,535 seconds This member is writable.
Library
Library that contains this door.

Remarks

The NTMS_IEDOORINFORMATION data structure is part of the NTMS_OBJECTINFORMATION structure used for the GetNtmsObjectInformation and SetNtmsObjectInformation functions.

If the MaxOpenSecs member is zero, an operator request to close the door is generated as soon as the door is open.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_IEPORTINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_IEPORTINFORMATION data structure defines properties specific to an insert/eject port object.

typedef struct _NTMS_IEPORTINFORMATION {
    DWORD      Number;
    DWORD      Content;
    DWORD      Position;
    WORD       MaxExtendSecs;
    NTMS_GUID  Library;
} NTMS_IEPORTINFORMATION;

Members

Number
The library port number.
Content
Full/Empty state of the NTMS_IEPORT object. This can be one of the following values.
Value | Meaning
NTMS_PORTCONTENT_FULL | Port is full.
NTMS_PORTCONTENT_EMPTY | Port is empty.
NTMS_PORTCONTENT_UNKNOWN | Content of port is not known.

Position
Position of the NTMS_IEPORT object. This can be one of the following values.
Value | Meaning
NTMS_PORTPOSITION_EXTENDED | Port is extended.
NTMS_PORTPOSITION_RETRACTED | Port is retracted.
NTMS_PORTPOSITION_UNKNOWN | Port position is unknown.

MaxExtendSecs
Maximum number of seconds the port is allowed to remain open before an operator request is issued. Valid values are between 0 and 65,535 seconds. This member is writable.
Library
Library that contains the port.

Remarks

The NTMS_IEPORTINFORMATION data structure is part of the NTMS_OBJECTINFORMATION structure used for the GetNtmsObjectInformation and SetNtmsObjectInformation functions.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_LIBRARYINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_LIBRARYINFORMATION data structure defines properties specific to a library object.

typedef struct _NTMS_LIBRARYINFORMATION {
    DWORD      LibraryType;
    NTMS_GUID  CleanerSlot;
    NTMS_GUID  CleanerSlotDefault;
    BOOL       LibrarySupportsDriveCleaning;
    BOOL       BarCodeReaderInstalled;
    DWORD      InventoryMethod;
    DWORD      dwCleanerUsesRemaining;
    DWORD      FirstDriveNumber;
    DWORD      dwNumberOfDrives;
    DWORD      FirstSlotNumber;
    DWORD      dwNumberOfSlots;
    DWORD      FirstDoorNumber;
    DWORD      dwNumberOfDoors;
    DWORD      FirstPortNumber;
    DWORD      dwNumberOfPorts;
    DWORD      FirstChangerNumber;
    DWORD      dwNumberOfChangers;
    DWORD      dwNumberOfMedia;
    DWORD      dwNumberOfMediaTypes;
    DWORD      dwNumberOfLibRequests;
    GUID       Reserved;
    BOOL       AutoRecovery
} NTMS_LIBRARYINFORMATION;

Members

LibraryType
Library type object. This can be one of the following values.
Value | Meaning
NTMS_LIBRARYTYPE_ONLINE | A robotic element that automates the mounting and dismounting of media into one or more drives.
NTMS_LIBRARYTYPE_STANDALONE | A standalone drive that is modeled as a library with one drive in RSM.
NTMS_LIBRARYTYPE_OFFLINE | Media that is not in an online library is in an offline library. There is one offline library unit per RSM system.
NTMS_LIBRARYTYPE_UNKNOWN | Library type cannot be determined.

CleanerSlot
For each online library, this represents the slot that was assigned to the cleaner cartridge. If this member is NULL, there is no cleaner slot defined for this library.
CleanerSlotDefault
Represents a libraries' default or preferred cleaner slot. If NULL, there is not a preferred slot.
LibrarySupportsDriveCleaning
Used by drives that require cleaning under robotics control. If TRUE, automatic drive cleaning operations are enabled.
BarCodeReaderInstalled
Returns TRUE if a bar code reader is installed in a library; otherwise returns FALSE.
InventoryMethod
The default or user-selected method for performing inventory of this online library. (This member is writable.) This can be one of the following values.
Value | Meaning
NTMS_INVENTORY_FAST | If the library has a bar-code reader installed, this value causes a bar-code inventory to be performed. If the library does not have a bar-code reader, this flag causes a differential inventory to be performed (slots which transitioned from empty to full are classified).
NTMS_INVENTORY_OMID | A full inventory involves mounting each partition in a library and reading the on-media identification from the media. This type of inventory can be very time consuming for some library units.
NTMS_INVENTORY_NONE | After the library door is closed, no inventory is performed. Inventory might be required if a mount label-check fails.

dwCleanerUsesRemaining
Number of uses remaining on the cleaner in the library. This member is zero if no cleaner is present or if the library does not support cleaning.
FirstDriveNumber
Number of the first drive in the online library.
dwNumberOfDrives
Number of drives in the online library.
FirstSlotNumber
Number of the first slot in the online library.
dwNumberOfSlots
Number of slots in the online library.
FirstDoorNumber
Number of the first access door in the online library.
dwNumberOfDoors
Number of access doors in the online library.
FirstPortNumber
Number of the first insert/eject port in the online library.
dwNumberOfPorts
Number of insert/eject ports in the online library.
FirstChangerNumber
Number of the first changer in the online library.
dwNumberOfChangers
Number of changers in the online library.
dwNumberOfMedia
Number of media in the online or offline library.
dwNumberOfMediaTypes
Number of media types supported by the library.
dwNumberOfLibRequests
Number of current library requests.
Reserved
Reserved.
AutoRecovery
If set a full inventory will be performed if a mount fails. The failure may be either hardware or label mismatch. For ATAPI CD libraries, AutoRecovery cannot be disabled. The default is true. Large library owners should disable this feature.

Remarks

For offline libraries, only LibraryType and dwNumberOfMedia are reported. All other values should be ignored.

The NTMS_LIBRARYINFORMATION data structure is included in the NTMS_OBJECTINFORMATION structure used for the GetNtmsObjectInformation and SetNtmsObjectInformation functions.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_LIBREQUESTINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_LIBREQUESTINFORMATION data structure defines the properties specific to a work request, which are queued to RSM.

typedef struct _NTMS_LIBREQUESTINFORMATION {
    DWORD      OperationCode;
    DWORD      OperationOption;
    DWORD      State;
    NTMS_GUID  PartitionId;
    NTMS_GUID  DriveId;
    NTMS_GUID  PhysMediaId;
    NTMS_GUID  Library;
    NTMS_GUID  SlotId;
    SYSTEMTIME TimeQueued;
    SYSTEMTIME TimeCompleted;
    TCHAR      szApplication[NTMS_APPLICATIONNAME_LENGTH];
    TCHAR      szUser[NTMS_USERNAME_LENGTH];
    TCHAR      szComputer[NTMS_COMPUTERNAME_LENGTH];
    DWORD      dwErrorCode;
    NTMS_GUID  WorkItemId;
} NTMS_LIBREQUESTINFORMATION;

Members

OperationCode
Item operation. This can be one of the following values.
Value | Meaning
NTMS_LM_CLASSIFY | Classify the medium.
NTMS_LM_CLEANDRIVE | Clean a drive.
NTMS_LM_DISABLELIBRARY | Disable the changer.
NTMS_LM_DISABLEDRIVE | Disable a drive.
NTMS_LM_DISABLEMEDIA | Disable the medium.
NTMS_LM_DISMOUNT | Dismount the medium from a drive.
NTMS_LM_DOORACCESS | Allow access to media through a library unit door.
NTMS_LM_EJECT | Eject the medium from the library.
NTMS_LM_EJECTCLEANER | Eject a cleaner.
NTMS_LM_ENABLELIBRARY | Enable the changer.
NTMS_LM_ENABLEDRIVE | Enable a drive.
NTMS_LM_ENABLEMEDIA | Enable the medium.
NTMS_LM_INJECT | Insert the medium into the library.
NTMS_LM_INJECTCLEANER | Insert a cleaner.
NTMS_LM_INVENTORY | Perform an inventory of the library.
NTMS_LM_MOUNT | Mount a partition to a drive.
NTMS_LM_PROCESSOMID | Process the OMID.
NTMS_LM_RELEASECLEANER | Release a cleaner slot.
NTMS_LM_REMOVE | Remove a work item from the queue.
NTMS_LM_RESERVECLEANER | Reserve a cleaner slot.
NTMS_LM_UPDATEOMID | Update the OMID.
NTMS_LM_WRITESCRATCH | Write a scratch label.

OperationOption
Work item options (command specific).
State
Current state of this work item. This can be one of the following values.
Value | Meaning
NTMS_LM_QUEUED | Operation is queued.
NTMS_LM_INPROCESS | Operation is being processed.
NTMS_LM_PASSED | Operation completed successfully.
NTMS_LM_FAILED | Operation has completed with an error.
NTMS_LM_WAITING | Operation is blocked.
NTMS_LM_CANCELLED | Operation has been canceled.
NTMS_LM_INVALID | Operation is invalid.

PartitionId
Unique identifier of a partition being serviced.
DriveId
Unique identifier of a drive being serviced.
PhysMediaId
Unique identifier of a piece of physical media being serviced.
Library
Library for this request.
SlotId
Unique identifier of a slot of the piece of physical media being serviced.
TimeQueued
System time that this request was queued to RSM.
TimeCompleted
System time that this request was completed by RSM.
szApplication
Application that submitted the operator request.
szUser
Interactive user logged on to the computer that submitted the operator request.
szComputer
Computer that submitted the operator request.
dwErrorCode
Error return for requests that return with state NTMS_LM_FAILED. This is a Win32 error code.
WorkItemId
Associated work item ID for this request. This is currently used to contain the work item ID to be canceled on an NTMS_LM_REMOVE request.

Remarks

The NTMS_LIBREQUESTINFORMATION data structure is part of the NTMS_OBJECTINFORMATION structure and is not used separately.

GUID in the workitmes may become invalid over time. For example, an eject of a scratch medium will delete the PMID after the media is ejected. However the work item is not updated upon completion of the eject.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_LMIDINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_LMIDINFORMATION data structure defines the properties specific to a logical media object.

typedef struct _NTMS_LMIDINFORMATION {
    NTMS_GUID    MediaPool;
    DWORD        dwNumberOfPartitions;
} NTMS_LMIDINFORMATION;

Members

MediaPool
The media pool that contains this logical media.
dwNumberOfPartitions
Number of partitions in the media object.

Remarks

The NTMS_LMIDINFORMATION data structure is part of the NTMS_OBJECTINFORMATION structure and is not used separately.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_MEDIAPOOLINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_MEDIAPOOLINFORMATION data structure defines the properties specific to a media pool object.

typedef struct _NTMS_MEDIAPOOLINFORMATION {
    DWORD       PoolType;
    NTMS_GUID   MediaType;
    NTMS_GUID   Parent;
    DWORD       AllocationPolicy;
    DWORD       DeallocationPolicy;
    DWORD       dwMaxAllocates;
    DWORD       dwNumberOfPhysicalMedia;
    DWORD       dwNumberOfLogicalMedia;
    DWORD       dwNumberOfMediaPools;
} NTMS_MEDIAPOOLINFORMATION;

Members

PoolType
NTMS supports the following media pool types.
Value | Meaning
NTMS_POOLTYPE_UNKNOWN | Unknown pool type.
NTMS_POOLTYPE_SCRATCH | Media that is available to other applications.
NTMS_POOLTYPE_FOREIGN | Media that has been written to and does not contain a recognizable on-media identifier label-type or label ID.
NTMS_POOLTYPE_IMPORT | Media that has been written to, has a recognizable on-media identifier label type but an unrecognizable label ID.
NTMS_POOLTYPE_APPLICATION | Media pool created by an application. One or more application media pools can be created per system.

MediaType
The single media type that makes up each media pool.
Parent
Parent media pool or NULL.
AllocationPolicy
Bit field indicating action at allocation time. This member is writable. This can be the following value.
Value | Meaning
NTMS_ALLOCATE_FROMSCRATCH | Draw media from scratch if none is available in the pool. The default is not to draw from scratch.

DeallocationPolicy
Bit field indicating action at deallocation time. This member is writable. This can be the following value.
Value | Meaning
NTMS_DEALLOCATE_TOSCRATCH | Return media to scratch when available. The default is not to return to scratch.

dwMaxAllocates
Number of times the medium can be allocated and deallocated. This member is writable.
DwNumberOfPhysicalMedia
Number of physical media in this media pool.
dwNumberOfLogicalMedia
Number of logical media in this media pool.
dwNumberOfMediaPools
Number of media pools in this media pool.

Remarks

The NTMS_MEDIAPOOLINFORMATION data structure is part of the NTMS_OBJECTINFORMATION structure and is not used separately.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_MEDIATYPEINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_MEDIATYPEINFORMATION data structure defines the properties specific to a type of media supported by RSM.

typedef struct _NTMS_MEDIATYPEINFORMATION {
    DWORD    MediaType;
    DWORD    NumberOfSides;
    DWORD    ReadWriteCharacteristics;
    DWORD    DeviceType;
} NTMS_MEDIATYPEINFORMATION;

Members

MediaType
Each disk or tape driver reports the media-type enumeration value of the medium that is currently mounted in the drive. The enumeration values are specified in Winoclt.h. This unique media type value is mapped to a human-readable string in the MediaType object szName member. Some examples of MediaType names are MP_8mm and MO_5_RW.
NumberOfSides
Number of sides on the media.
ReadWriteCharacteristics
Identifies the read/write characteristics of the media type. This can be one of the following values.
Value | Meaning
NTMS_MEDIARW_REWRITABLE | Media that can be rewritten. This includes magnetic tape, magnetic disk, and some optical disk media.
NTMS_MEDIARW_WRITEONCE | Media that can only be written to one time. Some optical media, for example, 5.25", 12", 14" WORM, and CD-R, are designed to be write-once.
NTMS_MEDIARW_READONLY | Media that cannot be written to CD-ROM and DVD-ROM.

DeviceType
The SCSI device type as reported from device inquiry data. From Winioctl.h. This can be one of the following values.
Value | Meaning
FILE_DEVICE_CD_ROM | CD-ROM device.
FILE_DEVICE_DISK | Direct access device.
FILE_DEVICE_TAPE | Sequential access device.

Remarks

The NTMS_MEDIATYPEINFORMATION data structure is part of the NTMS_OBJECTINFORMATION structure and is not used separately.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_NOTIFICATIONINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_NOTIFICATIONINFORMATION data structure defines an object and operation that occurred in the RSM database.

typedef struct _NTMS_NOTIFICATIONINFORMATION {
    DWORD       dwOperation;
    NTMS_GUID   ObjectId
} NTMS_NOTIFICATIONINFORMATION, *LPNTMS_NOTIFICATIONINFORMATION;

Members

dwOperation
Operation that occurred on the object. This can be one of the following values.
Value | Meaning
NTMS_OBJ_INSERT | New object was inserted.
NTMS_OBJ_DELETE | Object was deleted.
NTMS_OBJ_UPDATE | Object was updated.

ObjectId
Object identifier.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_OPREQUESTINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_OPREQUESTINFORMATION data structure defines the properties specific to operator-request system control for RSM.

typedef struct _NTMS_OPREQUESTINFORMATION {
    DWORD        Request;
    SYSTEMTIME   Submitted;
    DWORD        State;
    TCHAR        szMessage[NTMS_MESSAGE_LENGTH];
    DWORD        Arg1Type;
    NTMS_GUID    Arg1;
    DWORD        Arg2Type;
    NTMS_GUID    Arg2;
    TCHAR        szApplication[NTMS_APPLICATIONNAME_LENGTH];
    TCHAR        szUser[NTMS_USERNAME_LENGTH];
    TCHAR        szComputer[NTMS_COMPUTERNAME_LENGTH];
} NTMS_OPREQUESTINFORMATION;

Members

Request
Type of operator request. This can be one of the following values.
Value | Meaning
NTMS_OPREQ_NEWMEDIA | An application attempting to allocate media sends an operator request for new media when no media is available. When this flag is set, the Arg1 member should be set to the GUID of the media pool requiring new media. Optionally, the Arg2 parameter can be set to the particular library in which the new media should be placed.
NTMS_OPREQ_CLEANER | RSM sends an operator request for a cleaner when a clean operation is queued and no cleaner is online and available to the drive. When this flag is set, the Arg1 member should be set to the GUID of the library requiring the cleaning cartridge.
NTMS_OPREQ_DEVICESERVICE | An application or RSM sends an operator request for drive service when a changer device or drive is experiencing problems. When this flag is set, the Arg1 member should be set to the GUID of the device requiring service.
NTMS_OPREQ_MOVEMEDIA | An application or RSM sends an operator request to move the specified medium to service a mount for offline media or to eject media to an offline library. When this flag is set, the Arg1 member should be set to the GUID of the physical media to move and the Arg2 member should be set to the GUID of the library this media should be moved to.
NTMS_OPREQ_MESSAGE | An application-specific operator request. Text only.

Submitted
System time when the operator request was submitted.
State
Current state of the operator service request. This can be one of the following values.
Value | Meaning
NTMS_OPSTATE_SUBMITTED | The operator request has been submitted but not read by an operator console.
NTMS_OPSTATE_ACTIVE | The operator request has been read by one or more operator consoles and might be in process.
NTMS_OPSTATE_INPROGRESS | The user has acknowledged this operator request and is in the process of performing the service.
NTMS_OPSTATE_REFUSED | The user has rejected the operator service request.
NTMS_OPSTATE_COMPLETE | The user has completed the operator service request.

szMessage
Operator message text.
Arg1Type
Type of the Arg1 object. This can be one of the following values.
Value | Meaning
NTMS_UNKNOWN | No object provided in Arg1Type.
NTMS_CHANGER | Medium changer object.
NTMS_DRIVE | Drive object.
NTMS_IEDOOR | Library door object.
NTMS_IEPORT. | Library IE port object
NTMS_LIBRARY | Library object.
NTMS_PARTITION | Partition object.
NTMS_PHYSICAL_MEDIA | Physical media object.
NTMS_STORAGESLOT | Library slot object.

Arg1
Arg1 object ID used for move requests or other operator requests that require a reference object. The purpose of this object varies based on the type of operator request. For appropriate uses of Arg1, see the Request description.
Arg2Type
Type of Arg2 object. This can be one of the following values.
Value | Meaning
NTMS_UNKNOWN | No object provided in Arg2Type.
NTMS_LIBRARY | Library object.

Arg2
Arg2 object ID used for operator requests that require a second reference object. The purpose of this object varies based on the type of operator request. For appropriate uses of Arg2, see the Request description.
SzApplication
The application that submitted the operator request.
szUser
The interactive user logged on to the computer that submitted the operator request.
szComputer
The computer that submitted the operator request.

Remarks

The NTMS_OPREQUESTINFORMATION data structure is part of the NTMS_OBJECTINFORMATION structure and is not used separately.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_PARTITIONINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_PARTITIONINFORMATION structure defines the properties specific to the partition object.

typedef struct _NTMS_PARTITIONINFORMATION {
    NTMS_GUID      PhysicalMedia;
    NTMS_GUID      LogicalMedia;
    DWORD          State;
    WORD           Side;
    DWORD          dwOmidLabelIdLength;
    BYTE           OmidLabelId[255];
    TCHAR          szOmidLabelType[64];
    TCHAR          szOmidLabelInfo[256];
    DWORD          dwMountCount;
    DWORD          dwAllocateCount;
    LARGE_INTEGER  Capacity;
} NTMS_PARTITIONINFORMATION;

Members

PhysicalMedia
Unique physical media identifier for the medium that contains this partition.
LogicalMedia
Unique logical media identifier for a piece of logical media that contains this partition. This will be a NULL ID if the partition is not allocated.
State
Partition life cycle information. This can be one of the following values.
Value | Meaning
NTMS_PARTSTATE_ALLOCATED | The media has been allocated to an application.
NTMS_PARTSTATE_AVAILABLE | The media is available to be allocated.
NTMS_PARTSTATE_COMPLETE | The media has been completely written and marked as complete by an application.
NTMS_PARTSTATE_DECOMMISIONED | The media is unsuitable for data storage and can be decommissioned.
NTMS_PARTSTATE_INCOMPATIBLE | The media has been found to be and marked as incompatible with the drive.
NTMS_PARTSTATE_FOREIGN | The media is in a foreign pool.
NTMS_PARTSTATE_IMPORT | The media is in the import pool.
NTMS_PARTSTATE_UNPREPARED | The media is waiting for a scratch label to be applied.
NTMS_PARTSTATE_RESERVED | The partition has been reserved by the AllocateNtmsMedia function with the dwOption parameter set to NTMS_ALLOCATE_NEW.

Side
A zero-relative value that identifies the partition property of a piece of physical media. Optical disks that have two sides are represented as having two sides; one in which the Side member equals zero and one in which the Side member equals one.
dwOmidLabelIdLength
The length of the label ID string of the on-media identifier.
OmidLabelId
The label ID unique identifier of the on-media identifier.
szOmidLabelType
A string representing the label type of the on-media identifier.
szOmidLabelInfo
A string representing the label information of the on-media identifier.
dwMountCount
Number of times this media has been mounted into a drive. This is initialized to zero when the objects are created in the database.
dwAllocateCount
Number of times this media has been allocated.
Capacity
Number bytes of storage available on this partition.

Remarks

The NTMS_PARTITIONINFORMATION data structure is part of the NTMS_OBJECTINFORMATION structure and is not used separately.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_PMIDINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_PMIDINFORMATION data structure defines the properties specific to a physical media object.

typedef struct _NTMS_PMIDINFORMATION {
    NTMS_GUID     CurrentLibrary,
    NTMS_GUID     MediaPool;
    NTMS_GUID     Location;
    DWORD         LocationType;
    NTMS_GUID     HomeSlot;
    NTMS_GUID     MediaType;
    TCHAR         szBarCode[NTMS_BARCODE_LENGTH];
    DWORD         BarCodeState;
    TCHAR         szSequenceNumber[NTMS_SEQUENCE_LENGTH];
    DWORD         MediaState;
    DWORD         dwNumberOfPartitions;
    DWORD         dwMediaTypeCode;
    DWORD        dwDensityCode;
} NTMS_PMIDINFORMATION;

Members

CurrentLibrary
Unique ID of the library in which the media is contained.
MediaPool
Unique ID of the media pool to which the media is assigned.
Location
Unique ID of the physical location object for the media.
LocationType
Current location type of a piece of physical media. The value of this member can be set to NTMS_STORAGESLOT, NTMS_DRIVE, NTMS_IEPORT. (Offline media are in slots.)
HomeSlot
Unique ID of the library storage slot in which media is stored.
MediaType
Unique ID of a media type object.
szBarCode
String that matches the bar-code value on a bar-code label of a piece of physical media.
BarCodeState
Current state of the bar code. This can be one of the following values.
Value | Meaning
NTMS_BARCODESTATE_OK | The media has a bar code and it is readable.
NTMS_BARCODESTATE_UNREADABLE | The media either does not have a bar code or the bar code is unreadable.

szSequenceNumber
A sequential number assigned to the specified medium as a human-readable value that must be transcribed by a user on the medium so that the medium can be located in an offline library.
MediaState
Current state for the piece of physical media. This can be one of the following values.
Value | Meaning
NTMS_MEDIASTATE_IDLE | The media is in a slot in the library, in a drive dismounted, or in an offline library.
NTMS_MEDIASTATE_INUSE | The media is marked as in use as soon as a request for an operation is successfully made to RSM.
NTMS_MEDIASTATE_LOADED | The state of the media when RSM has determined that the media is available for reading and writing.
NTMS_MEDIASTATE_MOUNTED | The state of a piece of physical media when the media is placed in a drive.
NTMS_MEDIASTATE_OP_ERROR | The physical media is in an error state that is recoverable. No operator intervention is required.
NTMS_MEDIASTATE_UNLOADED | The state of the media when it is ready to be removed from a drive. The drive state, DISMOUNTABLE, also indicates that a drive can be removed at any time.
NTMS_MEDIASTATE_OPREQ | Media is waiting for operator request.

dwNumberOfPartitions
Number of partitions on the medium.
dwMediaTypeCode
SCSI media type code.
dwDensityCode
SCSI density code.

Remarks

The NTMS_PMIDINFORMATION data structure is part of the NTMS_OBJECTINFORMATION structure and is not used separately.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


NTMS_STORAGESLOTINFORMATION

[This is preliminary documentation and subject to change.]

The NTMS_STORAGESLOTINFORMATION data structure defines properties specific to a storage slot object.

typedef struct _NTMS_STORAGESLOTINFORMATION {
    DWORD         Number;
    DWORD         State;
    NTMS_GUID     Library;
} NTMS_STORAGEINFORMATION;

Members

Number
Number of the slot in the online library.
State
Current state of the slot. This can be one of the following values.
Value | Meaning
NTMS_SLOTSTATE_EMPTY | Slot is present, but does not contain a piece of physical media.
NTMS_SLOTSTATE_FULL | Slot is present and contains a piece of physical media.
NTMS_SLOTSTATE_NOTPRESENT | Slot is not present. If the library contains magazines, this value is reported for each slot when the associated magazine is missing.
NTMS_SLOTSTATE_UNKNOWN | Slot state cannot be determined.
NTMS_SLOTSTATE_NEEDSINVENTORY | Slot needs inventory.

Library
Online library that contains the slot.

Remarks

The NTMS_STORAGESLOTINFORMATION data structure is part of the NTMS_OBJECTINFORMATION structure used for the GetNtmsObjectInformation and SetNtmsObjectInformation functions.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in ntmsapi.h.
Import Library: Use ntmsapi.lib.


Glossary

[This is preliminary documentation and subject to change.]


A

Allocate
Mark media for use by an application. You can allocate media in the Available state.
Allocated state
Media that are in use and assigned to application media pools.
API
Application Programming Interface
Application media pool
Application media pools are created by applications. They determine which media can be accessed by which applications and set the policies for that media. There can be any number of application media pools in a Media Service system.
Available state
Media that can be allocated for use by applications.


B

Bar code
A machine-readable adhesive label that identifies a piece of physical media.It is assumed that all bar codes are unique in a system.


C

Changer
The robotic element of an online library unit.
Completed state
Media that can no longer be used for write operations.


D

Data Path
The software used by the application to read and write data to a medium. This is made up of a device driver and a small interface layer.
Deallocate
Return media to the Available state after it has been used by an application.
Decommissioned state
Media that have reached their allocation maximum.
differential inventory
slots which transitioned from empty to full slots are classified
Drive
A device used to write and read physical media. Drives can be in a library unit or stand-alone drives (directly accessible by the user).


F

Foreign media pool
Foreign media pools contain blank media and media that have unrecognized or no on-media identifiers.
Foreign state
Media whose label types and label IDs are not recognized by Media Service for Windows NT, and media that is new to Media Service for Windows NT.

H

HCL
Hardware Compatibility List


I

Import media pool
Media Service for Windows NT puts a medium in an import media pool when Media Service for Windows NT recognizes the on-media identifier, but the medium is not cataloged in the current Media Service database.
Imported state
Media whose label types are recognized by Media Service for Windows NT, but whose label IDs are not cataloged by Media Service for Windows NT.
Incompatible state
Media that are not compatible with the library in which they were classified. This media should be immediately ejected from the library hardware unit. Media Service for Windows NT puts Incompatible media in the foreign media pool.
ISV
Independent Software Vendor


L

Library
A media storage location. There are three types of libraries: online, stand-alone drives, and offline. A medium always exists in some type of library.
Library request
A request for an online library or stand-alone drive to perform a task. This request can be issued by an application or by Media Service for Windows NT.
LMID
A logical representation of a physical storage location. Media Service for Windows NT generally defines sides of the logical media for use by the application. The intent of logical media is to allow the underlying physical medium of the data to change without affecting the application.
Logical media
Logical media are abstract representations of partitions of physical media. All media that are currently allocated in Media Service for Windows NT are represented as logical media. Logical media are referenced by LMIDs (logical media IDs).


M

Media label
A label written and used by an application to track media. Applications write media labels when media are moved from a scratch media pool to an application media pool. Media Service for Windows NT uses a subset of the media label known as the application on-media identifier to track media.
Media label library
A DLL that can interpret the format of a media label written by a Media Service application.
Media pool
Media pools are logical collections of media that have the same media management policies. They are used by applications to control access to media within a Media Service system. A medium is contained in exactly one media pool.
Media state
Media states identify the condition of the media in a Media Service system.
Media Service, Media Service for Windows NT
Windows NT Media Services. It is a service included with Windows NT that facilitates communication among applications, robotic changers and media libraries.
Media Service for Windows NT MMC snap-in
The Media Service for Windows NT MMC snap-in is a user interface to Media Service for Windows NT that is a snap-in for the Microsoft Management Console (MMC) for Windows NT. It provides administrators with the ability to add Media Service objects, view and modify properties of Media Service objects, insert and eject media, perform inventories, mount and dismount media, and check status information.


O

Offline library
The offline library holds all media that are known by Media Service for Windows NT but are not in an online library or stand-alone drive. Media can only be moved from an offline library to an online library or stand-alone drive by the administrator physically inserting it into a library unit. A set of shelves is an example of an offline library. There is one offline library per Media Service system.
OMID
On-media identifiers are labels that are electronically recorded on each medium in a Media Service system. Media Service for Windows NT uses on-media identifiers to track media in the Media Service database. An application on-media identifier is a subset of the media label.
Online library
Online libraries are robotic library units. They are sometimes referred to as jukeboxes.
Operator request
A request for the operator to perform a task. This request can be issued by an application or by Media Service for Windows NT.


P

Partition
A portion of a piece of physical media. One side of a two-sided optical disk is an example of a side. Partition are referenced by PARTIDs.
Physical media
Disks and magnetic tapes are physical media. Physical media are referenced by PMIDs (physical media IDs).
PMID
Representation of a medium.
Port
An opening in a library hardware unit that is used to insert and eject media.


S

Scratch media pool
Scratch media pools contain media that are not allocated by an application and do not contain data. There is a one scratch media pool for each media type in a Media Service system.
Sequence numbers
Media Service for Windows NT assigns sequence numbers to media for visual reference by the administrator during inserting, ejecting, and offline tracking of media.
Stand-alone drive
An online drive that is not part of a library unit. Media Service for Windows NT treats stand-alone drives as online libraries with one drive and a port.
System media pool
Include scratch, foreign, and import media pools. RSM creates one scratch, one foreign, and one import media pool for each media type in an RSM system.
State
See Media state.


T


Access Control

The security provisions of Microsoft® Windows NT® are automatically available to Win32-based applications. Every application running on the system is subject to the security imposed by the particular configuration of the local Windows NT implementation. Windows NT is the only platform that supports Win32 security.

The impact of Windows NT security on most Win32 functions is minimal, and a Win32-based application not requiring security functionality usually does not need to incorporate any special code. However, you can use the security features of Windows NT to provide a number of services to a Win32-based application.

This overview describes the Windows NT security model for controlling access to Win32 objects such as files, and for controlling access to administrative functions such as setting the system time or auditing user actions. The Access-Control Model topic provides a high-level description of the access control components and how they interact with each other. Following this description are topics that discuss the access-control components:

  • Access Tokens
  • Security Descriptors
  • Access-Control Lists (ACLs)
  • Access-Control Entries (ACEs)
  • Access Rights and Access Masks
  • Security Identifiers (SIDs)

The following topics discuss common access-control tasks:

  • Modifying an Object's Security Descriptor
  • Checking a Thread's Access to an Object
  • Controlling Child Object Creation
  • Controlling Access to an Object's Properties
  • Requesting Access Rights to an Object

The following topics provide sample code for access-control tasks:

  • Modifying an Object's ACLs
  • Creating a Security Descriptor for a New Object
  • Enabling and Disabling Privileges
  • Searching for a SID in an Access Token
  • Taking Object Ownership
  • Converting a Binary SID to String Format


About Access Control

The Win32 security functions support the following access-control features:

  • Selective access to securable objects. You can specify different kinds of access for particular users or groups of users. For example, you can grant read and write access to all members of a group while denying write access to a particular member of the group.
  • Administrative privileges. You can control which users or groups have the privileges necessary to perform various administrative functions. For example, any application that manipulates a system-wide resource must use the security system to gain access to that resource.
  • Monitoring access to securable objects. For example, an administrator can cause the system to generate an audit record in the security event log every time a specified user reads a given file.


C2-Level Security

Windows NT supports C2-level security as defined by the U.S. Department of Defense. Following are some of the most important requirements of C2-level security:

  • It must be possible to control access to a resource by granting or denying access to individual users or named groups of users.
  • Memory must be protected so its contents cannot be read after a process frees it. Similarly, a secure file system, such as NTFS, must protect deleted files from being read.
  • Users must identify themselves in a unique manner when they log on. All auditable actions must identify the user performing the action.
  • System administrators must be able to audit security-related events. Access to this audit data must be limited to authorized administrators.
  • The system must protect itself from external interference or tampering, such as modification of the running system or of system files stored on disk.


Access-Control Model

Windows NT security enables you to control the ability of a process to access securable objects or to perform various system administration tasks. The following topics provide a high-level description of the components of the access-control model and how they interact with each other.

Access-Control Components

Interaction Between Threads and Securable Objects

DACLs and ACEs


Access-Control Components

There are two basic components of the access-control model:

  • Access tokens, which contain information about a logged-on user
  • Security descriptors, which contain the security information that protects a securable object

When a user logs on to a Windows NT system, the system authenticates the user's account name and password. If the logon is successful, the system creates an access token. Every process executed on behalf of this user will have a copy of this access token. The access token contains security identifiers (SIDs) that identify the user's account and any group accounts to which the user belongs. The token also contains a list of the privileges held by the user or the user's groups. The system uses this token to identify the associated user when a process tries to access a securable object or perform a system administration task that requires privileges.

When a securable object is created, the system assigns it a security descriptor containing security information specified by its creator, or default security information if none is specified. Applications can use Win32 functions to get and set the security information for an existing object.

A security descriptor identifies the object's owner and can also contain the following access-control lists (ACL):

  • A discretionary access-control list (DACL) that identifies the users and groups allowed or denied access to the object.
  • A system access-control list (SACL) that controls how the system audits attempts to access the object.

An ACL contains a list of access-control entries (ACEs). Each ACE specifies a set of access rights and contains a SID that identifies a trustee for whom the rights are allowed, denied, or audited. A trustee can be a user account, group account, or logon session.

Use the Win32 functions to manipulate the contents of security descriptors, SIDs, and ACLs rather than accessing them directly. This helps ensure that these structures remain syntactically accurate and prevents future enhancements to the security system from breaking existing code.


Interaction Between Threads and Securable Objects

When a thread attempts to use a securable object, the system gets the user and group SIDs from the thread's access token. The system checks the object's DACL, looking for ACEs that apply to these SIDs. The system checks each ACE until access is either granted or denied or until there are no more ACEs to check. Conceivably, an ACL could have several ACEs that apply to the token's SIDs. And, if this occurs, the access rights granted by each ACE accumulate. For example, if one ACE grants read access to a group and another ACE grants write access to a user who is a member of the group, the user can have both read and write access to the object.

The following illustration shows the relationship between these blocks of security information:


DACLs and ACEs

If a Win32 object does not have a DACL, the system allows everyone full access to it. If an object has a DACL, the system allows only the access that is explicitly allowed by the ACEs in the DACL. If there are no ACEs in the DACL, the system does not allow access to anyone. Similarly, if a DACL has ACEs that allow access to a limited set of users or groups, the system implicitly denies access to all trustees not included in the ACEs.

In most cases, you can control access to an object by using access-allowed ACEs; you don't need to explicitly deny access to an object. The exception is when an ACE allows access to a group, and you want to deny access to a member of the group. To do this, place an access-denied ACE for the user in the DACL ahead of the access-allowed ACE for the group. Note that the order of the ACEs is important because the system reads the ACEs in sequence until access is granted or denied. The user's access-denied ACE must appear first; otherwise, when the system reads the group's access allowed ACE, it will grant access to the restricted user.

The following table shows a DACL that denies access to one user and grants access to two groups. The members of Group A get READ, WRITE, EXECUTE access rights by accumulating the rights allowed to Group A and rights allowed to everyone. The exception is User X, who is denied access by the access-denied ACE in spite of being a member of Group B.

 | ACE Type | Trustee | Access Rights
ACE 1 | Access-Denied | User X | READ, WRITE, EXECUTE
ACE 2 | Access-Allowed | Group A | READ, WRITE
ACE 3 | Access-Allowed | Everyone | EXECUTE


Access Tokens

An access token is an object that describes the security context of a process or thread. The information in a token includes the identity and privileges of the user account associated with the process or thread. When a user logs on, the system verifies the user's password by comparing it with information stored in a security database. If the password is authenticated, the system produces an access token. Every process executed on behalf of this user has a copy of this access token.

The system uses an access token to identify the user when a thread interacts with a securable object or tries to perform a system task that requires privileges. Access tokens contain the following information:

  • The security identifier (SID) for the user's account
  • SIDs for the groups of which the user is a member
  • A logon SID that identifies the current logon session
  • A list of the privileges held by either the user or the user's groups
  • An owner SID
  • The SID for the primary group
  • The default DACL that the system uses when the user creates a securable object without specifying a security descriptor
  • The source of the access token
  • Whether the token is a primary or impersonation token
  • An optional list of restricting SIDs
  • Current impersonation levels
  • Other statistics

Every process has a primary token that describes the security context of the user account associated with the process. By default, the system uses the primary token when a thread of the process interacts with a securable object. However, a thread can impersonate a client account. This allows the thread to interact with securable objects using the client's security context. A thread that is impersonating a client has both a primary token and an impersonation token. Use the OpenProcessToken function to retrieve a handle to the primary token of a process. Use the OpenThreadToken function to retrieve a handle to the impersonation token of a thread. For more information, see Impersonation.

You can use the following functions to manipulate access tokens.

Function | Description
AdjustTokenGroups | Changes the group information in an access token.
AdjustTokenPrivileges | Enables or disables the privileges in an access token. It does not grant new privileges or revoke existing ones.
CheckTokenMembership | Determines whether a specified SID is enabled in a specified access token.
CreateRestrictedToken | Creates a new token that is a restricted version of an existing token. The restricted token can have disabled SIDs, deleted privileges, and a list of restricting SIDs.
DuplicateToken | Creates a new impersonation token that duplicates an existing token.
DuplicateTokenEx | Creates a new primary token or impersonation token that duplicates an existing token.
GetTokenInformation | Retrieves information about a token.
IsTokenRestricted | Determines whether a token has a list of restricting SIDs.
OpenProcessToken | Retrieves a handle to the primary access token for a process.
OpenThreadToken | Retrieves a handle to the impersonation access token for a thread.
SetThreadToken | Assigns or removes an impersonation token for a thread.
SetTokenInformation | Changes a token's owner, primary group, or default DACL.

The access token functions use the following structures to describe the components of an access token.

Structure | Specifies
TOKEN_CONTROL | Information that identifies an access token.
TOKEN_DEFAULT_DACL | The default DACL that the system uses in the security descriptors of new objects created by a thread using this access token.
TOKEN_GROUPS | Specifies the SIDs and attributes of the group SIDs in an access token.
TOKEN_OWNER | The default owner SID for the security descriptors of new objects.
TOKEN_PRIMARY_GROUP | The default primary group SID for the security descriptors of new objects.
TOKEN_PRIVILEGES | The privileges associated with an access token and whether the privileges are enabled.
TOKEN_SOURCE | The source of an access token.
TOKEN_STATISTICS | Statistics associated with an access token.
TOKEN_USER | The SID of the user associated with an access token.

The access token functions use the following enumeration types.

Enumeration Type | Specifies
TOKEN_INFORMATION_CLASS | Identifies the type of information being set or retrieved from an access token.
TOKEN_TYPE | Identifies an access token as a primary or impersonation token.


Restricted Tokens

[This is preliminary documentation and subject to change.]

A restricted token is a primary or impersonation access token that has been modified by the CreateRestrictedToken function. A process or impersonating thread running in the security context of a restricted token is restricted in its ability to access securable objects or perform privileged operations. CreateRestrictedToken can restrict a token in the following ways:

  • Remove privileges from the token.
  • Apply the deny-only attribute to SIDs in the token so they cannot be used to access secured objects. For more information about the deny-only attribute, see SID Attributes in an Access Token.
  • Specify a list of restricting SIDs, which can limit access to securable objects.

The system uses the list of restricting SIDs when it checks the token's access to a securable object. When a restricted process or thread tries to access a securable object, the system performs two access checks: one using the token's enabled SIDs, and another using the list of restricting SIDs. Access is granted only if both access checks allow the requested access rights. For more information about access checks, see Checking a Thread's Access to an Object.

You can use a restricted primary token in a call to the CreateProcessAsUser function. Typically, the process that calls CreateProcessAsUser must have the SE_ASSIGNPRIMARYTOKEN_NAME privilege, which is usually held only by system code or by services running in the LocalSystem account. However, if the CreateProcessAsUser call specifies a restricted version of the caller's primary token, this privilege is not required. This enables ordinary applications to create restricted processes.

You can also use a restricted primary or impersonation token in the ImpersonateLoggedOnUser function.


SID Attributes in an Access Token

[This is preliminary documentation and subject to change.]

Each user and group SID in an access token has a set of attributes that control how the system uses the SID in an access check. The following table lists the attributes that control access checking.

Attribute | Description
SE_GROUP_ENABLED | A SID with this attribute is enabled for access checks. When the system performs an access check, it checks for access-allowed and access-denied ACEs that apply to one of the enabled SIDs in the access token. A SID without this attribute is ignored during an access check unless the SE_GROUP_USE_FOR_DENY_ONLY attribute is set.
SE_GROUP_USE_FOR_DENY_ONLY | Windows NT 5.0 and later: A SID with this attribute is a deny-only SID. When the system performs an access check, it checks for access-denied ACEs that apply to the SID, but ignores access-allowed ACEs for the SID. If this attribute is set, the SE_GROUP_ENABLED is not set, and the SID cannot be re-enabled.

To set or clear the SE_GROUP_ENABLED attribute of a group SID, use the AdjustTokenGroups function. You cannot disable a group SID that has the SE_GROUP_MANDATORY attribute. You cannot use AdjustTokenGroups to disable the user SID of an access token.

To determine whether a SID is enabled in a token, that is, whether it has the SE_GROUP_ENABLED attribute, call the CheckTokenMembership function.

To set the SE_GROUP_USE_FOR_DENY_ONLY attribute of a SID, include the SID in the list of deny-only SIDs that you specify when you call the CreateRestrictedToken function. CreateRestrictedToken can apply the SE_GROUP_USE_FOR_DENY_ONLY attribute to any SID, including the user SID and group SIDs that have the SE_GROUP_MANDATORY attribute. However, you cannot remove the deny-only attribute from a SID; nor can you use AdjustTokenGroups to set the SE_GROUP_ENABLED attribute on a deny-only SID.

To get the attributes of a SID, call the GetTokenInformation function with the TokenGroups value. The function returns an array of SID_AND_ATTRIBUTES structures that identify the group SIDs and their attributes.


Access Rights for Access-Token Objects

Windows NT provides security support that enables you to control access to access-token objects. To get or set the security descriptor for an access token, call the SetKernelObjectSecurity and GetKernelObjectSecurity functions.

When you call the OpenProcessToken or OpenThreadToken function to get a handle to an access token, Windows NT checks the requested access rights against the DACL in the token's security descriptor.

The following are valid access rights for access token objects:

  • The DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER standard access rights. Access tokens do not support the SYNCHRONIZE standard access right.
  • The ACCESS_SYSTEM_SECURITY right to get or set the SACL in the object's security descriptor.
  • The specific access rights for access tokens, which are listed in the following table.
Value | Meaning
TOKEN_ADJUST_DEFAULT | Required to change the default owner, primary group, or DACL of an access token.
TOKEN_ADJUST_GROUPS | Required to adjust the attributes of the groups in an access token.
TOKEN_ADJUST_PRIVILEGES | Required to enable or disable the privileges in an access token.
TOKEN_ASSIGN_PRIMARY | Required to attach a primary token to a process. The SE_ASSIGNPRIMARYTOKEN_NAME privilege is also required to accomplish this task.
TOKEN_DUPLICATE | Required to duplicate an access token.
TOKEN_EXECUTE | Combines STANDARD_RIGHTS_EXECUTE and TOKEN_IMPERSONATE.
TOKEN_IMPERSONATE | Required to attach an impersonation access token to a process.
TOKEN_QUERY | Required to query an access token.
TOKEN_QUERY_SOURCE | Required to query the source of an access token.
TOKEN_READ | Combines STANDARD_RIGHTS_READ and TOKEN_QUERY.
TOKEN_WRITE | Combines STANDARD_RIGHTS_WRITE, TOKEN_ADJUST_PRIVILEGES, TOKEN_ADJUST_GROUPS, and TOKEN_ADJUST_DEFAULT.
TOKEN_ALL_ACCESS | Combines all possible access rights for a token.


Security Descriptors

A security descriptor contains the security information associated with a securable object. A security descriptor consists of a SECURITY_DESCRIPTOR structure and its associated security information. A security descriptor can include the following security information:

  • Security identifiers (SIDs) for the owner and primary group of an object.
  • A DACL that specifies the types of object access that the system grants to particular users or groups.
  • A SACL that specifies the types of access attempts that generate audit records for the object.
  • A set of control bits that qualify the meaning of a security descriptor or its individual members.

Applications must not directly manipulate the contents of a security descriptor. The Win32 API provides functions for setting and retrieving the security information in an object's security descriptor. In addition, there are functions for creating and initializing a security descriptor for a new object.

This overview describes the Win32 security functions for working with security descriptors for applications running on Windows NT versions 5.0 and later. For applications that must be compatible with versions of Windows NT earlier than 5.0, see Windows NT 4.0 Access Control and Low-Level Access Control.


Security Descriptor Operations

The Win32 API provides functions for getting and setting the security information in an object's security descriptor.

Windows NT version 5.0 introduces a set of access-control functions that support object-specific ACEs, automatic propagation of inheritable ACEs, and provider-independent access rights. These functions enable you to get and set the security information on a variety of securable objects as well as securable objects on other operating systems.

The SetSecurityInfoEx and SetNamedSecurityInfoEx functions can specify the security information for the DACL, SACL, owner SID, and group SID in an object's security descriptor. The GetSecurityInfoEx and GetNamedSecurityInfoEx functions can retrieve buffers containing the DACL, SACL, owner, and group information. For directory service objects, you can use these functions to get and set object-specific ACEs that apply only to a property set or property on the object, or that can be inherited only by a specified type of child object.

The GetSecurityInfoEx and SetSecurityInfoEx functions use handles to identify objects. You can use these functions with the following types of objects:

  • Local or remote files or directories on an NTFS file system
  • Mailslots and named pipes
  • Local or remote printers
  • Local or remote Win32 services
  • Windows NT network shares
  • Registry keys
  • Semaphores, events, mutexes, and waitable timers
  • Processes, threads, file-mapping objects
  • Window stations and desktops
  • Directory service objects

The GetNamedSecurityInfoEx and SetNamedSecurityInfoEx functions use names to identify objects. You can use these functions with the following types of objects:

  • Local or remote files or directories on an NTFS file system
  • Local or remote printers
  • Local or remote Win32 services
  • Windows NT network shares
  • Registry keys
  • Semaphores, events, mutexes, and waitable timers
  • File-mapping objects
  • Directory service objects

Note that these functions do not work explicitly with pointers to security descriptors, ACLs, or SIDs. Instead, they use ACTRL_ACCESS structures to describe DACLs, ACTRL_AUDITstructures to describe SACLs, and strings to identify owners and groups. You can use the ConvertAccessToSecurityDescriptor function to convert these structures and strings to a self-relative security descriptor. You can use the ConvertSecurityDescriptorToAccess and ConvertSecurityDescriptorToAccessNamed functions to extract the security information from a security descriptor and store it in these structures and strings.


Asynchronous Security Descriptor Operations

You can execute the SetSecurityInfoEx or SetNamedSecurityInfoEx function as an asynchronous operation. This can be useful when the function call involves a time-consuming operation, such as propagating inherited ACEs to the child objects of a file, registry, or DS object.

To start an asynchronous operation, specify a valid ACTRL_OVERLAPPED structure when you call SetSecurityInfoEx or SetNamedSecurityInfoEx. The function returns immediately, and the ACTRL_OVERLAPPED structure contains a handle to an event object that the system signals when the operation has been completed. You can call the GetOverlappedAccessResults function to wait for the operation to be completed and retrieve the results of the asynchronous operation.

Alternatively, you can call one of the wait functions, such as WaitForSingleObject, to wait for the event object to be signaled, and then call GetOverlappedAccessResults to determine the results of the operation. The wait functions also allow you to specify a time-out interval; if the interval elapses before the event is signaled, you can call the CancelOverlappedAccess function to cancel the asynchronous operation.


Security Descriptors for New Objects

When you create a securable object, you can assign a security descriptor to the new object. The Win32 functions for creating securable objects, such as CreateFile or RegCreateKeyEx, have a SECURITY_ATTRIBUTES parameter that can contain a pointer to the new object's security descriptor. For sample code that builds a security descriptor and then calls RegCreateKeyEx to assign the security descriptor to a new registry key, see Creating a Security Descriptor for a New Object.

If an object's creator does not specify a security descriptor, the system uses inherited or default security information to create a security descriptor. The system component or server that manages the object can store the specified or default security descriptor to make it a persistent attribute of the object. You can use Win32 functions to change the information in an object's security descriptor.

Directory service objects, files, directories, registry keys, and desktops are securable objects that can have a parent object. When you create one of these objects, the system checks for inheritable ACEs in the security descriptor of the parent object. The system typically merges any inheritable ACEs into the ACLs of the new object's security descriptor. You can prevent a DACL or SACL from inheriting ACEs by setting the SE_DACL_PROTECTED or SE_SACL_PROTECTED bits in the security descriptor's control bits. For more information, see ACE inheritance.


Modifying an Object's Security Descriptor

To get or set an object's security information, use the GetSecurityInfoEx, GetNamedSecurityInfoEx, SetSecurityInfoEx, and SetNamedSecurityInfoEx functions. For additional information, see Modifying an Object's ACLs.

To get a pointer to an object's security descriptor or to the ACLs and SIDs in an object's security descriptor, use the GetSecurityInfo or GetNamedSecurityInfo functions.

To get the control information in a security descriptor, call the GetSecurityDescriptorControl function. To set the control bits that relate to automatic ACE inheritance, call the SetSecurityDescriptorControl function. Other control bits are set by the various functions that set a security descriptor component. For example, if you use SetSecurityInfoEx to change an object's DACL, the function sets or clears the bits as appropriate to indicate whether the security descriptor has a DACL, whether it's a default DACL, and so on.


Access-Control Lists (ACLs)

An access-control list (ACL) is a list of access-control entries (ACEs). Each ACE in an ACL identifies a trustee and specifies the access rights allowed, denied, or audited for that trustee. The security descriptor for a securable object can contain two ACLs: a DACL and a SACL.

A DACL identifies the trustees that are allowed or denied access to a securable object. When a process tries to access a securable object, the system checks the ACEs in the object's DACL to determine whether to grant access. If the object does not have a DACL, the system grants full access to everyone. If the object's DACL has no ACEs, the system denies all attempts to access the object because the DACL does not allow any access rights. The system checks the ACEs in sequence until it finds one or more ACEs that allow all the requested access rights, or until any of the requested access rights are denied. For more information, see Checking a Thread's Access to an Object.

A SACL enables administrators to log attempts to access a secured object. Each ACE specifies the types of access attempts by a specified trustee that cause the system to generate a record in the security event log. An ACE in a SACL can generate audit records when an access attempt fails, when it succeeds, or both. In future releases, a SACL will also be able to raise an alarm when an unauthorized user attempts to gain access to an object. For more information about SACLs, see Audit Generation and SACL Access Right.

Do not try to work directly with the contents of an ACL. To ensure that ACLs are semantically correct, use the appropriate Win32 functions to create and manipulate ACLs. For more information, see Modifying an Object's ACLs.


Checking a Thread's Access to an Object

When a thread tries to access a securable object, the system either grants or denies access. If the object does not have a DACL, the system grants the requested access. Otherwise, the system looks for ACEs in the object's DACL that apply to the thread. Each ACE in the object's DACL specifies the access rights allowed or denied for a trustee, which can be a user account, group account, or logon session.

The system compares the trustee in each ACE to the trustees identified in the thread's access token. An access token contains SIDs that identify the user and the group accounts to which the user belongs. A token also contains a logon SID that identifies the current logon session. During an access check, the system ignores group SIDs that are not enabled. For more information on enabled, disabled, and deny-only SIDs, see SID Attributes in an Access Token.

Typically, the system uses the primary access token of the thread that is requesting access. However, if the thread is impersonating another user, the system uses the thread's impersonation token.

The system examines each ACE in sequence until one of the following events occurs:

  • An access-denied ACE explicitly denies any of the requested access rights to one of the trustees listed in the thread's access token.
  • One or more access-allowed ACEs for trustees listed in the thread's access token explicitly grant all the requested access rights.
  • All ACEs have been checked and there is still at least one requested access right that has not been explicitly allowed, in which case, access is implicitly denied.

The following diagram illustrates how an object's DACL can allow access to one thread while denying access to another.

For Thread A, the system reads ACE 1 and immediately denies access because the access-denied ACE applies to the user in the thread's access token. In this case, the system does not check ACEs 2 and 3. For Thread B, ACE 1 does not apply, so the system proceeds to ACE 2, which allows write access, and ACE 3 which allows read and execute access.

Because the system stops checking ACEs when the requested access is explicitly granted or denied, the order of ACEs in a DACL is important. Note that if the ACE order were different in the example, the system might have granted access to Thread A. For system objects, Microsoft defines a preferred order of ACEs in a DACL.

For some object types, you can use the TrusteeAccessToObject function to determine the types of access that an object's DACL grants to a specified trustee. TrusteeAccessToObject uses a name string to identify an object of interest.

You cannot use TrusteeAccessToObject with mailslot, named pipe, process, thread, window station, and desktop objects. Use the following procedure to determine a trustee's access rights to these types of objects, or to other objects identified by a handle.

To determine a trustee's access rights
  1. Call the GetSecurityInfo function to get a pointer to the object's DACL.
  2. Call the GetEffectiveRightsFromAcl function to retrieve the access rights that the DACL grants to a specified trustee.


Controlling Child Object Creation

The system typically assigns the creator of an object as the object's owner, and the owner has implicit rights to control the object. For example, the owner of an object implicitly has the right to modify the object's DACL, which means the owner can control access to the object. You can use the DACL of a container object to control which trustees have the right to create child objects or subcontainers within the container. This allows you to limit what controls access to these child objects.

The various types of container objects have specific access rights that control the ability to create child objects. For example, registry keys have the KEY_CREATE_SUB_KEY access right that controls the right to create subkeys. The DACL of a registry key can control the creation of subkeys by allowing or denying this access right to specified trustees. Similarly, NTFS directory objects support the FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY access rights.

Windows NT provides additional support for controlling child object creation in directory service objects, which can contain many different types of child objects. The DACL for a DS object can contain ACEs that allow or deny the right to create all types of child objects. It can also contain object-specific ACEs that allow or deny the right to create a specified type of child object. This enables you to allow a user to create one type of child object while preventing the user from creating other types of child objects. Use the following procedure to add an object-specific ACE that allows a specified trustee to create or delete a specified type of child object.

To add an object-specific ACE
  1. Use the GetSecurityInfoEx or GetNamedSecurityInfoEx function to get a pointer to an ACTRL_ACCESS buffer that contains the object's DACL information.
  2. Use the SetEntriesInAccessList function to add the object-specific ACE information to the ACTRL_ACCESS buffer. The lpProperty parameter identifies the type of child object. The pAccessEntryList parameter points to an ACTRL_ACCESS_ENTRY structure that identifies the trustee and specifies a combination of the ACTRL_DS_CREATE_CHILD and ACTRL_DS_DELETE_CHILD access rights.
  3. Use the SetSecurityInfoEx or SetNamedSecurityInfoEx function to set the object's DACL with the new access-control information.

To allow a specified trustee to create or delete all types of child objects, follow the same steps, but specify NULL for the lpProperty parameter when you call SetEntriesInAccessList. This creates an ACE that applies to the object itself rather than to a specified type of child object.


Controlling Access to an Object's Properties

[This is preliminary documentation and subject to change.]

The DACL of a directory service (DS) object can contain a hierarchy of ACEs, as follows:

  1. ACEs that protect the object itself
  2. Object-specific ACEs that protect a specified property set on the object
  3. Object-specific ACEs that protect a specified property on the object

Within this hierarchy, the rights granted or denied at a higher level apply also to the lower levels. For example, if an object-specific ACE on a property set grants a trustee the DS_READ_PROPERTY right, the trustee has implicit read access to all the properties of that property set. Similarly, an ACE on the object itself that grants DS_READ_PROPERTY access gives the trustee read access to all of the object's properties.

The following illustration shows the tree of a hypothetical DS object and its property sets and properties.

Suppose you want to allow the following access to the properties of this DS object:

  • Allow Group A read/write access to all of the object's properties, including Property D.
  • Allow everyone else read/write access to all properties except Property D.

To do this, set the ACEs in the object's DACL as shown in the following table.

Trustee | Object GUID | ACE Type | Provider-Independent Access Rights
Group A | None | Access-allowed ACE | ACTRL_DS_READ_PROP | ACTRL_DS_WRITE_PROP
Everyone | Property Set 1 | Access-allowed object ACE | ACTRL_DS_READ_PROP | ACTRL_DS_WRITE_PROP
Everyone | Property C | Access-allowed object ACE | ACTRL_DS_READ_PROP | ACTRL_DS_WRITE_PROP

The ACE for Group A does not have an object GUID, which means that it allows access to all the object's properties. The object-specific ACE for Property Set 1 allows everyone access to Properties A and B. The other object-specific ACE allows everyone access to Property C. Note that although this DACL does not have any access-denied ACEs, it implicitly denies Property D access to everyone except Group A.

When a user tries to access an object's property, the system checks the ACEs in order until the requested access is explicitly granted, denied, or there are no more ACEs, in which case, access is implicitly denied. The system evaluates:

  • ACEs that apply to the object itself
  • Object-specific ACEs that apply to the property set that contains the property being accessed
  • Object-specific ACEs that apply to the property being accessed

The system ignores object-specific ACEs that apply to other property sets or properties.


Access-Control Entries (ACEs)

An access-control entry (ACE) is an element in an access-control list (ACL). An ACL can have zero or more ACEs. Each ACE controls or monitors access to an object by a specified trustee. For information about adding, removing, or changing the ACEs in an object's ACLs, see Modifying an Object's ACLs.

Windows NT currently supports six types of ACEs. There are three ACE types supported by all securable objects. In addition, there are three types of object-specific ACEs supported by directory service objects.

All types of ACEs contain the following access-control information:

  • A security identifier (SID) that identifies the trustee that the ACE applies to.
  • An access mask that specifies the access rights controlled by the ACE.
  • A flag that indicates the type of ACE.
  • A set of bit flags that determine whether child containers or objects can inherit the ACE from the primary object to which the ACL is attached.

The following table lists the three ACE types supported by all securable objects.

Type | Description
Access-denied ACE | Used in a DACL to deny access rights to a trustee.
Access-allowed ACE | Used in a DACL to allow access rights to a trustee.
System-audit ACE | Used in a SACL to generate an audit record when the trustee attempts to exercise the specified access rights.

For a table of object-specific ACEs, see Object-Specific ACEs. Windows NT does not currently support system-alarm ACEs.


Trustees

A trustee is the user account, group account, or logon session to which an ACE applies. Each ACE in an ACL has one SID that identifies a trustee. User accounts include accounts that human users or programs such as Win32 services use to log on to the local computer. Group accounts cannot be used to log on to a computer, but are useful in ACEs to allow or deny a set of access rights to one or more user accounts. A logon SID that identifies the current logon session is useful to allow or deny access rights only until the user logs off.

The access-control functions for Windows NT version 4.0 and later use the TRUSTEE structure to identify a trustee. This structure enables you to use a name string or a SID to identify a trustee. If you use a name, the Win32 functions that create an ACE from the TRUSTEE structure perform the task of allocating the SID buffers and looking up the SID that corresponds to the account name. There are two helper functions, BuildTrusteeWithSid and BuildTrusteeWithName, that initialize a TRUSTEE structure with a specified SID or name. Three other helper functions, GetTrusteeForm, GetTrusteeName, and GetTrusteeType, retrieve the values of the various members of a TRUSTEE structure.


Object-Specific ACEs

[This is preliminary documentation and subject to change.]

Windows NT version 5.0 supports object-specific ACEs for directory service (DS) objects. Object-specific ACEs contain the same trustee and access right information found in the older ACE types. They also contain two GUID structures, which contain globally unique identifiers (GUIDs) that identify types of objects. These GUIDs enable the ACE to provide the following functionality:

  • Control access to a property or property set on the object.
  • Specify the type of child object that can inherit the ACE. This enables a finer degree of inheritance control for objects that can have different types of child objects.
  • Specify the type of child object for which the ACE grants or denies creation rights. For more information, see Controlling Child Object Creation.

Windows NT version 5.0 supports three types of object-specific ACEs. System-alarm object ACEs are not currently supported.

Type | Description
Access-denied object ACE | Windows NT 5.0 and later: Used in a DACL to deny a trustee access to a property or property set on the object, or to limit ACE inheritance to a specified type of child object. Uses the ACCESS_DENIED_OBJECT_ACE structure.
Access-allowed object ACE | Windows NT 5.0 and later: Used in a DACL to allow a trustee access to a property or property set on the object, or to limit ACE inheritance to a specified type of child object. Uses the ACCESS_ALLOWED_OBJECT_ACE structure.
System-audit object ACE | Windows NT 5.0 and later: Used in a SACL to log a trustee's attempts to access a property or property set on the object, or to limit ACE inheritance to a specified type of child object. Uses the SYSTEM_AUDIT_OBJECT_ACE structure.

Any ACL that contains an object-specific ACE must use the revision ACL_REVISION_DS.


Order of ACEs in a DACL

When a process tries to access a securable object, the system steps through the ACEs in the object's DACL until it finds ACEs that allow or deny the requested access. The access rights that a DACL allows a user could vary depending on the order of ACEs in the DACL. Consequently, Microsoft defines a preferred order for ACEs in the DACL of a securable object. The preferred order provides a simple framework that makes it easy to be assured that an access-denied ACE actually denies access. For more information about the system's algorithm for checking access, see Checking a Thread's Access to an Object.

For Windows NT versions 4.0 and earlier, the preferred order of ACEs is simple: In a DACL, all access-denied ACEs should precede any access-allowed ACEs. The SetEntriesInAcl function creates a DACL with ACEs in this order. However, the low-level functions for adding ACEs to a DACL do not enforce the preferred order. The AddAce function adds ACEs at a specified location in an ACL. Functions such as AddAccessAllowedAce add an ACE to the end of an ACL. It is the caller's responsibility to ensure that the ACEs are added in the preferred order.

The following diagram illustrates how the same ACEs can allow different access rights, depending on their order in the DACL. The system denies access to object A when it reads the access-denied ACE; but the out-of-order DACL for Object B causes the system to grant access without reading the access-denied ACE.

For Windows NT version 5.0 and later, the proper order of ACEs is more complicated because of the introduction of object-specific ACEs and automatic inheritance. When called for objects on Windows NT, the SetSecurityInfoEx and SetNamedSecurityInfoEx functions build an object's DACL using the preferred order. For objects on other systems, the ordering of access-control information depends on the provider.

The following describes the preferred order for Windows NT version 5.0 and later.

  • To ensure that noninherited ACEs have precedence over inherited ACEs, place all noninherited ACEs in a group before any inherited ACEs. This ordering ensures, for example, that a noninherited access-denied ACE is enforced regardless of any inherited ACE that allows access.
  • Within the groups of noninherited ACEs and inherited ACEs, order ACEs according to ACE type, as shown following:
    1. Access-denied ACEs that apply to the object itself
    2. Access-denied ACEs that apply to a subobject of the object, such as a property set or property
    3. Access-allowed ACEs that apply to the object itself
    4. Access-allowed ACEs that apply to a subobject of the object

Of course, not all ACE types are required in an ACL.

Functions such as AddAccessAllowedAceEx and AddAccessAllowedObjectAce add an ACE to the end of an ACL. It is the caller's responsibility to ensure that the ACEs are added in the proper order.


ACE Inheritance

An object's ACL can contain ACEs that it inherited from its parent container. For example, a registry subkey can inherit ACEs from the key above it in the registry hierarchy. A file in an NTFS file system can inherit ACEs from the directory that contains it.

The ACE_HEADER structure of an ACE contains a set of inheritance flags that control ACE inheritance and the effect of an ACE on the object to which it is attached. The system interprets the inheritance flags and other inheritance information according to the rules of ACE inheritance.

For Windows NT versions 5.0 and later, these rules have been enhanced with the following features:

  • Support for automatic propagation of inheritable ACEs.
  • A flag that differentiates between inherited ACEs and ACEs that were directly applied to an object.
  • Object-specific ACEs that allow you to specify the type of child object that can inherit the ACE.


Automatic Propagation of Inheritable ACEs

[This is preliminary documentation and subject to change.]

In Windows NT versions 4.0 and earlier, a securable object could inherit ACEs only when it was being created or when a new ACL was being applied to the object. The system did not propagate inheritable ACEs to existing child objects. The system did not differentiate between inherited ACEs and ACEs that were applied directly to the object. The system did not allow an object to protect itself from inherited ACEs.

For Windows NT version 5.0 and later, the SetNamedSecurityInfoEx and SetSecurityInfoEx functions support automatic propagation of inheritable ACEs. For example, if you use these functions to add an inheritable ACE to a directory in an NTFS file system, the system applies the ACE as appropriate to the ACLs of any subdirectories or files.

Windows NT version 5.0 also introduces a new inheritance model in which directly applied ACEs have precedence over inherited ACEs. The system implements this precedence by placing directly applied ACEs ahead of inherited ACEs in a DACL. Earlier versions of Windows NT did not distinguish between inherited and directly applied ACEs. Consequently, the order of ACEs in a DACL is different for the current and the previous inheritance models. When you call SetNamedSecurityInfoEx and SetSecurityInfoEx to set an object's security information, the system imposes. the new inheritance model on the ACLs of all objects in the hierarchy below the target object. For objects that have been converted to the new inheritance model, the SE_DACL_AUTO_INHERITED and SE_SACL_AUTO_INHERITED bits are set in the control field of the object's security descriptor.

The system uses the following rules for propagating inherited ACEs to child objects.

  • If a child object with no DACL inherits an ACE, the result is a child object with a DACL containing only the inherited ACE.
  • If a child object with an empty DACL inherits an ACE, the result is a child object with a DACL containing only the inherited ACE.
  • If you remove an inheritable ACE from a parent object, automatic inheritance removes any copies of the ACE inherited by child objects.
  • If automatic inheritance results in the removal of all ACEs from a child object's DACL, the child object has an empty DACL rather than no DACL.

These rules can have the unexpected result of converting an object with no DACL to an object with an empty DACL. An object with no DACL allows full access, but an object with an empty DACL allows no access. As an example of how these rules can create an empty DACL, suppose you add an inheritable ACE to the root object of a tree of objects. Automatic inheritance propagates the inheritable ACE to all the objects in the tree. Child objects that started with no DACL now have a DACL with the inherited ACE. If you remove the inheritable ACE from the root object, the system automatically propagates the change to the child objects. Child objects that started with no DACL (allowing full access) now have an empty DACL (allowing no access).

To ensure that a child object with no DACL is not affected by inheritable ACEs, set the SE_DACL_PROTECTED flag in the object's security descriptor.


ACE Inheritance Rules

The system propagates inheritable ACEs to child objects according to a set of inheritance rules. The system places inherited ACEs in the child's DACL according to the preferred order of ACEs in a DACL. For Windows NT versions 5.0 and later, the system sets the INHERITED_ACE flag in all inherited ACEs.

The following table shows the ACEs inherited by container and noncontainer child objects for different combinations of inheritance flags. These inheritance rules work the same for both DACLs and SACLs.

Parent ACE type | Effect on Child ACL
OBJECT_INHERIT_ACE only
 |  | Noncontainer child objects: Inherited as an effective ACE. Container child objects: Containers inherit an inherit-only ACE unless the NO_PROPAGATE_INHERIT_ACE bit flag is also set.
CONTAINER_INHERIT_ACE only
 |  | Noncontainer child objects: No effect on the child object. Container child objects: The child object inherits an effective ACE. The inherited ACE is inheritable unless the NO_PROPAGATE_INHERIT_ACE bit flag is also set.
CONTAINER_INHERIT_ACE and OBJECT_INHERIT_ACE
 |  | Noncontainer child objects: Inherited as an effective ACE. Container child objects: The child object inherits an effective ACE. The inherited ACE is inheritable unless the NO_PROPAGATE_INHERIT_ACE bit flag is also set.
No inheritance flags set
 |  | No effect on child container or noncontainer objects.

If an inherited ACE is an effective ACE for the child object, the system maps any generic rights to the specific rights for the child object. Similarly, the system maps generic SIDs, such as CREATOR_OWNER, to the appropriate SID. If an inherited ACE is an inherit-only ACE, any generic rights or generic SIDs are left unchanged so they can be mapped appropriately when the ACE is inherited by the next generation of child objects.

For a case in which a container object inherits an ACE that is both effective on the container and inheritable by its descendants, the container may inherit two ACEs. This occurs if the inheritable ACE contains generic information. The container inherits an inherit-only ACE containing the generic information, and an effective-only ACE in which the generic information has been mapped.

An object-specific ACE has an InheritedObjectType member that can contain a GUID to identify the type of object that can inherit the ACE. If the InheritedObjectType GUID is not specified, the inheritance rules for an object specific ACE are the same as for a standard ACE.

If the InheritedObjectType GUID is specified, the ACE is inheritable by objects that match the GUID if OBJECT_INHERIT_ACE is set, and by containers that match the GUID if CONTAINER_INHERIT_ACE is set. Note that currently only DS objects support object-specific ACEs, and the DS treats all object types as containers.


Access Rights and Access Masks

An access right is a bit flag that corresponds to a particular set of operations that a thread can perform on a securable object. For example, a registry key has the KEY_SET_VALUE access right, which corresponds to the ability of a thread to set a value under the key. If a thread tries to perform an operation on an object but does not have the necessary access right to the object, the system does not carry out the operation.

An access mask is a 32-bit value whose bits correspond to the access rights supported by an object. All securable objects use a Windows NT access mask format that includes bits for the following types of access rights:

  • Generic access rights
  • Standard access rights
  • The SACL access right
  • Object-specific access rights. Each type of securable object defines its own set of access rights. For a list of the specific access rights that apply to each type of object, see the documentation for that type of object.

When a thread tries to open a handle to an object, the thread typically specifies an access mask to request a set of access rights. For example, an application that needs to set and query the values of a registry key can open the key using an access mask to request the KEY_SET_VALUE and KEY_QUERY_VALUE access rights.


Windows NT Access Mask Format

All objects arrange their access rights using the access mask format shown in the following diagram.

In this format, the low-order 16 bits are for object-specific access rights, the next 7 bits are for standard access rights that apply to most types of objects, and the 4 high-order bits are used to specify generic access rights that each object type can map to a set of standard and object-specific rights. The ACCESS_SYSTEM_SECURITY bit corresponds to the right to access the object's SACL.


Provider-Independent Access Mask Format

[This is preliminary documentation and subject to change.]

For Windows NT versions 5.0 and later, the Win32 API provides support for controlling access to securable objects that were created by operating systems other than Windows NT. Objects on other systems can have their own access mask format that is different from the access mask format used by securable objects. To provide security support for these objects, the Win32 API defines a provider-independent access mask format that you can use with objects and with objects on systems other than Windows NT.

For each supported operating system, Windows NT has a provider that converts the provider-independent flags to the corresponding object-specific flags. For example, a provider for Novell NetWare maps provider-independent access rights to object-specific access rights for NetWare objects. For Win32 objects, the system maps the provider-independent access rights to the corresponding access rights. For tables that show the mapping for each type of Win32 object, see Provider-Independent and Windows NT Access Rights.

The following diagram shows the provider-independent access mask format.

Some Win32 functions interpret access masks using the provider-independent access mask format; others use the Windows NT access mask format.

Use Windows NT access rights with the following functions:

  • Functions for opening and creating securable objects, such as CreateFile or OpenProcess. These functions use the Windows NT access rights to specify the requested access and to specify the access masks in security descriptor ACEs.
  • The functions described in the Windows NT 4.0 Access Control or Low-Level Access-Control overviews. This includes all of the low-level functions added for Windows NT version 5.0, such as AddAccessAllowedAceEx.
  • The AccessCheck, AccessCheckAndAuditAlarm, AccessCheckByType, AccessCheckByTypeAndAuditAlarm, AccessCheckByTypeResultList, and AccessCheckByTypeResultListAndAuditAlarm functions.

Use provider-independent access rights with the following functions:

  • GetAccessPermissionsForObject
  • GetNamedSecurityInfoEx
  • GetSecurityInfoEx
  • SetEntriesInAccessList
  • SetEntriesInAuditList
  • SetNamedSecurityInfoEx
  • SetSecurityInfoEx
  • TrusteeAccessToObject

The following functions use both Windows NT access rights and provider-independent access rights:

  • The ConvertAccessToSecurityDescriptor function takes provider-independent access rights as input and generates a security descriptor that contains Windows NT access rights.
  • The ConvertSecurityDescriptorToAccessNamed and ConvertSecurityDescriptorToAccess functions take a security descriptor containing Windows NT access rights and return structures containing the corresponding provider-independent access rights.


Generic Access Rights

Securable objects use an access mask format in which the four high-order bits specify generic access rights. Each type of securable object maps these bits to a set of its standard and object specific access rights. For example, a Win32 file object maps the GENERIC_READ bit to the READ_CONTROL and SYNCHRONIZE standard access rights and the FILE_READ_DATA, FILE_READ_EA, and FILE_READ_ATTRIBUTES object-specific access rights. Other types of objects map the GENERIC_READ bit to whatever set of access rights is appropriate for that type of object.

You can use generic access rights to specify the type of access you need when you are opening a handle to an object. This is typically simpler than specifying all the corresponding standard and specific rights.

The following table shows the constants defined for the generic access rights.

Constant | Generic Meaning
GENERIC_ALL | Read, write, and execute access
GENERIC_EXECUTE | Execute access
GENERIC_READ | Read access
GENERIC_WRITE | Write access

Applications that define private securable objects can also use the generic access rights.

The provider-independent access mask format does not include generic access rights.


Standard Access Rights

Each type of securable object has a set of access rights that correspond to operations specific to that type of object. In addition to these object-specific access rights, there is a set of standard access rights that correspond to operations common to most types of securable objects.

Both the Windows NT access mask format and the provider-independent access mask format include a set of bits for the standard access rights. For a table that maps the Windows NT standard access rights to the corresponding provider-independent access rights, see Provider-Independent and Windows NT Access Rights.

The following table shows the Win32 constants defined for the standard access rights.

Constant | Meaning
DELETE | The right to delete the object.
READ_CONTROL | The right to read the information in the object's security descriptor, not including the information in the SACL.
SYNCHRONIZE | The right to use the object for synchronization. This enables a thread to wait until the object is in the signaled state. Some object types do not support this access right.
WRITE_DAC | The right to modify the DACL in the object's security descriptor.
WRITE_OWNER | The right to change the owner in the object's security descriptor.

The Win32 API also defines the following constants that are combinations of the standard access rights.

Constant | Meaning
STANDARD_RIGHTS_ALL | Combines DELETE, READ_CONTROL, WRITE_DAC, WRITE_OWNER, and SYNCHRONIZE access.
STANDARD_RIGHTS_EXECUTE | Currently defined to equal READ_CONTROL.
STANDARD_RIGHTS_READ | Currently defined to equal READ_CONTROL.
STANDARD_RIGHTS_REQUIRED | Combines DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER access.
STANDARD_RIGHTS_WRITE | Currently defined to equal READ_CONTROL.


SACL Access Right

The ACCESS_SYSTEM_SECURITY access right controls the ability to get or set the SACL in an object's security descriptor. The system grants this access right only if the SE_SECURITY_NAME privilege is enabled in the access token of the requesting thread.

To access an object's SACL
  1. Call the AdjustTokenPrivileges function to enable the SE_SECURITY_NAME privilege.
  2. Request the ACCESS_SYSTEM_SECURITY access right when you open a handle to the object.
  3. Get or set the object's SACL by using a function such as GetSecurityInfoEx or SetSecurityInfoEx.
  4. Call AdjustTokenPrivileges to disable the SE_SECURITY_NAME privilege.

If you access a SACL using the GetNamedSecurityInfoEx or SetNamedSecurityInfoEx functions, enable the SE_SECURITY_NAME privilege and the function internally requests the access right.

The ACCESS_SYSTEM_SECURITY access right is not valid in a DACL because DACLs do not control access to a SACL. However, you can use this access right in a SACL to audit attempts to use the access right.

In the provider-independent access mask format, the ACTRL_SYSTEM_ACCESS access right is equivalent to ACCESS_SYSTEM_SECURITY.


Requesting Access Rights to an Object

When you open a handle to an object, the returned handle has some combination of access rights to the object. Some functions, such as CreateSemaphore, do not require you to specify a set of requested access rights; they always try to open the handle for full access. Other functions, such as CreateFile and OpenProcess, allow you to specify the set of access rights that you want. You should request only the access rights that you need, rather than opening a handle for full access. This prevents you from using the handle in a way that you didn't intend, and also increases the chances that your access request will succeed if the object's DACL only allows you limited access.

You can use generic access rights to specify the type of access you need when you are opening a handle to an object. This is typically simpler than specifying all the corresponding standard and specific rights. Alternatively, you can use the MAXIMUM_ALLOWED constant to request that the object be opened with all the access rights that are valid for the caller. Note that you cannot use the MAXIMUM_ALLOWED constant in an ACE.

To get or set the SACL in an object's security descriptor, you must request the ACCESS_SYSTEM_SECURITY access right when you open a handle to the object.


Security Identifiers (SIDs)

A security identifier (SID) is a unique value of variable length used to identify a trustee. Each account has a unique SID issued by an authority, such as a Windows NT server domain, and stored in a security database. Each time a user logs on, the system retrieves the user's SID from the database and places it in the user's access token. The system uses the SID in the user's access token to identify the user in all subsequent interactions with Windows NT security. When a SID has been used as the unique identifier for a user or group, it cannot ever be used again to identify another user or group.

Windows NT security uses SIDs in the following security elements:

  • In security descriptors to identify an object's owner and primary group
  • In access-control entries (ACEs), to identify the trustee for whom access is allowed, denied, or audited
  • In access tokens, to identify the user and the groups to which the user belongs

In addition to the uniquely-created, domain-specific SIDs assigned to specific users and groups, there are well-known SIDs that identify generic groups and generic users. For example, there is a well-known SID used to identify Everyone or World, which is a group that includes all users.

Most applications never need to work with SIDs. For example, in Windows NT versions 4.0 and later, the security functions for getting and setting the ACEs in an ACL allow you to use names rather than SIDs to identify users and groups. However, when you are working with well-known SIDs, you should use the Win32 functions to build the SID from predefined constants rather than using the name of the well-known SID. This is because the names of well-known SIDs can vary. For example, the U.S. English version of Windows NT has a well-known SID named "BUILTIN\Administrators" that might have a different name on international versions of Windows NT. For sample code that builds a well-known SID, see Searching for a SID in an Access Token.

If you do need to work with SIDs, do not manipulate them directly. Instead, use the following Win32 functions.

Function | Description
AllocateAndInitializeSid | Allocates and initializes a SID with the specified number of subauthorities.
CopySid | Copies a source SID to a buffer.
EqualPrefixSid | Tests two SID prefix values for equality. A SID prefix is the entire SID except for the last subauthority value.
EqualSid | Tests two SIDs for equality. They must match exactly to be considered equal.
FreeSid | Frees a SID previously allocated by using the AllocateAndInitializeSid function.
GetLengthSid | Retrieves the length of a SID.
GetSidIdentifierAuthority | Retrieves a pointer to a SID's identifier authority.
GetSidLengthRequired | Retrieves the size of the buffer required to store a SID with a specified number of subauthorities.
GetSidSubAuthority | Retrieves a pointer to a specified subauthority in a SID.
GetSidSubAuthorityCount | Retrieves the number of subauthorities in a SID.
InitializeSid | Initializes a SID structure.
IsValidSid | Tests the validity of a SID by verifying that the revision number is within a known range and that the number of subauthorities is less than the maximum.
LookupAccountName | Retrieves the SID corresponding to a specified account name.
LookupAccountSid | Retrieves the account name corresponding to a specified SID.


SID Components

A SID value includes components that provide information about the SID structure and components that uniquely identify a trustee. A SID consists of the following components:

  • The revision level of the SID structure
  • A 48-bit identifier authority value that identifies the authority, such as a Windows NT server domain, that issued the SID.
  • A variable number of subauthority or relative identifier (RID) values that uniquely identify the trustee relative to the authority that issued the SID.

The combination of the identifier authority value and the subauthority values ensures that no two SIDs will be the same, even if two different SID-issuing authorities issue the same combination of RID values. Each SID-issuing authority issues a given RID only once.

SIDs are stored in binary format in a SID structure. To display a SID, you can convert a binary SID to string format. For sample code that shows how to do this, see Converting a Binary SID to String Format. The following standardized string notation for SIDs makes it simpler to visualize their components:

S-R-I-S-S...

In this notation, the literal character S identifies the series of digits as a SID, R is the revision level, I is the identifier-authority value, and S... is one or more subauthority values.

The following example uses this notation to display the well-known domain-relative SID of the local Administrators group:

S-1–5-32-544

In this example, the SID has the following components. The constants in parentheses are well-known identifier authority and RID values defined in WINNT.H.

  • A revision level of 1
  • An identifier-authority value of 5 (SECURITY_NT_AUTHORITY)
  • A first subauthority value of 32 (SECURITY_BUILTIN_DOMAIN_RID)
  • A second subauthority value of 544 (DOMAIN_ALIAS_RID_ADMINS)


Well-Known SIDs

Well-known SIDs identify generic groups and generic users. For example, there are well-known SIDs to identify the following groups and users:

  • Everyone or World, which is a group that includes all users.
  • CREATOR_OWNER, which is used as a placeholder in an inheritable ACE. When the ACE is inherited, the system replaces the CREATOR_OWNER SID with the SID of the object's creator.
  • The Administrators group for the built-in domain on the local computer.

There are universal well-known SIDs, which are meaningful on all secure systems using this security model, including operating systems other than Windows NT. In addition, there are well-known SIDs that are meaningful only on Windows NT systems.

The Win32 API defines a set of constants for well-known identifier authority and RID values. You can use these constants to create well-known SIDs. The following example combines the SECURITY_WORLD_SID_AUTHORITY and SECURITY_WORLD_RID constants to show the universal well-known SID for the special group representing all users (Everyone or World):

S-1–1–0

This example uses the string notation for SIDs in which S identifies the string as a SID, the first 1 is the revision level of the SID, and the remaining two digits are the SECURITY_WORLD_SID_AUTHORITY and SECURITY_WORLD_RID constants.

You can use the AllocateAndInitializeSid function to build a SID by combining an identifier authority value with up to eight subauthority values. For example, to determine whether the logged-on user is a member of a particular well-known group, call AllocateAndInitializeSid to build a SID for the well-known group and use the EqualSid function to compare that SID to the group SIDs in the user's access token. For sample code, see Searching for a SID in an Access Token. You must call the FreeSid function to free a SID allocated by AllocateAndInitializeSid.

The remainder of this section contains tables of well-known SIDs and tables of identifier authority and subauthority constants that you can use to build well-known SIDs.

The following are some universal well-known SIDs.

Universal well-known SID | Value | Identifies
Null SID | (S-1–0–0) | A group with no members. This is often used when a SID value is not known.
World | (S-1–1–0) | A group that includes all users.
Local | (S-1–2–0) | Users who log on to terminals locally (physically) connected to the system.
Creator Owner ID | (S-1–3–0) | A security identifier to be replaced by the security identifier of the user who created a new object. This SID is used in inheritable ACEs.
Creator Group ID | (S-1–3–1) | Identifies a security identifier to be replaced by the primary-group SID of the user who created a new object. Use this SID in inheritable ACEs.

The following table lists the predefined identifier authority constants. The first four values are used with universal well-known SIDs; the last value is used with Windows NT well-known SIDs.

Identifier authority | Value | SID string prefix
SECURITY_NULL_SID_AUTHORITY | 0 | S-1–0
SECURITY_WORLD_SID_AUTHORITY | 1 | S-1–1
SECURITY_LOCAL_SID_AUTHORITY | 2 | S-1–2
SECURITY_CREATOR_SID_AUTHORITY | 3 | S-1–3
SECURITY_NT_AUTHORITY | 5 | S-1–5

The following RID values are used with universal well-known SIDs. The Identifier authority column shows the prefix of the identifier authority with which you can combine the RID to create a universal well-known SID.

Relative identifier authority | Value | Identifier authority
SECURITY_NULL_RID | 0 | S-1–0
SECURITY_WORLD_RID | 0 | S-1–1
SECURITY_LOCAL_RID | 0 | S-1–2
SECURITY_CREATOR_OWNER_RID | 0 | S-1–3
SECURITY_CREATOR_GROUP_RID | 1 | S-1–3

The SECURITY_NT_AUTHORITY (S-1–5) predefined identifier authority produces SIDs that are not universal but are meaningful only on Windows NT installations. You can use the following RID values with SECURITY_NT_AUTHORITY to create well-known SIDs.

Constant | Identifies
SECURITY_DIALUP_RID (S-1–5–1)
 |  | Users who log on to terminals using a dial-up modem. This is a group identifier.
SECURITY_NETWORK_RID (S-1–5–2)
 |  | Users who can log on across a network. This is a group identifier.
SECURITY_BATCH_RID (S-1–5–3)
 |  | Users who can log on using a batch queue facility. This is a group identifier.
SECURITY_INTERACTIVE_RID (S-1–5–4)
 |  | Users who can log on for interactive operation. This is a group identifier.
SECURITY_LOGON_IDS_RID (S-1–5–5-X-Y)
 |  | A logon session. This is used to ensure that only processes in a given logon session can gain access to the window-station objects for that session. The X and Y values for these SIDs are different for each logon session. The value SECURITY_LOGON_IDS_RID_COUNT is the number of RIDs in this identifier (5-X-Y).
SECURITY_SERVICE_RID (S-1–5–6)
 |  | Accounts authorized to log on as a service.
SECURITY_LOCAL_SYSTEM_RID (S-1–5–0x12)
 |  | A special account used by the operating system.
SECURITY_BUILTIN_DOMAIN_RID (S-1–5–0x20)
 |  | The built-in system domain.

The following RIDs are relative to each domain.

RID | Identifies
DOMAIN_USER_RID_ADMIN | The administrative user account in a domain.
DOMAIN_USER_RID_GUEST | The guest-user account in a domain. Users who do not have an account can automatically log onto this account.
DOMAIN_GROUP_RID_ADMINS | The domain administrator's group. This account exists only on systems running Windows NT Server, not Windows NT Workstation.
DOMAIN_GROUP_RID_USERS | A group containing all user accounts in a domain. All users are automatically added to this group.

The following table has examples of domain-relative RIDs you can use to form well-known SIDs for local groups (aliases). For more information about local and global groups, see Local Group Functions and Group Functions.

RID | Identifies
DOMAIN_ALIAS_RID_ADMINS | A local group used for administration of the domain.
DOMAIN_ALIAS_RID_USERS | A local group representing all users in the domain.
DOMAIN_ALIAS_RID_GUESTS | A local group representing guests of the domain.
DOMAIN_ALIAS_RID_POWER_USERS | A local group used to represent a user or set of users who expect to treat a system as if it were their personal computer rather than as a workstation for multiple users.
DOMAIN_ALIAS_RID_ACCOUNT_OPS | A local group existing only on systems running Windows NT Server. This local group permits control over non-administrator accounts.
DOMAIN_ALIAS_RID_SYSTEM_OPS | A local group existing only on systems running Windows NT Server. This local group performs system administrative functions, not including security functions. It establishes network shares, controls printers, unlocks workstations, and performs other operations.
DOMAIN_ALIAS_RID_PRINT_OPS | A local group existing only on systems running Windows NT Server. This local group controls printers and print queues.
DOMAIN_ALIAS_RID_BACKUP_OPS | A local group used for controlling assignment of file backup-and-restore privileges.
DOMAIN_ALIAS_RID_REPLICATOR | A local group responsible for copying security databases from the primary domain controller to the backup domain controllers. These accounts are used only by the system.


Privileges

A privilege is the right of a user to perform various system-related operations on the local computer, such as shutting down the system, loading device drivers, or changing the system time. Privileges differ from access rights in two ways:

  • Privileges control access to system resources and system-related tasks, whereas access rights control access to securable objects.
  • A system administrator assigns privileges to user and group accounts, whereas the system grants or denies access rights to a securable object based on the ACEs in the object's DACL.

Each Windows NT system has an account database that stores the privileges held by user and group accounts. When a user logs on, the system produces an access token that contains a list of the user's privileges, including those granted to the user or to groups to which the user belongs. Note that the privileges apply only to the local computer; a domain account can have different privileges on different computers.

When the user tries to perform a privileged operation, the system checks the user's access token to determine whether the user holds the necessary privileges, and if so, it checks whether the privileges are enabled. If the user fails these tests, the system does not perform the operation. For a table of the privileges defined by Windows NT, see Windows NT Privileges.

To determine the privileges held in an access token, call the GetTokenInformation function, which also indicates which privileges are enabled. Most privileges are disabled by default.

A system administrator can use the Windows NT administrative tool, User Manager, to add or remove privileges for user and group accounts. Administrators can use the LsaAddAccountRights and LsaRemoveAccountRights functions to programmatically add or remove account privileges.

Before you can perform a privileged operation, you must first enable the necessary privileges in your access token. To do this, call the OpenThreadToken function to get a handle to your primary or impersonation access token, then call the AdjustTokenPrivileges function to enable the necessary privileges. After performing the privileged operation, call AdjustTokenPrivileges again to disable the privileges. For sample code that enables and disables a token's privileges, see Enabling and Disabling Privileges.

The GetTokenInformation and AdjustTokenPrivileges functions use a TOKEN_PRIVILEGES structure to specify an array of privileges and their attributes. This structure contains an array of LUID_AND_ATTRIBUTES structures, each of which specifies the LUID of a privilege and a set of bit flags that indicate the attributes of the privilege, such as whether the privilege is enabled.

The Win32 API defines a set of string constants to identify the various privileges. These constants are the same on all Windows NT systems. However, the functions that get and adjust the privileges in an access token use the LUID type to identify privileges. The LUID values for a privilege can differ from one computer to another, and from one boot to another on the same computer. To get the current LUID that corresponds to one of the string constants, use the LookupPrivilegeValue function. Use the LookupPrivilegeName function to convert a LUID to its corresponding string constant.

The system provides a set of strings that describe each of the Windows NT privileges defined in WINNT.H. These are useful when you need to display a description of a privilege to the user. Use the LookupPrivilegeDisplayName function to retrieve a description string that corresponds to the string constant for a privilege. For example, on systems that use U.S. English, the display name for the SE_SYSTEMTIME_NAME privilege is "Change the system time".

You can use the PrivilegeCheck function to determine whether an access token holds a specified set of privileges. This is useful primarily to server applications that are impersonating a client.


Audit Generation

C2-level security requirements specify that system administrators must be able to audit security-related events and that access to this audit data must be limited to authorized administrators. The Win32 API provides functions enabling an administrator to monitor security-related events.

The security descriptor for a securable object can have a system access-control list (SACL). A SACL contains access-control entries (ACEs) that specify the types of access attempts that generate audit reports. Each ACE identifies a trustee, a set of access rights, and a set of flags that indicate whether the system generates audit messages for failed access attempts, successful access attempts, or both.

The system writes audit messages to the security event log. For information about accessing the records in an event log, see Event Logging.

To read or write an object's SACL, a thread must first enable the SE_SECURITY_NAME privilege. For more information, see SACL Access Right.

The Win32 API also provides support for server applications to generate audit messages when a client tries to access a private object. For more information, see Auditing Access To Private Objects.


Securable Objects

A securable object is an object that can have a security descriptor. All named Win32 objects are securable. Some unnamed objects, such as process and thread objects, can have security descriptors too. For most securable objects, you can specify an object's security descriptor in the function call that creates the object. For example, you can specify a security descriptor in the CreateFile and CreateProcess functions.

In addition, the Win32 security functions enable you to get and set the security information for securable objects created on operating systems other than Windows NT. The Win32 security functions also provide support for using security descriptors with private, application-defined objects. For more information about private securable objects, see Client-Server Access Control.

Each type of securable object defines its own set of specific access rights and its own mapping of generic access rights. For information about the specific and generic access rights for each type of securable object, see the overview for that type of object.

The following table shows the functions to use to manipulate the security information for each type of securable object.

Object type | Security Descriptor Functions
Local or remote files or directories on an NTFS file system | GetNamedSecurityInfoEx, SetNamedSecurityInfoEx, GetSecurityInfoEx, SetSecurityInfoEx
Mailslots | GetSecurityInfoEx, SetSecurityInfoEx
Named and anonymous pipes | GetSecurityInfoEx, SetSecurityInfoEx
Console screen buffers | Not supported.
Processes and threads | GetSecurityInfoEx, SetSecurityInfoEx
File-mapping objects | GetNamedSecurityInfoEx, SetNamedSecurityInfoEx, GetSecurityInfoEx, SetSecurityInfoEx
Access tokens | SetKernelObjectSecurity, GetKernelObjectSecurity
Window-management objects (window stations and desktops) | GetSecurityInfoEx, SetSecurityInfoEx
Registry keys | GetNamedSecurityInfoEx, SetNamedSecurityInfoEx, GetSecurityInfoEx, SetSecurityInfoEx
Local or remote Windows NT services | GetNamedSecurityInfoEx, SetNamedSecurityInfoEx, GetSecurityInfoEx, SetSecurityInfoEx
Local or remote printers | GetNamedSecurityInfoEx, SetNamedSecurityInfoEx, GetSecurityInfoEx, SetSecurityInfoEx
Windows NT network shares | GetNamedSecurityInfoEx, SetNamedSecurityInfoEx, GetSecurityInfoEx, SetSecurityInfoEx
Interprocess synchronization objects (semaphores, events, mutexes, and waitable timers) | GetNamedSecurityInfoEx, SetNamedSecurityInfoEx, GetSecurityInfoEx, SetSecurityInfoEx
Job objects | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo


Using Access Control

The topics in this section demonstrate some practical applications of the Win32 security functions and structures. The examples use the access-control functions that are new for Windows NT version 5.0.

For examples that use the Windows NT 4.0 access control functions, see Using Windows NT 4.0 Access Control.

For examples that use the older low-level access control functions, see Using Low-Level Access Control.


Modifying an Object's ACLs

[This is preliminary documentation and subject to change.]

The following example adds an access-denied ACE to the DACL of an object. The example uses the GetNamedSecurityInfoEx function to get the access-control information from the existing DACL. Then it initializes an ACTRL_ACCESS_ENTRY structure with information about the access-denied ACE to be added. The SetEntriesInAccessList function merges the new ACE information into the existing access-control information. The example then calls the SetNamedSecurityInfoEx function to set the new access-control information in the object's DACL.

ACTRL_ACCESS_ENTRY      AccessEntry;
PACTRL_ACCESS           pOldAccessList, pNewAccessList;
DWORD                   dwErr;

// Get the current DACL information from the object.

dwRes = GetNamedSecurityInfoEx(
    TEXT("myfile"),    // name of the object
    SE_FILE_OBJECT,    // type of object
    DACL_SECURITY_INFORMATION,   // type of information to set
    NULL,              // provider is Windows NT
    NULL,              // name or GUID of property or property set
    &pOldAccessList,   // receives existing DACL information
    NULL,              // receives existing SACL information
    NULL,              // receives name of owner
    NULL);             // receives name of group

// Initialize the access list entry.

ZeroMemory(&AccessEntry, sizeof(ACTRL_ACCESS_ENTRY) );
BuildTrusteeWithName(&(AccessEntry.Trustee), "ludwig");
AccessEntry.Inheritance = NO_INHERITANCE;
AccessEntry.fAccessFlags = ACTRL_ACCESS_DENIED;

// Set provider-independent standard rights.

AccessEntry.Access = ACTRL_READ_CONTROL | ACTRL_SYNCHRONIZE |
    ACTRL_CHANGE_ACCESS | ACTRL_DELETE;

// Set provider-independent rights for file objects.

AccessEntry.Access |= ACTRL_FILE_READ | ACTRL_FILE_READ_ATTRIB |
    ACTRL_FILE_READ_PROP | ACTRL_FILE_WRITE |
    ACTRL_FILE_APPEND | ACTRL_FILE_WRITE_ATTRIB |
    ACTRL_FILE_WRITE_PROP;

// Build an access list from the access list entry.

dwErr = SetEntriesInAccessList(
     1,                  // Number of entries in array
     AccessEntry,        // array of entries
     SET_ACCESS,         // replace any existing items
     NULL,               // property name
     pOldAccessList,     // existing access list
     &pNewAccessList);   // new access list

// Set the access-control information in the object's DACL.

dwRes = SetNamedSecurityInfoEx(
    TEXT("myfile"),              // name of the object
    SE_FILE_OBJECT,              // type of object
    DACL_SECURITY_INFORMATION,   // type of information to set
    NULL,                        // name of provider
    pNewAccessList,              // new access list
    NULL,                        // audit list
    NULL,                        // name of owner
    NULL,                        // name of group
    NULL);                       // pointer to OVERLAPPED structure

// Free the returned buffers.

if (pOldAccessList)
    LocalFree(pOldAccessList);
if (pNewAccessList)
    LocalFree(pNewAccessList);

You can use similar code to remove all ACEs for a specified trustee. Initialize an ACTRL_ACCESS_ENTRY structure to identify the trustee, then call SetEntriesInAccessList function with the REVOKE_ACCESS flag.

The code to modify an object's SACL is similar except that it uses the SetEntriesInAuditList function and the ACTRL_AUDIT structure.

For securable objects, such as DS objects, you can use similar code to add object-specific ACEs to an object's ACL. To add object-specific ACEs, you need to create an array of ACTRL_ACCESS_ENTRY structures and call SetEntriesInAccessList for each property or property set that needs its own ACEs. For example, you would make one SetEntriesInAccessList call to add ACEs that control access to the object itself, and another call to add ACEs that control access to a property on the object.

Note that the GetSecurityInfoEx, GetNamedSecurityInfoEx, SetSecurityInfoEx, and SetNamedSecurityInfoEx functions allow you to get and set ACL information for a specified type of sub-object. For example, you could call GetSecurityInfoEx to get the ACEs that apply to a specified property on an object, merge in a new ACE for that property, and call SetSecurityInfoEx to attach the modified property-specific ACL information to the object.


Creating a Security Descriptor for a New Object

[This is preliminary documentation and subject to change.]

The following example creates a security descriptor for a new registry key. The example initializes an ACTRL_ACCESS_ENTRY structure with information about an access-allowed ACE for the key's DACL. The SetEntriesInAccessList function creates an ACTRL_ACCESS buffer containing the new ACE information. The example then calls the ConvertAccessToSecurityDescriptor function to create a security descriptor from the ACTRL_ACCESS buffer. Finally, the example assigns the security descriptor to a SECURITY_ATTRIBUTES structure which is then passed to the RegCreateKeyEx function.

Note The security functions must use the provider-independent access rights, such as ACTRL_REG_LIST, and RegCreateKeyEx uses the Windows NT-specific access rights, such as KEY_READ.

ACTRL_ACCESS_ENTRY      AccessEntry;
PACTRL_ACCESS           pAccessList;
DWORD                   dwErr, dwDisposition;
PSECURITY_DESCRIPTOR    pSD;
SECURITY_ATTRIBUTES sa;
LONG lRes;
HKEY hk, hkSub;

// Initialize the access list entry.

ZeroMemory (&AccessEntry, sizeof(ACTRL_ACCESS_ENTRY) );
BuildTrusteeWithName(&(AccessEntry.Trustee), "george");
AccessEntry.Inheritance = NO_INHERITANCE;
AccessEntry.fAccessFlags = ACTRL_ACCESS_ALLOWED;

// Set provider-independent rights for registry objects.

AccessEntry.Access = ACTRL_REG_LINK | ACTRL_REG_CREATE_CHILD |
         ACTRL_REG_LIST | ACTRL_REG_NOTIFY |
         ACTRL_REG_QUERY | ACTRL_REG_SET;

// Build an access list from the access list entry.

dwErr = SetEntriesInAccessList(
     1,                  // Number of entries in array
     AccessEntry,        // array of entries
     SET_ACCESS,         // replace any existing items
     NULL,               // property name
     NULL,               // existing access list
     &pAccessList);      // receives new access list

// Initialize a security descriptor from the access list.

dwErr = ConvertAccessToSecurityDescriptor(
    pAccessList,    // pointer to the access-control information
    NULL,           // pointer to the audit-control information
    NULL,           // name of the object's owner
    NULL,           // name of the object's primary group
    &pSD            // receives pointer to security descriptor
   );

// Initialize a security attributes structure.

sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = TRUE;

// Use the security attributes to create a key.

lRes = RegCreateKeyEx(hk, "mykey", 0, "", 0,
        KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);

// Free the returned buffers.

if (pAccessList)
    LocalFree(pAccessList);
if (pSD)
    LocalFree(pSD);


Enabling and Disabling Privileges

The following example shows how to enable or disable a privilege in an access token. The example calls the LookupPrivilegeValue function to get the LUID that the local system uses to identify the privilege. Then the example calls the AdjustTokenPrivileges function, which either enables or disables the privilege that depends on the value of the bEnablePrivilege parameter.

BOOL SetPrivilege(
    HANDLE hToken,          // access token handle
    LPCTSTR lpszPrivilege,  // name of privilege to enable/disable
    BOOL bEnablePrivilege   // to enable or disable privilege
    )
{
TOKEN_PRIVILEGES tp;
LUID luid;

if ( !LookupPrivilegeValue(
        NULL,            // lookup privilege on local system
        lpszPrivilege,   // privilege to lookup
        &luid ) ) {      // receives LUID of privilege
    printf("LookupPrivilegeValue error: %u\n", GetLastError() );
    return FALSE;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
    tp.Privileges[0].Attributes = 0;

// Enable the privilege or disable all privileges.

AdjustTokenPrivileges(
       hToken,
       FALSE,
       &tp,
       sizeof(TOKEN_PRIVILEGES),
       (PTOKEN_PRIVILEGES) NULL,
       (PDWORD) NULL);

// Call GetLastError to determine whether the function succeeded.

if (GetLastError() != ERROR_SUCCESS) {
      printf("AdjustTokenPrivileges failed: %u\n", GetLastError() );
      return FALSE;
}

return TRUE;
}


Searching for a SID in an Access Token

The following example uses the OpenProcessToken and GetTokenInformation functions to get the group memberships in an access token. Then it uses the AllocateAndInitializeSid function to create a SID that identifies the well-known SID of the administrator's group for the local computer. Next, it uses the EqualSid function to compare the well-known SID with the group SIDs from the access token. If the SID is present in the token, the function checks the SIDs attributes to see if it is enabled.

Windows NT 5.0 and later: You can use the CheckTokenMembership function to determine whether a specified SID is present and enabled in an access token.

#define MAX_NAME 256

BOOL SearchTokenGroupsForSID (VOID)
{
DWORD i, dwSize = 0, dwResult = 0;
HANDLE hToken;
PTOKEN_GROUPS pGroupInfo;
SID_NAME_USE SidType;
char lpName[MAX_NAME];
char lpDomain[MAX_NAME];
BYTE sidBuffer[100];
PSID pSID = (PSID)&sidBuffer;
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;

// Open a handle to the access token for the calling process.

if (!OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken )) {
    printf( "OpenProcessToken Error %u\n", GetLastError() );
    return FALSE;
}

// Call GetTokenInformation to get the buffer size.

if(!GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize)) {
    dwResult = GetLastError();
    if( dwResult != ERROR_INSUFFICIENT_BUFFER ) {
        printf( "GetTokenInformation Error %u\n", dwResult );
        return FALSE;
    }
}

// Allocate the buffer.

pGroupInfo = (PTOKEN_GROUPS) GlobalAlloc( GPTR, dwSize );

// Call GetTokenInformation again to get the group information.

if(! GetTokenInformation(hToken, TokenGroups, pGroupInfo,
                        dwSize, &dwSize ) ) {
    printf( "GetTokenInformation Error %u\n", GetLastError() );
    return FALSE;
   }

// Create a SID for the BUILTIN\Administrators group.

if(! AllocateAndInitializeSid( &SIDAuth, 2,
                 SECURITY_BUILTIN_DOMAIN_RID,
                 DOMAIN_ALIAS_RID_ADMINS,
                 0, 0, 0, 0, 0, 0,
                 &pSID) ) {
    printf( "AllocateAndInitializeSid Error %u\n", GetLastError() );
    return FALSE;
   }

// Loop through the group SIDs looking for the administrator SID.

for(i=0; i<pGroupInfo->GroupCount; i++) {
    if ( EqualSid(pSID, pGroupInfo->Groups[i].Sid) ) {

        // Lookup the account name and print it.

        dwSize = MAX_NAME;
        if( !LookupAccountSid( NULL, pGroupInfo->Groups[i].Sid,
                              lpName, &dwSize, lpDomain,
                              &dwSize, &SidType ) ) {
            dwResult = GetLastError();
            if( dwResult == ERROR_NONE_MAPPED )
                strcpy( lpName, "NONE_MAPPED" );
            else {
                printf("LookupAccountSid Error %u\n", GetLastError());
                return FALSE;
            }
        }
        printf( "Current user is a member of the %s\\%s group\n",
                lpDomain, lpName );

        // Find out if the SID is enabled in the token

        if (pGroupInfo->Groups[i].Attributes & SE_GROUP_ENABLED)
            printf("The group SID is enabled.\n");
         else if (pGroupInfo->Groups[i].Attributes &
                          SE_GROUP_USE_FOR_DENY_ONLY)
            printf("The group SID is a deny-only SID.\n");
         else
            printf("The group SID is not enabled.\n");
    }
}

if (pSID)
    FreeSid(pSID);
if ( pGroupInfo )
    GlobalFree( pGroupInfo );
return TRUE;
}


Taking Object Ownership

The following example tries to change the DACL of a file object. This will succeed only if the caller has WRITE_DAC access to the object or is the owner of the object. If the initial attempt to change the DACL fails, an administrator can take ownership of the object. To do this, the example enables the SE_TAKE_OWNERSHIP_NAME privilege in the caller's access token, and makes the local system's Administrators group the owner of the object. If the caller is a member of the Administrators group, the code will then be able to change the object's DACL.

To enable and disable privileges, this example uses the SetPrivilege sample function described in Enabling and Disabling Privileges.

BOOL TakeOwnership(LPTSTR lpszOwnFile)
{
HANDLE hToken;
BYTE sidBuffer[100];
PSID pSID = (PSID)&sidBuffer;
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
DWORD dwRes;

// Try to remove the object's DACL.

dwRes = SetNamedSecurityInfo (
    lpszOwnFile,                 // name of the object
    SE_FILE_OBJECT,              // type of object
    DACL_SECURITY_INFORMATION,   // change only the object's DACL
    NULL, NULL,     // don't change owner or group
    NULL,           // no DACL specified allows everyone access
    NULL);          // don't change SACL

if (dwRes == ERROR_SUCCESS)
    return TRUE;
else if (dwRes != ERROR_ACCESS_DENIED) {
    printf("First SetNamedSecurityInfo call failed: %u\n", dwRes );
    return FALSE;
}

// If the preceding call failed because access was denied,
// enable the SE_TAKE_OWNERSHIP_NAME privilege, create a SID for
// the Administrators group, take ownership of the object, and
// disable the privilege. Then try again to set the object's DACL.

// Open a handle to the access token for the calling process.

if (!OpenProcessToken( GetCurrentProcess(),
                       TOKEN_ADJUST_PRIVILEGES, &hToken) {
      printf("OpenProcessToken failed: %u\n", GetLastError() );
      return FALSE;
}

// Enable the SE_TAKE_OWNERSHIP_NAME privilege.

if (! SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE) ) {
    printf("You must be logged on as Administrator\n");
    return FALSE;
}

// Create a SID for the BUILTIN\Administrators group.

if(! AllocateAndInitializeSid( &SIDAuth, 2,
                 SECURITY_BUILTIN_DOMAIN_RID,
                 DOMAIN_ALIAS_RID_ADMINS,
                 0, 0, 0, 0, 0, 0,
                 &pSID) ) {
    printf( "AllocateAndInitializeSid Error %u\n", GetLastError() );
    return FALSE;
}

// Set the owner in the object's security descriptor.

dwRes = SetNamedSecurityInfo (
    lpszOwnFile,                 // name of the object
    SE_FILE_OBJECT,              // type of object
    OWNER_SECURITY_INFORMATION,  // change only the object's pwner
    pSID,                        // SID of Administrator group
    NULL, NULL, NULL);
if (pSID)
    FreeSid(pSID);
if (dwRes != ERROR_SUCCESS) {
    printf("Could not set owner. Error: %u\n", dwRes );
    return FALSE;
}

// Disable the SE_TAKE_OWNERSHIP_NAME privilege.

if (! SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, FALSE) ) {
    printf("You must be logged on as Administrator\n");
    return FALSE;
}

// Try again to remove the object's DACL, now that we are the owner.

dwRes = SetNamedSecurityInfo (
    lpszOwnFile,                 // name of the object
    SE_FILE_OBJECT,              // type of object
    DACL_SECURITY_INFORMATION,   // change only the object's DACL
    NULL, NULL,     // don't change owner or group
    NULL,           // no DACL specified allows everyone access
    NULL);          // don't change SACL

if (dwRes == ERROR_SUCCESS)
    return TRUE;

printf("Second SetNamedSecurityInfo call failed: %u\n", dwRes );
return FALSE;
}


Converting a Binary SID to String Format

The following example takes a pointer to a SID and converts it to a string format that you can display on the screen. For a description of the string format, see SID Components.

BOOL GetTextualSid(
    PSID pSid,            // binary Sid
    LPTSTR TextualSid,    // buffer for Textual representation of Sid
    LPDWORD lpdwBufferLen // required/provided TextualSid buffersize
    )
{
    PSID_IDENTIFIER_AUTHORITY psia;
    DWORD dwSubAuthorities;
    DWORD dwSidRev=SID_REVISION;
    DWORD dwCounter;
    DWORD dwSidSize;

    // Validate the binary SID.

    if(!IsValidSid(pSid)) return FALSE;

    // Get the identifier authority value from the SID.

    psia = GetSidIdentifierAuthority(pSid);

    // Get the number of subauthorities in the SID.

    dwSubAuthorities = *GetSidSubAuthorityCount(pSid);

    // Compute the buffer length.
    // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL

    dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);

    // Check input buffer length.
    // If too small, indicate the proper size and set last error.

    if (*lpdwBufferLen < dwSidSize)
    {
        *lpdwBufferLen = dwSidSize;
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        return FALSE;
    }

    // Add 'S' prefix and revision number to the string.

    dwSidSize=wsprintf(TextualSid, TEXT("S-%lu-"), dwSidRev );

    // Add SID identifier authority to the string.

    if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )
    {
        dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid),
                    TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
                    (USHORT)psia->Value[0],
                    (USHORT)psia->Value[1],
                    (USHORT)psia->Value[2],
                    (USHORT)psia->Value[3],
                    (USHORT)psia->Value[4],
                    (USHORT)psia->Value[5]);
    }
    else
    {
        dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid),
                    TEXT("%lu"),
                    (ULONG)(psia->Value[5]      )   +
                    (ULONG)(psia->Value[4] <<  8)   +
                    (ULONG)(psia->Value[3] << 16)   +
                    (ULONG)(psia->Value[2] << 24)   );
    }

    // Add SID subauthorities to the string.
    //
    for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
    {
        dwSidSize+=wsprintf(TextualSid + dwSidSize, TEXT("-%lu"),
                    *GetSidSubAuthority(pSid, dwCounter) );
    }

    return TRUE;
}


Access Control Reference

The Win32 API provides three sets of functions for working with security descriptors and access-control lists (ACLs).

  • Functions for Windows NT version 5.0 and later that support object-specific ACEs, directory service (DS) objects, and securable objects on systems other than Windows NT. Use these functions if you are designing your application to run on Windows NT versions 5.0 and later. These functions are described in this overview.
  • Functions for Windows NT version 4.0 and later that provide an interface for working with security descriptors and access-control lists (ACLs). For more information, see Windows NT 4.0 Access Control.
  • Low-level functions for manipulating security descriptors, ACLs, and ACEs. You must use these functions if your application needs to be compatible with Windows NT versions 3.51 and earlier. For more information, see Low-Level Access Control.

Windows NT versions 5.0 and later support all three sets. In general, you should use one set of access-control functions throughout your application.

All versions of Windows NT support a single set of security functions for working with privileges, access tokens, and SIDs.

The following elements are used with access control.

  • Access Control Functions
  • Access Control Structures
  • Access Control Enumeration Types
  • Windows NT Privileges
  • Provider-Independent and Windows NT Access Rights


Access Control Functions

The following functions are used with privileges.

AllocateLocallyUniqueId | Windows NT 3.1 and later
LookupPrivilegeDisplayName | Windows NT 3.1 and later
LookupPrivilegeName | Windows NT 3.1 and later
LookupPrivilegeValue | Windows NT 3.1 and later

The following functions are used with access tokens.

AdjustTokenGroups | Windows NT 3.1 and later
AdjustTokenPrivileges | Windows NT 3.1 and later
DuplicateToken | Windows NT 3.1 and later
GetTokenInformation | Windows NT 3.1 and later
OpenProcessToken | Windows NT 3.1 and later
OpenThreadToken | Windows NT 3.1 and later
SetTokenInformation | Windows NT 3.1 and later
SetThreadToken | Windows NT 3.51 and later
DuplicateTokenEx | Windows NT 4.0 and later
CheckTokenMembership | Windows NT 5.0 and later
CreateRestrictedToken | Windows NT 5.0 and later
IsTokenRestricted | Windows NT 5.0 and later

The following functions are used with security identifiers (SIDs).

AllocateAndInitializeSid | Windows NT 3.1 and later
CopySid | Windows NT 3.1 and later
EqualPrefixSid | Windows NT 3.1 and later
EqualSid | Windows NT 3.1 and later
FreeSid | Windows NT 3.1 and later
GetLengthSid | Windows NT 3.1 and later
GetSidIdentifierAuthority | Windows NT 3.1 and later
GetSidLengthRequired | Windows NT 3.1 and later
GetSidSubAuthority | Windows NT 3.1 and later
GetSidSubAuthorityCount | Windows NT 3.1 and later
InitializeSid | Windows NT 3.1 and later
IsValidSid | Windows NT 3.1 and later
LookupAccountName | Windows NT 3.1 and later
LookupAccountSid | Windows NT 3.1 and later

The following functions are used to get and set the components of an object's security descriptor.

GetSecurityDescriptorControl | Windows NT 3.51 and later
CancelOverlappedAccess | Windows NT 5.0 and later
ConvertAccessToSecurityDescriptor | Windows NT 5.0 and later
ConvertSecurityDescriptorToAccess | Windows NT 5.0 and later
ConvertSecurityDescriptorToAccessNamed | Windows NT 5.0 and later
GetNamedSecurityInfoEx | Windows NT 5.0 and later
GetOverlappedAccessResults | Windows NT 5.0 and later
GetSecurityInfoEx | Windows NT 5.0 and later
SetNamedSecurityInfoEx | Windows NT 5.0 and later
SetSecurityDescriptorControl | Windows NT 5.0 and later
SetSecurityInfoEx | Windows NT 5.0 and later

The following functions are used to manipulate access-control lists.

BuildTrusteeWithName | Windows NT 4.0 and later
BuildTrusteeWithSid | Windows NT 4.0 and later
GetTrusteeForm | Windows NT 4.0 and later
GetTrusteeName | Windows NT 4.0 and later
GetTrusteeType | Windows NT 4.0 and later
SetEntriesInAccessList | Windows NT 5.0 and later
SetEntriesInAuditList | Windows NT 5.0 and later
TrusteeAccessToObject | Windows NT 5.0 and later

The following access-control functions are obsolete. Do not use them.

BuildImpersonateExplicitAccessWithName
BuildImpersonateTrustee
GetMultipleTrustee
GetMultipleTrusteeOperation


AdjustTokenGroups

The AdjustTokenGroups function adjusts groups in the specified access token. TOKEN_ADJUST_GROUPS access is required to enable or disable groups in an access token.

BOOL AdjustTokenGroups(
  HANDLE TokenHandle,      // handle to token that contains groups
  BOOL ResetToDefault,     // flag for default settings
  PTOKEN_GROUPS NewState,  // address of address of new group
                           // information
  DWORD BufferLength,      // size of buffer for previous information
  PTOKEN_GROUPS PreviousState,
                           // address of previous group information
  PDWORD ReturnLength      // address of required buffer size
);

Parameters

TokenHandle
Identifies the access token containing the groups to be modified. The handle must have TOKEN_ADJUST_GROUPS access to the token. If the PreviousState parameter is not NULL, the handle must also have TOKEN_QUERY access.
ResetToDefault
Specifies whether the groups are to be set to their default enabled and disabled states. If this value is TRUE, the groups are set to their default states and the NewState parameter is ignored. If this value is FALSE, the groups are set according to the information pointed to by the NewState parameter.
NewState
Pointer to a TOKEN_GROUPS structure containing the groups whose states are to be set. If the ResetToDefault parameter is FALSE, the function sets each of the groups to the value of that group's SE_GROUP_ENABLED attribute in the TOKEN_GROUPS structure. If ResetToDefault is TRUE, this parameter is ignored.
BufferLength
Specifies the size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be NULL if the PreviousState parameter is NULL.
PreviousState
Pointer to a buffer receiving a TOKEN_GROUPS structure containing the previous state of any groups the function modifies. This parameter can be NULL.

If a buffer is specified but it does not contain enough space to receive the complete list of modified groups, no group states are changed and the function fails. In this case, the function sets the variable pointed to by the ReturnLength parameter to the number of bytes required to hold the complete list of modified groups.

ReturnLength
Pointer to a variable set by the function that contains the actual number of bytes needed for the buffer pointed to by the PreviousState parameter. This parameter can be NULL and is ignored if PreviousState is NULL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The information retrieved in the PreviousState parameter is formatted as a TOKEN_GROUPS structure. This means a pointer to the buffer can be passed as the NewState parameter in a subsequent call to the AdjustTokenGroups function, restoring the original state of the groups.

The NewState parameter can list groups to be changed that are not present in the access token. This does not affect the successful modification of the groups in the token.

Mandatory groups cannot be disabled. They are identified by the SE_GROUP_MANDATORY attribute in the TOKEN_GROUPS structure. If an attempt is made to disable any mandatory groups, AdjustTokenGroups fails and leaves the state of all groups unchanged.

You cannot enable a group that has the SE_GROUP_USE_FOR_DENY_ONLY attribute.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AdjustTokenPrivileges, GetTokenInformation, OpenProcessToken, OpenThreadToken, SetTokenInformation, TOKEN_GROUPS


AdjustTokenPrivileges

The AdjustTokenPrivileges function enables or disables privileges in the specified access token. Enabling or disabling privileges in an access token requires TOKEN_ADJUST_PRIVILEGES access.

BOOL AdjustTokenPrivileges(
  HANDLE TokenHandle,  // handle to token that contains privileges
  BOOL DisableAllPrivileges,
                       // flag for disabling all privileges
  PTOKEN_PRIVILEGES NewState,
                       // pointer to new privilege information
  DWORD BufferLength,  // size, in bytes, of the PreviousState buffer
  PTOKEN_PRIVILEGES PreviousState,
                       // receives original state of changed
                       // privileges
  PDWORD ReturnLength  // receives required size of the
                       // PreviousState buffer
);

Parameters

TokenHandle
Identifies the access token that contains the privileges to be modified. The handle must have TOKEN_ADJUST_PRIVILEGES access to the token. If the PreviousState parameter is not NULL, the handle must also have TOKEN_QUERY access.
DisableAllPrivileges
Specifies whether the function disables all of the token's privileges. If this value is TRUE, the function disables all privileges and ignores the NewState parameter. If it is FALSE, the function modifies privileges based on the information pointed to by the NewState parameter.
NewState
Pointer to a TOKEN_PRIVILEGES structure that specifies an array of privileges and their attributes. If the DisableAllPrivileges parameter is FALSE, AdjustTokenPrivileges enables or disables these privileges for the token. If you set the SE_PRIVILEGE_ENABLED attribute for a privilege, the function enables that privilege; otherwise, it disables the privilege.

If DisableAllPrivileges is TRUE, the function ignores this parameter.

BufferLength
Specifies the size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be NULL if the PreviousState parameter is NULL.
PreviousState
Pointer to a buffer that the function fills with a TOKEN_PRIVILEGES structure containing the previous state of any privileges the function modifies. This parameter can be NULL.

If you specify a buffer that is too small to receive the complete list of modified privileges, the function fails and does not adjust any privileges. In this case, the function sets the variable pointed to by the ReturnLength parameter to the number of bytes required to hold the complete list of modified privileges.

ReturnLength
Pointer to a variable that receives the required size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be NULL if PreviousState is NULL.

Return Values

If the function succeeds, the return value is nonzero. To determine whether the function adjusted all of the specified privileges, call GetLastError, which returns one of the following values when the function succeeds:

Value | Description
ERROR_SUCCESS | The function adjusted all specified privileges.
ERROR_NOT_ALL_ASSIGNED | The token does not have one or more of the privileges specified in the NewState parameter. The function may succeed with this error value even if no privileges were adjusted. The PreviousState parameter indicates the privileges that were adjusted.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The AdjustTokenPrivileges function cannot add new privileges to the access token. It can only enable or disable the token's existing privileges. To determine the token's privileges, call the GetTokenInformation function.

Note that the NewState parameter can specify privileges that the token does not have, without causing the function to fail. In this case, the function adjusts the privileges that the token does have, ignores the other privileges, and returns success. Call the GetLastError function to determine whether the function adjusted all of the specified privileges. The PreviousState parameter indicates the privileges that were adjusted.

The PreviousState parameter retrieves a TOKEN_PRIVILEGES structure containing the the original state of the adjusted privileges. To restore the original state, pass the PreviousState pointer as the NewState parameter in a subsequent call to the AdjustTokenPrivileges function

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AdjustTokenGroups, GetTokenInformation, OpenProcessToken, OpenThreadToken, SetTokenInformation, TOKEN_PRIVILEGES


AllocateAndInitializeSid

The AllocateAndInitializeSid function allocates and initializes a security identifier (SID) with up to eight subauthorities.

BOOL AllocateAndInitializeSid(
  PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
                            // pointer to identifier authority
  BYTE nSubAuthorityCount,  // count of subauthorities
  DWORD dwSubAuthority0,    // subauthority 0
  DWORD dwSubAuthority1,    // subauthority 1
  DWORD dwSubAuthority2,    // subauthority 2
  DWORD dwSubAuthority3,    // subauthority 3
  DWORD dwSubAuthority4,    // subauthority 4
  DWORD dwSubAuthority5,    // subauthority 5
  DWORD dwSubAuthority6,    // subauthority 6
  DWORD dwSubAuthority7,    // subauthority 7
  PSID *pSid                // pointer to pointer to SID
);

Parameters

pIdentifierAuthority
Pointer to an SID_IDENTIFIER_AUTHORITY structure, giving the top-level identifier authority value to set in the SID.
nSubAuthorityCount
Specifies the number of subauthorities to place in the SID. This parameter also identifies how many of the subauthority parameters have meaningful values. This parameter must contain a value from 1 through 8.

For example, a value of 3 indicates that the subauthority values specified by the dwSubAuthority0, dwSubAuthority1, and dwSubAuthority2 parameters have meaningful values and to ignore the remainder.

dwSubAuthority0 through dwSubAuthority7
Specify subauthority values to place in the SID.
pSid
Pointer to a variable that receives the pointer to the allocated and initialized SID structure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

An SID allocated with the AllocateAndInitializeSid function must be freed by using the FreeSid function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, FreeSid, GetSidIdentifierAuthority, InitializeSid, SID_IDENTIFIER_AUTHORITY


AllocateLocallyUniqueId

The AllocateLocallyUniqueId function allocates a locally unique identifier (LUID).

BOOL AllocateLocallyUniqueId(
  PLUID Luid     // address of locally unique identifier
);

Parameters

Luid
Pointer to a buffer that receives the allocated LUID.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

An LUID is unique only within a single session. The same LUID value can be used on different computers or on the same computer after it has been restarted.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, LookupPrivilegeValue


BuildImpersonateExplicitAccessWithName

Obsolete; do not use.

See Also

Access Control Overview, Access Control Functions


BuildImpersonateTrustee

Obsolete; do not use.

See Also

Access Control Overview, Access Control Functions


BuildTrusteeWithName

The BuildTrusteeWithName function initializes a TRUSTEE structure. The caller specifies the trustee name. The function sets other members of the structure to default values.

VOID BuildTrusteeWithName(
  PTRUSTEE pTrustee,  // pointer to the structure to initialize
  LPTSTR pName        // name of the trustee to put in the structure
);

Parameters

pTrustee
Pointer to a TRUSTEE structure to initialize. The BuildTrusteeWithName function does not allocate any memory. If this parameter is NULL, the function does nothing.
pName
Pointer to a null-terminated string that contains the name of the trustee for the ptstrName member of the TRUSTEE structure. The BuildTrusteeWithName function sets the other members of the TRUSTEE structure as follows:
Member | Value
pMultipleTrustee | NULL
MultipleTrusteeOperation | NO_MULTIPLE_TRUSTEE
TrusteeForm | TRUSTEE_IS_NAME
TrusteeType | TRUSTEE_IS_UNKNOWN

Return Values

None.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, BuildTrusteeWithSid, TRUSTEE


BuildTrusteeWithSid

The BuildTrusteeWithSid function initializes a TRUSTEE structure. The caller specifies the security identifier (SID) of the trustee. The function sets other members of the structure to default values. The function does not look up the name associated with the SID.

VOID BuildTrusteeWithSid(
  PTRUSTEE pTrustee,  // pointer to the structure to initialize
  PSID pSid           // name of the trustee to put in the structure
);

Parameters

pTrustee
Pointer to a TRUSTEE structure to initialize. The BuildTrusteeWithSid function does not allocate any memory. If this parameter is NULL, the function does nothing.
pSid
Pointer to a SID that identifies the trustee. The BuildTrusteeWithSid function assigns this pointer to the ptstrName member of the TRUSTEE structure. The function sets the other members of the TRUSTEE structure as follows:
Member | Value
pMultipleTrustee | NULL
MultipleTrusteeOperation | NO_MULTIPLE_TRUSTEE
TrusteeForm | TRUSTEE_IS_SID
TrusteeType | TRUSTEE_IS_UNKNOWN

Return Values

None.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, BuildTrusteeWithName, TRUSTEE


CancelOverlappedAccess

[This is preliminary documentation and subject to change.]

The CancelOverlappedAccess function cancels an asynchronous operation started by the SetSecurityInfoEx or SetNamedSecurityInfoEx functions.

DWORD CancelOverlappedAccess(
  PACTRL_OVERLAPPED pOverlapped  // pointer to the structure filled
                                 // in by the asynchronous call
);

Parameters

pOverlapped
Pointer to the ACTRL_OVERLAPPED structure that was filled in by the SetSecurityInfoEx or SetNamedSecurityInfoEx call that started the asynchronous operation.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
ERROR_CANCEL_IN_PROGRESS | A cancel is currently in progress and cannot be restarted.
ERROR_INVALID_PARAMETER | The pOverlapped parameter is invalid.
ERROR_OPERATION_ABORTED | The asynchronous operation has already been canceled.

Remarks

If the CancelOverlappedAccess function is successful, the pOverlapped structure is no longer valid for GetOverlappedAccessResults or CancelOverlappedAccess calls.

The SetSecurityInfoEx or SetNamedSecurityInfoEx functions can start an asynchronous operation that sets the security on multiple objects, such as on a container object and the objects it contains. If such an operation is canceled, some of the objects might have the new security state while other objects remain in their original security state. In this case, an administrator must examine the objects to determine the appropriate action depending on their states.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, ACTRL_OVERLAPPED, GetOverlappedAccessResults, SetSecurityInfoEx, SetNamedSecurityInfoEx


ConvertAccessToSecurityDescriptor

[This is preliminary documentation and subject to change.]

The ConvertAccessToSecurityDescriptor function creates a self-relative security descriptor and initializes it from the specified security information.

DWORD ConvertAccessToSecurityDescriptor(
  PACTRL_ACCESS pAccessList,
                    // pointer to the access-control information
  PACTRL_AUDIT pAuditList,
                    // pointer to the audit-control information
  LPCTSTR lpOwner,  // name of the object's owner
  LPCTSTR lpGroup,  // name of the object's primary group
  PSECURITY_DESCRIPTOR *ppSecDescriptor
                    // receives a pointer to the new security
                    // descriptor
);

Parameters

pAccessList
Pointer to an ACTRL_ACCESS structure that specifies information for the DACL of the security descriptor.
pAuditList
Pointer to an ACTRL_AUDIT structure that specifies information for the SACL of the security descriptor.
lpOwner
Pointer to a null-terminated string containing the name of the owner for the security descriptor. The function attempts to convert the name to an SID.
lpGroup
Pointer to a null-terminated string containing the name of the primary group for the security descriptor. The function attempts to convert the name to an SID.
ppSecDescriptor
Pointer to a variable that receives a pointer to a self-relative security descriptor. Call the LocalFree function to free the returned buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
ERROR_NOT_ENOUGH_MEMORY | A memory allocation failed.
ERROR_INVALID_PARAMETER | An invalid parameter was specified.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, ACTRL_ACCESS, ACTRL_AUDIT, ConvertSecurityDescriptorToAccess, ConvertSecurityDescriptorToAccessNamed, LocalFree


CheckTokenMembership

[This is preliminary documentation and subject to change.]

The CheckTokenMembership function determines whether a specified SID is enabled in an access token.

BOOL CheckTokenMembership(
  HANDLE TokenHandle,  // handle to an access token
  PSID SidToCheck,     // SID to check for
  PBOOL IsMember       // receives results of the check
);

Parameters

TokenHandle
Handle to an access token. The handle must have TOKEN_QUERY access to the token. The token must be an impersonation token.

If TokenHandle is NULL, CheckTokenMembership uses the impersonation token of the calling thread. If the thread is not impersonating, the function duplicates the thread's primary token to create an impersonation token.

SidToCheck
Pointer to a SID. CheckTokenMembership checks for the presence of this SID in the user and group SIDs of the access token.
IsMember
Pointer to a BOOL variable that receives the results of the check. If the SID is present and has the SE_GROUP_ENABLED attribute, IsMember returns TRUE; otherwise, it returns FALSE.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The CheckTokenMembership function simplifies the process of determining whether a SID is both present and enabled in an access token.

Just because a SID is present in the token, doesn't mean that the system will use it in an access check. The SID may be disabled or have the SE_GROUP_USE_FOR_DENY_ONLY attribute. The system uses only enabled SIDs to grant access when performing an access check. For more information, see SID Attributes in an Access Token.

If TokenHandle is a restricted token, or if TokenHandle is NULL and the current effective token of the calling thread is a restricted token, CheckTokenMembership also checks whether the SID is present in the list of restricting SIDs.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AccessCheck, CreateRestrictedToken


ConvertSecurityDescriptorToAccess

[This is preliminary documentation and subject to change.]

The ConvertSecurityDescriptorToAccess function retrieves the security information from a specified security descriptor. The function converts the security descriptor's SIDs and ACLs into name strings and data structures that you can use with the access-control functions introduced for Windows NT version 5.0.

For security descriptors that contain object-specific ACEs, you can specify the handle and type of the object associated with the security descriptor. The function uses the handle to retrieve display names for the GUIDs in any object-specific ACEs.

DWORD ConvertSecurityDescriptorToAccess(
  HANDLE hObject,             // handle to the associated object
  SE_OBJECT_TYPE ObjectType,  // type of object
  PSECURITY_DESCRIPTOR pSecDescriptor,
                              // pointer to a security descriptor
  PACTRL_ACCESS *ppAccessList,
                    // receives a pointer to access-control info
  PACTRL_AUDIT *ppAuditList,
                    // receives a pointer to audit-control info
  LPTSTR *lppOwner, // receives the name of the object's owner
  LPTSTR *lppGroup  // receives the name of the object's primary group
);

Parameters

hObject
A handle to the object associated with the pSecDescriptor security descriptor. The function uses the handle to retrieve display names for the GUIDs in any object-specific ACEs. If this handle is NULL, the returned access-control structures contain the GUIDs in string format rather than the display names of the objects associated with the GUIDs.

If the ACLs in the security descriptor do not contain object specific ACEs, the hObject and ObjectType parameters are ignored.

ObjectType
Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object identified by the hObject parameter.
pSecDescriptor
Pointer to the security descriptor from which to retrieve security information.
ppAccessList
Pointer to a variable that receives a pointer to an ACTRL_ACCESS structure that describes the security descriptor's DACL. This parameter can be NULL if you do not need the DACL information. Call the LocalFree function to free the returned buffer.
ppAuditList
Pointer to a variable that receives a pointer to an ACTRL_AUDIT structure that describes the security descriptor's SACL. This parameter can be NULL if you do not need the SACL information. Call the LocalFree function to free the returned buffer.
lppOwner
Pointer to a variable that receives a pointer to a null-terminated string containing the name of the object's owner. This parameter can be NULL if you do not need the information. Call the LocalFree function to free the returned buffer.
lppGroup
Pointer to a variable that receives a pointer to a null-terminated string containing the name of the object's primary group. This parameter can be NULL if you do not need the information. Call the LocalFree function to free the returned buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
ERROR_NOT_ENOUGH_MEMORY | A memory allocation failed.
ERROR_INVALID_PARAMETER | An invalid parameter was specified.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, ACTRL_ACCESS, ACTRL_AUDIT, ConvertAccessToSecurityDescriptor, ConvertSecurityDescriptorToAccessNamed, LocalFree


ConvertSecurityDescriptorToAccessNamed

[This is preliminary documentation and subject to change.]

The ConvertSecurityDescriptorToAccessNamed function retrieves the security information from a specified security descriptor. The function converts the security descriptor's SIDs and ACLs into name strings and data structures that you can use with the access-control functions introduced for Windows NT version 5.0.

For security descriptors that contain object-specific ACEs, you can specify the name and type of the object associated with the security descriptor. The function uses the object's name to retrieve display names for the GUIDs in any object-specific ACEs.

DWORD ConvertSecurityDescriptorToAccessNamed(
  LPCTSTR lpObject,           // name of the associated object
  SE_OBJECT_TYPE ObjectType,  // type of object
  PSECURITY_DESCRIPTOR pSecDescriptor,
                    // pointer to the object's security descriptor
  PACTRL_ACCESS *ppAccessList,
                    // receives a pointer to access-control info
  PACTRL_AUDIT *ppAuditList,
                    // receives a pointer to audit-control info
  LPTSTR *lppOwner, // receives the name of the object's owner
  LPTSTR *lppGroup  // receives the name of the object's primary group
);

Parameters

lpObject
Pointer to a null-terminated string that specifies the name of the object associated with the pSecDescriptor security descriptor. For descriptions of the string formats for the different object types, see SE_OBJECT_TYPE.

The function accesses the object to retrieve display names for the GUIDs in any object-specific ACEs. If lpObject is NULL, the returned access-control structures contain the GUIDs in string format rather than the display names of the objects associated with the GUIDs.

If the ACLs in the security descriptor do not contain object specific ACEs, the lpObject and ObjectType parameters are ignored.

ObjectType
Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object identified by the lpObject parameter.
pSecDescriptor
Pointer to the security descriptor from which to retrieve security information.
ppAccessList
Pointer to a variable that receives a pointer to an ACTRL_ACCESS structure that describes the security descriptor's DACL. Call the LocalFree function to free the returned buffer. This parameter can be NULL if you do not need the DACL information.
ppAuditList
Pointer to a variable that receives a pointer to an ACTRL_AUDIT structure that describes the security descriptor's SACL. Call the LocalFree function to free the returned buffer. This parameter can be NULL if you do not need the SACL information.
lppOwner
Pointer to a variable that receives a pointer to a null-terminated string containing the name of the object's owner. Call the LocalFree function to free the returned buffer. This parameter can be NULL if you do not need the information.
lppGroup
Pointer to a variable that receives a pointer to a null-terminated string containing the name of the object's primary group. Call the LocalFree function to free the returned buffer. This parameter can be NULL if you do not need the information.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
ERROR_NOT_ENOUGH_MEMORY | A memory allocation failed.
ERROR_INVALID_PARAMETER | An invalid parameter was specified.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, ACTRL_ACCESS, ACTRL_AUDIT, ConvertAccessToSecurityDescriptor, ConvertSecurityDescriptorToAccess, LocalFree


CopySid

The CopySid function copies a security identifier (SID) to a buffer.

BOOL CopySid(
  DWORD nDestinationSidLength,  // size of buffer for copied SID
  PSID pDestinationSid,         // pointer to buffer for copied SID
  PSID pSourceSid               // pointer to source SID
);

Parameters

nDestinationSidLength
Specifies the length, in bytes, of the buffer receiving the copy of the SID.
pDestinationSid
Pointer to a buffer receiving a copy of the source SID structure.
pSourceSid

Pointer to a SID structure the function copies to the buffer pointed to by the pDestinationSid parameter.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

An application can use the CopySid function to make a copy of a SID in an access token (in a TOKEN_GROUPS structure, for instance) to use in an access-control entry.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AllocateAndInitializeSid, EqualSid, GetLengthSid, GetSidIdentifierAuthority, GetSidLengthRequired, GetSidSubAuthority, GetSidSubAuthorityCount, InitializeSid, IsValidSid, SID


CreateRestrictedToken

[This is preliminary documentation and subject to change.]

The CreateRestrictedToken function creates a new access token that is a restricted version of an existing access token.

BOOL CreateRestrictedToken(
  HANDLE ExistingTokenHandle,   // handle to existing token
  DWORD Flags,       // flags to delete all privileges
                     // or apply the deny-only attribute to all SIDs
  DWORD DisableSidCount,              // number of deny-only SIDs
  PSID_AND_ATTRIBUTES SidsToDisable,  // array of deny-only SIDs
  DWORD DeletePrivilegeCount,   // number of privileges to delete
  PLUID_AND_ATTRIBUTES PrivilegesToDelete,  // privileges to delete
  DWORD RestrictedSidCount,     // number of restricting SIDs
  PSID_AND_ATTRIBUTES SidsToRestrict,  // array of restricting SIDs
  PHANDLE NewTokenHandle        // receives handle to new token
);

Parameters

ExistingTokenHandle
Handle to a primary or impersonation token. The token can also be a restricted token. The handle must have TOKEN_DUPLICATE access to the token.
Flags
A set of bit flags you can use to delete all privileges or apply the deny-only attribute to all SIDs in the new token. This parameter can be zero, or it can be a combination of the following flags.
Flag Meaning
DELETE_MAX_PRIVILEGES Deletes all privileges in the new token.

If this flag is specified, the DeletePrivilegeCount and PrivilegesToDelete parameters are ignored.
DISABLE_MAX_SIDS Applies the deny-only attribute to the user SID and all group SIDs in the new token. The system uses a deny-only SID to deny access to a securable object, but not to allow access.

If this flag is specified, the DisableSidCount and SidsToDisable parameters are ignored.

DisableSidCount
Specifies the number of entries in the SidsToDisable array.
SidsToDisable
Pointer to an array of SID_AND_ATTRIBUTES structures that specify the deny-only SIDs in the restricted token. The system uses a deny-only SID to deny access to a securable object, but not to allow access.

You can apply the deny-only attribute to any combination of the existing token's SIDs, including the user SID and group SIDs that have the SE_GROUP_MANDATORY attribute. To get the SIDs associated with the existing token, use the GetTokenInformation function with the TokenUser and TokenGroups flags. The function ignores any SIDs in the array that are not also found in the existing token.

The function ignores the Attributes members of the SID_AND_ATTRIBUTES structures.

This parameter can be NULL if you don't want to disable any SIDs.

DeletePrivilegeCount
Specifies the number of entries in the PrivilegesToDelete array.
PrivilegesToDelete
Pointer to an array of LUID_AND_ATTRIBUTES structures that specify the privileges to delete in the restricted token.

You can use the GetTokenInformation function with the TokenPrivileges flag to get the privileges held by the existing token. The function ignores any privileges in the array that are not held by the existing token.

The function ignores the Attributes members of the LUID_AND_ATTRIBUTES structures.

This parameter can be NULL if you don't want to delete any privileges.

RestrictedSidCount
Specifies the number of entries in the SidsToRestrict array.
SidsToRestrict
Pointer to an array of SID_AND_ATTRIBUTES structures that specify a list of restricting SIDs for the new token. If the existing token is a restricted token, the list of restricting SIDs for the new token is the intersection of this array and the list of restricting SIDs for the existing token.

The Attributes members of the SID_AND_ATTRIBUTES structures must be zero. Restricting SIDs are always enabled for access checks.

This parameter can be NULL if you don't want to specify any restricting SIDs.

NewTokenHandle
Pointer to a variable that receives a handle to the new restricted token. This handle has the same access rights as ExistingTokenHandle. The new token is the same type, primary or impersonation, as the existing token. The handle returned in NewTokenHandle can be duplicated.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The CreateRestrictedToken function can restrict the token in the following ways:

  • Apply the deny-only attribute to SIDs in the token so they cannot be used to access secured objects. For more information about the deny-only attribute, see SID Attributes in an Access Token.
  • Remove privileges from the token.
  • Specify a list of restricting SIDs, which the system uses when it checks the token's access to a securable object. The system performs two access checks: one using the token's enabled SIDs, and another using the list of restricting SIDs. Access is granted only if both access checks allow the requested access rights.

You can use the restricted token in the CreateProcessAsUser function to create a process that has restricted access rights and privileges. If a process calls CreateProcessAsUser using a restricted version of its own token, the calling process does not need to have the SE_ASSIGNPRIMARYTOKEN_NAME privilege.

You can use the restricted token in the ImpersonateLoggedOnUser function.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, CreateProcessAsUser, GetTokenInformation, ImpersonateLoggedOnUser, IsTokenRestricted, LUID_AND_ATTRIBUTES, SID_AND_ATTRIBUTES


DuplicateToken

The DuplicateToken function creates a new access token that duplicates one already in existence.

BOOL DuplicateToken(
  HANDLE ExistingTokenHandle,    // handle to token to duplicate
  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
                                 // impersonation level
  PHANDLE DuplicateTokenHandle   // handle to duplicated token
);

Parameters

ExistingTokenHandle
Identifies an access token opened with TOKEN_DUPLICATE access.
ImpersonationLevel
Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that supplies the impersonation level of the new token.
DuplicateTokenHandle
Pointer to a variable that receives the handle of the duplicate token. This handle has TOKEN_IMPERSONATE and TOKEN_QUERY access to the new token.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The DuplicateToken function creates an impersonation token, which you can use in functions such as SetThreadToken and ImpersonateLoggedOnUser. The token created by DuplicateToken cannot be used in the CreateProcessAsUser function, which requires a primary token. To create a token that you can pass to CreateProcessAsUser, use the DuplicateTokenEx function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, CreateProcessAsUser, DuplicateTokenEx, ImpersonateLoggedOnUser, SECURITY_IMPERSONATION_LEVEL, SetThreadToken


DuplicateTokenEx

The DuplicateTokenEx function creates a new access token that duplicates an existing token. This function can create either a primary token or an impersonation token.

BOOL DuplicateTokenEx(
  HANDLE hExistingToken, // handle to token to duplicate
  DWORD dwDesiredAccess, // access rights of new token
  LPSECURITY_ATTRIBUTES lpTokenAttributes,
                         // security attributes of the new token
  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
                         // impersonation level of new token
  TOKEN_TYPE TokenType,  // primary or impersonation token
  PHANDLE phNewToken     // handle to duplicated token
);

Parameters

hExistingToken
Identifies an access token opened with TOKEN_DUPLICATE access.
dwDesiredAccess
Specifies the requested access rights for the new token. The DuplicateTokenEx function compares the requested access rights with the existing token's discretionary access-control list (ACL) to determine which rights are granted or denied. To request the same access rights as the existing token, specify zero. To request all access rights that are valid for the caller, specify MAXIMUM_ALLOWED. Otherwise, specify a combination of the following access rights.
Value | Meaning
TOKEN_ADJUST_DEFAULT | Required to change the default ACL, primary group, or owner of an access token.
TOKEN_ADJUST_GROUPS | Required to change the groups specified in an access token.
TOKEN_ADJUST_PRIVILEGES | Required to change the privileges specified in an access token.
TOKEN_ALL_ACCESS | Combines the STANDARD_RIGHTS_REQUIRED standard access rights and all individual access rights for tokens.
TOKEN_ASSIGN_PRIMARY | Required to attach a primary token to a process in addition to the SE_CREATE_TOKEN_NAME privilege.
TOKEN_DUPLICATE | Required to duplicate an access token.
TOKEN_EXECUTE | Combines the STANDARD_RIGHTS_EXECUTE standard access rights and the TOKEN_IMPERSONATE access right.
TOKEN_IMPERSONATE | Required to attach an impersonation access token to a process.
TOKEN_QUERY | Required to query the contents of an access token.
TOKEN_QUERY_SOURCE | Required to query the source of an access token.
TOKEN_READ | Combines the STANDARD_RIGHTS_READ standard access rights and the TOKEN_QUERY access right.
TOKEN_WRITE | Combines the STANDARD_RIGHTS_WRITE standard access rights and the TOKEN_ADJUST_PRIVILEGES, TOKEN_ADJUST_GROUPS, and TOKEN_ADJUST_DEFAULT access rights.

lpTokenAttributes
Pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new token and determines whether child processes can inherit the token. If lpTokenAttributes is NULL, the token gets a default security descriptor and the handle cannot be inherited.
ImpersonationLevel
Specifies a value from the SECURITY_IMPERSONATION_LEVEL enumeration that indicates the impersonation level of the new token.
TokenType
Specifies one of the following values from the TOKEN_TYPE enumeration.
Value | Meaning
TokenPrimary | The new token is a primary token that you can use in the CreateProcessAsUser function.
TokenImpersonation | The new token is an impersonation token.

phNewToken
Pointer to a HANDLE variable that receives the new token.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The DuplicateTokenEx function allows you to create a primary token that you can use in the CreateProcessAsUser function. This allows a server application that is impersonating a client to create a process that has the security context of the client. Note that the DuplicateToken function can create only impersonation tokens, which are not valid for CreateProcessAsUser.

The following is a typical scenario for using DuplicateTokenEx to create a primary token. A server application creates a thread that calls one of the impersonation functions, such as ImpersonateNamedPipeClient, to impersonate a client. The impersonating thread then calls the OpenThreadToken function to get its own token, which is an impersonation token that has the security context of the client. The thread specifies this impersonation token in a call to DuplicateTokenEx, specifying the TokenPrimary flag. DuplicateTokenEx creates a primary token that has the security context of the client.

When you have finished using the new token, call the CloseHandle function to close the token handle.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, CloseHandle, CreateProcessAsUser, DdeImpersonateClient, DuplicateToken, ImpersonateNamedPipeClient, OpenThreadToken, RevertToSelf, RpcImpersonateClient, SECURITY_ATTRIBUTES, SECURITY_IMPERSONATION_LEVEL


EqualPrefixSid

The EqualPrefixSid function tests two security-identifier (SID) prefix values for equality. A SID prefix is the entire SID except for the last subauthority value.

BOOL EqualPrefixSid(
  PSID pSid1,  // pointer to first SID to compare
  PSID pSid2   // pointer to second SID to compare
);

Parameters

pSid1
Pointer to the first SID structure to compare. This structure is assumed to be valid.
pSid2
Pointer to the second SID structure to compare. It also is assumed to be valid.

Return Values

If the SID prefixes are equal, the return value is nonzero.

If the SID prefixes are not equal, the return value is zero. To get extended error information, call GetLastError.

Remarks

The EqualPrefixSid function enables a server application in one domain to verify an attempt by a user to log on to another domain. For example, if a user attempts to log on to RemoteDomain from a workstation in LocalDomain, the server for LocalDomain can request the SIDs for the user and the user's groups from RemoteDomain. The domain controller for RemoteDomain responds with the relevant SIDs.

All SIDs for a specified domain necessarily have the same prefix. When the server receives the user's SIDs, it can call the EqualPrefixSid function for each SID, comparing the user or group SID against the SID for RemoteDomain. If any of the SID prefixes are not equal, the server refuses the logon attempt.

It is advisable to modify the SID for a domain before comparing it with a group or user SID. If the SID for RemoteDomain is S-1–1234–8, each group or user SID for that domain will have S-1–1234–8 as its prefix. To compare the SIDs by using the EqualPrefixSid function, an application copies the domain SID and adds any subauthority (RID) value to the copy, thereby creating a SID in the form S-1–1234–8–0. The application then uses the modified domain SID as a template against which the group and user SIDs are compared.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, CopySid, EqualSid, IsValidSid, SID


EqualSid

The EqualSid function tests two security identifier (SID) values for equality. Two SIDs must match exactly to be considered equal.

BOOL EqualSid(
  PSID pSid1,  // pointer to first SID to compare
  PSID pSid2   // pointer to second SID to compare
);

Parameters

pSid1
Pointer to the first SID structure to compare. This structure is assumed to be valid.
pSid2
Pointer to the second SID structure to compare. It also is assumed to be valid.

Return Values

If the SID structures are equal, the return value is nonzero.

If the SID structures are not equal, the return value is zero. To get extended error information, call GetLastError.

If either SID structure is invalid, the return value is undefined.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, EqualPrefixSid, IsValidSid, SID


FreeSid

The FreeSid function frees a security identifier (SID) previously allocated by using the AllocateAndInitializeSid function.

PVOID FreeSid(
  PSID pSid   // pointer to SID to free
);

Parameters

pSid
Pointer to the SID structure to free.

Return Values

This function does not return a value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AllocateAndInitializeSid, SID


GetLengthSid

The GetLengthSid function returns the length, in bytes, of a valid SID structure. A SID is a security identifier.

DWORD GetLengthSid(
  PSID pSid   // address of SID to query
);

Parameters

pSid
Pointer to the SID structure whose length is returned. The structure is assumed to be valid.

Return Values

If the SID structure is valid, the return value is the length, in bytes, of the SID structure.

If the SID structure is not valid, the return value is undefined. Before calling GetLengthSid, pass the SID to the IsValidSid function to verify that it is valid.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetSidLengthRequired, GetSidSubAuthorityCount, IsValidSid, SID


GetMultipleTrustee

Obsolete; do not use.

See Also

Access Control Overview, Access Control Functions


GetMultipleTrusteeOperation

Obsolete; do not use.

See Also

Access Control Overview, Access Control Functions


GetNamedSecurityInfoEx

[This is preliminary documentation and subject to change.]

The GetNamedSecurityInfoEx function retrieves security information for an object identified by a name. The function can also retrieve object-specific access-control and audit-control information. GetNamedSecurityInfoEx uses provider-independent access flags, which enables it to retrieve security information for objects on systems other than Windows NT.

DWORD GetNamedSecurityInfoEx(
  LPCTSTR lpObject,    // name of the object
  SE_OBJECT_TYPE ObjectType,
                       // type of object
  SECURITY_INFORMATION SecurityInfo,
                       // type of security information to retrieve
  LPCTSTR lpProvider,  // name of provider to handle request
  LPCTSTR lpProperty,  // identifies a property, property set, or
                       // child object
  PACTRL_ACCESS *ppAccessList,
                       // receives a pointer to access-control info
  PACTRL_AUDIT *ppAuditList,
                       // receives a pointer to audit-control info
  LPTSTR *lppOwner,    // receives the name of the object's owner
  LPTSTR *lppGroup     // receives the name of the object's primary
                       // group
);

Parameters

lpObject
Pointer to a null-terminated string that specifies the name of the object from which to retrieve security information. For descriptions of the string formats for the different object types, see SE_OBJECT_TYPE.
ObjectType
Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object named by the lpObject parameter.
SecurityInfo
A set of SECURITY_INFORMATION bit flags that indicate the type of security information to retrieve. This parameter can be a combination of the following values.
Value | Meaning
OWNER_SECURITY_INFORMATION | If this flag is set, the lppOwner pointer receives a pointer to a null-terminated string that names the object's owner.
GROUP_SECURITY_INFORMATION | If this flag is set, the lppGroup pointer receives a pointer to a null-terminated string that names the object's primary group.
DACL_SECURITY_INFORMATION | If this flag is set, the ppAccessList pointer receives a pointer to a structure that describes DACL information for the object or for the sub-object identified by the lpProperty parameter.
SACL_SECURITY_INFORMATION | If this flag is set, the ppAuditList pointer receives a pointer to a structure that describes SACL information for the object or for the sub-object identified by the lpProperty parameter.

lpProvider
Pointer to a null-terminated string that specifies the name of the provider to handle the request. If this parameter is NULL, the system determines the proper provider to handle the request.
lpProperty
Pointer to a null-terminated string that identifes the type of child object, property set, or property for which to retrieve object-specific access-control and audit-control information. This string can be the display name of the object, or it can be a string representation of the GUID that identifies the object. You can use the UuidToString function to generate a string representation of a GUID.

If this parameter is NULL, the function retrieves information for the object itself. For object types that do not support object-specific ACEs, set lpProperty to NULL.

If ObjectType specifies SE_DS_OBJECT_ALL, lpProperty is ignored and the function retrieves all the DACL and SACL information for the specified DS object.

ppAccessList
Pointer to a variable that receives a pointer to an ACTRL_ACCESS structure. The structure describes discretionary access-control information for the object or for the sub-object identified by the lpProperty parameter. The returned pointer is valid only if you set the DACL_SECURITY_INFORMATION flag. Call the LocalFree function to free the returned buffer. This parameter can be NULL if you do not need the DACL information.
ppAuditList
Pointer to a variable that receives a pointer to an ACTRL_AUDIT structure. The structure describes system access-control information for the object or for the sub-object identified by the lpProperty parameter. The returned pointer is valid only if you set the SACL_SECURITY_INFORMATION flag. Call the LocalFree function to free the returned buffer. This parameter can be NULL if you do not need the SACL information.
lppOwner
Pointer to a variable that receives a pointer to a null-terminated string containing the name of the object's owner. The returned pointer is valid only if you set the OWNER_SECURITY_INFORMATION flag. Call the LocalFree function to free the returned buffer. This parameter can be NULL if you do not need the information.
lppGroup
Pointer to a variable that receives a pointer to a null-terminated string containing the name of the object's primary group. The returned pointer is valid only if you set the GROUP_SECURITY_INFORMATION flag. Call the LocalFree function to free the returned buffer. This parameter can be NULL if you do not need the information.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
ERROR_BAD_PROVIDER | The lpProvider parameter specified an invalid provider name.
ERROR_INVALID_PARAMETER | An invalid parameter was specified.
ERROR_NOT_ENOUGH_MEMORY | A memory allocation failed

Remarks

To read the owner, group, or DACL from the object's security descriptor, the object's DACL must grant READ_CONTROL access to the caller or the caller must be the owner of the object.

To read the SACL of the object, the SE_SECURITY_NAME privilege must be enabled for the calling process.

Call the LocalFree function to free any pointers returned by the ppAccessList, ppAccessList, lppOwner, or lppOwner parameters.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, ACTRL_ACCESS, ACTRL_AUDIT, ACTRL_PROPERTY_ENTRY, GetSecurityInfoEx, LocalFree, SE_OBJECT_TYPE, SECURITY_INFORMATION, SetNamedSecurityInfoEx, SetSecurityInfoEx


GetOverlappedAccessResults

[This is preliminary documentation and subject to change.]

The GetOverlappedAccessResults function returns the results of an asynchronous call to the SetSecurityInfoEx or SetNamedSecurityInfoEx functions. GetOverlappedAccessResults can wait for the asynchronous operation to be completed, or it can return immediately with the current state of the operation.

DWORD GetOverlappedAccessResults(
  PACTRL_OVERLAPPED pOverlapped,
                   // pointer to the structure filled in by the
                   // asynchronous call
  BOOL fWaitForCompletion,
                   // TRUE indicates to wait for completion
  PDWORD pResult,  // receives the result of the asynchronous
                   // operation
  PULONG pcItemsProcessed
                   // receives the number of objects processed
);

Parameters

pOverlapped
Pointer to the ACTRL_OVERLAPPED structure that was filled in by the SetSecurityInfoEx or SetNamedSecurityInfoEx call that started the asynchronous operation.
fWaitForCompletion
Flag that indicates whether GetOverlappedAccessResults returns immediately or waits for the asynchronous operation to be completed. If this value is FALSE, the function returns immediately with the current status of the operation. Otherwise, the function does not return until the operation has been completed.
pResult
Pointer to a DWORD value. If the function returns ERROR_SUCCESS, this value receives one of the following values to indicate the results of the asynchronous operation.
Value | Meaning
ERROR_SUCCESS | The operation successfully set the object's security information.
ERROR_OPERATION_ABORTED | The operation was canceled.

pcItemsProcessed
Pointer to a ULONG value. If the function returns ERROR_SUCCESS or ERROR_IO_PENDING, this value receives the number of objects for which the security information has been set. This is useful for an operation that sets the security on multiple objects, such as a container object and the objects it contains. This parameter can be NULL.

Return Values

If the asynchronous operation has been completed, the return value is ERROR_SUCCESS and the pResult parameter receives the results of the operation.

If the asynchronous operation has not been completed, the return value is ERROR_IO_PENDING.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
ERROR_BAD_PROVIDER | The asynchronous operation failed because an invalid provider name was specified.
ERROR_INVALID_PARAMETER | The pOverlapped parameter is invalid.
ERROR_NOT_ENOUGH_MEMORY | The asynchronous operation failed due to a memory allocation failure.

Remarks

The first time you call the GetOverlappedAccessResults function for a given ACTRL_OVERLAPPED structure, the function closes the handle to the event object in the structure's hEvent member. Subsequent calls to GetOverlappedAccessResults for the same ACTRL_OVERLAPPED structure identify the operation by the information stored in the reserved members of the ACTRL_OVERLAPPED structure.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, ACTRL_OVERLAPPED, CancelOverlappedAccess, SetSecurityInfoEx, SetNamedSecurityInfoEx


GetSecurityDescriptorControl

The GetSecurityDescriptorControl function retrieves a security descriptor's control and revision information.

BOOL GetSecurityDescriptorControl(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
                         // address of security descriptor
  PSECURITY_DESCRIPTOR_CONTROL pControl,
                         // address of  control structure
  LPDWORD lpdwRevision   // address of revision value
);

Parameters

pSecurityDescriptor
Pointer to a SECURITY_DESCRIPTOR structure whose control and revision information the function retrieves.
pControl
Pointer to a SECURITY_DESCRIPTOR_CONTROL structure receiving the security descriptor's control information.
lpdwRevision
Pointer to a variable receiving the security descriptor's revision value. This value is always set, even when GetSecurityDescriptorControl returns an error.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorLength, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL


GetSecurityInfoEx

[This is preliminary documentation and subject to change.]

The GetSecurityInfoEx function retrieves security information for an object identified by a handle. The function can also retrieve object-specific access-control and audit-control information. GetSecurityInfoEx uses provider-independent access flags, which enables it to retrieve security information for objects on systems other than Windows NT.

DWORD GetSecurityInfoEx(
  HANDLE hObject,      // handle to the object
  SE_OBJECT_TYPE ObjectType,
                       // type of object
  SECURITY_INFORMATION SecurityInfo,
                       // type of security information to retrieve
  LPCTSTR lpProvider,  // name of provider to handle request
  LPCTSTR lpProperty,  // identifies a property, property set, or
                       // child object
  PACTRL_ACCESS *ppAccessList,
                       // receives a pointer to access-control info
  PACTRL_AUDIT *ppAuditList,
                       // receives a pointer to audit-control info
  LPTSTR *lppOwner,    // receives the name of the object's owner
  LPTSTR *lppGroup     // receives the name of the object's primary
                       // group
);

Parameters

hObject
A handle to the object from which to retrieve security information.
ObjectType
Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object identified by the hObject parameter.
SecurityInfo
A set of SECURITY_INFORMATION bit flags that indicate the type of security information to retrieve. This parameter can be a combination of the following values.
Value | Meaning
OWNER_SECURITY_INFORMATION | If this flag is set, the lppOwner pointer receives a pointer to a null-terminated string that names the object's owner.
GROUP_SECURITY_INFORMATION | If this flag is set, the lppGroup pointer receives a pointer to a null-terminated string that names the object's primary group.
DACL_SECURITY_INFORMATION | If this flag is set, the ppAccessList pointer receives a pointer to a structure that describes DACL information for the object or for the sub-object identified by the lpProperty parameter.
SACL_SECURITY_INFORMATION | If this flag is set, the ppAuditList pointer receives a pointer to a structure that describes SACL information for the object or for the sub-object identified by the lpProperty parameter.

lpProvider
Pointer to a null-terminated string that specifies the name of the provider to handle the request. If this parameter is NULL, the system determines the proper provider to handle the request.
lpProperty
Pointer to a null-terminated string that identifes the type of child object, property set, or property for which to retrieve object-specific access-control and audit-control information. This string can be the display name of the object, or it can be a string representation of the GUID that identifies the object. You can use the UuidToString function to generate a string representation of a GUID.

If this parameter is NULL, the function retrieves information for the object itself. For object types that do not support object-specific ACEs, set lpProperty to NULL.

If ObjectType specifies SE_DS_OBJECT_ALL, lpProperty is ignored and the function retrieves all the DACL and SACL information for the specified DS object.

ppAccessList
Pointer to a variable that receives a pointer to an ACTRL_ACCESS structure. The structure describes discretionary access-control information for the object or for the sub-object identified by the lpProperty parameter. The returned pointer is valid only if you set the DACL_SECURITY_INFORMATION flag. Call the LocalFree function to free the returned buffer. This parameter can be NULL if you do not need the DACL information.
ppAuditList
Pointer to a variable that receives a pointer to an ACTRL_AUDIT structure. The structure describes system audit-control information for the object or for the sub-object identified by the lpProperty parameter. The returned pointer is valid only if you set the SACL_SECURITY_INFORMATION flag. Call the LocalFree function to free the returned buffer. This parameter can be NULL if you do not need the SACL information.
lppOwner
Pointer to a variable that receives a pointer to a null-terminated string containing the name of the object's owner. The returned pointer is valid only if you set the OWNER_SECURITY_INFORMATION flag. Call the LocalFree function to free the returned buffer. This parameter can be NULL if you do not need the information.
lppGroup
Pointer to a variable that receives a pointer to a null-terminated string containing the name of the object's primary group. The returned pointer is valid only if you set the GROUP_SECURITY_INFORMATION flag. Call the LocalFree function to free the returned buffer. This parameter can be NULL if you do not need the information.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
ERROR_NOT_ENOUGH_MEMORY | A memory allocation failed
ERROR_INVALID_PARAMETER | An invalid parameter was specified.
ERROR_BAD_PROVIDER | The lpProvider parameter specified an invalid provider name.

Remarks

To read the owner, group, or DACL from the object's security descriptor, the calling process must have been granted READ_CONTROL access when the handle was opened. To get READ_CONTROL access, the caller must be the owner of the object or the object's DACL must grant the access.

To read the SACL from the security descriptor, the calling process must have been granted ACCESS_SYSTEM_SECURITY access when the handle was opened. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

Call the LocalFree function to free any pointers returned by the ppAccessList, ppAccessList, lppOwner, or lppOwner parameters.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, ACTRL_ACCESS, ACTRL_AUDIT, ACTRL_PROPERTY_ENTRY, GetNamedSecurityInfoEx, LocalFree, SE_OBJECT_TYPE, SECURITY_INFORMATION, SetNamedSecurityInfoEx, SetSecurityInfoEx


GetSidIdentifierAuthority

The GetSidIdentifierAuthority function returns the address of the SID_IDENTIFIER_AUTHORITY structure in a specified security identifier (SID).

PSID_IDENTIFIER_AUTHORITY GetSidIdentifierAuthority(
  PSID pSid   // address of SID to query
);

Parameters

pSid
Pointer to the SID structure for which the address of the SID_IDENTIFIER_AUTHORITY structure is returned.

Return Values

If the function succeeds, the return value is the address of the SID_IDENTIFIER_AUTHORITY structure for the specified SID structure.

If the function fails, the return value is undefined. The function fails if the SID structure pointed to by the pSid parameter is invalid. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetLengthSid, GetSidLengthRequired, GetSidSubAuthority, GetSidSubAuthorityCount, IsValidSid, SID, SID_IDENTIFIER_AUTHORITY


GetSidLengthRequired

The GetSidLengthRequired function returns the length, in bytes, of the buffer required to store a SID structure with a specified number of subauthorities.

DWORD GetSidLengthRequired(
  UCHAR nSubAuthorityCount   // count of subauthorities
);

Parameters

nSubAuthorityCount
Specifies the number of subauthorities to be stored in the SID structure.

Return Values

The return value is the length, in bytes, of the buffer required to store the SID structure. This function cannot fail.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AllocateAndInitializeSid, GetLengthSid, GetSidIdentifierAuthority, GetSidSubAuthority, GetSidSubAuthorityCount, InitializeSid, IsValidSid, SID


GetSidSubAuthority

The GetSidSubAuthority function returns the address of a specified subauthority in a SID structure. The subauthority value is a relative identifier (RID). A SID is a security identifier.

PDWORD GetSidSubAuthority(
  PSID pSid,            // address of security identifier to query
  DWORD nSubAuthority   // index of subauthority to retrieve
);

Parameters

pSid
Pointer to the SID structure from which the address of a subauthority is to be returned.
nSubAuthority
Specifies an index value identifying the subauthority array element whose address the function will return. The function performs no validation tests on this value. An application can call the GetSidSubAuthorityCount function to discover the range of acceptable values.

Return Values

If the function succeeds, the return value is the address of the specified SID subauthority. To get extended error information, call GetLastError.

If the function fails, the return value is undefined. The function fails if the specified SID structure is invalid or if the index value specified by the nSubAuthority parameter is out of bounds.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetLengthSid, GetSidIdentifierAuthority, GetSidLengthRequired, GetSidSubAuthorityCount, IsValidSid, SID


GetSidSubAuthorityCount

The GetSidSubAuthorityCount function returns the address of the field in a SID structure containing the subauthority count. A SID is a security identifier.

PUCHAR GetSidSubAuthorityCount(
  PSID pSid   // address of security identifier to query
);

Parameters

pSid
Pointer to the SID structure from which a pointer to the subauthority count is returned.

Return Values

If the function succeeds, the return value is a pointer to the subauthority count for the specified SID structure.

If the function fails, the return value is undefined. The function fails if the specified SID structure is invalid. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetLengthSid, GetSidIdentifierAuthority, GetSidLengthRequired, GetSidSubAuthority, IsValidSid, SID


GetTokenInformation

The GetTokenInformation function retrieves a specified type of information about an access token. The calling process must have appropriate access rights to obtain the information.

BOOL GetTokenInformation(
  HANDLE TokenHandle,       // handle of access token
  TOKEN_INFORMATION_CLASS TokenInformationClass,
                            // type of information to retrieve
  LPVOID TokenInformation,  // address of retrieved information
  DWORD TokenInformationLength,
                            // size of information buffer
  PDWORD ReturnLength       // address of required buffer size
);

Parameters

TokenHandle
Identifies an access token from which information is retrieved. If TokenInformationClass specifies TokenSource, the handle must have TOKEN_QUERY_SOURCE access. For all other TokenInformationClass values, the handle must have TOKEN_QUERY access.
TokenInformationClass
Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type identifying the type of information the function retrieves.
TokenInformation
Pointer to a buffer the function fills with the requested information. The structure put into this buffer depends upon the type of information specified by the TokenInformationClass parameter, as shown in the following list:
Token Information Class | Structure Returned
TokenUser | The buffer receives a TOKEN_USER structure containing the token's user account.
TokenGroups | The buffer receives a TOKEN_GROUPS structure containing the group accounts associated with the token.
TokenPrivileges | The buffer receives a TOKEN_PRIVILEGES structure containing the token's privileges.
TokenOwner | The buffer receives a TOKEN_OWNER structure containing the default owner SID for newly created objects.
TokenPrimaryGroup | The buffer receives a TOKEN_PRIMARY_GROUP structure containing the default primary group SID for newly created objects.
TokenDefaultDacl | The buffer receives a TOKEN_DEFAULT_DACL structure containing the default DACL for newly created objects.
TokenSource | The buffer receives a TOKEN_SOURCE structure containing the source of the token. TOKEN_QUERY_SOURCE access is needed to retrieve this information.
TokenType | The buffer receives a TOKEN_TYPE value indicating whether the token is a primary or impersonation token.
TokenImpersonationLevel | The buffer receives a SECURITY_IMPERSONATION_LEVEL value indicating the impersonation level of the token. If the access token is not an impersonation token, the function fails.
TokenStatistics | The buffer receives a TOKEN_STATISTICS structure containing various token statistics.
TokenRestrictedSids | The buffer receives a TOKEN_GROUPS structure containing the list of restricting SIDs in a restricted token.

TokenInformationLength
Specifies the size, in bytes, of the buffer pointed to by the TokenInformation parameter.
ReturnLength
Pointer to a variable receiving the actual number of bytes needed for the buffer pointed to by the TokenInformation parameter. If this value is larger than the value specified in the TokenInformationLength parameter, the function fails and stores no data in the buffer.

If the value of the TokenInformationClass parameter is TokenDefaultDacl and the token has no default DACL, the function sets the variable pointed to by ReturnLength to sizeof(TOKEN_DEFAULT_DACL) and sets the DefaultDacl member of the TOKEN_DEFAULT_DACL structure to NULL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AdjustTokenGroups, AdjustTokenPrivileges, OpenProcessToken, OpenThreadToken, SetTokenInformation, SECURITY_IMPERSONATION_LEVEL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


GetTrusteeForm

The GetTrusteeForm function retrieves the value assigned to the TrusteeForm member of a specified TRUSTEE structure. This value indicates whether the structure uses a name string or a security identifier (SID) to identify the trustee.

TRUSTEE_FORM GetTrusteeForm(
  PTRUSTEE pTrustee  // pointer to a TRUSTEE structure
);

Parameters

pTrustee
Pointer to a TRUSTEE structure.

Return Values

The return value is one of the constants from the TRUSTEE_FORM enumeration.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, GetTrusteeName, GetTrusteeType, TRUSTEE, TRUSTEE_FORM


GetTrusteeName

The GetTrusteeName function retrieves the trustee name from a TRUSTEE structure.

LPTSTR GetTrusteeName(
  PTRUSTEE pTrustee  // pointer to a TRUSTEE structure
);

Parameters

pTrustee
Pointer to a TRUSTEE structure.

Return Values

If the TrusteeForm member of the TRUSTEE structure is TRUSTEE_IS_NAME, the return value is the pointer assigned to the ptstrName member of the structure.

If the TrusteeForm member is TRUSTEE_IS_SID, the return value is NULL. The function does not look up the name associated with a security identifier (SID).

Remarks

The GetTrusteeName function does not allocate any memory.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, TRUSTEE, SID


GetTrusteeType

The GetTrusteeType function retrieves the value assigned to the TrusteeType member of a specified TRUSTEE structure. This value indicates whether the trustee is a user, a group, or the trustee type is unknown.

TRUSTEE_TYPE GetTrusteeType(
  PTRUSTEE pTrustee  // pointer to the TRUSTEE structure
);

Parameters

pTrustee
Pointer to a TRUSTEE structure.

Return Values

The return value is one of the constants from the TRUSTEE_TYPE enumeration.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, TRUSTEE, TRUSTEE_TYPE


InitializeSid

The InitializeSid function initializes a SID structure. An SID is a security identifier.

BOOL InitializeSid(
  PSID Sid,                 // address of SID to initialize
  PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
                            // address of identifier authority
  BYTE nSubAuthorityCount   // count of subauthorities
);

Parameters

Sid
Pointer to a SID structure to be initialized.
pIdentifierAuthority
Pointer to a SID_IDENTIFIER_AUTHORITY structure to set in the SID structure.
nSubAuthorityCount
Specifies the number of subauthorities to set in the SID. Values of the subauthority must be set separately, as described in the following Remarks section.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Although the InitializeSid function sets the number of subauthorities for the SID, it does not set the subauthority values. This must be done separately, using functions, such as GetSidSubAuthority.

An application can use the AllocateAndInitializeSid function to initialize a SID and set its subauthority values.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AllocateAndInitializeSid, GetLengthSid, GetSidIdentifierAuthority, GetSidLengthRequired, GetSidSubAuthority, GetSidSubAuthorityCount, IsValidSid, SID, SID_IDENTIFIER_AUTHORITY


IsTokenRestricted

[This is preliminary documentation and subject to change.]

The IsTokenRestricted function indicates whether a token contains a list of restricting SIDs.

BOOL IsTokenRestricted(
  HANDLE TokenHandle         // handle to an access token to test
);

Parameters

TokenHandle
Handle to an access token to test.

Return Values

If the token contains a list of restricting SIDs, the return value is nonzero.

If the token does not contain a list of restricting SIDs, the return value is zero.

If an error occurs, the return value is zero. To get extended error information, call GetLastError.

Remarks

The CreateRestrictedToken function can restrict a token by disabling SIDs, deleting privileges, and specifying a list of restricting SIDs. The IsTokenRestricted function checks only for the list of restricting SIDs. If a token does not have any restricting SIDs, IsTokenRestricted returns FALSE even though the token was created by a call to CreateRestrictedToken.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, CreateRestrictedToken


IsValidSid

The IsValidSid function validates a SID structure by verifying that the revision number is within a known range and that the number of subauthorities is less than the maximum. A SID is a security identifier.

BOOL IsValidSid(
  PSID pSid   // address of SID to query
);

Parameters

pSid
Pointer to the SID structure to validate. This must be a non-NULL value.

Return Values

If the SID structure is valid, the return value is nonzero.

If the SID structure is not valid, the return value is zero. There is no extended error information for this function; do not call GetLastError.

Remarks

If pSid is NULL, the application will fail with an access violation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetLengthSid, GetSidIdentifierAuthority, GetSidLengthRequired, GetSidSubAuthority, GetSidSubAuthorityCount, SID


LookupAccountName

The LookupAccountName function accepts the name of a system and an account as input. It retrieves a security identifier (SID) for the account and the name of the domain on which the account was found.

BOOL LookupAccountName(
  LPCTSTR lpSystemName,  // address of string for system name
  LPCTSTR lpAccountName, // address of string for account name
  PSID Sid,              // address of security identifier
  LPDWORD cbSid,         // address of size of security identifier
  LPTSTR ReferencedDomainName,
                         // address of string for referenced domain
  LPDWORD cbReferencedDomainName,
                         // address of size of domain string
  PSID_NAME_USE peUse    // address of SID-type indicator
);

Parameters

lpSystemName
Pointer to a null-terminated string specifying the system. This string can be the name of a remote computer. If this string is NULL, the account name is looked up on the local system.
lpAccountName
Pointer to a null-terminated string specifying the account name.
Sid
Pointer to a buffer receiving the SID structure that corresponds to the account name pointed to by the lpAccountName parameter.
cbSid
Pointer to a DWORD variable. On input, this value specifies the size, in bytes, of the Sid buffer. If the function fails because the buffer is too small, this variable receives the required buffer size.
ReferencedDomainName
Pointer to a buffer receiving the name of the domain where the account name is found.
cbReferencedDomainName
Pointer to a DWORD variable. On input, this value specifies the size, in bytes (ANSI version) or characters (Unicode version), of the ReferencedDomainName buffer. If the function fails because the buffer is too small, this variable receives the required buffer size, including the terminating null character.
peUse
Pointer to a SID_NAME_USE enumerated type indicating the type of the account when the function returns.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The LookupAccountName function attempts to find a security identifier for the specified name by first checking a list of well-known SIDs. If the name does not correspond to a well-known SID, the function checks built-in and administratively defined local accounts. Next, the function checks the primary domain. If the name is not found there, trusted domains are checked.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, EqualPrefixSid, GetUserName, LookupAccountSid


LookupAccountSid

The LookupAccountSid function accepts a security identifier (SID) as input. It retrieves the name of the account for this SID and the name of the first domain on which this SID is found.

BOOL LookupAccountSid(
  LPCTSTR lpSystemName, // address of string for system name
  PSID Sid,             // address of security identifier
  LPTSTR Name,          // address of string for account name
  LPDWORD cbName,       // address of size account string
  LPTSTR ReferencedDomainName,
                        // address of string for referenced domain
  LPDWORD cbReferencedDomainName,
                        // address of size domain string
  PSID_NAME_USE peUse   // address of structure for SID type
);

Parameters

lpSystemName
Pointer to a null-terminated string specifying the system. This string can be the name of a remote computer. If this string is NULL, the SID is looked up on the local system.
Sid
Pointer to a SID structure for which the account name is looked up.
Name
Pointer to a buffer receiving a null-terminated string representing the account name corresponding to the Sid parameter.
cbName
Pointer to a DWORD variable. On input, this value specifies the size, in bytes (ANSI version) or characters (Unicode version), of the Name buffer. If the function fails because the buffer is too small, this variable receives the required buffer size, including the terminating null character.
ReferencedDomainName
Pointer to a buffer that will receive a null-terminated string giving the name of the domain where the account name was found.

For Windows NT systems, the domain name returned for most accounts in the local computer's security database is the computer's name as of the last start of the system. Backslashes are excluded. If the computer's name changes, the old name continues to be returned as the domain name until the system is restarted.

For Windows NT Server systems, the domain name returned for most accounts in the local computer's security database is the name of the domain for which the Windows NT Server is a domain controller.

Some accounts are predefined by the system. The domain name returned for these accounts is BUILTIN.

cbReferencedDomainName
Pointer to a DWORD variable. On input, this value specifies the size, in bytes (ANSI version) or characters (Unicode version), of the ReferencedDomainName buffer. If the function fails because the buffer is too small, this variable receives the required buffer size, including the terminating null character.
peUse
Pointer to an SID_NAME_USE enumerated type indicating the type of the account when the function returns.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The LookupAccountSid function attempts to find a name for the specified security identifier by first checking a list of well-known SIDs. If the supplied SID does not correspond to a well-known SID, the function checks built-in and administratively defined local accounts. Next, the function checks the primary domain. Security identifiers not recognized by the primary domain are checked against the trusted domains corresponding to their SID prefixes.

LookupAccountSid fails and GetLastError returns ERROR_NONE_MAPPED if it cannot find an account name for the SID. This can occur if a network timeout prevents the function from finding the name. It also occurs for SIDs that have no corresponding account name, such as a logon SID that identifies a logon session.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, EqualPrefixSid, LookupAccountName


LookupPrivilegeDisplayName

The LookupPrivilegeDisplayName function retrieves a displayable name representing a specified privilege.

BOOL LookupPrivilegeDisplayName(
  LPCTSTR lpSystemName,  // pointer to string specifying the system
  LPCTSTR lpName,        // pointer to string specifying the
                         // privilege
  LPTSTR lpDisplayName,  // pointer to string receiving the
                         // displayable name
  LPDWORD cbDisplayName, // pointer to size of string for
                         // displayable name
  LPDWORD lpLanguageId   // pointer to language identifier
);

Parameters

lpSystemName
Pointer to a null-terminated string specifying the name of the system on which the displayable privilege name is looked up. If a null string is specified, the function attempts to find the displayable name on the local system.
lpName
Pointer to a null-terminated string that specifies the name of the privilege, as defined in the WINNT.H header file. For example, this parameter could specify the constant SE_REMOTE_SHUTDOWN_NAME, or its corresponding string, "SeRemoteShutdownPrivilege".
lpDisplayName
Pointer to a buffer receiving a null-terminated string giving the privilege's displayable name. For example, if the lpName parameter is SE_REMOTE_SHUTDOWN_NAME, the displayable name is "Force shutdown from a remote system."
cbDisplayName
Pointer to a variable specifying the size, in characters, of the lpDisplayName buffer. When the function returns, this parameter contains the length of the displayable privilege name, not including the terminating null character. If the buffer pointed to by the lpDisplayName parameter is too small, this variable contains the required size when the function returns.
lpLanguageId
Pointer to a variable receiving the language identifier for the returned displayable name.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The LookupPrivilegeDisplayName function retrieves display names only for the privileges specified in the Defined Privileges section of WINNT.H.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, LookupPrivilegeName, LookupPrivilegeValue


LookupPrivilegeName

The LookupPrivilegeName function retrieves the name corresponding to the privilege represented on a specific system by a specified locally unique identifier (LUID).

BOOL LookupPrivilegeName(
  LPCTSTR lpSystemName,
                  // address of string specifying the system
  PLUID lpLuid,   // address of locally unique identifier
  LPTSTR lpName,  // address of string specifying the privilege
  LPDWORD cbName  // address of size of string for displayable name
);

Parameters

lpSystemName
Pointer to a null-terminated string specifying the name of the system on which the privilege name is looked up. If a null string is specified, the function attempts to find the privilege name on the local system.
lpLuid
Pointer to the locally unique identifier by which the privilege is known on the target system.
lpName
Pointer to a buffer that receives a null-terminated string that represents the privilege's name. For example, this string could be "SeSecurityPrivilege".
cbName
Pointer to a variable specifying the size, in characters, of the lpName buffer. When the function returns, this parameter contains the length of the privilege name, not including the terminating null character. If the buffer pointed to by the lpName parameter is too small, this variable contains the required size when the function returns.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

For the current release of Windows NT, only the privileges specified in the Defined Privileges section of WINNT.H are supported by this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, LookupPrivilegeDisplayName, LookupPrivilegeValue


LookupPrivilegeValue

The LookupPrivilegeValue function retrieves the locally unique identifier (LUID) used on a specified system to locally represent the specified privilege name.

BOOL LookupPrivilegeValue(
  LPCTSTR lpSystemName,
                   // address of string specifying the system
  LPCTSTR lpName,  // address of string specifying the privilege
  PLUID lpLuid     // address of locally unique identifier
);

Parameters

lpSystemName
Pointer to a null-terminated string specifying the name of the system on which the privilege name is looked up. If a null string is specified, the function attempts to find the privilege name on the local system.
lpName
Pointer to a null-terminated string that specifies the name of the privilege, as defined in the WINNT.H header file. For example, this parameter could specify the constant SE_SECURITY_NAME, or its corresponding string, "SeSecurityPrivilege".
lpLuid
Pointer to a variable that receives the locally unique identifier by which the privilege is known on the system specified by the lpSystemName parameter.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

For the current release of Windows NT, only the privileges specified in the Defined Privileges section of WINNT.H are supported by this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, LookupPrivilegeDisplayName, LookupPrivilegeName


OpenProcessToken

The OpenProcessToken function opens the access token associated with a process.

BOOL OpenProcessToken(
  HANDLE ProcessHandle, // handle to process
  DWORD DesiredAccess,  // desired access to process
  PHANDLE TokenHandle   // pointer to handle of open access token
);

Parameters

ProcessHandle
Identifies the process whose access token is opened.
DesiredAccess
Specifies an access mask that specifies the requested types of access to the access token. These requested access types are compared with the token's discretionary access-control list (ACL) to determine which accesses are granted or denied. The following access rights have been defined for access tokens.
Value | Meaning
TOKEN_ADJUST_DEFAULT | Required to change the default ACL, primary group, or owner of an access token.
TOKEN_ADJUST_GROUPS | Required to change the groups specified in an access token.
TOKEN_ADJUST_PRIVILEGES | Required to change the privileges specified in an access token.
TOKEN_ALL_ACCESS | Combines the STANDARD_RIGHTS_REQUIRED standard access rights and all individual access rights for tokens.
TOKEN_ASSIGN_PRIMARY | Required to attach a primary token to a process in addition to the SE_CREATE_TOKEN_NAME privilege.
TOKEN_DUPLICATE | Required to duplicate an access token.
TOKEN_EXECUTE | Combines the STANDARD_RIGHTS_EXECUTE standard access rights and the TOKEN_IMPERSONATE access right.
TOKEN_IMPERSONATE | Required to attach an impersonation access token to a process.
TOKEN_QUERY | Required to query the contents of an access token.
TOKEN_QUERY_SOURCE | Required to query the source of an access token.
TOKEN_READ | Combines the STANDARD_RIGHTS_READ standard access rights and the TOKEN_QUERY access right.
TOKEN_WRITE | Combines the STANDARD_RIGHTS_WRITE standard access rights and the TOKEN_ADJUST_PRIVILEGES, TOKEN_ADJUST_GROUPS, and TOKEN_ADJUST_DEFAULT access rights.

TokenHandle
Pointer to a handle identifying the newly-opened access token when the function returns.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AdjustTokenGroups, AdjustTokenPrivileges, GetTokenInformation, OpenThreadToken, SetTokenInformation


OpenThreadToken

The OpenThreadToken function opens the access token associated with a thread.

BOOL OpenThreadToken(
  HANDLE ThreadHandle,  // handle to thread
  DWORD DesiredAccess,  // access to process
  BOOL OpenAsSelf,      // flag for process or thread security
  PHANDLE TokenHandle   // pointer to handle to open access token
);

Parameters

ThreadHandle
Identifies the thread whose access token is opened.
DesiredAccess
Specifies an access mask that specifies the requested types of access to the access token. These requested access types are reconciled against the token's discretionary access-control list (ACL) to determine which accesses are granted or denied. The following access rights have been defined for access tokens.
Value | Meaning
TOKEN_ADJUST_DEFAULT | Required to change the default ACL, primary group, or owner of an access token.
TOKEN_ADJUST_GROUPS | Required to change the groups specified in an access token.
TOKEN_ADJUST_PRIVILEGES | Required to change the privileges specified in an access token.
TOKEN_ALL_ACCESS | Combines the STANDARD_RIGHTS_REQUIRED standard access rights and all individual access rights for tokens.
TOKEN_ASSIGN_PRIMARY | Required to attach a primary token to a process in addition to the SE_CREATE_TOKEN_NAME privilege.
TOKEN_DUPLICATE | Required to duplicate an access token.
TOKEN_EXECUTE | Combines the STANDARD_RIGHTS_EXECUTE standard access rights and the TOKEN_IMPERSONATE access right.
TOKEN_IMPERSONATE | Required to attach an impersonation access token to a process.
TOKEN_QUERY | Required to query the contents of an access token.
TOKEN_QUERY_SOURCE | Required to query the source of an access token.
TOKEN_READ | Combines the STANDARD_RIGHTS_READ standard access rights and the TOKEN_QUERY access right.
TOKEN_WRITE | Combines the STANDARD_RIGHTS_WRITE standard access rights and the TOKEN_ADJUST_PRIVILEGES, TOKEN_ADJUST_GROUPS, and TOKEN_ADJUST_DEFAULT access rights.

OpenAsSelf
Specifies a flag indicating whether the access check is to be made against the security context of the thread calling the OpenThreadToken function or against the security context of the process for the calling thread.

If this parameter is FALSE, the access check is performed using the security context for the calling thread. If the thread is impersonating a client, this security context can be that of a client process. If this parameter is TRUE, the access check is made using the security context of the process for the calling thread.

TokenHandle
Pointer to a handle identifying the newly opened access token when the function returns.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The OpenAsSelf parameter allows a server process to open the access token for a client process when the client process has specified the SecurityIdentification impersonation level for the SECURITY_IMPERSONATION_LEVEL enumerated type. Without this parameter, the calling process is not be able to open the client's access token using the client's security context, because it is impossible to open executive-level objects using the SecurityIdentification impersonation level.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AdjustTokenGroups, AdjustTokenPrivileges, GetTokenInformation, OpenProcessToken, SetThreadToken, SetTokenInformation


SetEntriesInAccessList

[This is preliminary documentation and subject to change.]

The SetEntriesInAccessList function creates a new access-control list by merging specified access-control information into an existing access-control list. You can specify access-control information for an object or for a specified property on an object.

DWORD SetEntriesInAccessList(
  ULONG cEntries,      // Number of entries in the entry list
  PACTRL_ACCESS_ENTRY pAccessEntryList,
                       // array of access-control entry information
  ACCESS_MODE AccessMode,  // merge, replace, or revoke trustee
                           // access
  LPCTSTR lpProperty,  // GUID string of a property
  PACTRL_ACCESS pOldList,  // pointer to the old access-control list
  PACTRL_ACCESS *ppNewList
                       // receives a pointer to the new list
);

Parameters

cEntries
Specifies the number of entries in the pAccessEntryList array.
pAccessEntryList
Pointer to an array of ACTRL_ACCESS_ENTRY structures. Each entry in the array specifies access-control information for a trustee.
AccessMode
A flag that indicates how to combine the new entries in the pAccessEntryList array with the existing entries in the pOldList access-control list. This parameter can be one of the following values from the ACCESS_MODE enumeration.
Value | Meaning
GRANT_ACCESS | Adds the new entries to the front of the access-control list. Existing entries are not removed from the list.
REVOKE_ACCESS | Remove from the existing list explicit entries for trustees specified in the pAccessEntryList array.
SET_ACCESS | Adds the new entries to the front of the access-control list. Existing entries for the same trustees are removed from the list.

If you specify REVOKE_ACCESS or SET_ACCESS, the function can remove entries for trustees specified in the pAccessEntryList array. However, the function's behavior depends on the lpProperty parameter. If lpProperty is non-NULL, the function removes only the object-specific entries that apply to the properties, property sets, or child objects identified by lpProperty. However, if lpProperty is NULL, the function removes all entries for the specified trustees, including any object-specific entries, as well as entries for the object itself.

lpProperty
Pointer to a null-terminated string that identifes a type of object. This string can be the display name of the object, or it can be a string representation of the GUID that identifies the object. You can use the UuidToString function to generate a string representation of a GUID.

Use this parameter to create object-specific ACEs that apply to a child object, property set, or property of the object. If this parameter is NULL, the access-control information applies to the object itself.

pOldList
Pointer to an existing ACTRL_ACCESS structure containing the access-control list to be modified.
ppNewList
Pointer to a variable that receives a pointer to an ACTRL_ACCESS structure containing the new access-control list. Call the LocalFree function to free the returned buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
ERROR_NOT_ENOUGH_MEMORY | A memory allocation failed
ERROR_INVALID_PARAMETER | An invalid parameter was specified.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, SetEntriesInAuditList


SetEntriesInAuditList

[This is preliminary documentation and subject to change.]

The SetEntriesInAuditList function creates a new audit-control list by merging specified audit-control information into an existing audit-control list. You can specify audit-control information for an object or for a specified property on an object.

DWORD SetEntriesInAuditList(
  ULONG cEntries,      // Number of entries in the entry list
  PACTRL_ACCESS_ENTRY pAccessEntryList,
                       // array of audit-control entry information
  ACCESS_MODE AccessMode,  //
  LPCTSTR lpProperty,  // GUID string of a property
  PACTRL_AUDIT pOldList,
                       // pointer to the old audit-control list
  PACTRL_AUDIT *ppNewList  // receives a pointer to the new list
);

Parameters

cEntries
Specifies the number of entries in the pAccessEntryList array.
pAccessEntryList
Pointer to an array of ACTRL_ACCESS_ENTRY structures. Each entry in the array specifies audit-control information for a trustee.
AccessMode
A flag that indicates how to combine the new entries in the pAccessEntryList array with the existing entries in the pOldList audit-control list. This parameter can be one of the following values from the ACCESS_MODE enumeration.
Value | Meaning
GRANT_ACCESS | Adds the new entries to the front of the audit-control list. Existing entries are not removed from the list.
REVOKE_ACCESS | Remove from the existing list explicit entries for trustees specified in the pAccessEntryList array.
SET_ACCESS | Adds the new entries to the front of the audit-control list. Existing entries for the same trustees are removed from the list.

If you specify REVOKE_ACCESS or SET_ACCESS, the function can remove entries for trustees specified in the pAccessEntryList array. However, the function's behavior depends on the lpProperty parameter. If lpProperty is non-NULL, the function removes only the object-specific entries that apply to the properties, property sets, or child objects identified by lpProperty. However, if lpProperty is NULL, the function removes all entries for the specified trustees, including any object-specific entries, as well as entries for the object itself.

lpProperty
Pointer to a null-terminated string that identifes a type of object. This string can be the display name of the object, or it can be a string representation of the GUID that identifies the object. You can use the UuidToString function to generate a string representation of a GUID.

Use this parameter to create object-specific ACEs that apply to a child object, property set, or property of the object. If this parameter is NULL, the audit-control information applies to the object itself.

pOldList
Pointer to an existing ACTRL_AUDIT structure containing the audit-control list to be modified.
ppNewList
Pointer to a variable that receives a pointer to an ACTRL_AUDIT structure containing the new audit-control list. Call the LocalFree function to free the returned buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
ERROR_INVALID_PARAMETER | An invalid parameter was specified.
ERROR_NOT_ENOUGH_MEMORY | A memory allocation failed.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, ACTRL_ACCESS_ENTRY, ACTRL_AUDIT, ACTRL_PROPERTY_ENTRY, LocalFree, SetEntriesInAccessList


SetNamedSecurityInfoEx

[This is preliminary documentation and subject to change.]

The SetNamedSecurityInfoEx function sets the specified security information for an object specified by name.

SetNamedSecurityInfoEx differs from the SetNamedSecurityInfo function in that it allows you to set access-control information for the properties on an object, as well as for the object itself. In addition, SetNamedSecurityInfoEx uses provider-independent access flags, but SetNamedSecurityInfo uses Windows NT-specific access flags.

DWORD SetNamedSecurityInfoEx(
  LPCTSTR lpObject,           // name of the object
  SE_OBJECT_TYPE ObjectType,  // type of object
  SECURITY_INFORMATION SecurityInfo,
                             // type of security information to set
  LPCTSTR lpProvider,        // name of provider to handle request
  PACTRL_ACCESS pAccessList,  // pointer to the DACL information
  PACTRL_AUDIT pAuditList,  // pointer to the SACL information
  LPTSTR lpOwner,           // name of the object's owner
  LPTSTR lpGroup,           // name of the object's primary group
  PACTRL_OVERLAPPED pOverlapped
                            // pointer to a structure for
                            // asynchronous operation
);

Parameters

lpObject
Pointer to a null-terminated string that specifies the name of the object on which to set security information. For descriptions of the string formats for the different object types, see SE_OBJECT_TYPE.
ObjectType
Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object named by the lpObject parameter.
SecurityInfo
A set of SECURITY_INFORMATION bit flags that indicate the type of security information to set. This parameter can be a combination of the following values.
Value | Meaning
OWNER_SECURITY_INFORMATION | Set the object's owner. The lpOwner parameter points to the new name of the object's owner.
GROUP_SECURITY_INFORMATION | Set the object's primary group. The lpGroup parameter points to the new name of the object's primary group.
DACL_SECURITY_INFORMATION | Set the discretionary access-control list (DACL) for the object. The pAccessList parameter points to a structure containing new access-control information for the object. For DS objects, the pAccessList buffer can also contain access-control information for any properties on the object.
SACL_SECURITY_INFORMATION | Set the system access-control list (SACL) for the object. The pAuditList parameter points to a structure containing new audit-control information for the object. For DS objects, the pAuditList buffer can also contain audit-control information for any properties on the object.

lpProvider
Pointer to a null-terminated string that specifies the name of the provider to handle the request. If this parameter is NULL, the system determines the proper provider to handle the request.
pAccessList
Pointer to an ACTRL_ACCESS structure containing the new access-control information for the object's DACL. For DS objects, the structure can also contain access-control information for the object's properties. The SecurityInfo parameter must include the DACL_SECURITY_INFORMATION flag. The caller must have WRITE_DAC access to the object or be the object's owner. This parameter can be NULL if you are not setting the DACL.
pAuditList
Pointer to an ACTRL_AUDIT structure containing the new audit-control information for the object's SACL. For DS objects, the structure can also contain audit-control information for the object's properties. The SecurityInfo parameter must include the SACL_SECURITY_INFORMATION flag. The caller must have the SE_SECURITY_NAME privilege enabled. This parameter can be NULL if you are not setting the SACL.
lpOwner
Pointer to a null-terminated string containing the new name of the object's owner. The function attempts to convert the name to an SID. The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION flag. The caller must have WRITE_OWNER access to the object or have the SE_TAKE_OWNERSHIP_NAME privilege enabled. This parameter can be NULL if you are not setting the owner SID.

The function uses a NULL owner for objects on systems other than Windows NT that do not support object owners.

lpGroup
Pointer to a null-terminated string containing the name of the object's primary group. The SecurityInfo parameter must include the GROUP_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the primary group SID.

The function uses a NULL primary group for objects on systems other than Windows NT that do not support object groups.

pOverlapped
Pointer to an ACTRL_OVERLAPPED structure. If this parameter is non-NULL, the function returns immediately and the set operation is performed asynchronously. SetNamedSecurityInfoEx returns a handle to an event object in the hEvent member of this structure. The system sets this event object to the signaled state when the operation has been completed.

If this parameter is NULL, the function is performed synchronously and does not return until the operation has been completed. Note that a synchronous operation can take an extended period of time and cannot be cancelled.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS. If the pOverlapped parameter was NULL, the function successfully set the specified security information. If pOverlapped was not NULL, the function started the asynchronous operation.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
ERROR_BAD_PROVIDER | The lpProvider parameter specified an invalid provider name.
ERROR_INVALID_PARAMETER | An invalid parameter was specified.
ERROR_NOT_ENOUGH_MEMORY | A memory allocation failed

Remarks

If the pOverlapped parameter is points to a valid ACTRL_OVERLAPPED structure, SetNamedSecurityInfoEx returns immediately and returns a handle to an event object in the hEvent member of the ACTRL_OVERLAPPED structure. The system sets this event object to the signaled state when the operation has been completed. You can call the GetOverlappedAccessResults function to wait for the operation to be completed and retrieve the results of the asynchronous operation. Alternatively, you can call one of the wait functions, such as WaitForSingleObject, to wait for the event object to be signaled, and then call GetOverlappedAccessResults to determine the results of the operation. The wait functions also allow you to specify a time-out interval; if the interval elapses before the event is signaled, you can call the CancelOverlappedAccess function to cancel the asynchronous operation. If the pOverlapped parameter is NULL, the operation is performed synchronously.

To set the security information for a DS object and all its properties, specify SE_DS_OBJECT in the ObjectType parameter and use the pAccessList and pAuditList parameters to specify the security information. Set the pPropertyAccessList member of the ACTRL_ACCESS or ACTRL_AUDIT structure to point to an array of ACTRL_PROPERTY_ENTRY structures. Use one ACTRL_PROPERTY_ENTRY structure to specify access-control information for the object, and additional structures to specify information for each property that requires explicit security. Properties that are not explicitly identified in the array of ACTRL_PROPERTY_ENTRY structures are protected only by the object's access control.

For file, registry, and DS objects, the SetNamedSecurityInfoEx function can propagate access-control information to the child objects of the specified object. This can occur when the child objects inherit access-control entries from their parent object. This propagation can be time consuming, so you might want to perform it as an asynchronous operation.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, ACTRL_ACCESS, ACTRL_AUDIT, ACTRL_PROPERTY_ENTRY, GetNamedSecurityInfoEx, GetSecurityInfoEx, SE_OBJECT_TYPE, SECURITY_INFORMATION, SetSecurityInfoEx


SetSecurityDescriptorControl

[This is preliminary documentation and subject to change.]

The SetSecurityDescriptorControl function sets the control bits of a security descriptor. The function can set only the control bits that relate to automatic inheritance of ACEs. To set the other control bits of a security descriptor, use the Win32 functions, such as SetSecurityDescriptorDacl, for modifying the components of a security descriptor.

BOOL SetSecurityDescriptorControl(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,    // security descriptor
  SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,  // bits to set
  SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet // new control bits
);

Parameters

pSecurityDescriptor
Pointer to a SECURITY_DESCRIPTOR structure whose control and revision information are set.
ControlBitsOfInterest
A SECURITY_DESCRIPTOR_CONTROL mask that indicates the control bits to set. This mask can be a combination of the following flags.
Value | Meaning
SE_DACL_AUTO_INHERIT_REQ | Requests that the provider for the object protected by the security descriptor automatically propagate the DACL to existing child objects. If the provider supports automatic inheritance, it propagates the DACL to any existing child objects, and sets the SE_DACL_AUTO_INHERITED bit in the security descriptors of the object and its child objects.
SE_DACL_AUTO_INHERITED Indicates a security descriptor in which the DACL is set up to support automatic propagation of inheritable ACEs to existing child objects. This bit is set only if the automatic inheritance algorithm has been performed for the object and its existing child objects.

This bit is not set in security descriptors for Windows NT versions 4.0 and earlier, which did not support automatic propagation of inheritable ACEs.
SE_DACL_PROTECTED | Protects the DACL of the security descriptor from being modified by inheritable ACEs.
SE_SACL_AUTO_INHERIT_REQ | Requests that the provider for the object protected by the security descriptor automatically propagate the SACL to existing child objects. If the provider supports automatic inheritance, it propagates the SACL to any existing child objects, and sets the SE_SACL_AUTO_INHERITED bit in the security descriptors of the object and its child objects.
SE_SACL_AUTO_INHERITED Indicates a security descriptor in which the SACL is set up to support automatic propagation of inheritable ACEs to existing child objects. This bit is set only if the automatic inheritance algorithm has been performed for the object and its existing child objects.

This bit is not set in security descriptors for Windows NT versions 4.0 and earlier, which did not support automatic propagation of inheritable ACEs.
SE_SACL_PROTECTED | Protects the SACL of the security descriptor from being modified by inheritable ACEs.

ControlBitsToSet
A SECURITY_DESCRIPTOR_CONTROL mask that indicates the new values for the control bits specified by the ControlBitsOfInterest mask. This parameter can be a combination of the flags listed for the ControlBitsOfInterest parameter.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The SetSecurityDescriptorControl function specifies the control bit or bits to modify, and whether the bits are on or off. For example, the following code marks the DACL on the security descriptor as protected:

SetSecurityDescriptorControl( &SecDesc,
            SE_DACL_PROTECTED, SE_DACL_PROTECTED );

And this code marks the DACL as not protected:

SetSecurityDescriptorControl( &SecDesc,
            SE_DACL_PROTECTED, 0 );

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetSecurityDescriptorControl, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL


SetSecurityInfoEx

[This is preliminary documentation and subject to change.]

The SetSecurityInfoEx function sets the specified security information for an object identified by a handle.

SetSecurityInfoEx differs from the SetSecurityInfo function in that it allows you to set access-control information for the properties on an object, as well as for the object itself. In addition, SetSecurityInfoEx uses provider-independent access flags, but SetSecurityInfo uses Windows NT-specific access flags.

DWORD SetSecurityInfoEx(
  HANDLE hObject,           // handle to the object
  SE_OBJECT_TYPE ObjectType,  // type of object
  SECURITY_INFORMATION SecurityInfo,
                            // type of security information to set
  LPCTSTR lpProvider,       // name of provider to handle request
  PACTRL_ACCESS pAccessList,  // pointer to access-control
                              // information
  PACTRL_AUDIT pAuditList,  // pointer to audit-control information
  LPTSTR lpOwner,           // name of the object's owner
  LPTSTR lpGroup,           // name of the object's primary group
  PACTRL_OVERLAPPED pOverlapped
                            // pointer to a structure for
                            // asynchronous operation
);

Parameters

hObject
A handle to the object for which to set security information.
ObjectType
Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object identified by the hObject parameter.
SecurityInfo
Specifies the components of the security descriptor to set. This parameter can be a combination of the following values.
Value Meaning
OWNER_SECURITY_INFORMATION
Sets the object's owner security identifier (SID). The lpOwner parameter points to the new name of the object's owner. The hObject handle must have WRITE_OWNER access, or the calling process must be the object's owner or have the SE_TAKE_OWNERSHIP_NAME privilege enabled.
GROUP_SECURITY_INFORMATION
Sets the object's primary group SID. The lpGroup parameter points to the new name of the object's primary group. The hObject handle must have WRITE_OWNER access, or the calling process must be the object's owner.
DACL_SECURITY_INFORMATION
Sets the object's discretionary access control list (DACL). The pAccessList parameter points to a structure containing new access-control information for the object. For DS objects, the pAccessList buffer can also contain access-control information for any properties on the object.

The hObject handle must have WRITE_DAC access, or the calling process must be the object's owner.
SACL_SECURITY_INFORMATION
Sets the object's system access control list (SACL). The pAuditList parameter points to a structure containing new audit-control information for the object. For DS objects, the pAuditList buffer can also contain audit-control information for any properties on the object. The hObject handle must have ACCESS_SYSTEM_SECURITY access. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current access token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

lpProvider
Pointer to a null-terminated string that specifies the name of the provider to handle the request. If this parameter is NULL, the system determines the proper provider to handle the request.
pAccessList
Pointer to an ACTRL_ACCESS structure containing the new access-control information for the object's DACL. For DS objects, the structure can also contain access-control information for the object's properties. The SecurityInfo parameter must include the DACL_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the DACL.
pAuditList
Pointer to an ACTRL_AUDIT structure containing the new audit-control information for the object's SACL. For DS objects, the structure can also contain audit-control information for the object's properties. The SecurityInfo parameter must include the SACL_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the SACL.
lpOwner
Pointer to a null-terminated string containing the new name of the object's owner. The function attempts to convert the name to an SID. The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the owner SID.

The function uses a NULL owner for objects on systems other than Windows NT that do not support object owners.

lpGroup
Pointer to a null-terminated string containing the name of the object's primary group. The SecurityInfo parameter must include the GROUP_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the primary group SID.

The function uses a NULL primary group for objects on systems other than Windows NT that do not support object groups.

pOverlapped
Pointer to an ACTRL_OVERLAPPED structure. If this parameter is non-NULL, the function returns immediately and the set operation is performed asynchronously. SetSecurityInfoEx returns a handle to an event object in the hEvent member of this structure. The system sets this event object to the signaled state when the operation has been completed.

If this parameter is NULL, the function is performed synchronously and does not return until the operation has been completed. Note that a synchronous operation can take an extended period of time and cannot be cancelled.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS. If the pOverlapped parameter was NULL, the function successfully set the specified security information. If pOverlapped was not NULL, the function started the asynchronous operation.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
ERROR_NOT_ENOUGH_MEMORY | A memory allocation failed
ERROR_INVALID_PARAMETER | An invalid parameter was specified.
ERROR_BAD_PROVIDER | The lpProvider parameter specified an invalid provider name.

Remarks

If the pOverlapped parameter points to a valid ACTRL_OVERLAPPED structure, SetSecurityInfoEx returns immediately and returns a handle to an event object in the hEvent member of the ACTRL_OVERLAPPED structure. The system sets this event object to the signaled state when the operation has been completed. You can call the GetOverlappedAccessResults function to wait for the operation to be completed and retrieve the results of the asynchronous operation. Alternatively, you can call one of the wait functions, such as WaitForSingleObject, to wait for the event object to be signaled, and then call GetOverlappedAccessResults to determine the results of the operation. The wait functions also allow you to specify a time-out interval; if the interval elapses before the event is signaled, you can call the CancelOverlappedAccess function to cancel the asynchronous operation. If the pOverlapped parameter is NULL, the operation is performed synchronously.

To set the security information for a DS object and all its properties, specify SE_DS_OBJECT in the ObjectType parameter and use the pAccessList and pAuditList parameters to specify the security information. Set the pPropertyAccessList member of the ACTRL_ACCESS or ACTRL_AUDIT structure to point to an array of ACTRL_PROPERTY_ENTRY structures. Use one ACTRL_PROPERTY_ENTRY structure to specify access-control information for the object, and additional structures to specify information for each property that requires explicit security. Properties that are not explicitly identified in the array of ACTRL_PROPERTY_ENTRY structures are protected only by the object's access control.

For file, registry, and DS objects, the SetSecurityInfoEx function can propagate access-control information to the child objects of the specified object. This can occur when the child objects inherit ACEs from their parent object. This propagation can be time consuming, so you might want to perform it as an asynchronous operation.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, ACTRL_ACCESS, ACTRL_AUDIT, ACTRL_PROPERTY_ENTRY, GetNamedSecurityInfoEx, GetSecurityInfoEx, SE_OBJECT_TYPE, SECURITY_INFORMATION, SetNamedSecurityInfoEx


SetThreadToken

The SetThreadToken function assigns an impersonation token to a thread. The function can also cause a thread to stop using an impersonation token.

BOOL SetThreadToken(
  PHANDLE Thread,  // points to a handle to the thread
  HANDLE Token     // handle to the impersonation token
);

Parameters

Thread
Pointer to a handle to the thread to which the function assigns the impersonation token.

If Thread is NULL, the function assigns the impersonation token to the calling thread.

Token
An open handle to the impersonation token to assign to the thread. This handle must have been opened with TOKEN_IMPERSONATE access rights. For more information, see Access Rights for Access-Token Objects.

If Token is NULL, the function causes the thread to stop using an impersonation token.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, OpenThreadToken


SetTokenInformation

The SetTokenInformation function sets various types of information for a specified access token. The information it sets replaces existing information. The calling process must have appropriate access rights to set the information.

BOOL SetTokenInformation(
  HANDLE TokenHandle,            // handle of access token
  TOKEN_INFORMATION_CLASS TokenInformationClass,
                                 // type of information to set
  LPVOID TokenInformation,       // address of information to set
  DWORD TokenInformationLength   // size of information buffer
);

Parameters

TokenHandle
Identifies the access token for which information is to be set.
TokenInformationClass
Specifies a variable of the TOKEN_INFORMATION_CLASS enumerated type identifying the type of information the function sets. The valid values from TOKEN_INFORMATION_CLASS are TokenOwner, TokenPrimaryGroup, and TokenDefaultDacl. For more information about these values, see the description of the TokenInformation parameter, following.
TokenInformation
Pointer to a buffer containing the information set in the access token. The structure of this buffer depends on the type of information specified by the TokenInformationClass parameter. The following three values are valid in calls to this function:
Token Information Class | Structure Provided
TokenOwner | TOKEN_OWNER structure. The TOKEN_ADJUST_DEFAULT access right is needed to set owner information. A valid owner value is a user or group identifier with an attribute allowing assignment as the owner of objects.
TokenPrimaryGroup | TOKEN_PRIMARY_GROUP structure. The TOKEN_ADJUST_DEFAULT access right is needed to set primary group information.
TokenDefaultDacl | TOKEN_DEFAULT_DACL structure. The TOKEN_ADJUST_DEFAULT access right is needed to set information in the default discretionary access-control list (ACL). The ACL structure provided as a new default discretionary ACL is not validated for correctness or consistency. If the TokenInformation parameter is NULL, the current default discretionary ACL is removed and no replacement is established.

The formats for the structures this function can set are listed in the following Remarks section.

TokenInformationLength
Specifies the length, in bytes, of the buffer pointed to by TokenInformation.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

To set privilege information, an application can call the AdjustTokenPrivileges function. To set a token's groups, an application can call the AdjustTokenGroups function.

Token-type information can be set only when an access token is created.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AdjustTokenGroups, AdjustTokenPrivileges, GetTokenInformation, OpenProcessToken, OpenThreadToken, TOKEN_DEFAULT_DACL, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP


TrusteeAccessToObject

[This is preliminary documentation and subject to change.]

The TrusteeAccessToObject function determines whether a trustee has specified access rights to a specified object or its properties.

DWORD TrusteeAccessToObject(
  LPCTSTR lpObject,   // name of the object
  SE_OBJECT_TYPE ObjectType,
                      // type of object
  LPCTSTR lpProvider, // name of provider to handle request
  PTRUSTEE pTrustee,  // pointer to trustee information
  ULONG cEntries,     // number of entries in trustee access list
  PTRUSTEE_ACCESS pTrusteeAccess
                      // pointer to a trustee access list
);

Parameters

lpObject
Pointer to a null-terminated string that specifies the name of an object. For descriptions of the string formats for the different object types, see SE_OBJECT_TYPE.
ObjectType
Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object named by the lpObject parameter.
lpProvider
Pointer to a null-terminated string that specifies the name of the provider to handle the request. If this parameter is NULL, the system determines the proper provider to handle the request.
pTrustee
Pointer to a TRUSTEE structure that identifies a user, group, or program (such as a Win32 service).
cEntries
Specifies the number of entries in the array of TRUSTEE_ACCESS structures.
pTrusteeAccess
Pointer to an array of TRUSTEE_ACCESS structures. Each entry specifies the access rights to check. An entry can check access rights to the object or to a property set or property on the object. When the function returns successfully, the fReturnedAccess member of each structure indicates whether the trustee has the requested access rights.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
ERROR_BAD_PROVIDER | The lpProvider parameter specified an invalid provider name.
ERROR_INVALID_PARAMETER | An invalid parameter was specified.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Access Control Overview, Access Control Functions, SE_OBJECT_TYPE, TRUSTEE, TRUSTEE_ACCESS


Access Control Structures

The following structures are used with access control.

ACCESS_MASK
ACE
ACE_HEADER
ACL
ACTRL_ACCESS
ACTRL_ACCESS_ENTRY
ACTRL_ACCESS_ENTRY_LIST
ACTRL_ACCESS_INFO
ACTRL_AUDIT
ACTRL_OVERLAPPED
ACTRL_PROPERTY_ENTRY
LUID
LUID_AND_ATTRIBUTES
SECURITY_ATTRIBUTES
SECURITY_DESCRIPTOR
SECURITY_INFORMATION
SID_AND_ATTRIBUTES
SID_IDENTIFIER_AUTHORITY
SID
TOKEN_CONTROL
TOKEN_DEFAULT_DACL
TOKEN_GROUPS
TOKEN_OWNER
TOKEN_PRIMARY_GROUP
TOKEN_PRIVILEGES
TOKEN_SOURCE
TOKEN_STATISTICS
TOKEN_USER
TRUSTEE
TRUSTEE_ACCESS


ACCESS_MASK

The ACCESS_MASK structure is one doubleword value containing standard, specific, and generic rights. These rights are used in access-control entries (ACEs) and are the primary means of specifying the requested or granted access to an object.

typedef DWORD ACCESS_MASK;

The bits in this value are allocated as follows:

Bits | Meaning
0 through 15 | Specific rights. Contains the access mask specific to the object type associated with the mask.
16 through 23 | Standard rights. Contains the object's standard access rights and can be a combination of the following predefined flags:

Bit | Flag | Meaning
16 | DELETE | Delete access
17 | READ_CONTROL | Read access to the owner, group, and discretionary access-control list (ACL) of the security descriptor
18 | WRITE_DAC | Write access to the discretionary access-control list (ACL)
19 | WRITE_OWNER | Write access to owner
20 | SYNCHRONIZE | Windows NT: Synchronize access

Bits | Meaning
24 | Access system security (ACCESS_SYSTEM_SECURITY). This flag is not a typical access type. It is used to indicate access to a system ACL. This type of access requires the calling process to have a specific privilege.
25 | Maximum allowed (MAXIMUM_ALLOWED)
26 through 27 | Reserved
28 | Generic all (GENERIC_ALL)
29 | Generic execute (GENERIC_EXECUTE)
30 | Generic write (GENERIC_WRITE)
31 | Generic read (GENERIC_READ)

The following constants represent the specific and standard access rights:

#define SPECIFIC_RIGHTS_ALL           0x0000FFFF
#define STANDARD_RIGHTS_REQUIRED      0x000F0000
#define STANDARD_RIGHTS_ALL           0x001F0000

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, GENERIC_MAPPING


ACE

An ACE is an access-control entry (ACE) in an access-control list (ACL).

Following are the currently defined ACE types:

ACE type | Structure | ACL Type
Access allowed | ACCESS_ALLOWED_ACE | Discretionary
Access denied | ACCESS_DENIED_ACE | Discretionary
System alarm | SYSTEM_ALARM_ACE | System
System audit | SYSTEM_AUDIT_ACE | System

System-alarm ACEs are not supported in the current version of Windows NT.

Remarks

An ACL contains a list of ACEs. An ACE defines access to an object for a specific user or group or defines the types of access that generate system-administration messages or alarms for a specific user or group. The user or group is identified by a security identifier (SID).

Each ACE starts with an ACE_HEADER structure. The format of the data following the header varies according to the ACE type specified in the header.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, AddAce, ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, ACL, SYSTEM_ALARM_ACE, SYSTEM_AUDIT_ACE


ACE_HEADER

The ACE_HEADER structure describes the type and size of an access-control entry (ACE).

typedef struct _ACE_HEADER { // acehdr
    BYTE AceType;
    BYTE AceFlags;
    WORD AceSize;
} ACE_HEADER;

Members

AceType
Specifies the ACE type. This member can be one of the following values:
Value Meaning
ACCESS_ALLOWED_ACE_TYPE
Access-allowed ACE that uses the ACCESS_ALLOWED_ACE structure.
ACCESS_DENIED_ACE_TYPE
Access-denied ACE that uses the ACCESS_DENIED_ACE structure.
SYSTEM_AUDIT_ACE_TYPE
System-audit ACE that uses the SYSTEM_AUDIT_ACE structure.
ACCESS_ALLOWED_OBJECT_ACE_TYPE
Windows NT 5.0 and later: Object-specific access-allowed ACE that uses the ACCESS_ALLOWED_OBJECT_ACE structure.
ACCESS_DENIED_OBJECT_ACE_TYPE
Windows NT 5.0 and later: Object-specific access-denied ACE that uses the ACCESS_DENIED_OBJECT_ACE structure.
SYSTEM_AUDIT_OBJECT_ACE_TYPE
Windows NT 5.0 and later: Object-specific system-audit ACE that uses the SYSTEM_AUDIT_OBJECT_ACE structure.

AceFlags
Specifies a set of ACE type-specific control flags. This member can be a combination of the following values:
Value Meaning
CONTAINER_INHERIT_ACE
Child objects that are containers, such as directories, inherit the ACE as an effective ACE. The inherited ACE is inheritable unless the NO_PROPAGATE_INHERIT_ACE bit flag is also set.
INHERIT_ONLY_ACE
Indicates an inherit-only ACE which does not control access to the object to which it is attached. If this flag is not set, the ACE is an effective ACE which controls access to the object to which it is attached.

Both effective and inherit-only ACEs can be inherited depending on the state of the other inheritance flags.

NO_PROPAGATE_INHERIT_ACE
If the ACE is inherited by a child object, the system clears the OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE flags in the inherited ACE. This prevents the ACE from being inherited by subsequent generations of objects.
OBJECT_INHERIT_ACE
Noncontainer child objects inherit the ACE as an effective ACE.

For child objects that are containers, the ACE is inherited as an inherit-only ACE unless the NO_PROPAGATE_INHERIT_ACE bit flag is also set.
FAILED_ACCESS_ACE_FLAG
Used with system-audit ACEs in a SACL to generate audit messages for failed access attempts.
SUCCESSFUL_ACCESS_ACE_FLAG
Used with system-audit ACEs in a SACL to generate audit messages for successful access attempts.
INHERITED_ACE
Windows NT 5.0 and later: .Indicates that the ACE was inherited. The system sets this bit when it propagates an inherited ACE to a child object.

AceSize
Specifies the size, in bytes, of the ACE.

Remarks

The ACE_HEADER structure is the first member of the various types of ACE structures, such as ACCESS_ALLOWED_ACE.

System-alarm ACEs are not supported in the current version of Windows NT. The AceType member cannot specify the SYSTEM_ALARM_ACE_TYPE or SYSTEM_ALARM_OBJECT_ACE_TYPE values. Do not use the SYSTEM_ALARM_ACE or SYSTEM_ALARM_OBJECT_ACE structures.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, ACCESS_ALLOWED_ACE, ACCESS_ALLOWED_OBJECT_ACE, ACCESS_DENIED_ACE, ACCESS_DENIED_OBJECT_ACE, ACL, SYSTEM_AUDIT_ACE, SYSTEM_AUDIT_OBJECT_ACE


ACL

The ACL structure is the header of an access-control list (ACL). A complete ACL consists of an ACL structure followed by an ordered list of zero or more access-control entries (ACEs).

typedef struct _ACL { // acl
    BYTE AclRevision;
    BYTE Sbz1;
    WORD AclSize;
    WORD AceCount;
    WORD Sbz2;
} ACL;

Members

AclRevision
Specifies the ACL's revision level. This value should be ACL_REVISION. All ACEs in an ACL must be at the same revision level.
Sbz1
Specifies a zero byte of padding that aligns the AclRevision member on a 16-bit boundary.
AclSize
Specifies the size, in bytes, of the ACL. This value includes both the ACL structure and all the ACEs.
AceCount
Specifies the number of ACEs stored in the ACL.
Sbz2
Specifies two zero bytes of padding that align the ACL structure on a 32-bit boundary.

Remarks

An ACL includes a sequential list of zero or more ACEs. The individual ACEs in an ACL are numbered from 0 to n, where n+1 is the number of ACEs in the ACL. When editing an ACL, an application refers to an ACE within the ACL by its index.

There are two types of ACL: discretionary and system.

A discretionary ACL is controlled by the owner of an object or anyone granted WRITE_DAC access to the object. It specifies the access particular users and groups can have to an object. For example, the owner of a file can use a discretionary ACL to control which users and groups can and cannot have access to the file.

An object may also have system-level security information associated with it, in the form of a system ACL controlled by a system administrator. A system ACL can allow the system administrator to audit any attempts to gain access to an object.

Three ACE structures are currently defined:

ACE structure | Description
ACCESS_ALLOWED_ACE | Grants specified rights to a user or group. This ACE is stored in a discretionary ACL.
ACCESS_DENIED_ACE | Denies specified rights to a user or group. This ACE is stored in a discretionary ACL.
SYSTEM_AUDIT_ACE | Specifies what types of access will cause system-level audits. This ACE is stored in a system ACL.

A fourth ACE structure, SYSTEM_ALARM_ACE, is not currently supported by Windows NT.

The ACL structure is to be treated as though it were opaque and applications are not to attempt to work with its members directly. To ensure that ACLs are semantically correct, applications can use the functions listed in the SeeAlso section to create and manipulate ACLs.

Each ACL and ACE structure begins on a doubleword boundary.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, AddAce, DeleteAce, GetAclInformation, GetSecurityDescriptorDacl, GetSecurityDescriptorSacl, InitializeAcl, IsValidAcl, SetAclInformation, SetSecurityDescriptorDacl, SetSecurityDescriptorSacl


ACTRL_ACCESS

[This is preliminary documentation and subject to change.]

The ACTRL_ACCESS structure contains an array of access-control lists for an object and its properties.

typedef struct _ACTRL_ALIST {
    ULONG                       cEntries;
    PACTRL_PROPERTY_ENTRY       pPropertyAccessList;
} ACTRL_ACCESS , *PACTRL_ACCESS;

Members

cEntries
Specifies the number of entries in the pPropertyAccessList array.
pPropertyAccessList
Pointer to an array of ACTRL_PROPERTY_ENTRY structures. Each structure contains a list of access-control entries for an object or a specified property on the object.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Access Control Overview, Access Control Structures, ACTRL_PROPERTY_ENTRY, ConvertAccessToSecurityDescriptor, ConvertSecurityDescriptorToAccessNamed, GetNamedSecurityInfoEx, GetSecurityInfoEx, SetEntriesInAccessList, SetNamedSecurityInfoEx, SetSecurityInfoEx


ACTRL_ACCESS_ENTRY

[This is preliminary documentation and subject to change.]

The ACTRL_ACCESS_ENTRY structure contains access-control information for a specified trustee. This structure stores information equivalent to the access-control information stored in an ACE.

typedef struct _ACTRL_ACCESS_ENTRY {
    TRUSTEE         Trustee;
    ULONG           fAccessFlags;
    ACCESS_RIGHTS   Access;
    ACCESS_RIGHTS   ProvSpecificAccess;
    INHERIT_FLAGS   Inheritance;
    LPCTSTR         lpInheritProperty;
} ACTRL_ACCESS_ENTRY;

Members

Trustee
A TRUSTEE structure that identifies the user, group, or program (such as a Win32 service) to which the access-control entry applies.
fAccessFlags
Indicates how the access rights specified by the Access and ProvSpecificAccess members apply to the trustee. This member can be one of the following values.
Value | Meaning
ACTRL_ACCESS_ALLOWED | The rights are allowed.
ACTRL_ACCESS_DENIED | The rights are denied.
ACTRL_AUDIT_FAILURE | The system generates audit messages for failed attempts to use the rights.
ACTRL_AUDIT_SUCCESS | The system generates audit messages for successful attempts to use the rights.

Access
A bit mask that specifies the access rights that the entry allows, denies, or audits for the trustee. This member must use the provider-independent access flags, such as ACTRL_READ_CONTROL, rather than the Windows NT-specific access flags, such as READ_CONTROL. The provider for the object type converts these provider-independent flags to the corresponding provider-specific flags.

For mappings of the Windows NT-specific access flags for the various object types to the corresponding provider-independent access flags, see Provider-Independent and Windows NT Access Rights.

ProvSpecificAccess
A bit mask that specifies access rights specific to the provider type. The functions that use the ACTRL_ACCESS_ENTRY structure pass these bits on to the provider without interpreting them. In most cases, this value should be zero.
Inheritance
A set of bit flags that determines whether other containers or objects can inherit the access-control entry from the primary object to which the access list is attached. This parameter can be NO_INHERITANCE to indicate that the access-control entry is not inheritable, or it can be a combination of the following values.
Value Meaning
CONTAINER_INHERIT_ACE
Other containers that are contained by the primary object inherit the entry.
INHERIT_ONLY_ACE
The ACE does not apply to the primary object to which the ACL is attached, but objects contained by the primary object inherit the entry.
NO_PROPAGATE_INHERIT_ACE
The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE flags are not propagated to an inherited entry.
OBJECT_INHERIT_ACE
Noncontainer objects contained by the primary object inherit the entry.
SUB_CONTAINERS_ONLY_INHERIT
Other containers that are contained by the primary object inherit the entry. This flag corresponds to the CONTAINER_INHERIT_ACE flag.
SUB_OBJECTS_ONLY_INHERIT
Noncontainer objects contained by the primary object inherit the entry. This flag corresponds to the OBJECT_INHERIT_ACE flag.
SUB_CONTAINERS_AND_OBJECTS_INHERIT
Both containers and noncontainer objects that are contained by the primary object inherit the entry. This flag corresponds to the combination of the CONTAINER_INHERIT_ACE and OBJECT_INHERIT_ACE flags.

lpInheritProperty
Pointer to a null-terminated string that identifies the object types that can inherit the entry.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Access Control Overview, Access Control Structures, TRUSTEE


ACTRL_ACCESS_ENTRY_LIST

[This is preliminary documentation and subject to change.]

The ACTRL_ACCESS_ENTRY_LIST structure contains a list of access entries.

typedef struct _ACTRL_ACCESS_ENTRY_LIST {
    ULONG                   cEntries;
    PACTRL_ACCESS_ENTRY     pAccessList;
} ACTRL_ACCESS_ENTRY_LIST, *PACTRL_ACCESS_ENTRY_LIST;

Members

cEntries
Specifies the number of entries in the pAccessList array.
pAccessList
Pointer to an array of ACTRL_ACCESS_ENTRY structures. Each structure specifies access-control information for a specified trustee.

Remarks

To create an empty access list, set cEntries to zero and pAccessList to NULL. An empty list does not grant access to any trustee, and thus, denies all access to an object.

To create a null access list, set the pAccessEntryList member of an ACTRL_PROPERTY_ENTRY structure to NULL. A null access list grants everyone full access to the object.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Access Control Overview, Access Control Structures, ACTRL_ACCESS_ENTRY, ACTRL_PROPERTY_ENTRY


ACTRL_ACCESS_INFO

[This is preliminary documentation and subject to change.]

The ACTRL_ACCESS_INFO structure is used to return information about the access rights an object supports.

typedef struct _ACTRL_ACCESS_INFO {
    ULONG       fAccessPermission;
    LPTSTR      lpAccessPermissionName;
} ACTRL_ACCESS_INFO, *PACTRL_ACCESS_INFO;

Members

fAccessPermission
A bit flag that specifies a provider-independent access right.
lpAccessPermissionName
Pointer to a null-terminated string containing the name of the access right.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Access Control Overview, Access Control Structures, GetAccessPermissionsForObject


ACTRL_AUDIT

[This is preliminary documentation and subject to change.]

The ACTRL_AUDIT structure contains an array of audit-control lists for an object and its properties.

typedef struct _ACTRL_ALIST {
    ULONG                       cEntries;
    PACTRL_PROPERTY_ENTRY       pPropertyAccessList;
} ACTRL_AUDIT, *PACTRL_AUDIT;

Members

cEntries
Specifies the number of entries in the pPropertyAccessList array.
pPropertyAccessList
Pointer to an array of ACTRL_PROPERTY_ENTRY structures. Each structure contains a list of access-control entries for an object or a specified property on an object.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Access Control Overview, Access Control Structures, ACTRL_PROPERTY_ENTRY, ConvertAccessToSecurityDescriptor, ConvertSecurityDescriptorToAccessNamed, GetNamedSecurityInfoEx, GetSecurityInfoEx, SetEntriesInAuditList, SetNamedSecurityInfoEx, SetSecurityInfoEx


ACTRL_OVERLAPPED

[This is preliminary documentation and subject to change.]

The ACTRL_OVERLAPPED structure stores an event object and state information for an asynchronous access-control operation.

typedef struct _ACTRL_OVERLAPPED {
    ULONG       Reserved1;
    ULONG       Reserved2;
    HANDLE      hEvent;

} ACTRL_OVERLAPPED, *PACTRL_OVERLAPPED;

Members

Reserved1
Reserved for internal use.
Reserved2
Reserved for internal use.
hEvent
Handle to an event object. The SetSecurityInfoEx and SetNamedSecurityInfoEx functions create the event object and return this handle when they start an asynchronous operation. The system sets this event object to the signaled state when the operation is completed successfully or unsuccessfully.

Remarks

The first call to the GetOverlappedAccessResults function for a given ACTRL_OVERLAPPED structure closes the event object handle. Subsequent calls to GetOverlappedAccessResults use information stored in the reserved members to identify the asynchronous operation.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.

See Also

Access Control Overview, Access Control Structures, GetOverlappedAccessResults, SetNamedSecurityInfoEx, SetSecurityInfoEx


ACTRL_PROPERTY_ENTRY

[This is preliminary documentation and subject to change.]

The ACTRL_PROPERTY_ENTRY structure stores a list of access-control entries for an object or a specified property on an object.

typedef struct _ACTRL_PROPERTY_ENTRY {
    LPCTSTR                     lpProperty;
    PACTRL_ACCESS_ENTRY_LIST    pAccessEntryList;
    ULONG                       fListFlags;
} ACTRL_PROPERTY_ENTRY, *PACTRL_PROPERTY_ENTRY;

Members

lpProperty
Pointer to a null-terminated string that specifies the GUID of a property on an object. You can use the UuidToString function to generate a string representation of a property GUID.

If this member is NULL, the access entry list applies to the object; otherwise, it applies to the specified property.

pAccessEntryList
Pointer to an ACTRL_ACCESS_ENTRY_LIST structure that contains a list of access-control entries.
fListFlags
Flags that specify information about the lpProperty property. This member can be the following value.
Value | Meaning
ACTRL_ACCESS_PROTECTED | Protects the object or property from inheriting access-control entries.

Remarks

To create an ACTRL_PROPERTY_ENTRY structure that grants everyone full access to an object, set the pAccessEntryList member to NULL.

To create an ACTRL_PROPERTY_ENTRY structure that denies all access to an object, set the pAccessEntryList member to point to an ACTRL_ACCESS_ENTRY_LIST structure whose cEntries member is zero and pAccessList member is NULL.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Access Control Overview, Access Control Structures, ACTRL_ACCESS, ACTRL_ACCESS_ENTRY_LIST, UuidToString


LUID

An LUID is a 64-bit value guaranteed to be unique only on the system on which it was generated. The uniqueness of a locally unique identifier (LUID) is guaranteed only until the system is restarted.

An LUID is not for direct manipulation. Applications are to use functions and structures to manipulate LUID values.

typedef LARGE_INTEGER LUID

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, AllocateLocallyUniqueId, LookupPrivilegeName, LookupPrivilegeValue, PrivilegeCheck, LUID_AND_ATTRIBUTES, PRIVILEGE_SET


LUID_AND_ATTRIBUTES

The LUID_AND_ATTRIBUTES structure represents a locally unique identifier (LUID) and its attributes.

typedef struct _LUID_AND_ATTRIBUTES { // luaa
    LUID   Luid;
    DWORD  Attributes;
} LUID_AND_ATTRIBUTES;

Members

Luid
Specifies an LUID value.
Attributes
Specifies attributes of the LUID. This value contains up to 32 one-bit flags. Its meaning is dependent on the definition and use of the LUID.

Remarks

An LUID_AND_ATTRIBUTES structure can represent an LUID whose attributes change frequently, such as when it is used to represent privileges in the PRIVILEGE_SET structure. Privileges are represented by LUIDs and have attributes indicating whether they are currently enabled or disabled.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, AllocateLocallyUniqueId, LUID, PRIVILEGE_SET, TOKEN_PRIVILEGES


SECURITY_ATTRIBUTES

The SECURITY_ATTRIBUTES structure contains the security descriptor for an object and specifies whether the handle retrieved by specifying this structure is inheritable.

typedef struct _SECURITY_ATTRIBUTES { // sa
    DWORD  nLength;
    LPVOID lpSecurityDescriptor;
    BOOL   bInheritHandle;
} SECURITY_ATTRIBUTES;

Members

nLength
Specifies the size, in bytes, of this structure. Set this value to the size of the SECURITY_ATTRIBUTES structure.

Windows NT: Some functions that use the SECURITY_ATTRIBUTES structure do not verify the value of the nLength member. However, an application should still set it properly. That ensures current, future, and cross-platform compatibility.

lpSecurityDescriptor
Pointer to a security descriptor for the object that controls the sharing of it. If NULL is specified for this member, the object may be assigned the default security descriptor of the calling process.

Windows 95 and Windows 98: The lpSecurityDescriptor member of the structure is ignored.

bInheritHandle
Specifies whether the returned handle is inherited when a new process is created. If this member is TRUE, the new process inherits the handle.

Remarks

A pointer to a SECURITY_ATTRIBUTES structure is used as a parameter in most kernel and window-management functions in the Win32 API that return a handle of an object.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, SECURITY_DESCRIPTOR


SECURITY_DESCRIPTOR

The SECURITY_DESCRIPTOR structure contains the security information associated with an object. Applications use this structure to set and query an object's security status.

Applications are not to modify the SECURITY_DESCRIPTOR structure directly. For creating and manipulating a security descriptor, use the functions listed in the See Also section.

typedef PVOID PSECURITY_DESCRIPTOR;

Remarks

A security descriptor includes information that specifies the following components of an object's security:

  • An owner (SID)
  • A primary group (SID)
  • A discretionary ACL
  • A system ACL
  • Qualifiers for the preceding items

Security descriptors use access-control lists (ACLs) and security identifiers (SIDs) to specify the information in this list.

A security descriptor can be in absolute or self-relative form. In self-relative form, all members of the structure are located contiguously in memory. In absolute form, the structure only contains pointers to the members.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorLength, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, InitializeSecurityDescriptor, IsValidSecurityDescriptor, SetSecurityDescriptorDacl, SetSecurityDescriptorGroup, SetSecurityDescriptorOwner, SetSecurityDescriptorSacl


SECURITY_INFORMATION

The SECURITY_INFORMATION structure identifies the object-related security information being set or queried. This security information includes:

  • The owner of an object
  • The primary group of an object
  • The discretionary access-control list (ACL) of an object
  • The system ACL of an object
typedef DWORD SECURITY_INFORMATION;

Each item of security information is designated by a bit flag. The following values specify the bits:

Value | Meaning
OWNER_SECURITY_INFORMATION | Indicates the owner identifier of the object is being referenced.
GROUP_SECURITY_INFORMATION | Indicates the primary group identifier of the object is being referenced.
DACL_SECURITY_INFORMATION | Indicates the discretionary ACL of the object is being referenced.
SACL_SECURITY_INFORMATION | Indicates the system ACL of the object is being referenced.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, GetFileSecurity, GetKernelObjectSecurity, GetPrivateObjectSecurity, GetUserObjectSecurity, SetFileSecurity, SetKernelObjectSecurity, SetPrivateObjectSecurity, SetUserObjectSecurity


SID

The SID structure is a variable-length structure used to uniquely identify users or groups. SID stands for security identifier.

Applications are not to modify the SID structure directly. To create and manipulate a security identifier, use the functions listed in the See Also section.

typedef PVOID PSID;

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, AllocateAndInitializeSid, CopySid, EqualSid, FreeSid, GetLengthSid, GetSidIdentifierAuthority, GetSidLengthRequired, GetSidSubAuthority, GetSidSubAuthorityCount, InitializeSid, IsValidSid, LookupAccountName, LookupAccountSid


SID_AND_ATTRIBUTES

The SID_AND_ATTRIBUTES structure represents a security identifier (SID) and its attributes. SIDs are used to uniquely identify users or groups.

typedef struct _SID_AND_ATTRIBUTES { // saa
    PSID  Sid;
    DWORD Attributes;
} SID_AND_ATTRIBUTES ;

Members

Sid
Pointer to a SID structure.
Attributes
Specifies attributes of the SID. This value contains up to 32 one-bit flags. Its meaning depends on the definition and use of the SID.

Remarks

A group is represented by a SID. SIDs have attributes that indicate whether they are currently enabled, disabled, or mandatory, and how they are used. A SID_AND_ATTRIBUTES structure can represent a SID whose attributes change frequently. For example, it is used to represent groups in the TOKEN_GROUPS structure.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, SID, TOKEN_GROUPS, TOKEN_USER


SID_IDENTIFIER_AUTHORITY

The SID_IDENTIFIER_AUTHORITY structure represents the top-level authority of a security identifier (SID).

typedef struct _SID_IDENTIFIER_AUTHORITY { // sia
    BYTE Value[6];
} SID_IDENTIFIER_AUTHORITY ;

Members

Value
An array of six bytes specifying a SID's top-level authority.

Remarks

The identifier authority value identifies the agency that issued the SID. Some identifier authorities are predefined:

Identifier authority | Value
SECURITY_NULL_SID_AUTHORITY | 0
SECURITY_WORLD_SID_AUTHORITY | 1
SECURITY_LOCAL_SID_AUTHORITY | 2
SECURITY_CREATOR_SID_AUTHORITY | 3
SECURITY_NT_AUTHORITY | 5

A SID must contain a top-level authority and at least one relative identifier (RID) value.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, AllocateAndInitializeSid, GetSidIdentifierAuthority, InitializeSid, SID


TOKEN_CONTROL

The TOKEN_CONTROL structure contains information that identifies an access token.

typedef struct _TOKEN_CONTROL { // tc
    LUID TokenId;
    LUID AuthenticationId;
    LUID ModifiedId;
    TOKEN_SOURCE TokenSource;
} TOKEN_CONTROL ;

Members

TokenId
Specifies a locally unique identifier (LUID) identifying this instance of the token object.
AuthenticationId
Specifies an LUID assigned to the session this token represents. There can be many tokens representing a single logon session.
ModifiedId
Specifies an LUID that changes each time the token is modified. An application can use this value as a test of whether a security context has changed since it was last used.
TokenSource
Specifies a TOKEN_SOURCE structure identifying the agency that issued the token. This information is used in audit logging.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, LUID, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_DEFAULT_DACL

The TOKEN_DEFAULT_DACL structure specifies a discretionary access-control list (ACL).

typedef struct _TOKEN_DEFAULT_DACL {  // tdd
    PACL DefaultDacl;
} TOKEN_DEFAULT_DACL;

Members

DefaultDacl
Pointer to an ACL structure assigned by default to any objects created by the user represented by the access token.

Remarks

The GetTokenInformation function retrieves the default discretionary ACL for an access token, in the form of a TOKEN_DEFAULT_DACL structure. This structure is also used with the SetTokenInformation function to set the default discretionary ACL.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, ACL, GetTokenInformation, SetTokenInformation, TOKEN_CONTROL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_GROUPS

[This is preliminary documentation and subject to change.]

The TOKEN_GROUPS structure contains information about the group SIDs in an access token.

typedef struct _TOKEN_GROUPS { // tg
    DWORD GroupCount;
    SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
} TOKEN_GROUPS;

Members

GroupCount
Specifies the number of groups in the access token.
Groups
Specifies an array of SID_AND_ATTRIBUTES structures containing a set of SIDs and corresponding attributes.

The Attributes members of the SID_AND_ATTRIBUTES structures can have the following attributes.
Value | Meaning
SE_GROUP_MANDATORY | The SID cannot have the SE_GROUP_ENABLED attribute cleared by a call to the AdjustTokenGroups function. However, you can use the CreateRestrictedToken function to convert a mandatory SID to a deny-only SID.
SE_GROUP_ENABLED_BY_DEFAULT | The SID is enabled by default.
SE_GROUP_ENABLED The SID is enabled for access checks. When the system performs an access check, it checks for access-allowed and access-denied ACEs that apply to the SID.

A SID without this attribute is ignored during an access check unless the SE_GROUP_USE_FOR_DENY_ONLY attribute is set.
SE_GROUP_OWNER | The SID identifies a group account for which the token's user is the owner of the group; or the SID can be assigned as the owner of the token or objects.
SE_GROUP_USE_FOR_DENY_ONLY Windows NT 5.0 and later: The SID is deny-only in a restricted token. When the system performs an access check, it checks for access-denied ACEs that apply to the SID, but ignores access-allowed ACEs for the SID.

If this attribute is set, the SE_GROUP_ENABLED is not set, and the SID cannot be re-enabled.
SE_GROUP_LOGON_ID | The SID is a logon SID that identifies the logon session associated with an access token.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, AdjustTokenGroups, SID_AND_ATTRIBUTES, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_OWNER

The TOKEN_OWNER structure contains the default owner SID that will be applied to newly created objects.

typedef struct _TOKEN_OWNER { // to
    PSID Owner;
} TOKEN_OWNER;

Members

Owner
Pointer to a SID structure representing a user who will become the owner of any objects created by a process using this access token. The security identifier (SID) must be one of the user or group SIDs already in the token.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, GetTokenInformation, SetTokenInformation, SID , TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_PRIMARY_GROUP

The TOKEN_PRIMARY_GROUP structure specifies a group security identifier (SID) for an access token.

typedef struct _TOKEN_PRIMARY_GROUP { // tpg
    PSID PrimaryGroup;
} TOKEN_PRIMARY_GROUP;

Members

PrimaryGroup
Pointer to a SID structure representing a group that will become the primary group of any objects created by a process using this access token. The security identifier (SID) must be one of the group SIDs already in the token.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, GetTokenInformation, SetTokenInformation, SID, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_PRIVILEGES

The TOKEN_PRIVILEGES structure contains information about a set of privileges for an access token.

typedef struct _TOKEN_PRIVILEGES { // tp
    DWORD PrivilegeCount;
    LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
} TOKEN_PRIVILEGES;

Members

PrivilegeCount
Specifies the number of entries in the Privileges array.
Privileges
Specifies an array of LUID_AND_ATTRIBUTES structures. Each structure contains the LUID and attributes of a privilege. The attributes of a privilege can be a combination of the following values:
Attribute Description
SE_PRIVILEGE_ENABLED_BY_DEFAULT
The privilege is enabled by default.
SE_PRIVILEGE_ENABLED
The privilege is enabled.
SE_PRIVILEGE_USED_FOR_ACCESS
The privilege was used to gain access to an object or service. This flag is used to identify the relevant privileges in a set passed by a client application that may contain unnecessary privileges.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, AdjustTokenPrivileges, GetTokenInformation, LUID, LUID_AND_ATTRIBUTES, PrivilegeCheck, PrivilegedServiceAuditAlarm, PRIVILEGE_SET, SetTokenInformation, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_SOURCE

The TOKEN_SOURCE structure identifies the source of an access token.

typedef struct _TOKEN_SOURCE { // ts
    Char Sourcename[8];
    LUID SourceIdentifier;
} TOKEN_SOURCE;

Members

SourceName
Specifies an 8-byte character string used to identify the source of an access token. This is used to distinguish between such sources as Session Manager, LAN Manager, and RPC Server. A string, rather than a constant, is used to identify the source so users and developers can make extensions to the system, such as by adding other networks, that act as the source of access tokens.
SourceIdentifier
Specifies a locally unique identifier (LUID) provided by the source component named by the SourceName member. This value aids the source component in relating context blocks, such as session-control structures, to the token. This value is typically, but not necessarily, an LUID.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, GetTokenInformation, LUID, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_STATISTICS

The TOKEN_STATISTICS structure contains information about an access token. An application can retrieve this information by calling the GetTokenInformation function.

typedef struct _TOKEN_STATISTICS { // tst
    LUID  TokenId;
    LUID  AuthenticationId;
    LARGE_INTEGER ExpirationTime;
    TOKEN_TYPE    TokenType;
    SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
    DWORD DynamicCharged;
    DWORD DynamicAvailable;
    DWORD GroupCount;
    DWORD PrivilegeCount;
    LUID  ModifiedId;
} TOKEN_STATISTICS;

Members

TokenId
Specifies a locally unique identifier (LUID) that identifies this instance of the token object.
AuthenticationId
Specifies an LUID assigned to the session this token represents. There can be many tokens representing a single logon session.
ExpirationTime
Specifies the time at which this token expires. Expiration times for access tokens are not supported in the current version of Windows NT.
TokenType
Specifies a TOKEN_TYPE enumerated type indicating whether the token is a primary or impersonation token.
ImpersonationLevel
Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type indicating the impersonation level of the token. This member is valid only if the TokenType is TokenImpersonation.
DynamicCharged
Specifies the amount, in bytes, of memory allocated for storing default protection and a primary group identifier.
DynamicAvailable
Specifies the portion of memory allocated for storing default protection and a primary group identifier not already in use. This value is returned as a count of free bytes.
GroupCount
Specifies the number of supplemental group security identifiers (SIDs) included in the token.
PrivilegeCount
Specifies the number of privileges included in the token.
ModifiedId
Specifies an LUID that changes each time the token is modified. An application can use this value as a test of whether a security context has changed since it was last used.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, GetTokenInformation, LUID, SECURITY_IMPERSONATION_LEVEL, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_TYPE, TOKEN_USER


TOKEN_USER

The TOKEN_USER structure identifies the user associated with an access token.

typedef struct _TOKEN_USER { // tu
    SID_AND_ATTRIBUTES User;
} TOKEN_USER;

Members

User
Specifies an SID_AND_ATTRIBUTES structure representing the user associated with the access token. There are currently no attributes defined for user security identifiers (SIDs).

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Structures, GetTokenInformation, SID_AND_ATTRIBUTES, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE


TRUSTEE

The TRUSTEE structure identifies the user account, group account, or logon session to which an ACE applies. The structure can use a name or a security identifier (SID) to identify the trustee.

Access control functions, such as SetEntriesInAcl and GetExplicitEntriesFromAcl, use this structure to identify the logon account associated with the access-control or audit-control information in an EXPLICIT_ACCESS structure.

typedef struct _TRUSTEE
{
    PTRUSTEE                    pMultipleTrustee;
    MULTIPLE_TRUSTEE_OPERATION  MultipleTrusteeOperation;
    TRUSTEE_FORM                TrusteeForm;
    TRUSTEE_TYPE                TrusteeType;
    LPTSTR                      ptstrName;
} TRUSTEE;

Members

pMultipleTrustee
Pointer to a TRUSTEE structure that identifies a server account that can impersonate the user identified by the ptstrName member. Windows NT does not currently support this functionality; therefore, this member must be NULL.
MultipleTrusteeOperation
Specifies a value from the MULTIPLE_TRUSTEE_OPERATION enumeration type. Currently, this member must be NO_MULTIPLE_TRUSTEE.
TrusteeForm
Specifies a value from the TRUSTEE_FORM enumeration type that indicates whether the trustee is identified by name or by a SID.
TrusteeType
Specifies a value from the TRUSTEE_TYPE enumeration type that indicates whether the trustee is a user account, a group account, or the account type is unknown.
ptstrName
If TrusteeForm is TRUSTEE_IS_NAME, this member is a pointer to a null-terminated string that contains the name of the trustee.

If TrusteeForm is TRUSTEE_IS_SID, this member is a pointer to the SID of the trustee.

Remarks

A trustee name can have any of the following formats:

  • A fully qualified name, such as "g:\remotedir\abc".
  • A Windows NT version 3.x or later domain account, such as "redmond\xyz".
  • One of the predefined group names, such as "EVERYONE" or "GUEST".
  • One of the following special names.
Name | Meaning
"CURRENT_USER" | Indicates the owner of the calling thread or process.
"CREATOR OWNER" | Indicates the CREATOR_OWNER security identifier. This is a SID used in inheritable ACEs. When a new object is created, the system replaces this SID with the SID of the user who created the object.
"CREATOR GROUP" | Indicates the CREATOR_GROUP security identifier. This is a SID used in inheritable ACEs. When a new object is created, the system replaces this SID with the primary group SID of the user who created the object.

A trustee SID can be any user or group SID. It can also be any of the universal, well-known SIDs. For more information, see Security Identifiers (SIDs).

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Access Control Overview, Access Control Structures, ACL, EXPLICIT_ACCESS, GetExplicitEntriesFromAcl, MULTIPLE_TRUSTEE_OPERATION, SetEntriesInAcl, SID, TRUSTEE_FORM, TRUSTEE_TYPE


TRUSTEE_ACCESS

[This is preliminary documentation and subject to change.]

The TRUSTEE_ACCESS structure is used with the TrusteeAccessToObject function to determine whether a trustee has specified access rights to an object or its properties.

typedef struct _TRUSTEE_ACCESS {
    LPTSTR          lpProperty;
    ACCESS_RIGHTS   Access;
    ULONG           fAccessFlags;
    ULONG           fReturnedAccess;
} TRUSTEE_ACCESS, *PTRUSTEE_ACCESS;

Members

lpProperty
Pointer to a null-terminated string that specifies the GUID of a property on an object. You can use the UuidToString function to generate a string representation of a property GUID. If this member is NULL, TrusteeAccessToObject checks the trustee's access to the object. If this member is non-NULL, the function checks the trustee's access to the specified property on the object.
Access
A bit mask that specifies the access rights to check. This member must use the provider-independent access flags, such as ACTRL_READ_CONTROL, rather than the Windows NT-specific access flags, such as READ_CONTROL. The provider for the object type converts these provider-independent flags to the corresponding provider-specific flags.

If fAccessFlags is TRUSTEE_ACCESS_READ_WRITE, set the Access member to zero.

For mappings of the Windows NT-specific access flags for the various object types to the corresponding provider-independent access flags, see Provider-Independent and Windows NT Access Rights.

fAccessFlags
Indicates whether the Access member specifies the access rights to check. This member can be one of the following values.
Value | Meaning
TRUSTEE_ACCESS_EXPLICIT | The Access member specifies the access rights to check.
TRUSTEE_ACCESS_READ_WRITE | Check for READ, WRITE, or READ_WRITE access to the object. Set the Access member to zero.

fReturnedAccess
When the TrusteeAccessToObject function returns, this member indicates the results of the access check. If fReturnedAccess returns zero, the trustee does not have the specified access to the object or property.

If the fAccessFlags member specified TRUSTEE_ACCESS_EXPLICIT, a value of TRUSTEE_ACCESS_ALLOWED indicates that the trustee has the access rights specified by the Access member.

If fAccessFlags specified TRUSTEE_ACCESS_READ_WRITE, this member can return one of the following values to indicate the allowed access rights.
Value | Meaning
TRUSTEE_ACCESS_READ | The trustee has only read access to the object or property.
TRUSTEE_ACCESS_READ_WRITE | The trustee has both read and write access.
TRUSTEE_ACCESS_WRITE | The trustee has only write access.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Access Control Overview, Access Control Structures, TrusteeAccessToObject, UuidToString


Access Control Enumeration Types

The following enumeration types are used with security.

ACL_INFORMATION_CLASS
MULTIPLE_TRUSTEE_OPERATION
SE_OBJECT_TYPE
SID_NAME_USE
TOKEN_INFORMATION_CLASS
TOKEN_TYPE
TRUSTEE_FORM
TRUSTEE_TYPE


ACL_INFORMATION_CLASS

The ACL_INFORMATION_CLASS enumeration type contains values that specify the type of information being assigned to or retrieved from an access-control list (ACL).

typedef enum _ACL_INFORMATION_CLASS {
    AclRevisionInformation = 1,    // ACL revision information
    AclSizeInformation             // ACL size information
} ACL_INFORMATION_CLASS;

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Enumeration Types, ACL, ACL_REVISION_INFORMATION, ACL_SIZE_INFORMATION, GetAclInformation, SetAclInformation


MULTIPLE_TRUSTEE_OPERATION

The MULTIPLE_TRUSTEE_OPERATION enumeration type contains values that indicate whether a TRUSTEE structure is an impersonate trustee.

typedef enum _MULTIPLE_TRUSTEE_OPERATION
{
    NO_MULTIPLE_TRUSTEE,
    TRUSTEE_IS_IMPERSONATE,
} MULTIPLE_TRUSTEE_OPERATION;

Enumerator Value | Meaning
NO_MULTIPLE_TRUSTEE | The trustee is not an impersonate trustee.
TRUSTEE_IS_IMPERSONATE | The trustee is an impersonate trustee. The pMultipleTrustee member of the TRUSTEE structure points to a trustee for a server that can impersonate the client trustee.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.

See Also

Access Control Overview, Access Control Enumeration Types, TRUSTEE


SE_OBJECT_TYPE

The SE_OBJECT_TYPE enumeration type contains values that correspond to the types of Win32 objects that support security. The functions, such as GetSecurityInfoEx and SetSecurityInfoEx, that set and retrieve an object's security information, use these values to indicate the type of object.

typedef enum _SE_OBJECT_TYPE
{
    SE_UNKNOWN_OBJECT_TYPE = 0,
    SE_FILE_OBJECT,
    SE_SERVICE,
    SE_PRINTER,
    SE_REGISTRY_KEY,
    SE_LMSHARE,
    SE_KERNEL_OBJECT,
    SE_WINDOW_OBJECT,
// #if(_WIN32_WINNT >= 0x0500)
    SE_DS_OBJECT,
    SE_DS_OBJECT_ALL,
    SE_PROVIDER_DEFINED_OBJECT
// #endif /* _WIN32_WINNT >=  0x0500 */
} SE_OBJECT_TYPE;
Enumerator Value | Meaning
SE_FILE_OBJECT Indicates a file or directory. The name string that identifies a file or directory object can be
  • A relative path, such as "abc.dat" or "..\abc.dat"
  • An absolute path, such as "\abc.dat", "c:\dir1\abc.dat", or "g:\remotedir\abc.dat"
  • A UNC name, such as "\\machinename\sharename\abc.dat".
  • A local file system root, such as "\\\\.\\c:". Security set on a file system root does not persist when the system is restarted.
SE_SERVICE | Indicates a Win32 service. A service object can be a local service, such as "servicename"; or a remote service, such as "\\machinename\servicename".
SE_PRINTER | Indicates a printer. A printer object can be a local printer, such as "printername"; or a remote printer, such as "\\machinename\printername".
SE_REGISTRY_KEY Indicates a registry key. A registry key object can be in the local registry, such as "CLASSES_ROOT\somepath"; or in a remote registry, such as "\\machinename\CLASSES_ROOT\somepath".

The names of registry keys must use the following literal strings to identify the predefined registry keys: "CLASSES_ROOT", "CURRENT_USER", "MACHINE", and "USERS".
SE_LMSHARE | Indicates a Windows NT network share. A share object can be local, such as "sharename"; or remote, such as "\\machinename\sharename".
SE_KERNEL_OBJECT Indicates a local kernel object, which includes the following object types: process, thread, semaphore, event, mutex, file mapping, waitable timer, access token, mailslot, named pipe, or anonymous pipe.

The GetSecurityInfoEx and SetSecurityInfoEx functions support all types of kernel objects for which provider-independent access rights are defined. The GetNamedSecurityInfoEx and SetNamedSecurityInfoEx functions work only with the following kernel objects: semaphore, event, mutex, waitable timer, and file mapping objects.

To access the security descriptor of an access token, use the GetSecurityInfo and SetSecurityInfo functions.

SE_WINDOW_OBJECT | Indicates a window station or desktop object on the local computer. You cannot use GetNamedSecurityInfoEx and SetNamedSecurityInfoEx with these objects because the names of window stations or desktops are not unique.
SE_DS_OBJECT Indicates a directory service (DS) object, or a property set or property of a directory service object.

The name string for a DS object can be a UNC name, such as "\\domain.microsoft.com\ou1\ou2\someobject".

The name string can also be in X.500 form, such as "CN=someobject,OU=ou2,OU=ou1,DC=domain,DC=microsoft,DC=com,O=internet".
SE_DS_OBJECT_ALL | Indicates a directory service object and all of its property sets and properties.
SE_PROVIDER_DEFINED_OBJECT | Indicates a provider-defined object.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.

See Also

Access Control Overview, Access Control Enumeration Types, GetSecurityInfo, GetSecurityInfoEx, GetNamedSecurityInfo, GetNamedSecurityInfoEx, SetSecurityInfo, SetSecurityInfoEx, SetNamedSecurityInfo, SetNamedSecurityInfoEx


SID_NAME_USE

The SID_NAME_USE enumeration type contains values that specify the type of a security identifier (SID).

typedef enum _SID_NAME_USE {
    SidTypeUser = 1,
    SidTypeGroup,
    SidTypeDomain,
    SidTypeAlias,
    SidTypeWellKnownGroup,
    SidTypeDeletedAccount,
    SidTypeInvalid,
    SidTypeUnknown
} SID_NAME_USE;

Enumerator Value | Meaning
SidTypeUser | Indicates a user SID.
SidTypeGroup | Indicates a group SID.
SidTypeDomain | Indicates a domain SID.
SidTypeAlias | Indicates an alias SID.
SidTypeWellKnownGroup | Indicates an SID for a well-known group.
SidTypeDeletedAccount | Indicates an SID for a deleted account.
SidTypeInvalid | Indicates an invalid SID.
SidTypeUnknown | Indicates an unknown SID type.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Enumeration Types, LookupAccountName, LookupAccountSid


TOKEN_INFORMATION_CLASS

The TOKEN_INFORMATION_CLASS enumeration type contains values that specify the type of information being assigned to or retrieved from an access token.

typedef enum _TOKEN_INFORMATION_CLASS { // tic
    TokenUser = 1,
    TokenGroups,
    TokenPrivileges,
    TokenOwner,
    TokenPrimaryGroup,
    TokenDefaultDacl,
    TokenSource,
    TokenType,
    TokenImpersonationLevel,
    TokenStatistics,
    TokenRestrictedSids
} TOKEN_INFORMATION_CLASS;

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Enumeration Types, GetTokenInformation, SetTokenInformation, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_TYPE

The TOKEN_TYPE enumeration type contains values that differentiate between a primary token and an impersonation token.

typedef enum tagTOKEN_TYPE { // tt
    TokenPrimary = 1,
    TokenImpersonation
} TOKEN_TYPE;

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Access Control Overview, Access Control Enumeration Types, GetTokenInformation, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_USER


TRUSTEE_FORM

The TRUSTEE_FORM enumeration type contains values that indicate how a TRUSTEE structure identifies the trustee.

typedef enum _TRUSTEE_FORM
{
    TRUSTEE_IS_SID,
    TRUSTEE_IS_NAME,
} TRUSTEE_FORM;

Enumerator Value | Meaning
TRUSTEE_IS_SID | The trustee is identified by a security identifier (SID).
TRUSTEE_IS_NAME | The trustee is identified by a name.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.

See Also

Access Control Overview, Access Control Enumeration Types, TRUSTEE


TRUSTEE_TYPE

The TRUSTEE_TYPE enumeration type contains values that indicate the type of trustee identified by a TRUSTEE structure.

typedef enum _TRUSTEE_TYPE
{
    TRUSTEE_IS_UNKNOWN,
    TRUSTEE_IS_USER,
    TRUSTEE_IS_GROUP,
} TRUSTEE_TYPE;

Enumerator Value | Meaning
TRUSTEE_IS_UNKNOWN | The trustee type is unknown, but not necessarily invalid. The functions that use TRUSTEE structures do not validate the trustee type information.
TRUSTEE_IS_USER | The trustee account is a user account.
TRUSTEE_IS_GROUP | The trustee account is a group account.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.

See Also

Access Control Overview, Access Control Enumeration Types, TRUSTEE


Windows NT Privileges

The following privilege constants are defined for Windows NT. These constants are defined as strings in WINNT.H. For example, the SE_AUDIT_NAME constant is defined as "SeAuditPrivilege".

The functions that get and adjust the privileges in an access token use the LUID type to identify privileges. Use the LookupPrivilegeValue function to determine the LUID on the local system that corresponds to a privilege constant. Use the LookupPrivilegeName function to convert a LUID to its corresponding string constant.

Privilege Constant | Description
SE_ASSIGNPRIMARYTOKEN_NAME | Required to assign the primary token of a process.
SE_AUDIT_NAME | Required to generate audit-log entries. Give this privilege to secure servers.
SE_BACKUP_NAME | Required to perform backup operations.
SE_CHANGE_NOTIFY_NAME | Required to receive notifications of changes to files or directories. This privilege also causes the system to skip all traversal access checks. It is enabled by default for all users.
SE_CREATE_PAGEFILE_NAME | Required to create a paging file.
SE_CREATE_PERMANENT_NAME | Required to create a permanent object.
SE_CREATE_TOKEN_NAME | Required to create a primary token.
SE_DEBUG_NAME | Required to debug a process.
SE_INC_BASE_PRIORITY_NAME | Required to increase the base priority of a process.
SE_INCREASE_QUOTA_NAME | Required to increase the quota assigned to a process.
SE_LOAD_DRIVER_NAME | Required to load or unload a device driver.
SE_LOCK_MEMORY_NAME | Required to lock physical pages in memory.
SE_PROF_SINGLE_PROCESS_NAME | Required to gather profiling information for a single process.
SE_REMOTE_SHUTDOWN_NAME | Required to shut down a system using a network request.
SE_RESTORE_NAME | Required to perform restore operations. This privilege enables you to set any valid user or group SID as the owner of an object.
SE_SECURITY_NAME | Required to perform a number of security-related functions, such as controlling and viewing audit messages. This privilege identifies its holder as a security operator.
SE_SHUTDOWN_NAME | Required to shut down a local system.
SE_SYSTEM_ENVIRONMENT_NAME | Required to modify the nonvolatile RAM of systems that use this type of memory to store configuration information.
SE_SYSTEM_PROFILE_NAME | Required to gather profiling information for the entire system.
SE_SYSTEMTIME_NAME | Required to modify the system time.
SE_TAKE_OWNERSHIP_NAME | Required to take ownership of an object without being granted discretionary access. This privilege allows the owner value to be set only to those values that the holder may legitimately assign as the owner of an object.
SE_TCB_NAME | This privilege identifies its holder as part of the trusted computer base. Some trusted protected subsystems are granted this privilege. This privilege is required to call the LogonUser function.
SE_UNSOLICITED_INPUT_NAME | Required to read unsolicited input from a terminal device.
SE_MACHINE_ACCOUNT_NAME | Required to create a machine account.


Provider-Independent and Windows NT Access Rights

The following tables map the Windows NT access rights for the various object types to the corresponding provider-independent access rights.

The following table shows the standard access rights.

Windows NT standard rights | Provider-independent rights
DELETE | ACTRL_DELETE
READ_CONTROL | ACTRL_READ_CONTROL
SYNCHRONIZE | ACTRL_SYNCHRONIZE
WRITE_DAC | ACTRL_CHANGE_ACCESS
WRITE_OWNER | ACTRL_CHANGE_OWNER

The following table shows the access rights for file objects.

Windows NT file rights | Provider-independent rights
FILE_APPEND_DATA | ACTRL_FILE_APPEND
FILE_EXECUTE | ACTRL_FILE_EXECUTE
FILE_READ_ATTRIBUTES | ACTRL_FILE_READ_ATTRIB
FILE_READ_DATA | ACTRL_FILE_READ
FILE_READ_EA | ACTRL_FILE_READ_PROP
FILE_WRITE_ATTRIBUTES | ACTRL_FILE_WRITE_ATTRIB
FILE_WRITE_DATA | ACTRL_FILE_WRITE
FILE_WRITE_EA | ACTRL_FILE_WRITE_PROP

The following table shows the access rights for directory objects.

Windows NT directory rights | Provider-independent rights
FILE_ADD_SUBDIRECTORY | ACTRL_DIR_CREATE_CHILD
FILE_ADD_FILE | ACTRL_DIR_CREATE_OBJECT
FILE_DELETE_CHILD | ACTRL_DIR_DELETE_CHILD
FILE_LIST_DIRECTORY | ACTRL_DIR_LIST
FILE_TRAVERSE | ACTRL_DIR_TRAVERSE

The following table shows the access rights for registry key.

Windows NT registry key rights | Provider-independent rights
KEY_CREATE_LINK | ACTRL_REG_LINK
KEY_CREATE_SUB_KEY | ACTRL_REG_CREATE_CHILD
KEY_ENUMERATE_SUB_KEYS | ACTRL_REG_LIST
KEY_NOTIFY | ACTRL_REG_NOTIFY
KEY_QUERY_VALUE | ACTRL_REG_QUERY
KEY_SET_VALUE | ACTRL_REG_SET

The following table shows the access rights for event objects.

Windows NT event rights | Provider-independent rights
EVENT_MODIFY_STATE | ACTRL_KERNEL_SET_INFO
SYNCHRONIZE | ACTRL_SYNCHRONIZE

The following table shows the access rights for semaphore objects.

Windows NT semaphore rights | Provider-independent rights
SEMAPHORE_MODIFY_STATE | ACTRL_KERNEL_SET_INFO
SYNCHRONIZE | ACTRL_SYNCHRONIZE

The following table shows the access rights for mutex objects.

Windows NT mutex rights | Provider-independent rights
MUTEX_MODIFY_STATE | ACTRL_KERNEL_SET_INFO
SYNCHRONIZE | ACTRL_SYNCHRONIZE

The following table shows the access rights for timer objects.

Windows NT timer rights | Provider-independent rights
TIMER_MODIFY_STATE | ACTRL_KERNEL_SET_INFO
SYNCHRONIZE | ACTRL_SYNCHRONIZE

The following table shows the access rights for thread objects.

Windows NT thread rights | Provider-independent rights
THREAD_ALERT | ACTRL_KERNEL_ALERT
THREAD_DIRECT_IMPERSONATION | ACTRL_KERNEL_DIMPERSONATE
THREAD_GET_CONTEXT | ACTRL_KERNEL_GET_CONTEXT
THREAD_IMPERSONATE | ACTRL_KERNEL_IMPERSONATE
THREAD_QUERY_INFORMATION | ACTRL_KERNEL_GET_INFO
THREAD_SET_CONTEXT | ACTRL_KERNEL_SET_CONTEXT
THREAD_SET_INFORMATION | ACTRL_KERNEL_SET_INFO
THREAD_SET_THREAD_TOKEN | ACTRL_KERNEL_TOKEN
THREAD_SUSPEND_RESUME | ACTRL_KERNEL_CONTROL
THREAD_TERMINATE | ACTRL_KERNEL_KILL

The following table shows the access rights for process objects.

Windows NT process rights | Provider-independent rights
PROCESS_CREATE_PROCESS | ACTRL_KERNEL_PROCESS
PROCESS_CREATE_THREAD | ACTRL_KERNEL_THREAD
PROCESS_DUP_HANDLE | ACTRL_KERNEL_DUP_HANDLE
PROCESS_QUERY_INFORMATION | ACTRL_KERNEL_GET_INFO
PROCESS_SET_INFORMATION | ACTRL_KERNEL_SET_INFO
PROCESS_TERMINATE | ACTRL_KERNEL_KILL
PROCESS_VM_OPERATION | ACTRL_KERNEL_VM
PROCESS_VM_READ | ACTRL_KERNEL_VM_READ
PROCESS_VM_WRITE | ACTRL_KERNEL_VM_WRITE

The following table shows the access rights for printer objects.

Windows NT printer rights | Provider-independent rights
JOB_ACCESS_ADMINISTER | ACTRL_PRINT_JADMIN
PRINTER_ACCESS_ADMINISTER | ACTRL_PRINT_PADMIN
PRINTER_ACCESS_USE | ACTRL_PRINT_PUSE
SERVER_ACCESS_ADMINISTER | ACTRL_PRINT_SADMIN
SERVER_ACCESS_ENUMERATE | ACTRL_PRINT_SLIST

The following table shows the access rights for Win32 service objects.

Windows NT service rights | Provider-independent rights
SERVICE_CHANGE_CONFIG | ACTRL_SVC_SET_INFO
SERVICE_ENUMERATE_DEPENDENTS | ACTRL_SVC_LIST
SERVICE_INTERROGATE | ACTRL_SVC_INTERROGATE
SERVICE_PAUSE_CONTINUE | ACTRL_SVC_PAUSE
SERVICE_QUERY_CONFIG | ACTRL_SVC_GET_INFO
SERVICE_QUERY_STATUS | ACTRL_SVC_STATUS
SERVICE_START | ACTRL_SVC_START
SERVICE_STOP | ACTRL_SVC_STOP
SERVICE_USER_DEFINED_CONTROL | ACTRL_SVC_UCONTROL

The following table shows the access rights for window station objects.

Windows NT window station rights | Provider-independent rights
WINSTA_ACCESSCLIPBOARD | ACTRL_WIN_CLIPBRD
WINSTA_ACCESSGLOBALATOMS | ACTRL_WIN_GLOBAL_ATOMS
WINSTA_CREATEDESKTOP | ACTRL_WIN_CREATE
WINSTA_ENUMDESKTOPS | ACTRL_WIN_LIST_DESK
WINSTA_ENUMERATE | ACTRL_WIN_LIST
WINSTA_EXITWINDOWS | ACTRL_WIN_EXIT
WINSTA_READATTRIBUTES | ACTRL_WIN_READ_ATTRIBS
WINSTA_READSCREEN | ACTRL_WIN_SCREEN
WINSTA_WRITEATTRIBUTES | ACTRL_WIN_WRITE_ATTRIBS

The following table shows the access rights for directory service objects.

Windows NT DS object rights | Provider-independent rights
DS_CREATE_CHILD | ACTRL_DS_CREATE_CHILD
DS_DELETE_CHILD | ACTRL_DS_DELETE_CHILD
DS_LIST_CONTENTS | ACTRL_DS_LIST
DS_OPEN | ACTRL_DS_OPEN
DS_READ_PROPERTY | ACTRL_DS_READ_PROP
DS_SELF_WRITE | ACTRL_DS_SELF
DS_WRITE_PROPERTY | ACTRL_DS_WRITE_PROP


Client/Server Access Control

In the client/server model, clients connect to a server to access the server's functionality and data. A protected server controls access to its functionality and data based on the identity and privileges of its clients.

Microsoft® Windows NT® provides a set of security functions that a protected server can use for access control. These functions extend the Windows NT access-control model to control access to private objects and to server functionality.


About Client/Server Access Control

A server application provides services to clients. For example, a server could perform the following services on behalf of a client:

  • Save and retrieve information from a private database.
  • Access network resources.
  • Start processes in the client's security context on the server's computer.

A protected server controls access to its services. Windows NT provides security support that enables a server to do the following:

  • Impersonate a client's security context, which causes the system to perform most access and privilege checks against the client's access token rather than the server's.
  • Log a client on to the server's computer.
  • Connect to network resources using the client's security context.
  • Create security descriptors to protect private objects.
  • Determine whether a security descriptor allows access to a client.
  • Determine whether a set of privileges are enabled in a client's token.
  • Generate audit messages in the security event log to record attempts by a client to access objects or use privileges.


The Client's Security Context

Like all processes, a protected server has a primary access token that describes its security context. When a client connects to a protected server, the server may want to perform actions using the client's security context instead of the server's security context. For example, when a client in a dynamic data exchange (DDE) conversation requests information from a DDE server, the server needs to verify that the client is allowed access to the information.

There are two ways that a server can act in the client's security context.

  • A thread of the server process can impersonate the client. In this case, the server's thread has an impersonation access token that identifies the client, the client's groups, and the client's privileges. For more information, see Client Impersonation.
  • The server can get the client's credentials and log the client on to the server's computer. This creates a new logon session and produces a primary access token for the client. The server can then use the client's access token to impersonate the client or to start a new process that runs in the security context of the client. For more information, see Client Logon Sessions.

In most cases, impersonating the client is sufficient. Impersonation enables the server to check the client's access to securable objects, to check the client's privileges, and to generate audit log entries that identify the client. Typically, a server needs to start a client logon session only if it needs to use the client's security context to access network resources.


Client Impersonation

Impersonation is the ability of a thread to execute in a security context different from that of the process that owns the thread. Typically, a thread in a server application impersonates a client. This allows the server thread to act on behalf of that client to access objects or validate access to its own objects.

The Microsoft® Win32® API provides the following functions a thread can use to begin an impersonation:

  • A DDE server application can call the DdeImpersonateClient function to impersonate a client.
  • A named-pipe server can call the ImpersonateNamedPipeClient function.
  • You can call the ImpersonateLoggedOnUser function to impersonate the security context of a logged-on user's access token.
  • The ImpersonateSelf function enables a thread to generate a copy of its own access token. This is useful when an application needs to change the security context of a single thread. For example, sometimes only one thread of a process needs to enable a privilege.
  • You can call the SetThreadToken function to cause the target thread to run in the security context of a specified impersonation token.
  • A Microsoft Remote Procedure Call (RPC) server application can call the RpcImpersonateClient function to impersonate a client.

For most of these impersonations, the impersonating thread can revert to its own security context by calling the RevertToSelf function. The exception is the RPC impersonation in which the RPC server application calls RpcRevertToSelf or RpcRevertToSelfEx to revert to its own security context.


Impersonation Levels

The SECURITY_IMPERSONATION_LEVEL enumeration defines four impersonation levels that determine the operations a server can perform in the client's context.

Level | Description
SecurityAnonymous | The server cannot impersonate or identify the client.
SecurityIdentification | The server can get the identity and privileges of the client, but cannot impersonate the client.
SecurityImpersonation | The server can impersonate the client's security context on the local system.
SecurityDelegation | The server can impersonate the client's security context on remote systems.

The client of a named pipe, RPC, or DDE connection can control the impersonation level. For example, a named pipe client can call the CreateFile function to open a handle to a named pipe and specify the server's impersonation level. DDE clients use the DdeSetQualityOfService function with the SECURITY_QUALITY_OF_SERVICE structure to specify the impersonation level. The SecurityImpersonation level is the default for named pipe, RPC, and DDE servers. The ImpersonateSelf, DuplicateToken, and DuplicateTokenEx functions allow the caller to specify an impersonation level. Use the GetTokenInformation function to get the impersonation level of an access token.

At the SecurityImpersonation level, most of the thread's actions occur in the security context of the thread's impersonation token rather than in the primary token of the process that owns the thread. For example, if an impersonating thread opens a securable object, the system uses the impersonation token to check the thread's access. Similarly, if an impersonating thread creates a new object, for example by calling the CreateFile function, the owner of the new object is the default owner from the client's access token.

However, the system uses the primary token of the process rather than the impersonation token of the calling thread in the following situations:

  • If an impersonating thread calls the CreateProcess function, the new process always inherits the primary token of the process.
  • For Win32 functions that require the SE_TCB_NAME privilege, such as the LogonUser function, the system always checks for the privilege in the primary token of the process.
  • For Win32 functions that require the SE_AUDIT_NAME privilege, such as the ObjectOpenAuditAlarm function, the system always checks for the privilege in the primary token of the process.
  • In a call to the OpenThreadToken function, a thread can specify whether the function uses the impersonation token or the primary token to determine whether to grant the requested access.


Impersonation Tokens

An impersonating thread has two access tokens:

  • A primary access token that describes the security context of the server. To get a handle to this token, call the OpenProcessToken function.
  • An impersonation access token that describes the security context of the client being impersonated. To get a handle to this token, call the OpenThreadToken function.

A server can use the impersonation token in the following functions:

  • In the AccessCheck, AccessCheckByType, and AccessCheckByTypeResultList functions to determine whether a security descriptor allows the client a set of access rights.
  • In the AdjustTokenPrivileges function to enable or disable the client's privileges.
  • In the PrivilegeCheck function to determine whether a set of privileges are enabled in the client's token.
  • In functions that generate entries in the security event log, such as ObjectOpenAuditAlarm or PrivilegedServiceAuditAlarm. These functions use an impersonation token to get information about the client for the log entry.


Client Logon Sessions

A server with the SE_TCB_NAME privilege, such as a Win32 service running in the LocalSystem account, can call the LogonUser function to log a client on to the server's computer. LogonUser starts a new logon session and returns a primary access token that contains the client's security information. You can use this primary token in a call to the ImpersonateLoggedOnUser function to impersonate the client or in a call to the CreateProcessAsUser function to create a process that runs in the security context of the client.

The advantage of logging on the client is that the server impersonating the logged on client or a process created in the context of the logged on client can connect to remote network resources as the client. If the server does not log on the client, it can connect to network resources only if it knows the account name and password to pass to the WNetAddConnection2 function.

The problem with logging on a client is that the server needs the client's credentials (domain name, user name, and password). If a server gets credentials from a remote client, it is the responsibility of the client and server applications to ensure that the credentials are transmitted in a secure manner. The LogonUser function uses Windows NT authentication which does not transmit the password over the network.


Processes in the Client's Security Context

A server application can call the CreateProcessAsUser function to create a new process that runs in a client's security context. When called with a client's access token, CreateProcessAsUser requires the SE_ASSIGNPRIMARYTOKEN_NAME and SE_INCREASE_QUOTA_NAME privileges, which are held by Win32 services running in the LocalSystem account.

CreateProcessAsUser also requires a primary access token. A server can get a primary access token for a client either by starting a logon session for the client, or by impersonating the client and duplicating the impersonation token.

To create a client process by logging on the client
  1. Use the client's credentials in a call to the LogonUser function to log the client on to the local computer. LogonUser produces a primary token for the client's logon session.
  2. If the server needs to use the client's security context to get access to the executable file for the client process, it can use the primary token in a call to the ImpersonateLoggedOnUser function.
  3. Use the primary token in a call to the CreateProcessAsUser function to create a process in the client's security context.
To create a client process by impersonating the client

Note that a process created by this technique may not be able to access network resources unless it has the client's credentials.

  1. Use an impersonation function, such as ImpersonateNamedPipeClient, to start the impersonation.
  2. Call the OpenThreadToken function to get an impersonation token that has the security context of the client.
  3. Call the DuplicateTokenEx function to convert the impersonation token into a primary token.
  4. Use the primary token in a call to the CreateProcessAsUser function to create a process in the client's security context.

By default CreateProcessAsUser creates the client process on a noninteractive window station and desktop. To create an interactive process, the server must first set the discretionary access-control lists (DACLs) of the interactive window station and desktop to ensure that the client is allowed access to them. The preferred way to do this is to log the client on, get the security identifier (SID) of the client's logon session, and use that SID in access-allowed ACEs on both the interactive window station and desktop. The server can then call CreateProcessAsUser, specifying the interactive window station and desktop, "winsta0\default". For sample code that shows this procedure, see Starting an Interactive Client Process.


Client Access to Network Resources

A server can use the following strategies to access network resources:

  • If the server has the account name and password of a client, it can call WNetAddConnection2 with the client's credentials to map a local drive letter to a network share. A thread of the service can then impersonate the client to access files on the network share. The impersonation ensures that access to the files is checked against the client's security context.
  • The server can call the CreateProcessAsUser function to create a process for the client. This new client process can access network resources using the client's security context. For example, the process can call the CreateFile function to open a file on a remote computer. The system uses the client's primary token to check access attempts by the client process.
  • A server can call WNetAddConnection2 with null credentials to establish a null session connection to a network resource. However, this works only for resources that allow null sessions. For more information, see The LocalSystem Account.


Access Control for Private Objects

Just as Windows NT uses security descriptors to control access to securable objects, a server can use security descriptors to control access to its private objects. For more information about the Windows NT security model, see Access Control Model.

A protected server can create a security descriptor with a DACL that specifies the types of access allowed for various trustees. In a simple case, the server could create a single security descriptor to control access to all of the server's data and functionality. For a finer granularity of protection, the server could create security descriptors for each of its private objects, or for different types of functionality.

For example, when a client asks the server to create a new object in a database, the server could create a security descriptor for the new private object. The server could then store the security descriptor with the private object in the database. When a client tries to access the object, the server retrieves the security descriptor to check the client's access rights. It is important to note that there is nothing in a security descriptor that associates it with the object or functionality it is protecting. Instead, it is up to the protected server to maintain the association.


Security Descriptors for Private Objects

To create a security descriptor, a protected server can use the same procedure that an application would use to create a security descriptor for a securable object. For sample code, see Creating a Security Descriptor for a New Object.

In addition, the Win32 API provides a set of functions for merging client security information with information inherited from the security descriptor for a parent object or from a default security descriptor. The CreatePrivateObjectSecurity, GetPrivateObjectSecurity, SetPrivateObjectSecurity, and DestroyPrivateObjectSecurity functions provide the ability to retrieve default information from an access token, support inheritance, and manipulate specific parts of the security descriptor. This can be useful when a client creates a private object in a hierarchy of secured objects. For example, you could use the CreatePrivateObjectSecurity function to create a security descriptor that contained ACEs specified by the client, ACEs inherited from a parent object, and the default owner from the creating client's access token.


Checking Access to Private Objects

A protected server application must check a client's access rights before allowing the client to access a protected private object. To do this, the server passes an impersonation token, a security descriptor, and a set of requested access rights to the AccessCheck function. The ACEs in the security descriptor's DACL specify the access rights allowed or denied for various trustees. AccessCheck compares the trustee in each ACE to the trustees identified in the impersonation token. For a description of the algorithm used to grant or deny access, see Checking a Thread's Access to an Object.

The AccessCheckAndAuditAlarm function performs a similar access check. In addition, it generates audit records in the security event log depending on the SACL in the security descriptor.

The AccessCheckByType and AccessCheckByTypeAndAuditAlarm functions are similar to AccessCheck and AccessCheckAndAuditAlarm except that they allow you to check access to the subobjects of an object, such as property sets or properties. The AccessCheckByTypeResultList and AccessCheckByTypeResultListAndAuditAlarm functions are also similar except that they provide the access check results for each subobject in a hierarchy of the object's properties and property sets. These functions use the OBJECT_TYPE_LIST structure to describe the hierarchy of objects for which access is checked. The functions that generate an audit message use the AUDIT_EVENT_TYPE enumeration type to indicate whether the object being checked is a directory service object. For more information about the hierarchy of an object and its subobjects, see Controlling Access to an Object's Properties.

The requested access rights passed to the AccessCheck and AccessCheckAndAuditAlarm functions must not include any generic access rights. The server can use the MapGenericMask function to convert any generic access rights to the corresponding specific and standard rights according to the mapping specified in the GENERIC_MAPPING structure.

The AreAllAccessesGranted and AreAnyAccessesGranted functions compare a requested access mask with a granted access mask.

For sample code that uses the AccessCheck function, see Checking A Client's Access.


Auditing Access To Private Objects

A protected server can use the following functions to generate audit reports in the security event log.

Function | Description
AccessCheckAndAuditAlarm
 | Same as the AccessCheck function except that it can generate audit messages for failed or successful access attempts.
AccessCheckByTypeAndAuditAlarm
 | Same as the AccessCheckByType function except that it can generate audit messages for failed or successful access attempts.
AccessCheckByTypeResultListAndAuditAlarm
 | Same as the AccessCheckByTypeResultList function except that it can generate audit messages for failed or successful access attempts.
ObjectCloseAuditAlarm
 | Generates an audit message to indicate a client tried to close a private object.
ObjectDeleteAuditAlarm
 | Generates an audit message to indicate a client tried to delete a private object.
ObjectOpenAuditAlarm
 | Generates an audit message to indicate a client tried to open or create a private object.
ObjectPrivilegeAuditAlarm
 | Generates an audit message to indicate a client tried to use a specified set of privileges in conjunction with an attempt to access a private object.
PrivilegedServiceAuditAlarm
 | Generates an audit message to indicate a client tried to use a specified set of privileges.


Using Client/Server Access Control

Following are some common tasks for the Win32 client/server access control functions and structures:

  • Getting the Logon SID
  • Starting an Interactive Client Process
  • Checking a Client's Access


Getting the Logon SID

A logon security identifier (SID) identifies the logon session associated with an access token. A typical use of a logon SID is in an ACE that allows access for the duration of a client's logon session. For example, a Win32 service can use the LogonUser function to start a new logon session. LogonUser returns an access token from which the service can extract the logon SID. The service can then use the SID in an ACE that allows the client's logon session to access the interactive window station and desktop.

The following example gets the logon SID from an access token. It uses the GetTokenInformation function to fill a TOKEN_GROUPS buffer with an array of the group SIDs from an access token. This array includes the logon SID, which is identified by the SE_GROUP_LOGON_ID attribute. The example function allocates a buffer for the logon SID; it is the caller's responsibility to free the buffer.

BOOL GetLogonSID (HANDLE hToken, PSID *ppsid) {

BOOL bSuccess = FALSE;
DWORD dwIndex;
DWORD dwLength = 0;
PTOKEN_GROUPS ptg = NULL;

// Get required buffer size and allocate the TOKEN_GROUPS buffer.

if (!GetTokenInformation(
         hToken,         // handle to the access token
         TokenGroups,    // get information about the token's groups
         (LPVOID) ptg,   // pointer to TOKEN_GROUPS buffer
         0,              // size of buffer
         &dwLength       // receives required buffer size
         ))
    {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
            goto Cleanup;
        ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
                 HEAP_ZERO_MEMORY, dwLength);
        if (ptg == NULL)
            goto Cleanup;
    }

// Get the token group information from the access token.

if (!GetTokenInformation(
         hToken,         // handle to the access token
         TokenGroups,    // get information about the token's groups
         (LPVOID) ptg,   // pointer to TOKEN_GROUPS buffer
         dwLength,       // size of buffer
         &dwLength       // receives required buffer size
         ))
    goto Cleanup;

// Loop through the groups to find the logon SID.

for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++)
    if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)
             ==  SE_GROUP_LOGON_ID)
    {
        // Found the logon SID; make a copy of it.

        dwLength = GetLengthSid(ptg->Groups[dwIndex].Sid);
        *ppsid = (PSID) HeapAlloc(GetProcessHeap(),
                    HEAP_ZERO_MEMORY, dwLength);
        if (*ppsid == NULL)
            goto Cleanup;
        if (!CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid)) {
            HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
            goto Cleanup;
        }
        break;
    }

bSuccess = TRUE;

Cleanup:

// Free the buffer for the token groups.

if (ptg != NULL)
    HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);

return bSuccess;
}

The following function frees the buffer allocated by the GetLogonSID example function.

VOID FreeLogonSID (PSID *ppsid) {
    HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
}


Starting an Interactive Client Process

The following example uses the LogonUser function to start a new logon session for a client. The example gets the logon SID from the client's access token, and uses it to add access-control entries (ACEs) to the DACLs of the interactive window station and desktop. The ACEs allow the client access to the interactive desktop for the duration of the logon session. Next, the example calls the ImpersonateLoggedOnUser function to ensure that it has access to the client's executable file. A call to the CreateProcessAsUser function creates the client's process, specifying that it run in the interactive desktop. Before the function returns, it calls the RevertToSelf function to end the caller's impersonation of the client.

This sample calls the GetLogonSID and FreeLogonSID sample functions described in Getting the Logon SID. It calls the AddAceToObjectsDACL sample function described in Modifying an Object's ACLs.

BOOL StartInteractiveClientProcess (
    LPTSTR lpszUsername,    // client to log on
    LPTSTR lpszDomain,      // domain of client's account
    LPTSTR lpszPassword,    // client's password
    LPTSTR lpCommandLine    // command line to execute
) {

HANDLE      hToken;
HDESK       hdesk = NULL;
HWINSTA     hwinsta = NULL, hwinstaSave = NULL;
PROCESS_INFORMATION pi;
PSID pSid = NULL;
STARTUPINFO si;
BOOL bResult = FALSE;

// Log the client on to the local computer.

if (!LogonUser(
        lpszUsername,
        lpszDomain,
        lpszPassword,
        LOGON32_LOGON_INTERACTIVE,
        LOGON32_PROVIDER_DEFAULT,
        &hToken) )
    goto Cleanup;

// Save a handle to the caller's current window station.

if ( (hwinstaSave = GetProcessWindowStation() ) == NULL)
    goto Cleanup;

// Get a handle to the interactive window station.

hwinsta = OpenWindowStation(
    "winsta0",                   // the interactive window station
    FALSE,                       // handle is not inheritable
    READ_CONTROL | WRITE_DAC);   // rights to read and write the DACL
if (hwinsta == NULL)
    goto Cleanup;

// To get the correct default desktop, set the caller's
// window station to the interactive window station.

if (!SetProcessWindowStation(hwinsta))
    goto Cleanup;

// Get a handle to the interactive desktop.

hdesk = OpenDesktop(
    "default",     // the interactive window station
    0,             // no interaction with other desktop processes
    FALSE,         // handle is not inheritable
    READ_CONTROL | // request the rights to read and write the DACL
    WRITE_DAC |
    DESKTOP_WRITEOBJECTS |
    DESKTOP_READOBJECTS);

// Restore the caller's window station.

if (!SetProcessWindowStation(hwinstaSave))
    goto Cleanup;

if (hdesk == NULL)
    goto Cleanup;

// Get the SID for the client's logon session.

if (!GetLogonSID(hToken, &pSid))
    goto Cleanup;

// Allow logon SID full access to interactive window station.

if (! AddAceToWindowStation(hwinsta, pSid) )
    goto Cleanup;

// Allow logon SID full access to interactive desktop.

if (! AddAceToDesktop(hdesk, pSid) )
    goto Cleanup;

// Impersonate client to ensure access to executable file.

if (! ImpersonateLoggedOnUser(hToken) )
    goto Cleanup;

// Initialize the STARTUPINFO structure.
// Specify that the process runs in the interactive desktop.

ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb= sizeof(STARTUPINFO);
si.lpDesktop = TEXT("winsta0\\default");

// Launch the process in the client's logon session.

bResult = CreateProcessAsUser(
    hToken,            // client's access token
    NULL,              // file to execute
    lpCommandLine,     // command line
    NULL,              // pointer to process SECURITY_ATTRIBUTES
    NULL,              // pointer to thread SECURITY_ATTRIBUTES
    FALSE,             // handles are not inheritable
    NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,   // creation flags
    NULL,              // pointer to new environment block
    NULL,              // name of current directory
    &si,               // pointer to STARTUPINFO structure
    &pi                // receives information about new process
    );

// End impersonation of client.

RevertToSelf();

if (bResult && pi.hProcess != INVALID_HANDLE_VALUE) {
    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
}

if (pi.hThread != INVALID_HANDLE_VALUE)
    CloseHandle(pi.hThread);

Cleanup:

if (hwinstaSave != NULL)
    SetProcessWindowStation (hwinstaSave);

// Free the buffer for the logon SID.

if (pSid)
    FreeLogonSID(&pSid);

// Close the handles to the interactive window station and desktop.

if (hwinsta)
    CloseWindowStation(hwinsta);

if (hdesk)
    CloseDesktop(hdesk);

// Close the handle to the client's access token.

if (hToken != INVALID_HANDLE_VALUE)
    CloseHandle(hToken);

return bResult;
}


Checking A Client's Access

The following example shows how a server could check the access rights that a security descriptor allows for a client. The example uses the ImpersonateNamedPipeClient function, but it would work the same if you used any of the other impersonation functions. After impersonating the client, the example calls the OpenThreadToken function to get the impersonation token. It calls the MapGenericMask function to convert any generic access rights to the corresponding specific and standard rights according to the mapping specified in the GENERIC_MAPPING structure.

The AccessCheck function checks the requested access rights against the rights allowed for the client in the DACL of the security descriptor. To check access and generate an entry in the security event log, use the AccessCheckAndAuditAlarm function.

BOOL ImpersonateAndCheckAccess(
  HANDLE hNamedPipe,               // handle of pipe to impersonate
  PSECURITY_DESCRIPTOR pSD,        // security descriptor to check
  DWORD dwAccessDesired,           // access rights to check
  PGENERIC_MAPPING pGeneric,       // generic mapping for object
  PDWORD pdwAccessAllowed          // returns allowed access rights
) {

HANDLE hToken;
PRIVILEGE_SET PrivilegeSet;
DWORD dwPrivSetSize = sizeof( PRIVILEGE_SET );
BOOL fAccessGranted=FALSE;

// Impersonate the client.

if (! ImpersonateNamedPipeClient(hNamedPipe) )
    return FALSE;

// Get an impersonation token with the client's security context.

if (! OpenThreadToken( GetCurrentThread(), TOKEN_ALL_ACCESS,
                TRUE, &hToken ) )
    goto Cleanup;

// Use the GENERIC_MAPPING structure to convert any
// generic access rights to object-specific access rights.

MapGenericMask( &dwAccessDesired, pGeneric );

// Check the client's access rights.

if( !AccessCheck(
    pSD,                 // security descriptor to check
    hToken,              // impersonation token
    dwAccessDesired,     // requested access rights
    pGeneric,            // pointer to GENERIC_MAPPING
    &PrivilegeSet,       // receives privileges used in check
    &dwPrivSetSize,      // size of PrivilegeSet buffer
    pdwAccessAllowed,    // receives mask of allowed access rights
    &fAccessGranted )    // receives results of access check
)
    goto Cleanup;

Cleanup:

RevertToSelf();

if (hToken != INVALID_HANDLE_VALUE)
    CloseHandle(hToken);

return fAccessGranted;

}


Client/Server Access Control Reference

The following elements are used with client/server access control:

  • Client/Server Access Control Functions
  • Client/Server Access Control Structures
  • Client/Server Access Control Enumeration Types


Client/Server Access Control Functions

The following functions are used by servers to impersonate clients.

Function | History
CreateProcessAsUser | Windows NT 3.51 and later
ImpersonateLoggedOnUser | Windows NT 3.51 and later
LogonUser | Windows NT 3.51 and later
ImpersonateNamedPipeClient | Windows NT 3.1 and later
ImpersonateSelf | Windows NT 3.1 and later
RevertToSelf | Windows NT 3.1 and later

The following functions are used by servers to check and set the security descriptors on private objects.

Function | History
AccessCheck | Windows NT 3.1 and later
AccessCheckAndAuditAlarm | Windows NT 3.1 and later
AccessCheckByType | Windows NT 5.0 and later
AccessCheckByTypeAndAuditAlarm | Windows NT 5.0 and later
AccessCheckByTypeResultList | Windows NT 5.0 and later
AccessCheckByTypeResultListAndAuditAlarm | Windows NT 5.0 and later
AreAllAccessesGranted | Windows NT 3.1 and later
AreAnyAccessesGranted | Windows NT 3.1 and later
ConvertToAutoInheritPrivateObjectSecurity | Windows NT 5.0 and later
CreatePrivateObjectSecurity | Windows NT 3.1 and later
CreatePrivateObjectSecurityEx | Windows NT 5.0 and later
DestroyPrivateObjectSecurity | Windows NT 3.1 and later
GetAccessPermissionsForObject | Windows NT 5.0 and later
GetPrivateObjectSecurity | Windows NT 3.1 and later
MapGenericMask | Windows NT 3.1 and later
PrivilegeCheck | Windows NT 3.1 and later
SetPrivateObjectSecurity | Windows NT 3.1 and later
SetPrivateObjectSecurityEx | Windows NT 5.0 and later
BuildSecurityDescriptor | Windows NT 4.0 and later
LookupSecurityDescriptorParts | Windows NT 4.0 and later

The following functions are used by servers to generate audit messages in the security event log.

Function | History
ObjectDeleteAuditAlarm | Windows NT 3.1 and later
ObjectCloseAuditAlarm | Windows NT 3.1 and later
ObjectOpenAuditAlarm | Windows NT 3.1 and later
ObjectPrivilegeAuditAlarm | Windows NT 3.1 and later
PrivilegedServiceAuditAlarm | Windows NT 3.1 and later


AccessCheck

The AccessCheck function determines whether a security descriptor grants a specified set of access rights to the client identified by an access token. Typically, server applications use this function to check access to a private object.

BOOL AccessCheck(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,   // security descriptor
  HANDLE ClientToken,               // handle to client access token
  DWORD DesiredAccess,              // requested access rights
  PGENERIC_MAPPING GenericMapping,  // map generic to specific rights
  PPRIVILEGE_SET PrivilegeSet,      // receives privileges used
  LPDWORD PrivilegeSetLength,       // size of privilege-set buffer
  LPDWORD GrantedAccess,     // retrieves mask of granted rights
  LPBOOL AccessStatus        // retrieves results of access check
);

Parameters

pSecurityDescriptor
Pointer to a SECURITY_DESCRIPTOR structure against which access is checked.
ClientToken
Handle to an impersonation token that represents the client attempting to gain access. The handle must have TOKEN_QUERY access to the token; otherwise, the function fails with ERROR_ACCESS_DENIED.
DesiredAccess
Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function to contain no generic access rights.

If this parameter is MAXIMUM_ALLOWED, the function sets the GrantedAccess access mask to indicate the maximum access rights the security descriptor allows the client.

GenericMapping
Pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
PrivilegeSet
Pointer to a PRIVILEGE_SET structure that receives the privileges used to perform the access validation. If no privileges were used, the function sets the PrivilegeCount member to zero.
PrivilegeSetLength
Specifies the size, in bytes, of the buffer pointed to by the PrivilegeSet parameter.
GrantedAccess
Pointer to an access mask that receives the granted access rights. If AccessStatus returns FALSE, the function sets the access mask to zero. If the function fails, it does not set the access mask.
AccessStatus
Pointer to a variable that receives the results of the access check. If the security descriptor allows the requested access rights to the client identified by the access token, AccessStatus returns TRUE. Otherwise, AccessStatus returns FALSE, and you can call GetLastError to get extended error information.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The AccessCheck function compares the specified security descriptor with the specified access token and indicates, in the AccessStatus parameter, whether access is granted or denied. If access is granted, the requested access mask becomes the object's granted access mask.

If the security descriptor's DACL is NULL, the AccessStatus parameter returns TRUE indicating that the client has the requested access.

AccessCheck fails with ERROR_INVALID_SECURITY_DESCR if the security descriptor does not contain owner and group SIDs.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheckAndAuditAlarm, AreAllAccessesGranted, AreAnyAccessesGranted, GENERIC_MAPPING, MapGenericMask, PrivilegeCheck, PRIVILEGE_SET, SECURITY_DESCRIPTOR


AccessCheckAndAuditAlarm

The AccessCheckAndAuditAlarm function determines whether a security descriptor grants a specified set of access rights to the client being impersonated by the calling thread. If the security descriptor has a SACL with ACEs that apply to the client, the function generates any necessary audit messages in the security event log. Alarms are not supported in the current version of Windows NT.

BOOL AccessCheckAndAuditAlarm(
  LPCTSTR SubsystemName,     // subsystem name
  LPVOID HandleId,           // object's handle identifier
  LPTSTR ObjectTypeName,     // type of object
  LPTSTR ObjectName,         // name of object
  PSECURITY_DESCRIPTOR SecurityDescriptor,
                             // address of security descriptor
  DWORD DesiredAccess,       // mask for requested access rights
  PGENERIC_MAPPING GenericMapping,
                             // address of GENERIC_MAPPING
  BOOL ObjectCreation,       // flag is TRUE if creating an object
  LPDWORD GrantedAccess,     // retrieves mask of granted rights
  LPBOOL AccessStatus        // retrieves results of access check
  LPBOOL pfGenerateOnClose   // retrieves flag for audit generation
);

Parameters

SubsystemName
Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit message that the function generates.
HandleId
Pointer to a unique 32-bit value representing the client's handle to the object. If the access is denied, the system ignores this value.
ObjectTypeName
Pointer to a null-terminated string specifying the type of object being created or accessed. This string appears in any audit message that the function generates.
ObjectName
Pointer to a null-terminated string specifying the name of the object being created or accessed. This string appears in any audit message that the function generates.
SecurityDescriptor
Pointer to the SECURITY_DESCRIPTOR structure against which access is checked.
DesiredAccess
Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function to contain no generic access rights.

If this parameter is MAXIMUM_ALLOWED, the function sets the GrantedAccess access mask to indicate the maximum access rights the security descriptor allows the client.

GenericMapping
Pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
ObjectCreation
Specifies a flag that determines whether the calling application will create a new object when access is granted. A value of TRUE indicates the application will create a new object. A value of FALSE indicates the application will open an existing object.
GrantedAccess
Pointer to an access mask that receives the granted access rights. If AccessStatus returns FALSE, the function sets the access mask to zero. If the function fails, it does not set the access mask.
AccessStatus
Pointer to a variable that receives the results of the access check. If the security descriptor allows the requested access rights to the client, AccessStatus returns TRUE. Otherwise, AccessStatus returns FALSE.
pfGenerateOnClose
Pointer to a flag set by the audit-generation routine when the function returns. Pass this flag to the ObjectCloseAuditAlarm function when the object handle is closed.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The AccessCheckAndAuditAlarm function requires the calling process to have the SE_AUDIT_NAME privilege enabled. The test for this privilege is performed against the primary token of the calling process, not the impersonation token of the thread.

The AccessCheckAndAuditAlarm function fails if the calling thread is not impersonating a client.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, GENERIC_MAPPING, MapGenericMask, ObjectCloseAuditAlarm, ObjectOpenAuditAlarm, ObjectPrivilegeAuditAlarm, PrivilegeCheck, PrivilegedServiceAuditAlarm, SECURITY_DESCRIPTOR


AccessCheckByType

[This is preliminary documentation and subject to change.]

The AccessCheckByType function determines whether a security descriptor grants a specified set of access rights to the client identified by an access token. The function can check the client's access to a hierarchy of objects, such as an object, its property sets, and properties. The function grants or denies access to the hierarchy as a whole. Typically, server applications use this function to check access to a private object.

BOOL AccessCheckByType(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,   // security descriptor
  PSID PrincipalSelfSid,            // SID of object being checked
  HANDLE ClientToken,               // handle to client access token
  DWORD DesiredAccess,              // requested access rights
  POBJECT_TYPE_LIST ObjectTypeList, // array of object types
  DWORD ObjectTypeListLength,       // number of object type elements
  PGENERIC_MAPPING GenericMapping,  // map generic to specific rights
  PPRIVILEGE_SET PrivilegeSet,      // receives privileges used
  LPDWORD PrivilegeSetLength,       // size of privilege-set buffer
  LPDWORD GrantedAccess,     // retrieves mask of granted rights
  LPBOOL AccessStatus        // retrieves results of access check
);

Parameters

pSecurityDescriptor
Pointer to a SECURITY_DESCRIPTOR structure against which access is checked.
PrincipalSelfSid
Pointer to a SID. If the security descriptor is associated with an object that represents a principal (for example, a user object), the PrincipalSelfSid parameter should be the SID of the object. When evaluating access, this SID logically replaces the SID in any ACE containing the well-known PRINCIPAL_SELF SID (S-1-5-10).

This parameter should be NULL if the protected object does not represent a principal.

ClientToken
Handle to an impersonation token that represents the client attempting to gain access. The handle must have TOKEN_QUERY access to the token; otherwise, the function fails with ERROR_ACCESS_DENIED.
DesiredAccess
Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function to contain no generic access rights.

If this parameter is MAXIMUM_ALLOWED, the function sets the GrantedAccess access mask to indicate the maximum access rights the security descriptor allows the client.

ObjectTypeList
Pointer to an array of OBJECT_TYPE_LIST structures that identify the hierarchy of object types for which to check access. Each element in the array specifies a GUID that identifies the object type and a value indicating the level of the object type in the hierarchy of object types. The array should not have two elements with the same GUID.

The array must have at least one element. The first element in the array must be at level zero and identify the object itself. The array can have only one level zero element. The second element is a subobject, such as a property set, at level 1. Following each level 1 entry are subordinate entries for the level 2 through 4 subobjects. Thus, the levels for the elements in the array might be {0, 1, 2, 2, 1, 2, 3}. If the object type list is out of order, AccessCheckByType fails and GetLastError returns ERROR_INVALID_PARAMETER.

If ObjectTypeList is NULL, AccessCheckByType is the same as the AccessCheck function.

ObjectTypeListLength
Specifies the number of elements in the ObjectTypeList array.
GenericMapping
Pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
PrivilegeSet
Pointer to a PRIVILEGE_SET structure that receives the privileges used to perform the access validation. If no privileges were used, the function sets the PrivilegeCount member to zero.
PrivilegeSetLength
Specifies the size, in bytes, of the buffer pointed to by the PrivilegeSet parameter.
GrantedAccess
Pointer to an access mask that receives the granted access rights. If AccessStatus returns FALSE, the function sets the access mask to zero. If the function fails, it does not set the access mask.
AccessStatus
Pointer to a variable that receives the results of the access check. If the security descriptor allows the requested access rights to the client identified by the access token, AccessStatus returns TRUE. Otherwise, AccessStatus returns FALSE, and you can call GetLastError to get extended error information.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The AccessCheckByType function compares the specified security descriptor with the specified access token and indicates, in the AccessStatus parameter, whether access is granted or denied.

The ObjectTypeList array does not necessarily represent the entire defined object. Rather, it represents that subset of the object for which to check access. For instance, to check access to two properties in a property set, specify an object type list with four elements: the object itself at level zero, the property set at level 1, and the two properties at level 2.

The AccessCheckByType function evaluates ACEs that apply to the object itself and object-specific ACEs for the object types listed in the ObjectTypeList array. The function ignores object-specific ACEs for object types not listed in the ObjectTypeList array. Thus, the results returned in the AccessStatus parameter indicate the access allowed to the subset of the object defined by the ObjectTypeList parameter, not to the entire object.

For more information about how a hierarchy of ACEs controls access to an object and its subobjects, see Controlling Access to an Object's Properties.

If the security descriptor's DACL is NULL, the AccessStatus parameter returns TRUE, indicating that the client has the requested access.

If the security descriptor does not contain owner and group SIDs, AccessCheckByType fails with ERROR_INVALID_SECURITY_DESCR.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, AccessCheckByTypeAndAuditAlarm, AccessCheckByTypeResultList, AccessCheckByTypeResultListAndAuditAlarm, GENERIC_MAPPING, MapGenericMask, PRIVILEGE_SET, SECURITY_DESCRIPTOR


AccessCheckByTypeAndAuditAlarm

[This is preliminary documentation and subject to change.]

The AccessCheckByTypeAndAuditAlarm function determines whether a security descriptor grants a specified set of access rights to the client being impersonated by the calling thread. The function can check the client's access to a hierarchy of objects, such as an object, its property sets, and properties. The function grants or denies access to the hierarchy as a whole. If the security descriptor has a SACL with ACEs that apply to the client, the function generates any necessary audit messages in the security event log. Alarms are not supported in the current version of Windows NT.

BOOL AccessCheckByTypeAndAuditAlarm(
  LPCTSTR SubsystemName,            // subsystem name
  LPVOID HandleId,                  // object's handle identifier
  LPCTSTR ObjectTypeName,           // type of object
  LPCTSTR ObjectName,               // name of object
  PSECURITY_DESCRIPTOR pSecurityDescriptor,   // security descriptor
  PSID PrincipalSelfSid,            // SID of object being checked
  DWORD DesiredAccess,              // requested access rights
  AUDIT_EVENT_TYPE AuditType,       // type of audit
  DWORD Flags,          // allows access check if no audit privilege
  POBJECT_TYPE_LIST ObjectTypeList, // array of object types
  DWORD ObjectTypeListLength,       // number of object type elements
  PGENERIC_MAPPING GenericMapping,  // map generic to specific rights
  BOOL ObjectCreation,       // flag is TRUE if creating an object
  LPDWORD GrantedAccess,     // retrieves mask of granted rights
  LPBOOL AccessStatus        // retrieves results of access check
  LPBOOL pfGenerateOnClose   // retrieves flag for audit generation
);

Parameters

SubsystemName
Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit message that the function generates.
HandleId
Pointer to a unique 32-bit value representing the client's handle to the object. If the access is denied, the system ignores this value.
ObjectTypeName
Pointer to a null-terminated string specifying the type of object being created or accessed. This string appears in any audit message that the function generates.
ObjectName
Pointer to a null-terminated string specifying the name of the object being created or accessed. This string appears in any audit message that the function generates.
pSecurityDescriptor
Pointer to a SECURITY_DESCRIPTOR structure against which access is checked.
PrincipalSelfSid
Pointer to a SID. If the security descriptor is associated with an object that represents a principal (for example, a user object), the PrincipalSelfSid parameter should be the SID of the object. When evaluating access, this SID logically replaces the SID in any ACE containing the well-known PRINCIPAL_SELF SID (S-1-5-10).

This parameter should be NULL if the protected object does not represent a principal.

DesiredAccess
Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function to contain no generic access rights.

If this parameter is MAXIMUM_ALLOWED, the function sets the GrantedAccess access mask to indicate the maximum access rights the security descriptor allows the client.

AuditType
Specifies the type of audit to be generated. This can be one of the values from the AUDIT_EVENT_TYPE enumeration type.
Flags
Flag that controls the function's behavior if the calling process does not have the SE_AUDIT_NAME privilege enabled. If the AUDIT_ALLOW_NO_PRIVILEGE flag is set, the function performs the access check without generating audit messages when the privilege is not enabled. If this parameter is zero, the function fails if the privilege is not enabled.
ObjectTypeList
Pointer to an array of OBJECT_TYPE_LIST structures that identify the hierarchy of object types for which to check access. Each element in the array specifies a GUID that identifies the object type and a value indicating the level of the object type in the hierarchy of object types. The array should not have two elements with the same GUID.

The array must have at least one element. The first element in the array must be at level zero and identify the object itself. The array can have only one level zero element. The second element is a subobject, such as a property set, at level 1. Following each level 1 entry are subordinate entries for the level 2 through 4 subobjects. Thus, the levels for the elements in the array might be {0, 1, 2, 2, 1, 2, 3}. If the object type list is out of order, AccessCheckByTypeAndAuditAlarm fails and GetLastError returns ERROR_INVALID_PARAMETER.

ObjectTypeListLength
Specifies the number of elements in the ObjectTypeList array.
GenericMapping
Pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
ObjectCreation
Specifies a flag that determines whether the calling application will create a new object when access is granted. A value of TRUE indicates the application will create a new object. A value of FALSE indicates the application will open an existing object.
GrantedAccess
Pointer to an access mask that receives the granted access rights. If AccessStatus returns FALSE, the function sets the access mask to zero. If the function fails, it does not set the access mask.
AccessStatus
Pointer to a variable that receives the results of the access check. If the security descriptor allows the requested access rights to the client, AccessStatus returns TRUE. Otherwise, AccessStatus returns FALSE and you can call GetLastError to get extended error information.
pfGenerateOnClose
Pointer to a flag set by the audit-generation routine when the function returns. Pass this flag to the ObjectCloseAuditAlarm function when the object handle is closed.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the PrincipalSelfSid and ObjectTypeList parameters are NULL, the AuditType parameter is AuditEventObjectAccess, and the Flags parameter is zero, AccessCheckByTypeAndAuditAlarm performs in the same way as the AccessCheckAndAuditAlarm function.

The ObjectTypeList array does not necessarily represent the entire defined object. Rather, it represents that subset of the object for which to check access. For instance, to check access to two properties in a property set, specify an object type list with four elements: the object itself at level zero, the property set at level 1, and the two properties at level 2.

AccessCheckByTypeAndAuditAlarm evaluates ACEs that apply to the object itself and object-specific ACEs for the object types listed in the ObjectTypeList array. The function ignores object-specific ACEs for object types not listed in the ObjectTypeList array. Thus, the results returned in the AccessStatus parameter indicate the access allowed to the subset of the object defined by the ObjectTypeList parameter, not to the entire object.

For more information about how a hierarchy of ACEs controls access to an object and its subobjects, see Controlling Access to an Object's Properties.

To generate audit messages in the security event log, the calling process must have the SE_AUDIT_NAME privilege enabled. The system checks for this privilege in the primary token of the calling process, not the impersonation token of the thread. If the Flags parameter includes the AUDIT_ALLOW_NO_PRIVILEGE flag, the function performs the access check without generating audit messages when the privilege is not enabled.

The AccessCheckByTypeAndAuditAlarm function fails if the calling thread is not impersonating a client.

If the security descriptor does not contain owner and group SIDs, AccessCheckByTypeAndAuditAlarm fails with ERROR_INVALID_SECURITY_DESCR.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, AccessCheckByType, AccessCheckByTypeResultList, AccessCheckByTypeResultListAndAuditAlarm, GENERIC_MAPPING, MapGenericMask, PRIVILEGE_SET, SECURITY_DESCRIPTOR


AccessCheckByTypeResultListAndAuditAlarm

[This is preliminary documentation and subject to change.]

The AccessCheckByTypeResultListAndAuditAlarm function determines whether a security descriptor grants a specified set of access rights to the client being impersonated by the calling thread. The function can check access to a hierarchy of objects, such as an object, its property sets, and properties. The function reports the access rights granted or denied to each object type in the hierarchy. If the security descriptor has a SACL with ACEs that apply to the client, the function generates any necessary audit messages in the security event log. Alarms are not supported in the current version of Windows NT.

BOOL AccessCheckByTypeResultListAndAuditAlarm(
  LPCTSTR SubsystemName,            // subsystem name
  LPVOID HandleId,                  // object's handle identifier
  LPCTSTR ObjectTypeName,           // type of object
  LPCTSTR ObjectName,               // name of object
  PSECURITY_DESCRIPTOR pSecurityDescriptor,   // security descriptor
  PSID PrincipalSelfSid,            // SID of object being checked
  DWORD DesiredAccess,              // requested access rights
  AUDIT_EVENT_TYPE AuditType,       // type of audit
  DWORD Flags,          // allows access check if no audit privilege
  POBJECT_TYPE_LIST ObjectTypeList, // array of object types
  DWORD ObjectTypeListLength,       // number of object type elements
  PGENERIC_MAPPING GenericMapping,  // map generic to specific rights
  BOOL ObjectCreation,        // flag is TRUE if creating an object
  LPDWORD GrantedAccessList,  // retrieves array of granted rights
  LPDWORD AccessStatusList,   // retrieves array of results flags
  LPBOOL pfGenerateOnClose    // retrieves flag for audit generation
);

Parameters

SubsystemName
Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit message that the function generates.
HandleId
Pointer to a unique 32-bit value representing the client's handle to the object. If the access is denied, the system ignores this value.
ObjectTypeName
Pointer to a null-terminated string specifying the type of object being created or accessed. This string appears in any audit message that the function generates.
ObjectName
Pointer to a null-terminated string specifying the name of the object being created or accessed. This string appears in any audit message that the function generates.
pSecurityDescriptor
Pointer to a SECURITY_DESCRIPTOR structure against which access is checked.
PrincipalSelfSid
Pointer to a SID. If the security descriptor is associated with an object that represents a principal (for example, a user object), the PrincipalSelfSid parameter should be the SID of the object. When evaluating access, this SID logically replaces the SID in any ACE containing the well-known PRINCIPAL_SELF SID (S-1-5-10).

This parameter should be NULL if the protected object does not represent a principal.

DesiredAccess
Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function so that it contains no generic access rights.

If this parameter is MAXIMUM_ALLOWED, the function sets the access masks in the GrantedAccessList to indicate the maximum access rights the security descriptor allows the client.

AuditType
Specifies the type of audit to be generated. This can be one of the values from the AUDIT_EVENT_TYPE enumeration type.
Flags
Flag that controls the function's behavior if the calling process does not have the SE_AUDIT_NAME privilege enabled. If the AUDIT_ALLOW_NO_PRIVILEGE flag is set, the function performs the access check without generating audit messages when the privilege is not enabled. If this parameter is zero, the function fails if the privilege is not enabled.
ObjectTypeList
Pointer to an array of OBJECT_TYPE_LIST structures that identify the hierarchy of object types for which to check access. Each element in the array specifies a GUID that identifies the object type and a value indicating the level of the object type in the hierarchy of object types. The array should not have two elements with the same GUID.

The array must have at least one element. The first element in the array must be at level zero and identify the object itself. The array can have only one level zero element. The second element is a subobject, such as a property set, at level 1. Following each level 1 entry are subordinate entries for the level 2 through 4 subobjects. Thus, the levels for the elements in the array might be {0, 1, 2, 2, 1, 2, 3}. If the object type list is out of order, AccessCheckByTypeResultListAndAuditAlarm fails, and GetLastError returns ERROR_INVALID_PARAMETER.

ObjectTypeListLength
Specifies the number of elements in the ObjectTypeList array.
GenericMapping
Pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
ObjectCreation
Specifies a flag that determines whether the calling application will create a new object when access is granted. A value of TRUE indicates the application will create a new object. A value of FALSE indicates the application will open an existing object.
GrantedAccessList
Pointer to an array of DWORD access masks. The function sets each access mask to indicate the access rights granted to the corresponding element in the object type list. If the function fails, it does not set the access masks.
AccessStatusList
Pointer to an array of DWORD elements. The function sets a DWORD to a nonzero value if the client has the requested access to the corresponding element in the object type list; otherwise, the function sets the DWORD to zero. If the function fails, it does not set any of the elements in the array.
pfGenerateOnClose
Pointer to a flag set by the audit-generation routine when the function returns. Pass this flag to the ObjectCloseAuditAlarm function when the object handle is closed.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The AccessCheckByTypeResultListAndAuditAlarm function is a combination of the AccessCheckByTypeResultList and AccessCheckAndAuditAlarm functions.

The AccessStatusList parameter returns several success or failure status results. Thus, it is possible for a single AccessCheckByTypeResultListAndAuditAlarm call to generate both success and failure audit messages in the security event log.

The ObjectTypeList array does not necessarily represent the entire defined object. Rather, it represents that subset of the object for which to check access. For instance, to check access to two properties in a property set, specify an object type list with four elements: the object itself at level zero, the property set at level 1, and the two properties at level 2.

The AccessCheckByTypeResultListAndAuditAlarm function evaluates ACEs that apply to the object itself and object-specific ACEs for the object types listed in the ObjectTypeList array. The function ignores object-specific ACEs for object types not listed in the ObjectTypeList array.

For more information about how a hierarchy of ACEs controls access to an object and its subobjects, see Controlling Access to an Object's Properties.

To generate audit messages in the security event log, the calling process must have the SE_AUDIT_NAME privilege enabled. The system checks for this privilege in the primary token of the calling process, not the impersonation token of the thread. If the Flags parameter includes the AUDIT_ALLOW_NO_PRIVILEGE flag, the function performs the access check without generating audit messages when the privilege is not enabled.

The AccessCheckByTypeResultListAndAuditAlarm function fails if the calling thread is not impersonating a client.

If the security descriptor does not contain owner and group SIDs, AccessCheckByTypeResultListAndAuditAlarm fails with ERROR_INVALID_SECURITY_DESCR.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, AccessCheckByType, AccessCheckByTypeResultList, AccessCheckByTypeResultListAndAuditAlarm, GENERIC_MAPPING, MapGenericMask, PRIVILEGE_SET, SECURITY_DESCRIPTOR


AccessCheckByTypeResultList

[This is preliminary documentation and subject to change.]

The AccessCheckByTypeResultList function determines whether a security descriptor grants a specified set of access rights to the client identified by an access token. The function can check the client's access to a hierarchy of objects, such as an object, its property sets, and properties. The function reports the access rights granted or denied to each object type in the hierarchy. Typically, server applications use this function to check access to a private object.

BOOL AccessCheckByTypeResultList(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,   // security descriptor
  PSID PrincipalSelfSid,            // SID of object being checked
  HANDLE ClientToken,               // handle to client access token
  DWORD DesiredAccess,              // requested access rights
  POBJECT_TYPE_LIST ObjectTypeList, // array of object types
  DWORD ObjectTypeListLength,       // number of object type elements
  PGENERIC_MAPPING GenericMapping,  // map generic to specific rights
  PPRIVILEGE_SET PrivilegeSet,      // receives privileges used
  LPDWORD PrivilegeSetLength,       // size of privilege-set buffer
  LPDWORD GrantedAccessList,  // retrieves array of granted rights
  LPDWORD AccessStatusList    // retrieves array of results flags
);

Parameters

pSecurityDescriptor
Pointer to a SECURITY_DESCRIPTOR structure against which access is checked.
PrincipalSelfSid
Pointer to a SID. If the security descriptor is associated with an object that represents a principal (for example, a user object), the PrincipalSelfSid parameter should be the SID of the object. When evaluating access, this SID logically replaces the SID in any ACE containing the well-known PRINCIPAL_SELF SID (S-1-5-10).

This parameter should be NULL if the protected object does not represent a principal.

ClientToken
Handle to an impersonation token that represents the client attempting to gain access. The handle must have TOKEN_QUERY access to the token; otherwise, the function fails with ERROR_ACCESS_DENIED.
DesiredAccess
Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function to contain no generic access rights.

If this parameter is MAXIMUM_ALLOWED, the function sets the access masks in the GrantedAccess array to indicate the client's maximum access rights to each element in the object type list.

ObjectTypeList
Pointer to an array of OBJECT_TYPE_LIST structures that identify the hierarchy of object types for which to check access. Each element in the array specifies a GUID that identifies the object type and a value indicating the level of the object type in the hierarchy of object types. The array should not have two elements with the same GUID.

The array must have at least one element. The first element in the array must be at level zero and identify the object itself. The array can have only one level zero element. The second element is a subobject, such as a property set, at level 1. Following each level 1 entry are subordinate entries for the level 2 through 4 subobjects. Thus, the levels for the elements in the array might be {0, 1, 2, 2, 1, 2, 3}. If the object type list is out of order, AccessCheckByTypeResultList fails and GetLastError returns ERROR_INVALID_PARAMETER.

ObjectTypeListLength
Specifies the number of elements in the ObjectTypeList array. This is also the number of elements in the arrays pointed to by the GrantedAccessList and AccessStatusList parameters.
GenericMapping
Pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
PrivilegeSet
Pointer to a PRIVILEGE_SET structure that receives the privileges used to perform the access validation. If no privileges were used, the function sets the PrivilegeCount member to zero.
PrivilegeSetLength
Specifies the size, in bytes, of the buffer pointed to by the PrivilegeSet parameter.
GrantedAccessList
Pointer to an array of DWORD access masks. The function sets each access mask to indicate the access rights granted to the corresponding element in the object type list. If the function fails, it does not set the access masks.
AccessStatusList
Pointer to an array of DWORD elements. The function sets a DWORD to TRUE if the client has the requested access to the corresponding element in the object type list; otherwise, the function sets the DWORD to FALSE. If the function fails, it does not set any of the elements in the array.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The AccessCheckByTypeResultList function compares the specified security descriptor with the specified access token and indicates, in the AccessStatusList parameter, whether access is granted or denied for each of the elements in the object types list.

The ObjectTypeList array does not necessarily represent the entire defined object. Rather, it represents that subset of the object for which to check access. For instance, to check access to two properties in a property set, specify an object type list with four elements: the object itself at level zero, the property set at level 1, and the two properties at level 2.

The AccessCheckByTypeResultList function evaluates ACEs that apply to the object itself and object-specific ACEs for the object types listed in the ObjectTypeList array. The function ignores object-specific ACEs for object types not listed in the ObjectTypeList array. Thus, the results returned for element zero in the AccessStatusList parameter indicate the access allowed to the subset of the object defined by the ObjectTypeList parameter, not to the entire object.

For more information about how a hierarchy of ACEs controls access to an object and its subobjects, see Controlling Access to an Object's Properties.

If the security descriptor's DACL is NULL, the function grants the requested access to all of the elements in the object type list.

If the security descriptor does not contain owner and group SIDs, AccessCheckByTypeResultList fails with ERROR_INVALID_SECURITY_DESCR.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, AccessCheckByType, AccessCheckByTypeAndAuditAlarm, AccessCheckByTypeResultListAndAuditAlarm, GENERIC_MAPPING, MapGenericMask, PRIVILEGE_SET, SECURITY_DESCRIPTOR


AreAllAccessesGranted

The AreAllAccessesGranted function checks whether a set of requested access rights has been granted. The access rights are represented as bit flags in a 32-bit access mask.

BOOL AreAllAccessesGranted(
  DWORD GrantedAccess,  // access mask for granted access rights
  DWORD DesiredAccess   // access mask for requested access rights
);

Parameters

GrantedAccess
An access mask that specifies the access rights that have been granted.
DesiredAccess
An access mask that specifies the access rights that have been requested. This mask must have been mapped from generic to specific and standard access rights, usually by calling the MapGenericMask function.

Return Values

If all requested access rights have been granted, the return value is nonzero.

If not all requested access rights have been granted, the return value is zero.

Remarks

The AreAllAccessesGranted function is commonly used by a server application to check the access rights of a client attempting to gain access to an object. When the bits set in the DesiredAccess parameter match the bits set in the GrantedAccess parameter, all requested rights have been granted.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AreAnyAccessesGranted, MapGenericMask


AreAnyAccessesGranted

The AreAnyAccessesGranted function tests whether any of a set of requested access rights has been granted. The access rights are represented as bit flags in a 32-bit access mask.

BOOL AreAnyAccessesGranted(
  DWORD GrantedAccess,  // access mask for granted access rights
  DWORD DesiredAccess   // access mask for access rights requested
);

Parameters

GrantedAccess
Specifies the granted access mask.
DesiredAccess
Specifies the access mask to be requested. This mask must have been mapped from generic to specific and standard access rights, usually by calling the MapGenericMask function.

Return Values

If any of the requested access rights have been granted, the return value is nonzero.

If none of the requested access rights have been granted, the return value is zero.

Remarks

The AreAnyAccessesGranted function is often used by a server application to check the access rights of a client attempting to gain access to an object. When any of the bits set in the DesiredAccess parameter match the bits set in the GrantedAccess parameter, at least one of the requested access rights has been granted.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AreAllAccessesGranted, MapGenericMask


BuildSecurityDescriptor

The BuildSecurityDescriptor function allocates and initializes a new security descriptor. A security descriptor is an opaque structure that contains the security information associated with an object. The function can initialize the new security descriptor by merging specified security information with the information in an existing security descriptor. If you don't specify an existing security descriptor, the function initializes a new security descriptor based on the specified security information.

BuildSecurityDescriptor creates a self-relative security descriptor, which means that the security descriptor stores a SECURITY_DESCRIPTOR structure and associated security information in a contiguous block of memory. The self-relative format makes the security descriptor suitable for storing in a stream.

DWORD BuildSecurityDescriptor(
  PTRUSTEE pOwner,  // identifies owner for new security descriptor
  PTRUSTEE pGroup,  // identifies group for new security descriptor
  ULONG cCountOfAccessEntries,
                    // number of access-control entries in the list
  PEXPLICIT_ACCESS pListOfAccessEntries,
                    // pointer to list of access-control entries for
                    // DACL
  ULONG cCountOfAuditEntries,
                    // number of audit-control entries in the list
  PEXPLICIT_ACCESS pListOfAuditEntries,
                    // pointer to list of audit-control entries for
                    // SACL
  PSECURITY_DESCRIPTOR pOldSD,
                    // pointer to an existing security descriptor
  PULONG pSizeNewSD,
                    // pointer to the size of the new security
                    // descriptor
  PSECURITY_DESCRIPTOR * pNewSD
                    // pointer that receives the new security
                    // descriptor
);

Parameters

pOwner
Pointer to a TRUSTEE structure that identifies the owner for the new security descriptor. If the structure uses the TRUSTEE_IS_NAME form, BuildSecurityDescriptor looks up the SID associated with the specified trustee name.

If this parameter is NULL, the function uses the owner SID from the original security descriptor pointed to by pOldSD. If pOldSD is NULL, or if the owner SID in pOldSD is NULL, the owner SID is NULL in the new security descriptor.

pGroup
Pointer to a TRUSTEE structure that identifies the primary group SID for the new security descriptor. If the structure uses the TRUSTEE_IS_NAME form, BuildSecurityDescriptor looks up the SID associated with the specified trustee name.

If this parameter is NULL, the function uses the group SID from the original security descriptor pointed to by pOldSD. If pOldSD is NULL, or if the group SID in pOldSD is NULL, the group SID is NULL in the new security descriptor.

cCountOfAccessEntries
Specifies the number of EXPLICIT_ACCESS structures in the pListOfAccessEntries array.
pListOfAccessEntries
Pointer to an array of EXPLICIT_ACCESS structures that describe access control information for the DACL of the new security descriptor. The function creates the new DACL by merging the information in the array with the DACL in pOldSD, if any. If pOldSD is NULL, or if the DACL in pOldSD is NULL, the function creates a new DACL based solely on the information in the array. For a description of the rules for creating an ACL from an array of EXPLICIT_ACCESS structures, see the SetEntriesInAcl function.

If pListOfAccessEntries is NULL, the new security descriptor gets the DACL from pOldSD. In this case, if pOldSD is NULL, or if the DACL in pOldSD is NULL, the new DACL is NULL.

cCountOfAuditEntries
Specifies the number of EXPLICIT_ACCESS structures in the pListOfAuditEntries array.
pListOfAuditEntries
Pointer to an array of EXPLICIT_ACCESS structures that describe audit control information for the SACL of the new security descriptor. The function creates the new SACL by merging the information in the array with the SACL in pOldSD, if any. If pOldSD is NULL, or the SACL in pOldSD is NULL, the function creates a new SACL based solely on the information in the array.

If pListOfAuditEntries is NULL, the new security descriptor gets the SACL from pOldSD. In this case, if pOldSD is NULL, or the SACL in pOldSD is NULL, the new SACL is NULL.

pOldSD
Pointer to an existing self-relative SECURITY_DESCRIPTOR structure and its associated security information. The function builds the new security descriptor by merging the specified owner, group, access-control, and audit-control information with the information in this security descriptor. This parameter can be NULL.
pSizeNewSD
Pointer to a ULONG variable that receives the size, in bytes, of the returned security descriptor.
pNewSD
Pointer to a variable that receives a pointer to the new security descriptor. The function allocates memory for the new security descriptor. You must call the LocalFree function to free the returned buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H.

Remarks

The BuildSecurityDescriptor function is intended for trusted servers that implement or expose security on their own objects. The function uses self-relative security descriptors suitable for serializing into a stream and storing to disk, as a trusted server might require.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, ACL, EXPLICIT_ACCESS, LocalFree, SECURITY_DESCRIPTOR, SetEntriesInAcl, SID, TRUSTEE


ConvertToAutoInheritPrivateObjectSecurity

[This is preliminary documentation and subject to change.]

The ConvertToAutoInheritPrivateObjectSecurity function converts a security descriptor and its ACLs to a format that supports automatic propagation of inheritable ACEs.

BOOL ConvertToAutoInheritPrivateObjectSecurity(
  PSECURITY_DESCRIPTOR ParentDescriptor,
                            // security descriptor of parent object
  PSECURITY_DESCRIPTOR CurrentSecurityDescriptor,
                            // current security descriptor of object
  PSECURITY_DESCRIPTOR * NewSecurityDescriptor,
                            // receives new security descriptor
  GUID * ObjectType,        // type of object
  BOOLEAN IsDirectoryObject,       // identifies container objects
  PGENERIC_MAPPING GenericMapping  // map generic to specific rights
);

Parameters

ParentDescriptor
Pointer to the security descriptor for the parent container of the object. If there is no parent container, this parameter is NULL.
CurrentSecurityDescriptor
Pointer to the current security descriptor of the object.
NewSecurityDescriptor
Pointer to a variable that receives a pointer to the newly allocated self-relative security descriptor. It is the caller's responsibility to call the DestroyPrivateObjectSecurity function to free this security descriptor.
ObjectType
Pointer to a GUID structure that identifies the type of object associated with CurrentSecurityDescriptor. Set ObjectType to NULL if the object does not have a GUID.
IsDirectoryObject
Specifies whether the new object can contain other objects. A value of TRUE indicates that the new object is a container. A value of FALSE indicates that the new object is not a container.
GenericMapping
Pointer to a GENERIC_MAPPING structure that specifies the mapping from each generic right to specific rights for the object.

Remarks

The ConvertToAutoInheritPrivateObjectSecurity function attempts to determine whether the ACEs in the DACL and SACL of the current security descriptor were inherited from the parent security descriptor. The function passes the ParentDescriptor parameter to the CreatePrivateObjectSecurityEx function to get ACLs that contain only inherited ACEs. Then it compares these ACEs to the ACEs in the original security descriptor to determine which of the original ACEs were inherited. The ACEs do not need to match one-to-one. For instance, an ACE that allows read and write access to a trustee can be equivalent to two ACEs: an ACE that allows read access and an ACE that allows write access.

Any ACEs in the original security descriptor that are equivalent to the ACEs inherited from the parent security descriptor are marked with the INHERITED_ACE flag and added to the new security descriptor. All other ACEs in the original security descriptor are added to the new security descriptor as noninherited ACEs.

If the original DACL does not have any inherited ACEs, the function sets the SE_DACL_PROTECTED flag in the control bits of the new security descriptor. Similarly, the SE_SACL_PROTECTED flag is set if none of the ACEs in the SACL is inherited.

For DACLs that have inherited ACEs, the function reorders the ACEs into two groups. The first group has ACEs that were directly applied to the object. The second group has inherited ACEs. This ordering ensures that noninherited ACEs have precedence over inherited ACEs. For more information, see Order of ACEs in a DACL.

The function sets the SE_DACL_AUTO_INHERITED and SE_SACL_AUTO_INHERITED flags in the control bits of the new security descriptor.

The function does not change the ordering of access-allowed ACEs in relation to access-denied ACEs in the DACL, because to do so would change the semantics of the resulting security descriptor. If the function cannot convert the DACL without changing the semantics, it leaves the DACL unchanged and sets the SE_DACL_PROTECTED flag.

The new security descriptor has the same owner and primary group as the original security descriptor.

The new security descriptor is equivalent to the original security descriptor, so the caller needs no access rights or privileges to update the security descriptor to the new format.

This function works with ACL_REVISION and ACL_REVISION_DS ACLs.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreatePrivateObjectSecurityEx, GENERIC_MAPPING


CreatePrivateObjectSecurity

The CreatePrivateObjectSecurity function allocates and initializes a self-relative security descriptor for a new private object. A protected server calls this function when it creates a new private object.

BOOL CreatePrivateObjectSecurity(
  PSECURITY_DESCRIPTOR ParentDescriptor,
                           // pointer to parent directory SD
  PSECURITY_DESCRIPTOR CreatorDescriptor,
                           // pointer to creator SD
  PSECURITY_DESCRIPTOR *NewDescriptor,
                           // pointer to pointer to new SD
  BOOL IsDirectoryObject,  // container flag for new SD
  HANDLE Token,            // handle to client's access token
  PGENERIC_MAPPING GenericMapping
                           // pointer to access-rights structure
);

Parameters

ParentDescriptor
Pointer to the security descriptor for the parent directory in which a new object is being created. If there is no parent directory, this parameter can be NULL.
CreatorDescriptor
Pointer to a security descriptor provided by the creator of the object. If the object's creator does not explicitly pass security information for the new object, this parameter is intended to be NULL.
lppsdNew
Pointer to a variable that receives a pointer to the newly allocated self-relative security descriptor. The caller must call the DestroyPrivateObjectSecurity function to free this security descriptor.
IsDirectoryObject
Specifies whether the new object is a container. A value of TRUE indicates the object contains other objects, such as a directory.
Token
Identifies the access token for the client process on whose behalf the object is being created. If this is an impersonation token, it must be at SecurityIdentification level or higher. For a full description of the SecurityIdentification impersonation level, see the SECURITY_IMPERSONATION_LEVEL enumerated type

A client token is used to retrieve default security information for the new object, such as its default owner, primary group, and discretionary access-control list. The token must be open for TOKEN_QUERY access.

GenericMapping
Pointer to a GENERIC_MAPPING structure that specifies the mapping from each generic right to specific rights for the object.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If a system access-control list, or SACL, is specified in the SECURITY_DESCRIPTOR specified by CreatorDescriptor, Token must have the SE_SECURITY_NAME privilege enabled, and the caller's token must have the SE_AUDIT_NAME privilege enabled. The CreatePrivateObjectSecurity function performs access/privilege checks to ensure this, and may generate audits during the process.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, DestroyPrivateObjectSecurity, GENERIC_MAPPING, GetPrivateObjectSecurity, GetTokenInformation, OpenProcessToken, SECURITY_DESCRIPTOR, SECURITY_IMPERSONATION_LEVEL, SetPrivateObjectSecurity


CreatePrivateObjectSecurityEx

[This is preliminary documentation and subject to change.]

The CreatePrivateObjectSecurityEx function allocates and initializes a self-relative security descriptor for a new private object. A protected server calls this function when it creates a new private object.

The CreatePrivateObjectSecurityEx function is identical to the CreatePrivateObjectSecurity function except for the following:

  • CreatePrivateObjectSecurityEx can specify the object type GUID of the new object
  • CreatePrivateObjectSecurityEx can specify flags that control how ACEs are inherited from the security descriptor of the parent container.
BOOL CreatePrivateObjectSecurityEx(
  PSECURITY_DESCRIPTOR ParentDescriptor,
                            // security descriptor of parent object
  PSECURITY_DESCRIPTOR CreatorDescriptor,
                            // current security descriptor of object
  PSECURITY_DESCRIPTOR *NewDescriptor,
                            // receives the new security descriptor
  GUID * ObjectType,        // type of object
  BOOL IsContainerObject,   // identifies container objects
  ULONG AutoInheritFlags,   // identifies container objects
  HANDLE Token,             // identifies container objects
  PGENERIC_MAPPING GenericMapping  // map generic to specific rights
);

Parameters

ParentDescriptor
Pointer to the security descriptor for the parent container of the object. If there is no parent container, this parameter is NULL.
CreatorDescriptor
Pointer to a security descriptor provided by the creator of the object. If the object's creator does not explicitly pass security information for the new object, this parameter can be NULL. Alternatively, this parameter can point to a default security descriptor.
NewDescriptor
Pointer to a variable that receives a pointer to the newly allocated self-relative security descriptor. The caller must call the DestroyPrivateObjectSecurity function to free this security descriptor.
ObjectType
Pointer to a GUID structure that identifies the type of object associated with CurrentSecurityDescriptor. Set ObjectType to NULL if the object does not have a GUID.
IsContainerObject
Specifies whether the new object can contain other objects. A value of TRUE indicates that the new object is a container. A value of FALSE indicates that the new object is not a container.
AutoInheritFlags
A set of bit flags that control how ACEs are inherited from ParentDescriptor. This parameter can be a combination of the following values.
Value Meaning
SEF_DACL_AUTO_INHERIT
If this flag is set, the new DACL contains ACEs inherited from the DACL of the ParentDescriptor, as well as any explicit ACEs specified in the DACL of the CreatorDescriptor. If this flag is not set, the new DACL does not inherit ACEs.
SEF_SACL_AUTO_INHERIT
If this flag is set, the new SACL contains ACEs inherited from the SACL of the ParentDescriptor, as well as any explicit ACEs specified in the SACL of the CreatorDescriptor. If this flag is not set, the new SACL does not inherit ACEs.
SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT
If this flag is set, the CreatorDescriptor is the default descriptor for the type of object specified by ObjectType. As such, the CreatorDescriptor is ignored if the ParentDescriptor has any object-specific ACEs for the type of object specified by the ObjectType-parameter. If no such ACEs are inherited, the CreatorDescriptor is handled as though this flag were not specified.
SEF_AVOID_PRIVILEGE_CHECK
If this flag is set, the function does not perform privilege checking. The Token parameter can be NULL. This flag is useful while implementing automatic inheritance to avoid checking privileges on each child updated.

Token
Identifies the access token for the client process on whose behalf the object is being created. If this is an impersonation token, it must be at SecurityIdentification level or higher. For a full description of the SecurityIdentification impersonation level, see the SECURITY_IMPERSONATION_LEVEL enumerated type.

The client token contains default security information, such as the default owner, primary group, and DACL. The function uses these defaults if the information is not in the input security descriptors. The token must be open for TOKEN_QUERY access.

GenericMapping
Pointer to a GENERIC_MAPPING structure that specifies the mapping from each generic right to specific rights for the object.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The CreatePrivateObjectSecurity function is identical to calling the CreatePrivateObjectSecurityEx function with ObjectType set to NULL and AutoInheritFlags set to zero.

The AutoInheritFlags are distinct from the similarly named bits in the Control member of the SECURITY_DESCRIPTOR structure. For an explanation of the control bits, see SECURITY_DESCRIPTOR_CONTROL.

If AutoInheritFlags specifies the SEF_DACL_AUTO_INHERIT bit, the function applies the following rules to the DACL in the new security descriptor:

  • The SE_DACL_AUTO_INHERITED flag is set in the Control member of the new security descriptor.
  • The DACL of the new security descriptor inherits ACEs from the ParentDescriptor regardless of whether CreatorDescriptor is the default security descriptor or was explicitly specified by the creator. The new DACL is a combination of the parent and creator DACLs as defined by the rules of inheritance.
  • Inherited ACEs are marked as INHERITED_ACE.

If AutoInheritFlags specifies the SEF_SACL_AUTO_INHERIT bit, the function applies similar rules to the new SACL.

To create a security descriptor for a new object, call CreatePrivateObjectSecurityEx with ParentDescriptor set to the security descriptor of the parent container and CreatorDescriptor set to the security descriptor proposed by the creator of the object.

To verify the current security descriptor on an object, call CreatePrivateObjectSecurityEx with ParentDescriptor set to the security descriptor of the parent container and CreatorDescriptor set to the current security descriptor of the object. This call ensures that the ACEs are appropriately inherited from parent to child security descriptors.

If the CreatorDescriptor security descriptor contains a SACL, Token must have the SE_SECURITY_NAME privilege enabled, and the caller's token must have the SE_AUDIT_NAME privilege enabled. The CreatePrivateObjectSecurityEx function checks these privileges, and may generate audits if they are not enabled.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, DestroyPrivateObjectSecurity, GENERIC_MAPPING, GetPrivateObjectSecurity, GetTokenInformation, OpenProcessToken, SECURITY_DESCRIPTOR, SECURITY_IMPERSONATION_LEVEL, SetPrivateObjectSecurityEx


DestroyPrivateObjectSecurity

The DestroyPrivateObjectSecurity function deletes a private object's security descriptor. This security descriptor must have been created by a call to the CreatePrivateObjectSecurity function.

BOOL DestroyPrivateObjectSecurity(
  PSECURITY_DESCRIPTOR *ObjectDescriptor   // address of pointer to
                                           // SECURITY_DESCRIPTOR
);

Parameters

ObjectDescriptor
Pointer to a pointer to the SECURITY_DESCRIPTOR structure to be deleted.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreatePrivateObjectSecurity, GetPrivateObjectSecurity, SECURITY_DESCRIPTOR, SetPrivateObjectSecurity


GetAccessPermissionsForObject

[This is preliminary documentation and subject to change.]

The GetAccessPermissionsForObject function determines the access rights supported by a specified object.

DWORD GetAccessPermissionsForObject(
  LPCTSTR lpObject,    // name of the object
  SE_OBJECT_TYPE ObjectType,
                       // type of object
  LPCTSTR lpProvider,  // name of provider to handle request
  PULONG pcEntries,    // receives number of entries in the array
  PACTRL_ACCESS_INFO *ppAccessInfoList,
                       // receives an array of access information
  PULONG pfAccessFlags // receives access flags
);

Parameters

lpObject
Pointer to a null-terminated string that specifies the name of the object for which to get the list of supported access rights. For descriptions of the string formats for the different object types, see SE_OBJECT_TYPE.
ObjectType
Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object named by the lpObject parameter.
lpProvider
Pointer to a null-terminated string that specifies the name of the provider to handle the request. If this parameter is NULL, the system determines the proper provider to handle the request.
pcEntries
Pointer to a ULONG value that receives the number of entries returned in the ppAccessInfoList array.
ppAccessInfoList
Pointer to a variable that receives a pointer to an array of ACTRL_ACCESS_INFO structures. Each entry identifies an access right supported by the object. Call the LocalFree function to free the returned buffer.
pfAccessFlags
Pointer to a ULONG value that can receive the following access flag.
Value Meaning
ACTRL_ACCESS_SUPPORTS_OBJECT_ENTRIES
The object's provider supports setting access-control entries on the object's properties, and it also supports propagating inherited entries to child objects.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
ERROR_BAD_PROVIDER | The lpProvider parameter specified an invalid provider name.
ERROR_INVALID_PARAMETER | An invalid parameter was specified.
ERROR_NOT_ENOUGH_MEMORY | A memory allocation failed.

Remarks

The GetAccessPermissionsForObject function returns an array of ACTRL_ACCESS_INFO structures to indicate the access rights an object supports. For example, the array for an SE_FILE_OBJECT object type might include the following access rights and string descriptions.

{ACTRL_SYNCHRONIZE, "Synchronize"},
{ACTRL_CHANGE_OWNER, "Change Owner"},
{ACTRL_CHANGE_ACCESS, "Change Access"},
…
{ACTRL_FILE_READ, "Read File"},
{ACTRL_FILE_WRITE, "Write File"}
…

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, ACTRL_ACCESS_INFO, SE_OBJECT_TYPE


GetPrivateObjectSecurity

The GetPrivateObjectSecurity retrieves information from a private object's security descriptor.

BOOL GetPrivateObjectSecurity(
  PSECURITY_DESCRIPTOR ObjectDescriptor,
                        // address of SD to query
  SECURITY_INFORMATION SecurityInformation,
                        // requested information
  PSECURITY_DESCRIPTOR ResultantDescriptor,
                        // address of retrieved SD
  DWORD DescriptorLength,  // size of buffer for retrieved SD
  PDWORD ReturnLength   // address of buffer size required for SD
);

Parameters

ObjectDescriptor
Pointer to a SECURITY_DESCRIPTOR structure. This is the security descriptor to be queried.
SecurityInformation
A set of bit flags that indicate the parts of the security descriptor to retrieve. This value can be a combination of the SECURITY_INFORMATION bit flags.
ResultantDescriptor
Pointer to a buffer that receives a copy of the requested information from the specified security descriptor. The SECURITY_DESCRIPTOR structure is returned in self-relative format.
DescriptorLength
Specifies the size, in bytes, of the buffer pointed to by the ResultantDescriptor parameter.
ReturnLength
Pointer to a variable the function sets to zero if the descriptor is copied successfully. If the buffer is too small for the security descriptor, this variable receives the number of bytes required. If this variable's value is greater than the value of the DescriptorLength parameter when the function returns, the function returns FALSE and none of the security descriptor is copied to the buffer.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

An application must perform appropriate access/privilege checks and audits before calling this function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreatePrivateObjectSecurity, DestroyPrivateObjectSecurity, GetFileSecurity, GetKernelObjectSecurity, GetUserObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetPrivateObjectSecurity


ImpersonateLoggedOnUser

The ImpersonateLoggedOnUser function lets the calling thread impersonate the security context of a logged-on user. The user is represented by a token handle.

BOOL ImpersonateLoggedOnUser(
  HANDLE hToken  // handle to a token that represents a logged-on
                 // user
);

Parameters

hToken
Handle to a primary or impersonation access token that represents a logged-on user. This can be a token handle returned by a call to LogonUser, CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, OpenProcessToken, or OpenThreadToken functions. If hToken is a primary token, it must have TOKEN_QUERY and TOKEN_DUPLICATE access. If hToken is an impersonation token, it must have TOKEN_QUERY access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The impersonation lasts until the thread exits or until it calls RevertToSelf.

The calling thread does not need to have any particular privileges to call ImpersonateLoggedOnUser.

For more information about impersonation, see Client Impersonation.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use kernel32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreateProcessAsUser, CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, LogonUser, OpenProcessToken, or OpenThreadToken, RevertToSelf


ImpersonateNamedPipeClient

The ImpersonateNamedPipeClient function impersonates a named-pipe client application.

BOOL ImpersonateNamedPipeClient(
  HANDLE hNamedPipe   // handle of a named pipe
);

Parameters

hNamedPipe
Identifies a named pipe.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ImpersonateNamedPipeClient function allows the server end of a named pipe to impersonate the client end. When this function is called, the named-pipe file system changes the thread of the calling process to start impersonating the security context of the last message read from the pipe. Only the server end of the pipe can call this function.

The server can call the RevertToSelf function when the impersonation is complete.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, DdeImpersonateClient, DuplicateToken, RevertToSelf


ImpersonateSelf

The ImpersonateSelf function obtains an access token that impersonates the security context of the calling process. The token is assigned to the calling thread.

BOOL ImpersonateSelf(
  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel  // impersonation
                                                   // level
);

Parameters

ImpersonationLevel
Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that supplies the impersonation level of the new token.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ImpersonateSelf function is used for tasks, such as enabling a privilege for a single thread rather than for the entire process or for changing the default discretionary access-control list for a single thread.

The server can call the RevertToSelf function when the impersonation is complete.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, DuplicateToken, ImpersonateNamedPipeClient, RevertToSelf, SECURITY_IMPERSONATION_LEVEL


LogonUser

The LogonUser function attempts to log a user on to the local computer, that is, to the computer from which LogonUser was called. You cannot use LogonUser to log on to a remote computer. You specify the user with a user name and domain, and authenticate the user with a clear-text password. If the function succeeds, you receive a handle to a token that represents the logged-on user. You can then use this token handle to impersonate the specified user, or in most cases, to create a process running in the context of the specified user.

BOOL LogonUser(
  LPTSTR lpszUsername,    // string that specifies the user name
  LPTSTR lpszDomain,      // string that specifies the domain or
                          // server
  LPTSTR lpszPassword,    // string that specifies the password
  DWORD dwLogonType,      // specifies the type of logon operation
  DWORD dwLogonProvider,  // specifies the logon provider
  PHANDLE phToken         // pointer to variable to receive token
                          // handle
);

Parameters

lpszUsername
Pointer to a null-terminated string that specifies the user name. This is the name of the user account to log on to.
lpszDomain
Pointer to a null-terminated string that specifies the name of the domain or server whose account database contains the lpszUserName account. LogonUser asks the domain controller or server to search for and validate the account. If this parameter is ".", LogonUser validates the account using only the local account database. If this parameter is NULL, LogonUser first searches the local account database and then asks trusted domains to search their account databases until it finds the account or the search is exhausted.
lpszPassword
Pointer to a null-terminated string that specifies the clear-text password for the user account specified by lpszUsername.
dwLogonType
Specifies the type of logon operation to perform. The following logon types are defined:
Value | Meaning
LOGON32_LOGON_BATCH | This logon type is intended for batch servers, where processes may be executing on behalf of a user without their direct intervention; or for higher performance servers that process many clear-text authentication attempts at a time, such as mail or web servers. LogonUser does not cache credentials for this logon type.
LOGON32_LOGON_INTERACTIVE | This logon type is intended for users who will be interactively using the machine, such as a user being logged on by a terminal server, remote shell, or similar process. This logon type has the additional expense of caching logon information for disconnected operation, and is therefore inappropriate for some client/server applications, such as a mail server.
LOGON32_LOGON_SERVICE | Indicates a service-type logon. The account provided must have the service privilege enabled.
LOGON32_LOGON_NETWORK This logon type is intended for high performance servers to authenticate clear text passwords. LogonUser does not cache credentials for this logon type. This is the fastest logon path, but there are two limitations.

First, the function returns an impersonation token, not a primary token. You cannot use this token directly in the CreateProcessAsUser function. However, you can call the DuplicateTokenEx function to convert the token to a primary token, and then use it in CreateProcessAsUser.

Second, if you convert the token to a primary token and use it in CreateProcessAsUser to start a process, the new process will not be able to access other network resources, such as remote servers or printers, through the redirector.

dwLogonProvider
Specifies the logon provider. The following logon providers are defined:
Value | Meaning
LOGON32_PROVIDER_DEFAULT | Use the standard logon provider for the system. This is the recommended value for the dwLogonProvider parameter. It provides maximum compatibility with current and future releases of Windows NT.
LOGON32_PROVIDER_WINNT40 | Use the Windows NT 4.0 logon provider
LOGON32_PROVIDER_WINNT35 | Use the Windows NT 3.5 logon provider.

phToken
Pointer to a HANDLE variable that receives a handle to a token that represents the specified user.

You can use the returned handle in calls to the ImpersonateLoggedOnUser function.

In most cases, the returned handle is a primary token that you can use in calls to the CreateProcessAsUser function. However, if you specify the LOGON32_LOGON_NETWORK flag, LogonUser returns an impersonation token that you cannot use in CreateProcessAsUser unless you call DuplicateTokenEx to convert it to a primary token.

When you no longer need this handle, close it by calling the CloseHandle function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The process that calls LogonUser must have the SE_TCB_NAME privilege. The privilege does not need to be enabled. The LogonUser function enables the privilege as necessary. If the calling process does not have this privilege, LogonUser fails and GetLastError returns ERROR_PRIVILEGE_NOT_HELD.

In some cases, the process that calls LogonUser must also have the SE_CHANGE_NOTIFY_NAME privilege enabled; otherwise, LogonUser fails and GetLastError returns ERROR_ACCESS_DENIED. This privilege is not required for the local system account or accounts that are members of the administrators group. By default, SE_CHANGE_NOTIFY_NAME is enabled for all users, but some administrators may disable it for everyone. For more information about privileges, see Privileges.

A user is considered logged on as long as at least one token exists. If you call CreateProcessAsUser and then close the token, the system considers the user as still logged on until the process (and all child processes) have ended.

If the LogonUser call is successful, the system notifies network providers that the logon occurred by calling the provider's NPLogonNotify entry-point.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreateProcessAsUser, ImpersonateLoggedOnUser


LookupSecurityDescriptorParts

The LookupSecurityDescriptorParts function retrieves security information from a self-relative security descriptor.

DWORD LookupSecurityDescriptorParts(
  PTRUSTEE *pOwner,  // receives the owner SID from the security
                     // descriptor
  PTRUSTEE *pGroup,  // receives the group SID from the security
                     // descriptor
  PULONG cCountOfAccessEntries,
                     // receives number of access-control entries
  PEXPLICIT_ACCESS *pListOfAccessEntries,
                     // receives an array of DACL access-control
                     // entries
  PULONG cCountOfAuditEntries,
                     // receives number of audit-control entries
  PEXPLICIT_ACCESS *pListOfAuditEntries,
                     // receives an array of SACL audit-control
                     // entries
  PSECURITY_DESCRIPTOR pSD
                     // pointer to the security descriptor
);

Parameters

pOwner
Pointer to a variable that receives a pointer to a TRUSTEE structure. The function looks up the name associated with the owner SID in the pSD security descriptor, and returns a pointer to the name in the ptstrName member of the TRUSTEE structure. The function sets the TrusteeForm member to TRUSTEE_IS_NAME.

This parameter can be NULL if you are not interested in the name of the owner.

pGroup
Pointer to a variable that receives a pointer to a TRUSTEE structure. The function looks up the name associated with the primary group SID of the security descriptor, and returns a pointer to the name in the ptstrName member of the TRUSTEE structure. The function sets the TrusteeForm member to TRUSTEE_IS_NAME.

This parameter can be NULL if you are not interested in the name of the group.

cCountOfAccessEntries
Pointer to a ULONG that receives the number of EXPLICIT_ACCESS structures returned in the pListOfAccessEntries array. This parameter can be NULL only if the pListOfAccessEntries parameter is also NULL.
pListOfAccessEntries
Pointer to a variable that receives a pointer to an array of EXPLICIT_ACCESS structures that describe the ACEs in the DACL of the security descriptor. The TRUSTEE structure in these EXPLICIT_ACCESS structures use the TRUSTEE_IS_NAME form. For a description of how an array of EXPLICIT_ACCESS structures describes the ACEs in an ACL, see the GetExplicitEntriesFromAcl function. If this parameter is NULL, the cCountOfAccessEntries parameter must also be NULL.
cCountOfAuditEntries
Pointer to a ULONG that receives the number of EXPLICIT_ACCESS structures returned in the pListOfAuditEntries array. This parameter can be NULL only if the pListOfAuditEntries parameter is also NULL.
pListOfAuditEntries
Pointer to a variable that receives a pointer to an array of EXPLICIT_ACCESS structures that describe the ACEs in the SACL of the security descriptor. The TRUSTEE structure in these EXPLICIT_ACCESS structures uses the TRUSTEE_IS_NAME form. If this parameter is NULL, the cCountOfAuditEntries parameter must also be NULL.
pSD
Pointer to an existing self-relative security descriptor from which the function retrieves security information. A self-relative security descriptor stores a SECURITY_DESCRIPTOR structure and associated security information in a contiguous block of memory. This differs from an absolute security descriptor, which contains pointers to the associated security information.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H.

Remarks

The LookupSecurityDescriptorParts function retrieves the names of the owner and primary group of the security descriptor. It also returns descriptions of the access-control entries in the DACL and audit-control entries in the SACL of the security descriptor.

The parameters other than pSD can be NULL if you are not interested in the information. If you do not want information about the DACL, both pListOfAccessEntries and cCountOfAccessEntries must be NULL. If you do not want information about the SACL, both pListOfAuditEntries and cCountOfAuditEntries must be NULL. Similarly, if you do want DACL or SACL information, both of the corresponding parameters must be non-NULL.

You must call the LocalFree function to free any buffers returned by the pOwner, pGroup, pListOfAccessEntries, or pListOfAuditEntries parameters.

The LookupSecurityDescriptorParts function is intended for trusted servers that implement or expose security on their own objects. The function works with a self-relative security descriptor suitable for serializing into a stream and storing to disk, as a trusted server might require.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, ACE, ACL, EXPLICIT_ACCESS, LocalFree, SECURITY_DESCRIPTOR, GetExplicitEntriesFromAcl, SID, TRUSTEE


MapGenericMask

The MapGenericMask function maps the generic access rights in an access mask to specific and standard access rights. The function applies a mapping supplied in a GENERIC_MAPPING structure.

VOID MapGenericMask(
  PDWORD AccessMask,  // address of access mask
  PGENERIC_MAPPING GenericMapping
                      // address of GENERIC_MAPPING structure
);

Parameters

AccessMask
Pointer to an access mask receiving the specific and standard rights mapped from generic access rights.
GenericMapping
Pointer to a GENERIC_MAPPING structure specifying a mapping of generic access types to specific and standard access types.

Return Values

This function does not return a value.

Remarks

After calling the MapGenericMask function, the access mask pointed to by the AccessMask parameter has none of its generic bits (GenericRead, GenericWrite, GenericExecute, or GenericAll) or undefined bits set, although it can have other bits set. If bits other than the generic bits are provided on input, this function does not clear them.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AreAllAccessesGranted, AreAnyAccessesGranted, GENERIC_MAPPING


ObjectCloseAuditAlarm

The ObjectCloseAuditAlarm function generates an audit message in the security event log when a handle of an private object is deleted. Alarms are not supported in the current version of Windows NT.

BOOL ObjectCloseAuditAlarm(
  LPCTSTR SubsystemName, // address of string for subsystem name
  LPVOID HandleId,       // address of handle identifier
  BOOL GenerateOnClose   // flag for audit generation
);

Parameters

SubsystemName
Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit message that the function generates.
HandleId
Specifies a unique 32-bit value representing the client's handle of the object. This should be the same value that was passed to the AccessCheckAndAuditAlarm or ObjectOpenAuditAlarm function.
GenerateOnClose
Specifies a flag set by a call to the AccessCheckAndAuditAlarm or ObjectOpenAuditAlarm function when the object handle is created. If this flag is TRUE, the function generates an audit message. If it is FALSE, the function does not generate an audit message.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ObjectCloseAuditAlarm function requires the calling application to have the SE_AUDIT_NAME privilege enabled. The test for this privilege is always performed against the primary token of the calling process, allowing the calling process to impersonate a client.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheckAndAuditAlarm, ObjectDeleteAuditAlarm, ObjectOpenAuditAlarm, ObjectPrivilegeAuditAlarm


ObjectDeleteAuditAlarm

The ObjectDeleteAuditAlarm function generates audit messages when an object is deleted. Windows NT security does not support alarms.

BOOL ObjectDeleteAuditAlarm(
  LPCTSTR SubsystemName, // pointer to string for subsystem name
  LPVOID HandleId,       // handle to the object
  BOOL GenerateOnClose   // flag for audit generation
);

Parameters

SubsystemName
Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit message that the function generates.
HandleId
Specifies a unique 32-bit value representing the client's handle to the object. This should be the same value that was passed to the AccessCheckAndAuditAlarm or ObjectOpenAuditAlarm function.
GenerateOnClose
Specifies a flag set by a call to the AccessCheckAndAuditAlarm or ObjectOpenAuditAlarm function when the object handle is created.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ObjectDeleteAuditAlarm function requires the calling application to have the SE_AUDIT_NAME privilege enabled. The test for this privilege is always performed against the primary token of the calling process, allowing the calling process to impersonate a client.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, AreAllAccessesGranted, AreAnyAccessesGranted, MapGenericMask, ObjectCloseAuditAlarm, ObjectOpenAuditAlarm, ObjectPrivilegeAuditAlarm, PrivilegeCheck, PrivilegedServiceAuditAlarm


ObjectOpenAuditAlarm

The ObjectOpenAuditAlarm function generates audit messages when a client application attempts to gain access to an object or to create a new one. Alarms are not supported in the current version of Windows NT.

BOOL ObjectOpenAuditAlarm(
  LPCTSTR SubsystemName,  // address of string for subsystem name
  LPVOID HandleId,        // address of handle identifier
  LPTSTR ObjectTypeName,  // address of string for object type
  LPTSTR ObjectName,      // address of string for object name
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
                          // address of security descriptor
  HANDLE ClientToken,     // handle of client's access token
  DWORD DesiredAccess,    // mask for desired access rights
  DWORD GrantedAccess,    // mask for granted access rights
  PPRIVILEGE_SET Privileges,  // address of privileges
  BOOL ObjectCreation,    // flag for object creation
  BOOL AccessGranted,     // flag for results
  LPBOOL GenerateOnClose   // address of flag for audit generation
);

Parameters

SubsystemName
Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit message that the function generates.
HandleId
Pointer to a unique 32-bit value representing the client's handle of the object. If the access is denied, this parameter is ignored.
ObjectTypeName
Pointer to a null-terminated string specifying the type of object to which the client is requesting access. This string appears in any audit message that the function generates.
ObjectName
Pointer to a null-terminated string specifying the name of the object to which the client is requesting access. This string appears in any audit message that the function generates.
pSecurityDescriptor
Pointer to the SECURITY_DESCRIPTOR structure for the object being accessed.
ClientToken
Identifies an access token representing the client requesting the operation. This handle must be obtained by opening the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access.
DesiredAccess
Specifies the desired access mask. This mask must have been previously mapped by the MapGenericMask function to contain no generic access rights.
GrantedAccess
Specifies an access mask indicating which access rights are granted. This access mask is intended to be the same value set by one of the access-checking functions in its GrantedAccess parameter. Examples of access-checking functions include AccessCheckAndAuditAlarm and AccessCheck.
Privileges
Pointer to a PRIVILEGE_SET structure that specifies the set of privileges required for the access attempt. This parameter can be NULL.
ObjectCreation
Specifies a flag that determines whether the application creates a new object when access is granted. When this flag is TRUE, the application creates a new object; when it is FALSE, the application opens an existing object.
AccessGranted
Specifies a flag indicating whether access was granted or denied in a previous call to an access-checking function, such as AccessCheck. If access was granted, this flag is TRUE. If not, it is FALSE.
GenerateOnClose
Pointer to a flag set by the audit-generation routine when the function returns. This flag must be passed to the ObjectCloseAuditAlarm function when the object handle is closed.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ObjectOpenAuditAlarm function requires the calling application to have the SE_AUDIT_NAME privilege enabled. The test for this privilege is always performed against the primary token of the calling process, not the impersonation token of the thread. This allows the calling process to impersonate a client during the call.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, AreAllAccessesGranted, AreAnyAccessesGranted, MapGenericMask, ObjectCloseAuditAlarm, ObjectDeleteAuditAlarm, ObjectPrivilegeAuditAlarm, PrivilegeCheck, PrivilegedServiceAuditAlarm, PRIVILEGE_SET, SECURITY_DESCRIPTOR


ObjectPrivilegeAuditAlarm

The ObjectPrivilegeAuditAlarm function generates an audit message in the security event log. A protected server can use this function to log attempts by a client to use a specified set of privileges with an open handle to a private object. Alarms are not supported in the current version of Windows NT.

BOOL ObjectPrivilegeAuditAlarm(
  LPCTSTR SubsystemName,      // pointer to string for subsystem name
  LPVOID HandleId,            // pointer to handle identifier
  HANDLE ClientToken,         // handle to client's access token
  DWORD DesiredAccess,        // mask for desired access rights
  PPRIVILEGE_SET Privileges,  // pointer to privileges
  BOOL AccessGranted          // flag for results
);

Parameters

SubsystemName
Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in the audit message.
HandleId
Pointer to a unique 32-bit value representing the client's handle to the object.
ClientToken
Identifies an access token representing the client that requested the operation. This handle must have been obtained by opening the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access. The function uses this token to get the identity of the client for the audit message.
DesiredAccess
Specifies an access mask indicating the privileged access types being used or whose use is being attempted. The access mask can be mapped by the MapGenericMask function so it does not contain any generic access types.
Privileges
Pointer to a PRIVILEGE_SET structure containing the privileges that the client attempted to use. The names of the privileges appear in the audit message.
AccessGranted
Specifies a flag indicating whether the client's attempt to use the privileges was successful. If this flag is TRUE, the audit message indicates success. If this flag is FALSE, the audit message indicates failure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ObjectPrivilegeAuditAlarm function does not check the client's access to the object or check the client's access token to determine whether the privileges are held or enabled. Typically, you would call the PrivilegeCheck function to determine whether the specified privileges are enabled in the access token, call the AccessCheck function to check the client's access to the object, and then call ObjectPrivilegeAuditAlarm to log the results.

The ObjectPrivilegeAuditAlarm function requires the calling process to have SE_AUDIT_NAME privilege enabled. The test for this privilege is always performed against the primary token of the calling process, not the impersonation token of the thread. This allows the calling process to impersonate a client during the call.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, MapGenericMask, ObjectCloseAuditAlarm, ObjectOpenAuditAlarm, PrivilegeCheck, PrivilegedServiceAuditAlarm, PRIVILEGE_SET


PrivilegeCheck

The PrivilegeCheck function determines whether a specified set of privileges are enabled in an access token. PrivilegeCheck is typically called by a server application to check the privileges of a client's access token.

BOOL PrivilegeCheck(
  HANDLE ClientToken,              // handle of client's access token
  PPRIVILEGE_SET RequiredPrivileges,  // address of privileges
  LPBOOL pfResult                     // address of flag for result
);

Parameters

ClientToken
Handle to an access token representing a client process. This handle must have been obtained by opening the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access.
RequiredPrivileges
Pointer to a PRIVILEGE_SET structure. The Privilege member of this structure is an array of LUID_AND_ATTRIBUTES structures. Before calling PrivilegeCheck, use the Privilege array to indicate the set of privileges to check. Set the Control member to PRIVILEGE_SET_ALL_NECESSARY if all of the privileges must be enabled; or set it to zero if it is sufficient that any one of the privileges be enabled.

When PrivilegeCheck returns, the Attributes member of each LUID_AND_ATTRIBUTES structure is set to SE_PRIVILEGE_USED_FOR_ACCESS if the corresponding privilege is enabled.

pfResult
Pointer to a flag the function sets to indicate whether any or all of the specified privileges are enabled in the access token. If the Control member of the PRIVILEGE_SET structure specified PRIVILEGE_SET_ALL_NECESSARY, this flag returns TRUE only if all the privileges are enabled; otherwise, this flag returns TRUE if any of the privileges are enabled.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

An access token contains a list of the privileges held by the account associated with the token. These privileges can be enabled or disabled; most are disabled by default. The PrivilegeCheck function checks only for enabled privileges. To get a list of all the enabled and disabled privileges held by an access token, call the GetTokenInformation function. To enable or disable a set of privileges in an access token, call the AdjustTokenPrivileges function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AdjustTokenPrivileges, GetTokenInformation, LookupPrivilegeValue, LUID_AND_ATTRIBUTES, ObjectPrivilegeAuditAlarm, PRIVILEGE_SET, PrivilegedServiceAuditAlarm


PrivilegedServiceAuditAlarm

The PrivilegedServiceAuditAlarm function generates an audit message in the security event log. A protected server can use this function to log attempts by a client to use a specified set of privileges.

Alarms are not supported in the current version of Windows NT.

BOOL PrivilegedServiceAuditAlarm(
  LPCTSTR SubsystemName,      // address of string for subsystem name
  LPCTSTR ServiceName,        // address of string for service name
  HANDLE ClientToken,         // handle of access token
  PPRIVILEGE_SET Privileges,  // address of privileges
  BOOL AccessGranted          // flag for granted access rights
);

Parameters

SubsystemName
Pointer to a null-terminated string specifying the name of the subsystem calling the function. This information appears in the security event log record.
ServiceName
Pointer to a null-terminated string specifying the name of the privileged subsystem service. This information appears in the security event log record.
ClientToken
Identifies an access token representing the client that requested the operation. This handle must have been obtained by opening the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access. The function uses this token to get the identity of the client for the security event log record.
Privileges
Pointer to a PRIVILEGE_SET structure containing the privileges that the client attempted to use. The names of the privileges appear in the security event log record.
AccessGranted
Specifies a flag indicating whether the client's attempt to use the privileges was successful. If this flag is TRUE, the security event log record indicates success. If this flag is FALSE, the security event log record indicates failure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The PrivilegedServiceAuditAlarm function does not check the client's access token to determine whether the privileges are held or enabled. Typically, you would first call the PrivilegeCheck function to determine whether the specified privileges are enabled in the access token, and then call PrivilegedServiceAuditAlarm to log the results.

The PrivilegedServiceAuditAlarm function requires the calling process to have SE_AUDIT_NAME privilege enabled. The test for this privilege is always performed against the primary token of the calling process. This allows the calling process to impersonate a client during the call.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, ObjectPrivilegeAuditAlarm, PrivilegeCheck, PRIVILEGE_SET


RevertToSelf

The RevertToSelf function terminates the impersonation of a client application.

BOOL RevertToSelf(VOID);

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A process should call the RevertToSelf function after finishing any impersonation begun by using the DdeImpersonateClient, ImpersonateDdeClientWindow, ImpersonateLoggedOnUser, ImpersonateNamedPipeClient, ImpersonateSelf, or SetThreadToken function.

An RPC server that used the RpcImpersonateClient function to impersonate a client must call the RpcRevertToSelf or RpcRevertToSelfEx to end the impersonation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, DdeImpersonateClient, ImpersonateDdeClientWindow, ImpersonateLoggedOnUser, ImpersonateNamedPipeClient, ImpersonateSelf, RpcImpersonateClient, RpcRevertToSelf, RpcRevertToSelfEx, SetThreadToken


SetPrivateObjectSecurity

The SetPrivateObjectSecurity function modifies a private object's security descriptor.

BOOL SetPrivateObjectSecurity(
  SECURITY_INFORMATION SecurityInformation,     // type of security
                                                // information
  PSECURITY_DESCRIPTOR ModificationDescriptor,  // address of SD to
                                                // apply to object
  PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
                                        // address of object's SD
  PGENERIC_MAPPING GenericMapping,      // address of access-mapping
                                        // structure
  HANDLE Token                          // handle of client access token
);

Parameters

SecurityInformation
A set of bit flags that indicate the parts of the security descriptor to set. This value can be a combination of the SECURITY_INFORMATION bit flags.
ModificationDescriptor
Pointer to a SECURITY_DESCRIPTOR structure. The parts of this security descriptor indicated by the SecurityInformation parameter are applied to the ObjectsSecurityDescriptor security descriptor.
ObjectsSecurityDescriptor
Pointer to a pointer to a SECURITY_DESCRIPTOR structure. This security descriptor must be in self-relative form.

On input, this is the current security descriptor of the private object. The function modifies it to produce the new security descriptor. If necessary, the SetPrivateObjectSecurityEx function allocates additional memory to produce a larger security descriptor.

GenericMapping
Pointer to a GENERIC_MAPPING structure that specifies the specific and standard access rights that correspond to each of the generic access rights.
Token
Handle to the access token for the client on whose behalf the private object's security is being modified. This parameter is required to ensure that the client has provided a legitimate value for a new owner security identifier (SID). The token must be open for TOKEN_QUERY access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The SetPrivateObjectSecurity function is successful only if the following conditions are met:

  • If the object's owner is being set, the calling process must have either WRITE_OWNER permission or be the object's owner.
  • If the object's discretionary access-control list (ACL) is being set, the calling process must have either WRITE_DAC permission or be the object's owner.
  • If the object's system ACL is being set, the SE_SECURITY_NAME privilege must be enabled for the calling process.

The process calling this function must not be impersonating a client.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreatePrivateObjectSecurity, DestroyPrivateObjectSecurity, GENERIC_MAPPING, GetPrivateObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetFileSecurity, SetKernelObjectSecurity, SetUserObjectSecurity


SetPrivateObjectSecurityEx

[This is preliminary documentation and subject to change.]

The SetPrivateObjectSecurityEx function modifies the security descriptor of a private object. SetPrivateObjectSecurityEx has a flags parameter that allows you to specify whether the protected server supports automatic inheritance of ACEs.

BOOL SetPrivateObjectSecurityEx (
  SECURITY_INFORMATION SecurityInformation,
                            // type of security information
  PSECURITY_DESCRIPTOR ModificationDescriptor,
                            // security descriptor with new information
  PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
                            // object's security descriptor
  ULONG AutoInheritFlags,   // flags that control inheritance of ACEs
  PGENERIC_MAPPING GenericMapping,  // map generic to specific rights
  HANDLE Token                      // handle of client access token
);

Parameters

SecurityInformation
A set of bit flags that indicate the parts of the security descriptor to set. This value can be a combination of the SECURITY_INFORMATION bit flags.
ModificationDescriptor
Pointer to a SECURITY_DESCRIPTOR structure. The parts of this security descriptor indicated by the SecurityInformation parameter are applied to the ObjectsSecurityDescriptor security descriptor.
ObjectsSecurityDescriptor
Pointer to a pointer to a SECURITY_DESCRIPTOR structure. This security descriptor must be in self-relative form.

On input, this is the current security descriptor of the private object. The function modifies it to produce the new security descriptor. If necessary, the SetPrivateObjectSecurityEx function allocates additional memory to produce a larger security descriptor.

AutoInheritFlags
A set of bit flags that control automatic inheritance of ACEs. If the protected server does not implement automatic inheritance, it should specify zero; otherwise, it can specify a combination of the following flags.
Value | Meaning
SEF_DACL_AUTO_INHERIT | If this flag is set, the DACL is treated as an auto-inherit DACL and is processed as described in the following Remarks section. This bit is ignored if DACL_SECURITY_INFORMATION is not set in the SecurityInformation parameter.
SEF_SACL_AUTO_INHERIT | If this flag is set, the SACL is treated as an auto-inherit SACL and is processed as described in the following Remarks section. This bit is ignored if SACL_SECURITY_INFORMATION is not set in the SecurityInformation parameter.
SEF_AVOID_PRIVILEGE_CHECK | If this flag is set, the Token parameter can be NULL, and the token is not checked to determine if the ModificationDescriptor is valid. This flag is useful while implementing automatic inheritance to avoid checking privileges on each child updated.

GenericMapping
Pointer to a GENERIC_MAPPING structure that specifies the specific and standard access rights that correspond to each of the generic access rights.
Token
Identifies the access token for the client on whose behalf the private object's security is being modified. This parameter is required to ensure that the client has provided a legitimate value for a new owner SID. The token must be open for TOKEN_QUERY access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the AutoInheritFlags parameter is zero, SetPrivateObjectSecurityEx is identical to the SetPrivateObjectSecurity function.

The SetPrivateObjectSecurityEx function is successful only if the following conditions are met:

  • If the object's owner is being set, the calling process must have either WRITE_OWNER permission or be the object's owner.
  • If the object's DACL is being set, the calling process must have either WRITE_DAC permission or be the object's owner.
  • If the object's SACL is being set, the SE_SECURITY_NAME privilege must be enabled for the calling process.

The process calling this function must not be impersonating a client.

If AutoInheritFlags specifies the SEF_DACL_AUTO_INHERIT bit, the function applies the following rules to the DACL to create the new security descriptor from the current descriptor

  • If the SE_DACL_PROTECTED flag is not set in the control bits of the either the current security descriptor or the ModificationDescriptor, the function constructs the output security descriptor from the inherited ACEs of the current security descriptor and non-inherited ACEs of ModificationDescriptor. That is, it is impossible to change an inherited ACE by changing the ACL on an object. This behavior preserves the inherited ACEs as they were inherited from the parent container.

    An ACL editor should "gray" inherited ACEs to prevent them from being modified.

  • If SE_DACL_PROTECTED is set in the ModificationDescriptor, the current security descriptor is ignored. The output security descriptor is built as a copy of the ModificationDescriptor with any INHERITED_ACE bits turned off.

    Ideally an ACL editor should turn off the INHERITED_ACE bits indicating to its caller that the ACEs inherited from the object's parent are now being explicitly set on the object.

  • If SE_DACL_PROTECTED is set in the current security descriptor and not in the ModificationDescriptor, the current security descriptor is ignored. The output security descriptor is built as a copy of the ModificationDescriptor.

    It is the caller's responsibility to ensure that the correct ACEs have the INHERITED_ACE bit turned on and to properly set the SE_DACL_AUTO_INHERITED bit on the ModificationDescriptor.

If AutoInheritFlags specifies the SEF_SACL_AUTO_INHERIT bit, the function applies similar rules to the new SACL.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreatePrivateObjectSecurity, DestroyPrivateObjectSecurity, GENERIC_MAPPING, GetPrivateObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetFileSecurity, SetKernelObjectSecurity, SetPrivateObjectSecurity, SetUserObjectSecurity


Client/Server Access Control Structures

Use the following structures to implement client/server access control functionality:

ACTRL_CONTROL_INFO
GENERIC_MAPPING
OBJECT_TYPE_LIST
PRIVILEGE_SET
SECURITY_QUALITY_OF_SERVICE


ACTRL_CONTROL_INFO

The ACTRL_CONTROL_INFO structure contains the GUID and display name of an object type.

typedef struct _ACTRL_CONTROL_INFO {
    LPTSTR   lpControlId;
    LPTSTR   lpControlName;
} ACTRL_CONTROL_INFO, *PACTRL_CONTROL_INFO;

Members

lpControlId
Pointer to a null-terminated string that contains a string representation of a GUID that identifies a control access right.
lpControlName
Pointer to a null-terminated string that contains the display name of the control access right identified by the lpControlId member.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Client/Server Access Control Overview, Client/Server Access Control Structures, GetAccessPermissionsForObject


GENERIC_MAPPING

The GENERIC_MAPPING structure defines the mapping of generic access rights to specific and standard access rights for an object. When a client application requests generic access to an object, that request is mapped to the access rights defined in this structure.

typedef struct _GENERIC_MAPPING { // gm
    ACCESS_MASK GenericRead;
    ACCESS_MASK GenericWrite;
    ACCESS_MASK GenericExecute;
    ACCESS_MASK GenericAll;
} GENERIC_MAPPING;

Members

GenericRead
Specifies an access mask defining read access to an object.
GenericWrite
Specifies an access mask defining write access to an object.
GenericExecute
Specifies an access mask defining execute access to an object.
GenericAll
Specifies an access mask defining all possible types of access to an object.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Client/Server Access Control Overview, Client/Server Access Control Structures, AccessCheck, AccessCheckAndAuditAlarm, CreatePrivateObjectSecurity, MapGenericMask, SetPrivateObjectSecurity, ACCESS_MASK


OBJECT_TYPE_LIST

[This is preliminary documentation and subject to change.]

The OBJECT_TYPE_LIST structure identifies an object type element in a hierarchy of object types. The AccessCheckByType functions use an array of OBJECT_TYPE_LIST structures to define a hierarchy of an object and its subobjects, such as property sets and properties.

typedef struct _OBJECT_TYPE_LIST {
    WORD   Level;
    WORD   Sbz;
    GUID *ObjectType;
} OBJECT_TYPE_LIST, *POBJECT_TYPE_LIST;

Members

Level
Specifies the level of the object type in the hierarchy of an object and its subobjects. Level zero indicates the object itself. Level 1 indicates a subobject of the object, such as a property set. Level 2 indicates a subobject of the level 1 subobject, such as a property. There can be a maximum of 5 levels numbered 0 through 4.

Directory service objects use the following level values.
Value | Description
ACCESS_OBJECT_GUID | Indicates the object itself at level zero.
ACCESS_PROPERTY_SET_GUID | Indicates a property set at level 1.
ACCESS_PROPERTY_GUID | Indicates a property at level 2.

Sbz
Should be zero. Reserved for future use.
ObjectType
Pointer to the GUID for the object or subobject.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Client/Server Access Control Overview, Client/Server Access Control Structures, AccessCheckByType, AccessCheckByTypeAndAuditAlarm, AccessCheckByTypeResultList, AccessCheckByTypeResultListAndAuditAlarm


PRIVILEGE_SET

The PRIVILEGE_SET structure specifies a set of privileges. It is also used to indicate which, if any, privileges are held by a user or group requesting access to an object.

typedef struct _PRIVILEGE_SET { // ps
    DWORD PrivilegeCount;
    DWORD Control;
    LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];
} PRIVILEGE_SET;

Members

PrivilegeCount
Specifies the number of privileges in the privilege set.
Control
Specifies a control flag related to the privileges. The PRIVILEGE_SET_ALL_NECESSARY control flag is currently defined. It indicates that all of the specified privileges must be held by the process requesting access. If this flag is not set, the presence of any privileges in the user's access token grants the access.
Privilege
Specifies an array of LUID_AND_ATTRIBUTES structures describing the set's privileges. The following attributes are defined for privileges:
Attribute Description
SE_PRIVILEGE_ENABLED_BY_DEFAULT
The privilege is enabled by default.
SE_PRIVILEGE_ENABLED
The privilege is enabled.
SE_PRIVILEGE_USED_FOR_ACCESS
The privilege was used to gain access to an object or service. This flag is used to identify the relevant privileges in a set passed by a client application that may contain unnecessary privileges.

Remarks

A privilege is used to control access to an object or service more strictly than is typical with discretionary access control. A system manager uses privileges to control which users are able to manipulate system resources. An application uses privileges when it changes a system-wide resource, such as when it changes the system time or shuts down the system.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Client/Server Access Control Overview, Client/Server Access Control Structures, PrivilegeCheck, LUID, LUID_AND_ATTRIBUTES


SECURITY_QUALITY_OF_SERVICE

The SECURITY_QUALITY_OF_SERVICE data structure contains information used to support client impersonation. A client can specify this information when it connects to a server; the information determines whether or not the server may impersonate the client, and if so, to what extent.

typedef struct _SECURITY_QUALITY_OF_SERVICE { // sqos
    DWORD Length;
    SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
    SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;
    BOOLEAN EffectiveOnly;
} SECURITY_QUALITY_OF_SERVICE;

Members

Length
Specifies the size, in bytes, of this structure.
ImpersonationLevel
Specifies what the server may be told about the client, and how the server may represent, or impersonate, the client. Security impersonation levels govern the degree to which a server process can act on behalf of a client process. This member is a SECURITY_IMPERSONATION_LEVEL enumeration type value.
ContextTrackingMode
Specifies whether the server is to be given a snapshot of the client's security context (called static tracking), or is to be continually updated to track changes to the client's security context (called dynamic tracking). The value SECURITY_STATIC_TRACKING specifies static tracking, and the value SECURITY_DYNAMIC_TRACKING specifies dynamic tracking. Not all communications mechanisms support dynamic tracking; those that do not will default to static tracking.
EffectiveOnly
Specifies whether or not the server may enable or disable privileges and groups that the client's security context may include.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Client/Server Access Control Overview, Client/Server Access Control Structures, DdeSetQualityOfService, SECURITY_IMPERSONATION_LEVEL


Client/Server Access Control Enumeration Types

Use the following enumeration types to implement client/server access control functionality:

AUDIT_EVENT_TYPE
SECURITY_IMPERSONATION_LEVEL


AUDIT_EVENT_TYPE

[This is preliminary documentation and subject to change.]

The AUDIT_EVENT_TYPE enumeration type defines values that indicate the type of object being audited. The AccessCheckByTypeAndAuditAlarm and AccessCheckByTypeResultListAndAuditAlarm functions use these values.

typedef enum _AUDIT_EVENT_TYPE {
    AuditEventObjectAccess,
    AuditEventDirectoryServiceAccess
} AUDIT_EVENT_TYPE, *PAUDIT_EVENT_TYPE;

Values

AuditEventObjectAccess
Indicates an object that generates audit messages only if the system administrator has enabled auditing access to files and objects.
AuditEventDirectoryServiceAccess
Indicates a directory service object that generates audit messages only if the system administrator has enabled auditing access to directory service objects.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Client/Server Access Control Overview, Client/Server Access Control Enumeration Types, AccessCheckByTypeAndAuditAlarm, AccessCheckByTypeResultListAndAuditAlarm


SECURITY_IMPERSONATION_LEVEL

The SECURITY_IMPERSONATION_LEVEL enumeration type contains values that specify security impersonation levels. Security impersonation levels govern the degree to which a server process can act on behalf of a client process.

typedef enum _SECURITY_IMPERSONATION_LEVEL { // sil
    SecurityAnonymous,
    SecurityIdentification,
    SecurityImpersonation,
    SecurityDelegation
} SECURITY_IMPERSONATION_LEVEL;

Members

SecurityAnonymous
The server process cannot obtain identification information about the client and it cannot impersonate the client. It is defined with no value given, and thus, by ANSI C rules, defaults to a value of 0.
SecurityIdentification
The server process can obtain information about the client, such as security identifiers and privileges, but it cannot impersonate the client. This is useful for servers that export their own objects — for example, database products that export tables and views. Using the retrieved client-security information, the server can make access-validation decisions without being able to utilize other services using the client's security context.
SecurityImpersonation
The server process can impersonate the client's security context on its local system. The server cannot impersonate the client on remote systems.
SecurityDelegation
Windows NT security does not support this impersonation level.

Remarks

Impersonation is the ability of a process to take on the security attributes of another process.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Client/Server Access Control Overview, Client/Server Access Control Enumeration Types, CreatePrivateObjectSecurity, DuplicateToken, DuplicateTokenEx, GetTokenInformation, ImpersonateSelf, OpenThreadToken


Low-Level Access-Control

This overview describes the low-level access-control functions for working with security descriptors and access-control lists (ACLs). Most low-level access-control functions are supported on all versions of Microsoft® Windows NT®. The low-level functions for working with object-specific ACEs are supported by Windows NT versions 5.0 and later.

The low-level access-control functions are one of three sets of access-control functions. For information about when to use each set of functions, see Access-Control Reference.


About Low-Level Access Control

This overview describes the low-level security functions for working with security descriptors, access-control lists (ACLs), and access-control entries (ACEs).

The access control model is basically the same for all versions of Windows NT. For a description of the model, see Access-Control Model.


Low-Level Security Descriptor Functions

There are several pairs of low-level functions for setting and retrieving an object's security descriptor. Each of these pairs works only with a limited set of Win32 objects. For example, one pair works with file objects and another works with registry keys. The following table shows the low-level functions to use with the different types of securable objects.

Object type | Low-level functions
Files
Directories
Mailslots
Named pipes 		Use the GetFileSecurity and SetFileSecurity functions. These functions use character strings to identify the securable object, instead of using handles.
Processes
Threads
Access tokens
File-mapping objects
Semaphores
Events
Mutexes
Waitable timers 		Use the SetKernelObjectSecurity and GetKernelObjectSecurity functions.
Window stations
Desktops 		Use the GetUserObjectSecurity and SetUserObjectSecurity functions.
Registry keys | Use the RegGetKeySecurity and RegSetKeySecurity functions.
Windows NT Service objects | Use the QueryServiceObjectSecurity and SetServiceObjectSecurity functions.
Printer objects | Use the PRINTER_INFO_2 structure with the GetPrinter and SetPrinter functions.
Windows NT network shares | Use level 502 with the NetShareGetInfo and NetShareSetInfo functions.
Private objects (objects private to the creating application) | Use the CreatePrivateObjectSecurity, DestroyPrivateObjectSecurity, GetPrivateObjectSecurity and SetPrivateObjectSecurity functions.


Low-Level Security Descriptor Creation

Low-level access-control provides a set of functions for creating a security descriptor and getting and setting the components of a security descriptor. The low-level functions for initializing and setting the components of a security descriptor work only with absolute-format security descriptors. The low-level functions for getting the components of a security descriptor work with both absolute and self-relative security descriptors.

The InitializeSecurityDescriptor function initializes a SECURITY_DESCRIPTOR buffer. The initialized security descriptor is in absolute format and has no owner, primary group, discretionary access-control list (DACL), or system access-control list (SACL). You can use the following low-level functions to get or set specific components of a specified security descriptor.

Function | Description
GetSecurityDescriptorControl | Retrieves revision and control information from a security descriptor.
GetSecurityDescriptorDacl | Gets the DACL from a security descriptor.
GetSecurityDescriptorGroup | Retrieves the primary group security identifier (SID) from a security descriptor.
GetSecurityDescriptorLength | Returns the length of a security descriptor.
GetSecurityDescriptorOwner | Retrieves the owner SID from a security descriptor.
GetSecurityDescriptorSacl | Gets the SACL from a security descriptor.
SetSecurityDescriptorDacl | Puts a DACL into a security descriptor, superseding any existing DACL.
SetSecurityDescriptorGroup | Sets the primary group SID of a security descriptor.
SetSecurityDescriptorOwner | Sets the owner SID of a security descriptor.
SetSecurityDescriptorSacl | Puts a SACL into a security descriptor, superseding any existing SACL.

To check the revision level and structural integrity of a security descriptor, call the IsValidSecurityDescriptor function.


Absolute and Self-Relative Security Descriptors

A security descriptor can be in either absolute or self-relative format. In absolute format, a security descriptor contains pointers to its information, not the information itself. In self-relative format, a security descriptor stores a SECURITY_DESCRIPTOR structure and associated security information in a contiguous block of memory. To determine whether a security descriptor is self-relative or absolute, call the GetSecurityDescriptorControl function and check the SE_SELF_RELATIVE flag of the SECURITY_DESCRIPTOR_CONTROL parameter. You can use the MakeSelfRelativeSD and MakeAbsoluteSD functions for converting between these two formats.

The absolute format is useful when you are building a security descriptor and have pointers to all of the components, for example, when default settings for the owner, group, and discretionary ACL are available. In this case, you can simply call the InitializeSecurityDescriptor function to initialize a SECURITY_DESCRIPTOR structure, and then call functions such as SetSecurityDescriptorDacl to assign ACL and SID pointers to the security descriptor.

In self-relative format, a security descriptor always begins with a SECURITY_DESCRIPTOR structure, but the other components of the security descriptor can follow the structure in any order. Instead of using memory addresses, the security descriptor's components are identified by offsets from the beginning of the descriptor. This format is useful when a security descriptor must be stored on disk, transmitted by means of a communications protocol, or copied in memory.

All Win32 functions that return a security descriptor do so using the self-relative format. Security descriptors passed back to the operating system can be in either self-relative or absolute form, depending on the situation.


Low-Level ACL and ACE Functions

To create an access-control list (ACL) using the low-level functions, allocate a buffer for the ACL and then initialize it by calling the InitializeAcl function. To add access-control entries (ACEs) to the end of a DACL, use the AddAccessAllowedAce and AddAccessDeniedAce functions. The AddAuditAccessAce function adds an ACE to the end of a SACL. You can use the AddAce function to add one or more ACEs at a specified position in an ACL. The AddAce function also allows you to add an inheritable ACE to an ACL. The DeleteAce function removes an ACE from a specified position in an ACL. The GetAce function retrieves an ACE from a specified position in an ACL. The FindFirstFreeAce function retrieves a pointer to the first free byte in an ACL.

To modify an existing ACL in an object's security descriptor, use the GetSecurityDescriptorDacl or GetSecurityDescriptorSacl function to get the existing ACL. You can use the GetAce function to copy ACEs from the existing ACL. After allocating and initializing a new ACL, use functions such as AddAccessAllowedAce and AddAce to add ACEs to it. When you have finished building the new ACL, use the SetSecurityDescriptorDacl or SetSecurityDescriptorSacl function to add the new ACL to the object's security descriptor.

Windows NT 5.0 and later: You can use the AddAccessAllowedObjectAce, AddAccessDeniedObjectAce, or AddAuditAccessObjectAce functions to add object-specific ACEs to the end of an ACL.


Using Low-Level Access Control

The following examples use the Windows NT version 3.x security functions:

  • Denying Access Using Low-Level Functions
  • Allowing Access Using the Low-Level Functions


Denying Access Using Low-Level Functions

This example uses the low-level access-control functions to attach an empty DACL to a file object. The effect of an empty DACL is to deny all access to the object.

The example allocates a buffer for the security descriptor and calls the InitializeSecurityDescriptor function to initialize the buffer. Then it allocates a buffer for the ACL and calls the InitializeAcl function to initialize that buffer. Next, it calls the SetSecurityDescriptorDacl function to attach the ACL to the security descriptor; and calls the SetFileSecurity function to attach the security descriptor to a file.

PSECURITY_DESCRIPTOR pSD;
PACL pACL;
DWORD cbACL = 1024;

// Initialize a security descriptor.

pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
    SECURITY_DESCRIPTOR_MIN_LENGTH);   // defined in WINNT.H
if (pSD == NULL) {
    ErrorHandler("LocalAlloc");
    goto Cleanup;
}

if (!InitializeSecurityDescriptor(pSD,
        SECURITY_DESCRIPTOR_REVISION)) { // defined in WINNT.H
    ErrorHandler("InitializeSecurityDescriptor");
    goto Cleanup;
}

// Initialize a DACL.

pACL = (PACL) LocalAlloc(LPTR, cbACL);
if (pACL == NULL) {
    ErrorHandler("LocalAlloc");
    goto Cleanup;
}

if (!InitializeAcl(pACL, cbACL, ACL_REVISION2)) {
    ErrorHandler("InitializeAcl");
    goto Cleanup;
}

// Add an empty ACL to the SD to deny access.

if (!SetSecurityDescriptorDacl(pSD,
        TRUE,     // fDaclPresent flag
        pACL,
        FALSE)) { // not a default DACL
    ErrorHandler("SetSecurityDescriptorDacl");
    goto Cleanup;
}

// Use the new SD as the file's security info.

if (!SetFileSecurity(lpszTestFile,
        DACL_SECURITY_INFORMATION,
        pSD)) {
    ErrorHandler("SetFileSecurity");
    goto Cleanup;
}

Cleanup:
    if(pSD != NULL)
        LocalFree((HLOCAL) pSD);
    if(pACL != NULL)
        LocalFree((HLOCAL) pACL);


Allowing Access Using the Low-Level Functions

This section shows how to use the low-level functions to work with ACLs and ACEs that allow access to an object.

The first example shows the use of the low-level access-control functions to add a NULL DACL to a file's security descriptor. The low-level example allocates a security descriptor buffer and calls the InitializeSecurityDescriptor function to initialize it. Then it calls the SetSecurityDescriptorDacl function to attach a NULL DACL to the security descriptor. Finally, it calls the SetFileSecurity function to attach the security descriptor to a file. An equivalent high-level example could perform the same operation with a single call to the SetNamedSecurityInfo function.

Note You can write code that builds security descriptors from scratch, as in the example. However, when writing code that builds or manipulates security descriptors, your code should explore the default security descriptors that Windows NT places on objects. For example, an object may have a default DACL that contains ACEs inherited from its parent object. Rather than simply replacing the default DACL, your code should first examine the default DACL to determine whether you want to include its ACEs in the new DACL.

PSECURITY_DESCRIPTOR pSD;

// Initialize a security descriptor.

pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
    SECURITY_DESCRIPTOR_MIN_LENGTH);   // defined in WINNT.H
if (pSD == NULL) {
    ErrorHandler("LocalAlloc");
    goto Cleanup;
}

if (!InitializeSecurityDescriptor(pSD,
        SECURITY_DESCRIPTOR_REVISION)) { // defined in WINNT.H
    ErrorHandler("InitializeSecurityDescriptor");
    goto Cleanup;
}

// Add a NULL disc. ACL to the security descriptor.

if (!SetSecurityDescriptorDacl(pSD,
        TRUE,     // specifying a disc. ACL
        (PACL) NULL,
        FALSE)) { // not a default disc. ACL
    ErrorHandler("SetSecurityDescriptorDacl");
    goto Cleanup;
}

// Add the security descriptor to the file.

if (!SetFileSecurity(lpszTestFile,
        DACL_SECURITY_INFORMATION,
        pSD)) {
    ErrorHandler("SetFileSecurity");
    goto Cleanup;
}

Cleanup:
    if(pSD != NULL)
        LocalFree((HLOCAL) pSD);

The following example shows the use of the low-level access-control functions to add a DACL with an access-allowed ACE to a file's security descriptor. The example allocates and initializes a security descriptor, allocates and initializes an ACL, and allocates and looks up a SID for a specified account. Then it adds an ACE to the ACL, adds the ACL as the DACL of the security descriptor, and finally, attaches the security descriptor to the file. Note that the high-level functions perform many of these steps for you.

PSECURITY_DESCRIPTOR pSD;
    PACL pACLNew;
    DWORD cbACL = 1024;
    PSID pSID;
    DWORD cbSID = 1024;
    LPSTR lpszAccount = "UserABC";
    LPSTR lpszDomain;
    DWORD cchDomainName = 80;
    PSID_NAME_USE psnuType;

    // Initialize a new security descriptor.

    pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
        SECURITY_DESCRIPTOR_MIN_LENGTH);  // defined in WINNT.H
    if (pSD == NULL) {
        ErrorHandler("LocalAlloc");
        goto Cleanup;
    }

    if (!InitializeSecurityDescriptor(pSD,
            SECURITY_DESCRIPTOR_REVISION)) {
        ErrorHandler("InitializeSecurityDescriptor");
        goto Cleanup;
    }

    // Initialize a new ACL.

    pACLNew = (PACL) LocalAlloc(LPTR, cbACL);
    if (pACLNew == NULL) {
        ErrorHandler("LocalAlloc");
        goto Cleanup;
    }

    if (!InitializeAcl(pACLNew, cbACL, ACL_REVISION2)) {
        ErrorHandler("InitializeAcl");
        goto Cleanup;
    }

    // Retrieve the SID for UserABC.

    pSID = (PSID) LocalAlloc(LPTR, cbSID);
    psnuType = (PSID_NAME_USE) LocalAlloc(LPTR, 1024);
    lpszDomain = (LPSTR) LocalAlloc(LPTR, cchDomainName);
    if (pSID == NULL || psnuType == NULL ||
        lpszDomain == NULL) {
        ErrorHandler("LocalAlloc");
        goto Cleanup;
    }

    if (!LookupAccountName((LPSTR) NULL, // local name
            lpszAccount,
            pSID,
            &cbSID,
            lpszDomain,
            &cchDomainName,
            psnuType)) {
        ErrorHandler("LookupAccountName");
        goto Cleanup;
    }
    if (!IsValidSid(pSID))
        TextOut(hdc, 10, yIncrement += 18,
            "SID is not valid.", 17);
    else
        TextOut(hdc, 10, yIncrement += 18,
            "SID is valid.", 13);

    // Allow read but not write access to the file.

    if (!AddAccessAllowedAce(pACLNew,
            ACL_REVISION2,
            GENERIC_READ,
            pSID)) {
        ErrorHandler("AddAccessAllowedAce");
        goto Cleanup;
    }

    // Add a new ACL to the security descriptor.

    if (!SetSecurityDescriptorDacl(pSD,
            TRUE,              // fDaclPresent flag
            pACLNew,
            FALSE)) {          // not a default disc. ACL
        ErrorHandler("SetSecurityDescriptorDacl");
        goto Cleanup;
    }

    // Apply the new security descriptor to the file.

    if (!SetFileSecurity("d:\\ntfs_sample_file",
            DACL_SECURITY_INFORMATION,
            pSD)) {
        ErrorHandler("SetFileSecurity");
        goto Cleanup;
    }
    TextOut(hdc, 10, yIncrement += 18,
        "Successfully added access-allowed ACE to file's DACL.", 53);

    Cleanup:
        FreeSid(pSID);
        if(pSD != NULL)
            LocalFree((HLOCAL) pSD);
        if(pACLNew != NULL)
            LocalFree((HLOCAL) pACLNew);
        if(psnuType != NULL)
            LocalFree((HLOCAL) psnuType);
        if(lpszDomain != NULL)
            LocalFree((HLOCAL) lpszDomain);


Low-Level Access Control Reference

The following elements are used with low-level access control.

  • Low-Level Access Control Functions
  • Low-Level Access Control Structures


Low-Level Access Control Functions

The following low-level functions are used to manipulate security descriptors. Use these functions if your application needs to run on Windows NT version 3.51 or earlier.

GetSecurityDescriptorDacl
GetSecurityDescriptorGroup
GetSecurityDescriptorLength
GetSecurityDescriptorOwner
GetSecurityDescriptorSacl
InitializeSecurityDescriptor
IsValidSecurityDescriptor
MakeAbsoluteSD
MakeSelfRelativeSD
SetSecurityDescriptorDacl
SetSecurityDescriptorGroup
SetSecurityDescriptorOwner
SetSecurityDescriptorSacl

The following low-level functions are used to manipulate ACEs and ACLs. Use these functions if your application needs to run on Windows NT version 3.51 or earlier.

AddAccessAllowedAce
AddAccessDeniedAce
AddAce
AddAuditAccessAce
DeleteAce
FindFirstFreeAce
GetAce
GetAclInformation
InitializeAcl
IsValidAcl
SetAclInformation

The following low-level functions are used to get and set the components of a security descriptor on various types of Win32 objects. Use these functions if your application needs to run on Windows NT version 3.51 or earlier.

GetFileSecurity
GetKernelObjectSecurity
GetPrinter
GetUserObjectSecurity
NetShareGetInfo
NetShareGetInfo
QueryServiceObjectSecurity
RegGetKeySecurity
RegSetKeySecurity
SetFileSecurity
SetKernelObjectSecurity
SetPrinter
SetServiceObjectSecurity
SetUserObjectSecurity

The following low-level functions are used to add ACEs to an ACL. These functions are supported on Windows NT versions 5.0 and later.

AddAccessAllowedAceEx
AddAccessAllowedObjectAce
AddAccessDeniedAceEx
AddAccessDeniedObjectAce
AddAuditAccessAceEx
AddAuditAccessObjectAce


AddAccessAllowedAce

The AddAccessAllowedAce function adds an access-allowed ACE to an ACL. The access is granted to a specified SID.

An ACE is an access-control entry. An ACL is an access-control list. A SID is a security identifier.

BOOL AddAccessAllowedAce(
  PACL pAcl,            // pointer to access-control list
  DWORD dwAceRevision,  // ACL revision level
  DWORD AccessMask,     // access mask
  PSID pSid             // pointer to security identifier
);

Parameters

pAcl
Pointer to an ACL structure. This function adds an access-allowed ACE to the end of this ACL. The ACE is in the form of an ACCESS_ALLOWED_ACE structure.
dwAceRevision
Specifies the revision level of the ACL being modified. Currently, this value must be ACL_REVISION.
AccessMask
Specifies the mask of access rights to be granted to the specified SID.
pSid
Pointer to the SID structure representing a user, group, or logon account being granted access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The addition of an access-allowed ACE to an ACL is the most common form of ACL modification.

The AddAccessAllowedAce and AddAccessDeniedAce functions add a new ACE to the end of the list of ACEs for the ACL. These functions do not automatically place the new ACE in the proper canonical order. It is the caller's responsibility to ensure that the ACL is in canonical order by adding ACEs in the proper sequence. For Windows NT versions 4.0 and earlier, the canonical order for a DACL places all access-denied ACEs before any access-allowed ACEs.

The ACE_HEADER structure placed in the ACE by the AddAccessAllowedAce function specifies a type and size, but provides no inheritance and no ACE flags.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACCESS_ALLOWED_ACE, ACE_HEADER, ACL, AddAccessDeniedAce, AddAce, AddAuditAccessAce, DeleteAce, GetAce


AddAccessAllowedAceEx

[This is preliminary documentation and subject to change.]

The AddAccessAllowedAceEx function adds an access-allowed ACE to the end of a DACL. This function is identical to the AddAccessAllowedAce function, except that it allows you to also specify flags that control whether the new ACE can be inherited by child objects.

BOOL AddAccessAllowedAceEx(
  PACL pAcl,            // pointer to an ACL
  DWORD dwAceRevision,  // ACL revision level
  DWORD AceFlags,       // ACE inheritance flags
  DWORD AccessMask,     // access mask for the new ACE
  PSID pSid             // SID of the trustee for the new ACE
);

Parameters

pAcl
Pointer to a DACL. The AddAccessAllowedAceEx function adds an access-allowed ACE to the end of this DACL. The ACE is in the form of an ACCESS_ALLOWED_ACE structure.
dwAceRevision
Specifies the revision level of the ACL being modified. This value can be ACL_REVISION or ACL_REVISION_DS. Use ACL_REVISION unless you are sure the ACL contains object-specific ACEs.
AceFlags
A set of bit flags that control ACE inheritance. The function sets these flags in the AceFlags member of the ACE_HEADER structure of the new ACE. This parameter can be a combination of the following values:
Value Meaning
CONTAINER_INHERIT_ACE
The ACE is inherited by container objects.
INHERIT_ONLY_ACE
The ACE does not apply to the object to which the ACL is assigned, but it can be inherited by child objects.
INHERITED_ACE
Indicates an inherited ACE. This flag allows operations that change the security on a tree of objects to modify inherited ACEs while not changing ACEs that were directly applied to the object.
NO_PROPAGATE_INHERIT_ACE
The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE bits are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE
The ACE is inherited by noncontainer objects.

AccessMask
A set of bit flags that use the ACCESS_MASK format to specify the access rights that the new ACE grants to the specified SID. This mask must use the Windows NT access mask format, not the provider-independent access-mask format.
pSid
Pointer to a SID structure that identifies the user, group, or logon session to which the new ACE grants access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. If the AceFlags parameter specifies invalid flags, GetLastError returns ERROR_INVALID_FLAGS.

Remarks

The caller must ensure that ACEs are added to the DACL in the correct order. For more information, see Order of ACEs in a DACL.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACCESS_ALLOWED_ACE, ACE_HEADER, ACL, AddAccessAllowedAce, AddAccessDeniedAceEx, AddAuditAccessAceEx


AddAccessAllowedObjectAce

[This is preliminary documentation and subject to change.]

The AddAccessAllowedObjectAce function adds an access-allowed ACE to the end of a DACL. The new ACE can grant access to an object, or to a property set or property on an object. You can also use AddAccessAllowedObjectAce to add an ACE that only a specified type of child object can inherit.

BOOL AddAccessAllowedObjectAce(
  PACL pAcl,             // pointer to an ACL
  DWORD dwAceRevision,   // ACL revision level
  DWORD AceFlags,        // ACE inheritance flags
  DWORD AccessMask,      // access mask for the new ACE
  GUID *ObjectTypeGuid,  // type of object protected by the ACE
  GUID *InheritedObjectTypeGuid,
                         // type of object that can inherit the ACE
  PSID pSid              // SID of the trustee for the new ACE
);

Parameters

pAcl
Pointer to a DACL. The AddAccessAllowedObjectAce function adds an access-allowed ACE to the end of this DACL. The ACE is in the form of an ACCESS_ALLOWED_OBJECT_ACE structure.
dwAceRevision
Specifies the revision level of the DACL being modified. This value must be ACL_REVISION_DS. If the DACL's revision level is lower than ACL_REVISION_DS, the function changes it to ACL_REVISION_DS.
AceFlags
A set of bit flags that control ACE inheritance. The function sets these flags in the AceFlags member of the ACE_HEADER structure of the new ACE. This parameter can be a combination of the following values.
Value Meaning
CONTAINER_INHERIT_ACE
The ACE is inherited by container objects.
INHERIT_ONLY_ACE
The ACE does not apply to the object to which the ACL is assigned, but it can be inherited by child objects.
INHERITED_ACE
Indicates an inherited ACE. This flag allows operations that change the security on a tree of objects to modify inherited ACEs, while not changing ACEs that were directly applied to the object.
NO_PROPAGATE_INHERIT_ACE
The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE bits are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE
The ACE is inherited by noncontainer objects.

AccessMask
A set of bit flags that use the ACCESS_MASK format to specify the access rights that the new ACE grants to the specified SID. This mask must use the Windows NT access mask format, not the provider-independent access-mask format.
ObjectTypeGuid
Pointer to a GUID structure that identifies the type of object, property set, or property protected by the new ACE. If this parameter is NULL, the new ACE protects the object to which the DACL is assigned.
InheritedObjectTypeGuid
Pointer to a GUID structure that identifies the type of object that can inherit the new ACE. If this parameter is non-NULL, only the specified object type can inherit the ACE. If NULL, any type of child object can inherit the ACE. In either case, inheritance is also controlled by the value of the AceFlags parameter, as well as by any protection against inheritance placed on the child objects.
pSid
Pointer to a SID structure that identifies the user, group, or logon session to which the new ACE grants access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. If the AceFlags parameter specifies invalid flags, GetLastError returns ERROR_INVALID_FLAGS.

Remarks

If both ObjectTypeGuid and InheritedObjectTypeGuid are NULL, use the AddAccessAllowedAceEx function rather than AddAccessAllowedObjectAce. This is suggested because an ACCESS_ALLOWED_ACE is smaller and more efficient than an ACCESS_ALLOWED_OBJECT_ACE.

The caller must ensure that ACEs are added to the DACL in the correct order. For more information, see Order of ACEs in a DACL.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACCESS_ALLOWED_ACE, ACCESS_ALLOWED_OBJECT_ACE, ACE_HEADER, ACL, AddAccessAllowedAceEx, AddAccessDeniedObjectAce, AddAuditAccessObjectAce


AddAccessDeniedAce

The AddAccessDeniedAce function adds an access-denied ACE to an ACL. The access is denied to a specified SID.

An ACE is an access-control entry. An ACL is an access-control list. A SID is a security identifier.

BOOL AddAccessDeniedAce(
  PACL pAcl,            // pointer to access-control list
  DWORD dwAceRevision,  // ACL revision level
  DWORD AccessMask,     // access mask
  PSID pSid             // pointer to security identifier
);

Parameters

pAcl
Pointer to an ACL structure. This function adds an access-denied ACE to the end of this ACL. The ACE is in the form of an ACCESS_DENIED_ACE structure.
dwAceRevision
Specifies the revision level of the ACL being modified. Currently, this value must be ACL_REVISION.
AccessMask
Specifies the mask of access rights being denied to the specified SID.
pSid
Pointer to the SID structure representing the user, group, or logon account being denied access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The AddAccessAllowedAce and AddAccessDeniedAce functions add a new ACE to the end of the list of ACEs for the ACL. These functions do not automatically place the new ACE in the proper canonical order. It is the caller's responsibility to ensure that the ACL is in canonical order by adding ACEs in the proper sequence. For Windows NT versions 4.0 and earlier, the canonical order for a DACL places all access-denied ACEs before any access-allowed ACEs.

The ACE_HEADER structure placed in the ACE by the AddAccessDeniedAce function specifies a type and size, but provides no ACE flags.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACCESS_DENIED_ACE, ACE_HEADER, ACL, AddAccessAllowedAce, AddAce, AddAuditAccessAce, DeleteAce, GetAce


AddAccessDeniedAceEx

[This is preliminary documentation and subject to change.]

The AddAccessDeniedAceEx function adds an access-denied ACE to the end of a DACL. This function is identical to the AddAccessDeniedAce function, except that it allows you to also specify flags that control whether the new ACE can be inherited by child objects.

BOOL AddAccessDeniedAceEx(
  PACL pAcl,            // pointer to an ACL
  DWORD dwAceRevision,  // ACL revision level
  DWORD AceFlags,       // ACE inheritance flags
  DWORD AccessMask,     // access mask for the new ACE
  PSID pSid             // SID of the trustee for the new ACE
);

Parameters

pAcl
Pointer to a DACL. The AddAccessDeniedAceEx function adds an access-denied ACE to the end of this DACL. The ACE is in the form of an ACCESS_DENIED_ACE structure.
dwAceRevision
Specifies the revision level of the ACL being modified. This value can be ACL_REVISION or ACL_REVISION_DS. Use ACL_REVISION unless you are sure the ACL contains object-specific ACEs.
AceFlags
A set of bit flags that control ACE inheritance. The function sets these flags in the AceFlags member of the ACE_HEADER structure of the new ACE. This parameter can be a combination of the following values:
Value Meaning
CONTAINER_INHERIT_ACE
The ACE is inherited by container objects.
INHERIT_ONLY_ACE
The ACE does not apply to the object to which the ACL is assigned, but it can be inherited by child objects.
INHERITED_ACE
Indicates an inherited ACE. This flag allows operations that change the security on a tree of objects to modify inherited ACEs, while not changing ACEs that were directly applied to the object.
NO_PROPAGATE_INHERIT_ACE
The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE bits are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE
The ACE is inherited by noncontainer objects.

AccessMask
A set of bit flags that use the ACCESS_MASK format to specify the access rights that the new ACE denies to the specified SID. This mask must use the Windows NT access mask format, not the provider-independent access-mask format.
pSid
Pointer to a SID structure that identifies the user, group, or logon session to which the new ACE denies access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. If the AceFlags parameter specifies invalid flags, GetLastError returns ERROR_INVALID_FLAGS.

Remarks

Although the AddAccessDeniedAceEx function adds the new ACE to the end of the DACL, access-denied ACEs should appear at the beginning of a DACL. The caller must ensure that ACEs are added to the DACL in the correct order. For more information, see Order of ACEs in a DACL.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACCESS_DENIED_ACE, ACE_HEADER, ACL, AddAccessAllowedAceEx, AddAccessDeniedAce, AddAuditAccessAceEx


AddAccessDeniedObjectAce

[This is preliminary documentation and subject to change.]

The AddAccessDeniedObjectAce function adds an access-denied ACE to the end of a DACL. The new ACE can deny access to an object, or to a property set or property on an object. You can also use AddAccessDeniedObjectAce to add an ACE that only a specified type of child object can inherit.

BOOL AddAccessDeniedObjectAce(
  PACL pAcl,             // pointer to an ACL
  DWORD dwAceRevision,   // ACL revision level
  DWORD AceFlags,        // ACE inheritance flags
  DWORD AccessMask,      // access mask for the new ACE
  GUID *ObjectTypeGuid,  // type of object protected by the ACE
  GUID *InheritedObjectTypeGuid,
                         // type of object that can inherit the ACE
  PSID pSid              // SID of the trustee for the new ACE
);

Parameters

pAcl
Pointer to a DACL. The AddAccessDeniedObjectAce function adds an access-denied ACE to the end of this DACL. The ACE is in the form of an ACCESS_DENIED_OBJECT_ACE structure.
dwAceRevision
Specifies the revision level of the DACL being modified. This value must be ACL_REVISION_DS. If the DACL's revision level is lower than ACL_REVISION_DS, the function changes it to ACL_REVISION_DS.
AceFlags
A set of bit flags that control ACE inheritance. The function sets these flags in the AceFlags member of the ACE_HEADER structure of the new ACE. This parameter can be a combination of the following values.
Value Meaning
CONTAINER_INHERIT_ACE
The ACE is inherited by container objects.
INHERIT_ONLY_ACE
The ACE does not apply to the object to which the ACL is assigned, but it can be inherited by child objects.
INHERITED_ACE
Indicates an inherited ACE. This flag allows operations that change the security on a tree of objects to modify inherited ACEs, while not changing ACEs that were directly applied to the object.
NO_PROPAGATE_INHERIT_ACE
The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE bits are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE
The ACE is inherited by noncontainer objects.

AccessMask
A set of bit flags that use the ACCESS_MASK format to specify the access rights that the new ACE denies to the specified SID. This mask must use the Windows NT access mask format, not the provider-independent access-mask format.
ObjectTypeGuid
Pointer to a GUID structure that identifies the type of object, property set, or property protected by the new ACE. If this parameter is NULL, the new ACE protects the object to which the ACL is assigned.
InheritedObjectTypeGuid
Pointer to a GUID structure that identifies the type of object that can inherit the new ACE. If this parameter is non-NULL, only the specified object type can inherit the ACE. If NULL, any type of child object can inherit the ACE. In either case, inheritance is also controlled by the value of the AceFlags parameter, as well as by any protection against inheritance placed on the child objects.
pSid
Pointer to a SID structure that identifies the user, group, or logon session to which the new ACE grants access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. If the AceFlags parameter specifies invalid flags, GetLastError returns ERROR_INVALID_FLAGS.

Remarks

If both ObjectTypeGuid and InheritedObjectTypeGuid are NULL, use the AddAccessDeniedAceEx function rather than AddAccessDeniedObjectAce. This is suggested because an ACCESS_DENIED_ACE is smaller and more efficient than an ACCESS_DENIED_OBJECT_ACE.

Although the AddAccessDeniedObjectAce function adds the new ACE to the end of the ACL, access-denied ACEs should appear at the beginning of an ACL. The caller must ensure that ACEs are added to the DACL in the correct order. For more information, see Order of ACEs in a DACL.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACCESS_DENIED_ACE, ACCESS_DENIED_OBJECT_ACE, ACE_HEADER, ACL, AddAccessAllowedObjectAce, AddAccessDeniedAceEx, AddAuditAccessObjectAce


AddAce

The AddAce function adds one or more ACEs to a specified ACL.

An ACE is an access-control entry. An ACL is an access-control list.

BOOL AddAce(
  PACL pAcl,             // pointer to access-control list
  DWORD dwAceRevision,   // ACL revision level
  DWORD dwStartingAceIndex,  // index of ACE position in ACL
  LPVOID pAceList,       // pointer to one or more ACEs
  DWORD nAceListLength   // size of buffer for ACEs
);

Parameters

pAcl
Pointer to an ACL structure. This function adds an ACE to this ACL.
dwAceRevision
Specifies the revision level of the ACL being modified. Currently, this value must be ACL_REVISION.
dwStartingAceIndex
Specifies the position in the ACL's list of ACEs at which to add new ACEs. A value of zero inserts the ACEs at the beginning of the list. A value of MAXDWORD appends the ACEs to the end of the list.
pAceList
Pointer to a list of one or more ACEs to be added to the specified ACL. The ACEs in the list must be stored contiguously.
nAceListLength
Specifies the size, in bytes, of the input buffer pointed to by the pAceList parameter.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Applications frequently use the FindFirstFreeAce and GetAce functions when using the AddAce function to manipulate an ACL. In addition, the ACL_SIZE_INFORMATION structure retrieved by the GetAclInformation function contains the size of the ACL and the number of ACEs it contains.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, ACL_SIZE_INFORMATION, AddAccessAllowedAce, AddAccessDeniedAce, AddAuditAccessAce, DeleteAce, FindFirstFreeAce, GetAce, GetAclInformation


AddAuditAccessAce

The AddAuditAccessAce function adds a system-audit ACE to a system ACL. The access of a specified SID is audited.

An ACE is an access-control entry. An ACL is an access-control list. A SID is a security identifier.

BOOL AddAuditAccessAce(
  PACL pAcl,           // pointer to access-control list
  DWORD dwAceRevision, // ACL revision level
  DWORD dwAccessMask,  // access mask
  PSID pSid,           // pointer to security identifier
  BOOL bAuditSuccess,  // flag for auditing successful access
  BOOL bAuditFailure   // flag for auditing unsuccessful access
                       // attempts
);

Parameters

pAcl
Pointer to an ACL structure. This function adds a system-audit ACE to this ACL. The ACE is in the form of an SYSTEM_AUDIT_ACE structure.
dwAceRevision
Specifies the revision level of the ACL being modified. Currently, this value must be ACL_REVISION.
dwAccessMask
Specifies the mask of access rights to be audited for the specified SID.
pSid
Pointer to the SID structure representing the process whose access is being audited.
bAuditSuccess
Specifies whether successful access attempts are to be audited. Set this flag to TRUE to enable auditing; otherwise, set it to FALSE.
bAuditFailure
Specifies whether unsuccessful access attempts are to be audited. Set this flag to TRUE to enable auditing; otherwise, set it to FALSE.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ACE_HEADER structure placed in the ACE by the AddAuditAccessAce function specifies a type and size, but provides no ACE flags.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACE_HEADER, ACL, AddAccessAllowedAce, AddAccessDeniedAce, AddAce, DeleteAce, GetAce, SID, SYSTEM_AUDIT_ACE


AddAuditAccessAceEx

[This is preliminary documentation and subject to change.]

The AddAuditAccessAceEx function adds a system-audit ACE to the end of a SACL. This function is identical to the AddAuditAccessAce function, except that it allows you to also specify flags that control whether the new ACE can be inherited by child objects.

BOOL AddAuditAccessAceEx(
  PACL pAcl,            // pointer to an ACL
  DWORD dwAceRevision,  // ACL revision level
  DWORD AceFlags,       // flags for ACE inheritance and audit type
  DWORD dwAccessMask,   // access mask for the new ACE
  PSID pSid,            // SID of the trustee for the new ACE
  BOOL bAuditSuccess,   // audit successful access attempts
  BOOL bAuditFailure    // audit unsuccessful access attempts
);

Parameters

pAcl
Pointer to a SACL. The AddAuditAccessAceEx function adds a system-audit ACE to this SACL. The ACE is in the form of a SYSTEM_AUDIT_ACE structure.
dwAceRevision
Specifies the revision level of the ACL being modified. This value can be ACL_REVISION or ACL_REVISION_DS. Use ACL_REVISION unless you are sure the SACL contains object type ACEs.
AceFlags
A set of bit flags that control ACE inheritance and the type of access attempts to audit. The function sets these flags in the AceFlags member of the ACE_HEADER structure of the new ACE. This parameter can be a combination of the following values.
Value Meaning
CONTAINER_INHERIT_ACE
The ACE is inherited by container objects.
FAILED_ACCESS_ACE_FLAG
If you set this flag or specify TRUE for the bAuditFailure parameter, failed attempts to use the specified access rights cause the system to generate an audit record in the security event log.
INHERIT_ONLY_ACE
The ACE does not apply to the object to which the ACL is assigned, but it can be inherited by child objects.
INHERITED_ACE
Indicates an inherited ACE. This flag allows operations that change the security on a tree of objects to modify inherited ACEs, while not changing ACEs that were directly applied to the object.
NO_PROPAGATE_INHERIT_ACE
The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE bits are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE
The ACE is inherited by noncontainer objects.
SUCCESSFUL_ACCESS_ACE_FLAG
If you set this flag or specify TRUE for the bAuditSuccess parameter, successful uses of the specified access rights cause the system to generate an audit record in the security event log.

AccessMask
A set of bit flags that use the ACCESS_MASK format to specify the access rights that the new ACE audits for the specified SID. This mask must use the Windows NT access mask format, not the provider-independent access-mask format.
pSid
Pointer to a SID structure that identifies the user, group, or logon session for which the new ACE audits access.
bAuditSuccess
Specifies whether successful uses of the specified access rights cause the system to generate an audit record in the security event log. If this flag is TRUE or if the AceFlags parameter specifies the SUCCESSFUL_ACCESS_ACE_FLAG flag, the system records successful access attempts; otherwise, it does not.
bAuditFailure
Specifies whether failed attempts to use the specified access rights cause the system to generate an audit record in the security event log. If this flag is TRUE or if the AceFlags parameter specifies the FAILED_ACCESS_ACE_FLAG flag, the system records failed access attempts; otherwise, it does not.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. If the AceFlags parameter specifies invalid flags, GetLastError returns ERROR_INVALID_FLAGS.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACE_HEADER, ACL, AddAccessAllowedAceEx, AddAccessDeniedAceEx, AddAuditAccessAce, SYSTEM_AUDIT_ACE


AddAuditAccessObjectAce

[This is preliminary documentation and subject to change.]

The AddAuditAccessObjectAce function adds a system-audit ACE to the end of a SACL. The new ACE can audit access to an object, or to a property set or property on an object. You can also use AddAuditAccessObjectAce to add an ACE that only a specified type of child object can inherit.

BOOL AddAuditAccessObjectAce(
  PACL pAcl,             // pointer to an ACL
  DWORD dwAceRevision,   // ACL revision level
  DWORD AceFlags,        // ACE inheritance flags
  DWORD AccessMask,      // access mask for the new ACE
  GUID *ObjectTypeGuid,  // type of object protected by the ACE
  GUID *InheritedObjectTypeGuid,
                         // type of object that can inherit the ACE
  PSID pSid,             // SID of the trustee for the new ACE
  BOOL bAuditSuccess,    // audit successful access attempts
  BOOL bAuditFailure     // audit unsuccessful access attempts
);

Parameters

pAcl
Pointer to a SACL. The AddAuditAccessObjectAce function adds a system-audit ACE to the end of this SACL. The ACE is in the form of a SYSTEM_AUDIT_OBJECT_ACE structure.
dwAceRevision
Specifies the revision level of the SACL being modified. This value must be ACL_REVISION_DS. If the SACL's revision level is lower than ACL_REVISION_DS, the function changes it to ACL_REVISION_DS.
AceFlags
A set of bit flags that control ACE inheritance and the type of access attempts to audit. The function sets these flags in the AceFlags member of the ACE_HEADER structure of the new ACE. This parameter can be a combination of the following values.
Value Meaning
CONTAINER_INHERIT_ACE
The ACE is inherited by container objects.
FAILED_ACCESS_ACE_FLAG
If you set this flag or specify TRUE for the bAuditFailure parameter, failed attempts to use the specified access rights cause the system to generate an audit record in the security event log.
INHERIT_ONLY_ACE
The ACE does not apply to the object to which the ACL is assigned, but it can be inherited by child objects.
INHERITED_ACE
Indicates an inherited ACE. This flag allows operations that change the security on a tree of objects to modify inherited ACEs, while not changing ACEs that were directly applied to the object.
NO_PROPAGATE_INHERIT_ACE
The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE bits are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE
The ACE is inherited by noncontainer objects.
SUCCESSFUL_ACCESS_ACE_FLAG
If you set this flag or specify TRUE for the bAuditSuccess parameter, successful uses of the specified access rights cause the system to generate an audit record in the security event log.

AccessMask
An ACCESS_MASK that specifies the access rights that the new ACE audits for the specified SID. This mask must use the Windows NT access mask format, not the provider-independent access-mask format.
ObjectTypeGuid
Pointer to a GUID structure that identifies the type of object, property set, or property protected by the new ACE. If this parameter is NULL, the new ACE protects the object to which the ACL is assigned.
InheritedObjectTypeGuid
Pointer to a GUID structure that identifies the type of object that can inherit the new ACE. If this parameter is non-NULL, only the specified object type can inherit the ACE. If NULL, any type of child object can inherit the ACE. In either case, inheritance is also controlled by the value of the AceFlags parameter, as well as by any protection against inheritance placed on the child objects.
pSid
Pointer to a SID structure that identifies the user, group, or logon session for which the new ACE audits access.
bAuditSuccess
Specifies whether successful uses of the specified access rights cause the system to generate an audit record in the security event log. If this flag is TRUE or if the AceFlags parameter specifies the SUCCESSFUL_ACCESS_ACE_FLAG flag, the system records successful access attempts; otherwise, it does not.
bAuditFailure
Specifies whether failed attempts to use the specified access rights cause the system to generate an audit record in the security event log. If this flag is TRUE or if the AceFlags parameter specifies the FAILED_ACCESS_ACE_FLAG flag, the system records failed access attempts; otherwise, it does not.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. If the AceFlags parameter specifies invalid flags, GetLastError returns ERROR_INVALID_FLAGS.

Remarks

If both ObjectTypeGuid and InheritedObjectTypeGuid are NULL, use the AddAuditAccessAceEx function rather than AddAuditAccessObjectAce. This is suggested because a SYSTEM_AUDIT_ACE is smaller and more efficient than an SYSTEM_AUDIT_OBJECT_ACE.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACE_HEADER, ACL, AddAccessAllowedObjectAce, AddAccessDeniedObjectAce, AddAuditAccessAceEx, SYSTEM_AUDIT_ACE, SYSTEM_AUDIT_OBJECT_ACE


DeleteAce

The DeleteAce function deletes an ACE from an ACL.

An ACE is an access-control entry. An ACL is an access-control list.

BOOL DeleteAce(
  PACL pAcl,         // pointer to access-control list
  DWORD dwAceIndex   // index of ACE position in ACL
);

Parameters

pAcl
Points to an ACL structure. The ACE specified by the dwAceIndex parameter is removed from this ACL.
dwAceIndex
Specifies the ACE to delete. A value of 0 corresponds to the first ACE in the ACL, 1 to the second ACE, and so on.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

An application can use the ACL_SIZE_INFORMATION structure retrieved by the GetAclInformation function to discover the size of the ACL and the number of ACEs it contains. The GetAce function retrieves information about an individual ACE.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, ACL_SIZE_INFORMATION, AddAccessAllowedAce, AddAccessDeniedAce, AddAce, AddAuditAccessAce, GetAce, GetAclInformation


FindFirstFreeAce

The FindFirstFreeAce function retrieves a pointer to the first free byte in an access-control list (ACL).

BOOL FindFirstFreeAce(
  PACL pAcl,     // pointer to access-control list
  LPVOID *pAce   // pointer to pointer to first free byte
);

Parameters

pAcl
Points to an ACL structure.
pAce
Points to a pointer to the first free position in the ACL created when the function returns. If the ACL is invalid, this parameter is NULL. If the ACL is full, this parameter points to the byte immediately following the ACL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, GetAce, GetAclInformation


GetAce

The GetAce function obtains a pointer to an ACE in an ACL.

An ACE is an access control entry. An ACL is an access control list.

BOOL GetAce(
  PACL pAcl,         // pointer to access-control list
  DWORD dwAceIndex,  // index of ACE to retrieve
  LPVOID *pAce       // pointer to pointer to ACE
);

Parameters

pAcl
Points to an ACL structure containing the ACE to be retrieved.
dwAceIndex
Specifies the ACE to which a pointer is retrieved. A value of 0 corresponds to the first ACE in the ACL, 1 to the second ACE, and so on.
pAce
Points to a pointer the function sets to the address of the ACE.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, AddAccessAllowedAce, AddAccessDeniedAce, AddAce, AddAuditAccessAce, GetAclInformation, InitializeAcl


GetAclInformation

The GetAclInformation function retrieves information about an access-control list (ACL).

BOOL GetAclInformation(
  PACL pAcl,                    // pointer to access-control list
  LPVOID pAclInformation,       // pointer to ACL information
  DWORD nAclInformationLength,  // size of ACL information
  ACL_INFORMATION_CLASS dwAclInformationClass
                                // class of requested information
);

Parameters

pAcl
Points to an ACL structure. The function retrieves information about this ACL.
pAclInformation
Points to a buffer receiving the requested information. The structure put into the buffer depends on the information class requested in the dwAclInformationClass parameter.
nAclInformationLength
Specifies the size, in bytes, of the buffer pointed to by the pAclInformation parameter.
dwAclInformationClass
Specifies an ACL_INFORMATION_CLASS enumerated type that gives the class of information requested. This parameter can be one of two values from this enumerated type. If the value is AclRevisionInformation, the function fills the buffer pointed to by the pAclInformation parameter with an ACL_REVISION_INFORMATION structure.

If the value is AclSizeInformation, the function fills the buffer pointed to by the pAclInformation parameter with an ACL_SIZE_INFORMATION structure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, ACL_REVISION_INFORMATION, ACL_SIZE_INFORMATION, GetAce, InitializeAcl, IsValidAcl, SetAclInformation


GetFileSecurity

The GetFileSecurity function obtains specified information about the security of a file or directory. The information obtained is constrained by the caller's access rights and privileges.

BOOL GetFileSecurity(
  LPCTSTR lpFileName,       // address of string for file name
  SECURITY_INFORMATION RequestedInformation,
                            // requested information
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
                            // address of security descriptor
  DWORD nLength,            // size of security descriptor buffer
  LPDWORD lpnLengthNeeded   // address of required size of buffer
);

Parameters

lpFileName
Points to a null-terminated string specifying the file or directory for which security information is retrieved.
RequestedInformation
Specifies a SECURITY_INFORMATION value that identifies the security information being requested.
pSecurityDescriptor
Points to a buffer that receives a copy of the security descriptor of the object specified by the lpFileName parameter. The calling process must have the right to view the specified aspects of the object's security status. The SECURITY_DESCRIPTOR structure is returned in self-relative format.
nLength
Specifies the size, in bytes, of the buffer pointed to by the pSecurityDescriptor parameter.
lpnLengthNeeded
Points to a variable the function sets to zero if the file descriptor is copied successfully. If the buffer is too small for the security descriptor, this variable receives the number of bytes required. If this variable's value is greater than that of the nLength parameter when the function returns, none of the security descriptor is copied to the buffer.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

To read the owner, group, or DACL from the security descriptor for the specified file or directory, the DACL for the file or directory must grant READ_CONTROL access to the caller or the caller must be the owner of the file or directory.

To read the system access-control list (SACL) of a file or directory, the SE_SECURITY_NAME privilege must be enabled for the calling process.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetKernelObjectSecurity, GetPrivateObjectSecurity, GetUserObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetFileSecurity


GetKernelObjectSecurity

The GetKernelObjectSecurity function retrieves a copy of the security descriptor protecting a kernel object.

BOOL GetKernelObjectSecurity(
  HANDLE Handle,  // handle of object to query
  SECURITY_INFORMATION RequestedInformation,
                  // requested information
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
                  // address of security descriptor
  DWORD nLength,  // size of buffer for security descriptor
  LPDWORD lpnLengthNeeded
                  // address of required size of buffer
);

Parameters

Handle
Identifies a kernel object.
RequestedInformation
Specifies a SECURITY_INFORMATION value that identifies the security information being requested.
pSecurityDescriptor
Points to a buffer the function fills with a copy of the security descriptor of the specified object. The calling process must have the right to view the specified aspects of the object's security status. The SECURITY_DESCRIPTOR structure is returned in self-relative format.
nLength
Specifies the size, in bytes, of the buffer pointed to by the pSecurityDescriptor parameter.
lpnLengthNeeded
Points to a variable the function sets to zero if the descriptor is copied successfully. If the buffer is too small for the security descriptor, this variable receives the number of bytes required. If this variable's value is greater than the value of the nLength parameter when the function returns, none of the security descriptor is copied to the buffer.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

To read the owner, group, or DACL from the kernel object's security descriptor, the calling process must have been granted READ_CONTROL access when the handle was opened. To get READ_CONTROL access, the caller must be the owner of the object or the object's DACL must grant the access.

To read the SACL from the security descriptor, the calling process must have been granted ACCESS_SYSTEM_SECURITY access when the handle was opened. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetFileSecurity, GetPrivateObjectSecurity, GetUserObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetKernelObjectSecurity


GetSecurityDescriptorDacl

The GetSecurityDescriptorDacl function retrieves a pointer to the discretionary access-control list (ACL) in a specified security descriptor.

BOOL GetSecurityDescriptorDacl(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
                // address of security descriptor
  LPBOOL lpbDaclPresent,
                // address of flag for presence of disc. ACL
  PACL *pDacl,  // address of pointer to ACL
  LPBOOL lpbDaclDefaulted
                // address of flag for default disc. ACL
);

Parameters

pSecurityDescriptor
Points to the SECURITY_DESCRIPTOR structure containing the discretionary ACL. The function retrieves a pointer to it.
lpbDaclPresent
Points to a flag the function sets to indicate the presence of a discretionary ACL in the specified security descriptor. If this parameter is TRUE, the security descriptor contains a discretionary ACL, and the remaining output parameters in this function receive valid values. If this parameter is FALSE, the security descriptor does not contain a discretionary ACL, and the remaining output parameters do not receive valid values.
pDacl
Points to a pointer to an ACL structure. If a discretionary ACL exists, the function sets the pointer pointed to by pDacl to the address of the security descriptor's discretionary ACL. If a discretionary ACL does not exist, no value is stored.

If the function stores a NULL value in the pointer pointed to by pDacl, the security descriptor has a NULL discretionary ACL. A NULL discretionary ACL implicitly allows all access to an object.

lpbDaclDefaulted
Points to a flag set to the value of the SE_DACL_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure if a discretionary ACL exists for the security descriptor. If this flag is TRUE, the discretionary ACL was retrieved by a default mechanism; if FALSE, the discretionary ACL was explicitly specified by a user.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, GetSecurityDescriptorControl, GetSecurityDescriptorGroup, GetSecurityDescriptorLength, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, InitializeSecurityDescriptor, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorDacl


GetSecurityDescriptorGroup

The GetSecurityDescriptorGroup function retrieves the primary group information from a security descriptor.

BOOL GetSecurityDescriptorGroup(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
                             // address of security descriptor
  PSID *pGroup,              // address of pointer to group security
                             // identifier (SID)
  LPBOOL lpbGroupDefaulted   // address of flag for default
);

Parameters

pSecurityDescriptor
Points to a SECURITY_DESCRIPTOR structure whose primary group information the function retrieves.
pGroup
Points to a pointer to a SID structure identifying the primary group when the function returns. (A SID is a security identifier.) If the security descriptor does not contain a primary group, the function sets the pointer pointed to by pGroup to NULL and ignores the remaining output parameter, lpbGroupDefaulted. If the security descriptor contains a primary group, the function sets the pointer pointed to by pGroup to the address of the security descriptor's group SID structure and provides a valid value for the variable pointed to by lpbGroupDefaulted.
lpbGroupDefaulted
Points to a flag set to the value of the SE_GROUP_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure when the function returns. If the value stored in the variable pointed to by the pGroup parameter is NULL, no value is set.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorLength, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorGroup, SID


GetSecurityDescriptorLength

The GetSecurityDescriptorLength function returns the length, in bytes, of a structurally valid SECURITY_DESCRIPTOR structure. The length includes the length of all associated structures, such as SID and ACL structures.

DWORD GetSecurityDescriptorLength(
  PSECURITY_DESCRIPTOR pSecurityDescriptor   // address of security
                                             // descriptor
);

Parameters

pSecurityDescriptor
Points to the SECURITY_DESCRIPTOR structure whose length the function returns. The SECURITY_DESCRIPTOR structure is assumed to be valid.

Return Values

If the function succeeds, the return value is the length, in bytes, of the SECURITY_DESCRIPTOR structure. If the SECURITY_DESCRIPTOR structure is invalid, the return value is undefined.

Remarks

The minimum length of a security descriptor is SECURITY_DESCRIPTOR_MIN_LENGTH. A security descriptor of this length has no associated SID or ACL structures.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR


GetSecurityDescriptorOwner

The GetSecurityDescriptorOwner function retrieves the owner information from a security descriptor.

BOOL GetSecurityDescriptorOwner(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
                             // address of security descriptor
  PSID *pOwner,              // address of pointer to owner security
                             // identifier (SID)
  LPBOOL lpbOwnerDefaulted   // address of flag for default
);

Parameters

pSecurityDescriptor
Points to a SECURITY_DESCRIPTOR structure whose owner information the function retrieves.
pOwner
Points to a pointer to a SID structure identifying the owner when the function returns. (A SID is a security identifier.) If the security descriptor does not contain an owner, the function sets the pointer pointed to by pOwner to NULL and ignores the remaining output parameter, lpbOwnerDefaulted. If the security descriptor contains an owner, the function sets the pointer pointed to by pOwner to the address of the security descriptor's owner SID structure and provides a valid value for the variable pointed to by lpbOwnerDefaulted.
lpbOwnerDefaulted
Points to a flag set to the value of the SE_OWNER_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure when the function returns. If the value stored in the variable pointed to by the pOwner parameter is NULL, no value is set.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorLength, GetSecurityDescriptorSacl, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorOwner, SID


GetSecurityDescriptorSacl

The GetSecurityDescriptorSacl function retrieves a pointer to the system access-control list (ACL) in a specified security descriptor.

BOOL GetSecurityDescriptorSacl(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
                // address of security descriptor
  LPBOOL lpbSaclPresent,
                // address of flag for presence of system ACL
  PACL *pSacl,  // address of pointer to ACL
  LPBOOL lpbSaclDefaulted
                // address of flag for default system ACL
);

Parameters

pSecurityDescriptor
Points to the SECURITY_DESCRIPTOR structure containing the system ACL to which the function retrieves a pointer to.
lpbSaclPresent
Points to a flag the function sets to indicate the presence of a system ACL in the specified security descriptor. If this parameter is TRUE, the security descriptor contains a system ACL, and the remaining output parameters in this function receive valid values. If this parameter is FALSE, the security descriptor does not contain a system ACL, and the remaining output parameters do not receive valid values.
pSacl
Points to a pointer to an ACL structure. If a system ACL exists, the function sets the pointer pointed to by pSacl to the address of the security descriptor's system ACL. If a system ACL does not exist, no value is stored.

If the function stores a NULL value in the pointer pointed to by pSacl, the security descriptor has a NULL system ACL.

lpbSaclDefaulted
Points to a flag set to the value of the SE_SACL_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure if a system ACL exists for the security descriptor.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorLength, GetSecurityDescriptorOwner, InitializeSecurityDescriptor, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorSacl


GetUserObjectSecurity

The GetUserObjectSecurity function retrieves security information for the specified user object.

BOOL GetUserObjectSecurity(
  HANDLE hObj,    // handle of user object
  PSECURITY_INFORMATION pSIRequested,
                  // address of requested security information
  PSECURITY_DESCRIPTOR pSD,
                  // address of security descriptor
  DWORD nLength,  // size of buffer for security descriptor
  LPDWORD lpnLengthNeeded
                  // address of required size of buffer
);

Parameters

hObj
Identifies the user object for which to return security information.
pSIRequested
Points to a SECURITY_INFORMATION value specifying the security information being requested.
pSD
Points to a SECURITY_DESCRIPTOR structure in self-relative format that contains the requested information when the function returns.
nLength
Specifies the length, in bytes, of the buffer pointed to by the pSD parameter.
lpnLengthNeeded
Points to a variable receiving the number of bytes required to store the complete security descriptor. If this variable's value is greater than the value of the nLength parameter when the function returns, the function returns FALSE and none of the security descriptor is copied to the buffer. Otherwise, the entire security descriptor is copied.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

To read the owner, group, or DACL from the user object's security descriptor, the calling process must have been granted READ_CONTROL access when the handle was opened. To get READ_CONTROL access, the caller must be the owner of the object or the object's DACL must grant the access.

To read the SACL from the security descriptor, the calling process must have been granted ACCESS_SYSTEM_SECURITY access when the handle was opened. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, CreatePrivateObjectSecurity, GetKernelObjectSecurity, GetPrivateObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetUserObjectSecurity


InitializeAcl

The InitializeAcl function creates a new ACL structure.

An ACL is an access-control list.

BOOL InitializeAcl(
  PACL pAcl,            // address of access-control list
  DWORD nAclLength,     // size of access-control list
  DWORD dwAclRevision   // revision level of access-control list
);

Parameters

pAcl
Points to an ACL structure initialized by this function.
nAclLength
Specifies the length, in bytes, of the buffer pointed to by the pAcl parameter. This value must be large enough to contain the ACL header and all of the access-control entries (ACEs) to be stored in the ACL. See the following Remarks section for more information about calculating the size of an ACL.
dwAclRevision
Specifies the revision level of the ACL. This parameter must be set to the current revision level, defined as ACL_REVISION for this version of Windows NT.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ACL initialized by this function contains no ACEs. It is empty, as opposed to being a nonexistent ACL. If an empty ACL is applied to an object, it implicitly denies all access to that object.

To calculate the size of an ACL, add sizeof(ACL) to the size of all the ACEs to be stored in the ACL. To calculate the size of an ACE, add the size of the ACE structure, such as sizeof(ACCESS_ALLOWED_ACE), to the length of the SID associated with the ACE, and then subtract the size of the SidStart member (which is part of both the ACE structure and the SID). Use the GetSidLength function to get the length of a specified SID.

The following example shows how to calculate the size of an access-allowed ACE:

sizeof (ACCESS_ALLOWED_ACE) - sizeof (ACCESS_ALLOWED_ACE.SidStart)
        + GetLengthSid (pAceSid);

To calculate the size of an ACL, use the following algorithm, substituting the appropriate ACE structure in the sizeof(ACE) expression:

cbAcl = sizeof (ACL);
for (i = 0 ; i < nAceCount ; i++) {
    // subtract ACE.SidStart from the size
    cbAce = sizeof (ACE) - sizeof (DWORD);
    // add this ACE's SID length
    cbAce += GetLengthSid (pAceSid[i]);
    // add the length of each ACE to the total ACL length
    cbAcl += cbAce;
}

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, ACL, AddAccessAllowedAce, AddAccessDeniedAce, AddAce, AddAuditAccessAce, DeleteAce, GetAce, GetAclInformation, IsValidAcl, SetAclInformation, SID


InitializeSecurityDescriptor

The InitializeSecurityDescriptor function initializes a new security descriptor.

BOOL InitializeSecurityDescriptor(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
                     // address of security descriptor
  DWORD dwRevision   // revision level
);

Parameters

pSecurityDescriptor
Points to a SECURITY_DESCRIPTOR structure that the function initializes.
dwRevision
Specifies the revision level to assign to the security descriptor. This must be SECURITY_DESCRIPTOR_REVISION.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The InitializeSecurityDescriptor function initializes a security descriptor in absolute format, rather than self-relative format.

The InitializeSecurityDescriptor function initializes a security descriptor to have no system ACL, no discretionary ACL, no owner, no primary group, and all control flags set to FALSE (NULL). Thus, except for its revision level, it is empty.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorLength, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SetSecurityDescriptorDacl, SetSecurityDescriptorGroup, SetSecurityDescriptorOwner, SetSecurityDescriptorSacl


IsValidAcl

The IsValidAcl function validates an access-control list (ACL).

BOOL IsValidAcl(
  PACL pAcl   // address of access-control list
);

Parameters

pAcl
Points to an ACL structure validated by this function. This must be a non-NULL value.

Return Values

If the ACL is valid, the return value is nonzero.

If the ACL is not valid, the return value is zero. There is no extended error information for this function; do not call GetLastError.

Remarks

This function checks the revision level of the ACL and verifies that the number of access-control entries (ACEs) specified in the AceCount member of the ACL structure fits the space specified by the AclSize member of the ACL structure.

If pAcl is NULL, the application will fail with an access violation.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, GetAclInformation, InitializeAcl


IsValidSecurityDescriptor

The IsValidSecurityDescriptor function determines whether the components of a security descriptor are valid.

BOOL IsValidSecurityDescriptor(
  PSECURITY_DESCRIPTOR pSecurityDescriptor   // address of security
                                             // descriptor
);

Parameters

pSecurityDescriptor
Points to a SECURITY_DESCRIPTOR structure that the function validates.

Return Values

If the components of the security descriptor is valid, the return value is nonzero.

If any of the components of the security descriptor is not valid, the return value is zero. There is no extended error information for this function; do not call GetLastError.

Remarks

The IsValidSecurityDescriptor function checks the validity of the components that are present in the security descriptor. It does not verify whether certain components are present.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorLength, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, InitializeSecurityDescriptor, IsValidAcl, IsValidSid, SECURITY_DESCRIPTOR, SetSecurityDescriptorDacl, SetSecurityDescriptorGroup, SetSecurityDescriptorOwner, SetSecurityDescriptorSacl


MakeAbsoluteSD

The MakeAbsoluteSD function creates a security descriptor in absolute format by using a security descriptor in self-relative format as a template.

BOOL MakeAbsoluteSD(
  PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
                                // address of self-relative SD
  PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
                                // address of absolute SD
  LPDWORD lpdwAbsoluteSecurityDescriptorSize,
                                // address of size of absolute SD
  PACL pDacl,                   // address of discretionary ACL
  LPDWORD lpdwDaclSize,         // address of size of discretionary ACL
  PACL pSacl,                   // address of system ACL
  LPDWORD lpdwSaclSize,         // address of size of system ACL
  PSID pOwner,                  // address of owner SID
  LPDWORD lpdwOwnerSize,        // address of size of owner SID
  PSID pPrimaryGroup,           // address of primary-group SID
  LPDWORD lpdwPrimaryGroupSize  // address of size of group SID
);

Parameters

pSelfRelativeSecurityDescriptor
Points to a SECURITY_DESCRIPTOR structure in self-relative format. The function creates an absolute-format version of this security descriptor without modifying the original security descriptor.
pAbsoluteSecurityDescriptor
Points to a buffer that the function fills with the main body of an absolute-format security descriptor. This information is formatted as a SECURITY_DESCRIPTOR structure.
lpdwAbsoluteSecurityDescriptorSize
Points to a variable specifying the size of the buffer pointed to by the pAbsoluteSecurityDescriptor parameter. If the buffer is not large enough for the security descriptor, the function fails and sets this variable to the minimum required size.
pDacl
Points to a buffer the function fills with the discretionary access-control list (ACL) of the absolute-format security descriptor. The main body of the absolute-format security descriptor references this pointer.
lpdwDaclSize
Points to a variable specifying the size of the buffer pointed to by the pDacl parameter. If the buffer is not large enough for the ACL, the function fails and sets this variable to the minimum required size.
pSacl
Points to a buffer the function fills with the system ACL of the absolute-format security descriptor. The main body of the absolute-format security descriptor references this pointer.
lpdwSaclSize
Points to a variable specifying the size of the buffer pointed to by the pSacl parameter. If the buffer is not large enough for the ACL, the function fails and sets this variable to the minimum required size.
pOwner
Points to a buffer the function fills with the security identifier (SID) of the owner of the absolute-format security descriptor. The main body of the absolute-format security descriptor references this pointer.
lpdwOwnerSize
Points to a variable specifying the size of the buffer pointed to by the pOwner parameter. If the buffer is not large enough for the SID, the function fails and sets this variable to the minimum required size.
pPrimaryGroup
Points to a buffer the function fills with the SID of the absolute-format security descriptor's primary group. The main body of the absolute-format security descriptor references this pointer.
lpdwPrimaryGroupSize
Points to a variable specifying the size of the buffer pointed to by the pPrimaryGroup parameter. If the buffer is not large enough for the SID, the function fails and sets this variable to the minimum required size.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A security descriptor in absolute format contains pointers to the information it contains, rather than the information itself. A security descriptor in self-relative format contains the information in a contiguous block of memory. In a self-relative security descriptor, a SECURITY_DESCRIPTOR structure always starts the information, but the security descriptor's other components can follow the structure in any order. Instead of using memory addresses, the components of the self-relative security descriptor are identified by offsets from the beginning of the security descriptor. This format is useful when an security descriptor must be stored on a floppy disk or transmitted by means of a communications protocol.

A server that copies secured objects to various media can use the MakeAbsoluteSD function to create an absolute security descriptor from a self-relative security descriptor and the MakeSelfRelativeSD function to create a self-relative security descriptor from an absolute security descriptor.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, MakeSelfRelativeSD, SECURITY_DESCRIPTOR


MakeSelfRelativeSD

The MakeSelfRelativeSD function creates a security descriptor in self-relative format by using a security descriptor in absolute format as a template.

BOOL MakeSelfRelativeSD(
  PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
                             // address of absolute SD
  PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
                             // address self-relative SD
  LPDWORD lpdwBufferLength   // address of SD size
);

Parameters

pAbsoluteSecurityDescriptor
Points to a SECURITY_DESCRIPTOR structure in absolute format. The function creates a version of this security descriptor in self-relative format without modifying the original.
pSelfRelativeSecurityDescriptor
Points to a buffer the function fills with a security descriptor in self-relative format.
lpdwBufferLength
Points to a variable specifying the size of the buffer pointed to by the pSelfRelativeSecurityDescriptor parameter. If the buffer is not large enough for the security descriptor, the function fails and sets this variable to the minimum required size.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A security descriptor in absolute format contains pointers to the information it contains, rather than containing the information itself. A security descriptor in self-relative format contains the information in a contiguous block of memory. In a self-relative security descriptor, a SECURITY_DESCRIPTOR structure always starts the information, but the security descriptor's other components can follow the structure in any order. Instead of using memory addresses, the components of the security descriptor are identified by offsets from the beginning of the security descriptor. This format is useful when an security descriptor must be stored on a floppy disk or transmitted by means of a communications protocol.

A server that copies secured objects to various media can use the MakeSelfRelativeSD function to create a self-relative security descriptor from an absolute security descriptor and the MakeAbsoluteSD function to create an absolute security descriptor from a self-relative security descriptor.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, MakeAbsoluteSD, SECURITY_DESCRIPTOR


QueryServiceObjectSecurity

The QueryServiceObjectSecurity function retrieves a copy of the security descriptor associated with a service object.

BOOL QueryServiceObjectSecurity(
  SC_HANDLE hService,  // handle of service
  SECURITY_INFORMATION dwSecurityInformation,
                       // type of security information requested
  PSECURITY_DESCRIPTOR lpSecurityDescriptor,
                       // address of security descriptor
  DWORD cbBufSize,     // size of security descriptor buffer
  LPDWORD pcbBytesNeeded   // address of variable for bytes needed
);

Parameters

hService
Identifies the service. This handle is returned by the OpenService or CreateService function, and it must have READ_CONTROL access.
dwSecurityInformation
Specifies the security information being requested. Any or all of the following flags can be specified:
Value | Meaning
OWNER_SECURITY_INFORMATION | Requests the object's owner security identifier (SID).
GROUP_SECURITY_INFORMATION | Requests the object's primary group SID.
DACL_SECURITY_INFORMATION | Requests the object's discretionary access control list (ACL).
SACL_SECURITY_INFORMATION | Requests the object's system ACL. The calling process must have the SE_SECURITY_NAME privilege. For more information about privileges, see Privileges.

lpSecurityDescriptor
Points to a buffer that receives a copy of the security descriptor of the specified service object. The calling process must have the appropriate access to view the specified aspects of the object's security descriptor. The SECURITY_DESCRIPTOR structure is returned in self-relative format.
cbBufSize
Specifies the size, in bytes, of the buffer pointed to by the lpSecurityDescriptor parameter.
pcbBytesNeeded
Points to a variable that receives the number of bytes needed to return all the requested security descriptor information, if the function fails.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED | The specified handle was not opened with READ_CONTROL access, or the calling process is not the owner of the object.
ERROR_INVALID_HANDLE | The specified handle is invalid.
ERROR_INSUFFICIENT_BUFFER | There is more security descriptor information than would fit into the lpSecurityDescriptor buffer. The number of bytes required to get all the information is returned in the pcbBytesNeeded parameter. Nothing is written to the lpSecurityDescriptor buffer.
ERROR_INVALID_PARAMETER | The specified security information is invalid.

Remarks

The initial security descriptor of a service object is created by the service control manager, based on the security descriptor specified by the service control program that called the CreateService function to create the service. You can change the security descriptor by calling the SetServiceObjectSecurity function.

To read the owner, group, or DACL from the service object's security descriptor, the calling process must have been granted READ_CONTROL access when the handle was opened. To get READ_CONTROL access, the caller must be the owner of the object or the object's DACL must grant the access.

To read the SACL from the security descriptor, the calling process must have been granted ACCESS_SYSTEM_SECURITY access when the handle was opened. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, CreateService, OpenService, SECURITY_DESCRIPTOR, SetServiceObjectSecurity


RegGetKeySecurity

The RegGetKeySecurity function retrieves a copy of the security descriptor protecting the specified open registry key.

LONG RegGetKeySecurity(
  HKEY hKey,  // open handle of key to set
  SECURITY_INFORMATION SecurityInformation,
              // descriptor contents
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
              // address of descriptor for key
  LPDWORD lpcbSecurityDescriptor
              // address of size of buffer and descriptor
);

Parameters

hKey
Identifies an open key for which to retrieve the security descriptor.
SecurityInformation
Specifies a SECURITY_INFORMATION value that indicates the requested security information.
pSecurityDescriptor
Points to a buffer that receives a copy of the requested security descriptor.
lpcbSecurityDescriptor
Points to a variable that specifies the size, in bytes, of the buffer pointed to by the pSecurityDescriptor parameter. When the function returns, the variable contains the number of bytes written to the buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

If the buffer specified by the pSecurityDescriptor parameter is too small, the function returns ERROR_INSUFFICIENT_BUFFER and the lpcbSecurityDescriptor parameter contains the number of bytes required for the requested security descriptor.

To read the owner, group, or DACL from the key's security descriptor, the calling process must have been granted READ_CONTROL access when the handle was opened. To get READ_CONTROL access, the caller must be the owner of the key or the key's DACL must grant the access.

To read the SACL from the security descriptor, the calling process must have been granted ACCESS_SYSTEM_SECURITY access when the key was opened. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, RegDeleteKey, RegOpenKeyEx, RegSetKeySecurity, SECURITY_INFORMATION


RegSetKeySecurity

The RegSetKeySecurity function sets the security of an open registry key.

LONG RegSetKeySecurity(
  HKEY hKey,  // open handle of key to set
  SECURITY_INFORMATION SecurityInformation,
              // descriptor contents
  PSECURITY_DESCRIPTOR pSecurityDescriptor
              // address of descriptor for key
);

Parameters

hKey
Identifies an open key for which the security descriptor is set.
SecurityInformation
Specifies the components of the security descriptor to set. The value can be a combination of the following flags.
Value Meaning
OWNER_SECURITY_INFORMATION
Sets the key's owner security identifier (SID). The hKey handle must have WRITE_OWNER access, or the calling process must be the object's owner or have the SE_TAKE_OWNERSHIP_NAME privilege enabled.
GROUP_SECURITY_INFORMATION
Sets the key's primary group SID. The hKey handle must have WRITE_OWNER access, or the calling process must be the object's owner.
DACL_SECURITY_INFORMATION
Sets the key's discretionary access control list (DACL). The hKey handle must have WRITE_DAC access, or the calling process must be the object's owner.
SACL_SECURITY_INFORMATION
Sets the key's system access control list (SACL). The hKey handle must have ACCESS_SYSTEM_SECURITY access. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current access token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

pSecurityDescriptor
Points to a SECURITY_DESCRIPTOR structure that specifies the security attributes to set for the specified key.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

If hKey is one of the predefined keys, the predefined key should be closed with RegCloseKey. That ensures that the new security information is in effect the next time the predefined key is referenced.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winreg.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, RegCloseKey, RegDeleteKey, RegGetKeySecurity, SECURITY_INFORMATION


SetAclInformation

The SetAclInformation function sets information about an access-control list (ACL).

BOOL SetAclInformation(
  PACL pAcl,               // address of access-control list
  LPVOID pAclInformation,  // address of ACL information
  DWORD nAclInformationLength,
                           // size of ACL information
  ACL_INFORMATION_CLASS dwAclInformationClass
                           // specifies class of requested info
);

Parameters

pAcl
Points to an ACL structure. The function sets information in this ACL.
pAclInformation
Points to a buffer containing the information to be set. For the current version of Windows NT, this must be an ACL_REVISION_INFORMATION structure.
nAclInformationLength
Specifies the size, in bytes, of the buffer pointed to by the pAclInfo parameter.
dwAclInformationClass
Specifies an ACL_INFORMATION_CLASS enumerated type that gives the class of information requested.

Currently, this parameter can be AclRevisionInformation. This means that the buffer pointed to by the pAclInformation parameter contains an ACL_REVISION_INFORMATION structure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, ACL_INFORMATION_CLASS, ACL_REVISION_INFORMATION, GetAclInformation, InitializeAcl, IsValidAcl


SetFileSecurity

The SetFileSecurity function sets the security of a file or directory object.

BOOL SetFileSecurity(
  LPCTSTR lpFileName,  // address of string for filename
  SECURITY_INFORMATION SecurityInformation,
                       // type of information to set
  PSECURITY_DESCRIPTOR pSecurityDescriptor
                       // address of security descriptor
);

Parameters

lpFileName
Points to a null-terminated string specifying the file or directory for which security is set.
SecurityInformation
Specifies a SECURITY_INFORMATION structure identifying the contents of the security descriptor pointed to by the pSecurityDescriptor parameter.
pSecurityDescriptor
Points to a SECURITY_DESCRIPTOR structure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The SetFileSecurity function is successful only if the following conditions are met:

  • If the object's owner is being set, the calling process must have either WRITE_OWNER permission or be the object's owner.
  • If the object's discretionary access-control list (ACL) is being set, the calling process must have either WRITE_DAC permission or be the object's owner.
  • If the object's system ACL is being set, the SE_SECURITY_NAME privilege must be enabled for the calling process.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetFileSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetKernelObjectSecurity, SetPrivateObjectSecurity, SetUserObjectSecurity


SetKernelObjectSecurity

The SetKernelObjectSecurity function sets the security of a kernel object. For example, this can be a process, thread, or event.

BOOL SetKernelObjectSecurity(
  HANDLE Handle,  // handle of object
  SECURITY_INFORMATION SecurityInformation,
                  // type of information to set
  PSECURITY_DESCRIPTOR SecurityDescriptor
                  // address of security descriptor
);

Parameters

Handle
Identifies a kernel object for which security information is set.
SecurityInformation
Specifies the components of the security descriptor to set. The value can be a combination of the following flags.
Value Meaning
OWNER_SECURITY_INFORMATION
Sets the object's owner security identifier (SID). The Handle handle must have WRITE_OWNER access, or the calling process must be the object's owner or have the SE_TAKE_OWNERSHIP_NAME privilege enabled.
GROUP_SECURITY_INFORMATION
Sets the object's primary group SID. The Handle handle must have WRITE_OWNER access, or the calling process must be the object's owner.
DACL_SECURITY_INFORMATION
Sets the object's discretionary access control list (DACL). The Handle handle must have WRITE_DAC access, or the calling process must be the object's owner.
SACL_SECURITY_INFORMATION
Sets the object's system access control list (SACL). The Handle handle must have ACCESS_SYSTEM_SECURITY access. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current access token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

SecurityDescriptor
Pointer to a SECURITY_DESCRIPTOR structure containing the new security information.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetKernelObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetFileSecurity, SetPrivateObjectSecurity, SetUserObjectSecurity


SetSecurityDescriptorDacl

The SetSecurityDescriptorDacl function sets information in a discretionary access-control list (ACL). If a discretionary ACL is already present in the security descriptor, it is replaced.

BOOL SetSecurityDescriptorDacl(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
                        // address of security descriptor
  BOOL bDaclPresent,    // flag for presence of discretionary ACL
  PACL pDacl,           // address of discretionary ACL
  BOOL bDaclDefaulted   // flag for default discretionary ACL
);

Parameters

pSecurityDescriptor
Points to the SECURITY_DESCRIPTOR structure to which the function adds the discretionary ACL. This security descriptor must be in absolute format, meaning that its members must be pointers to other structures, rather than offsets to contiguous data.
bDaclPresent
Specifies a flag indicating the presence of a discretionary ACL in the security descriptor. If this parameter is TRUE, the function sets the SE_DACL_PRESENT flag in the SECURITY_DESCRIPTOR_CONTROL structure and uses the values in the pDacl and bDaclDefaulted parameters. If it is FALSE, the function clears the SE_DACL_PRESENT flag, and pDacl and bDaclDefaulted are ignored.
pDacl
Points to an ACL structure specifying the discretionary ACL for the security descriptor. If this parameter is NULL, a NULL discretionary ACL is assigned to the security descriptor, allowing all access to the object. The discretionary ACL is referenced by, not copied into, the security descriptor.
bDaclDefaulted
Specifies a flag indicating the source of the discretionary ACL. If this flag is TRUE, the discretionary ACL has been retrieved by some default mechanism. If FALSE, the discretionary ACL has been explicitly specified by a user. The function stores this value in the SE_DACL_DEFAULTED flag of the SECURITY_DESCRIPTOR_CONTROL structure. If this parameter is not specified, the SE_DACL_DEFAULTED flag is cleared.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

There is an important difference between an empty and a nonexistent discretionary ACL. When a discretionary ACL is empty, it contains no access-control entries and no access rights have been explicitly granted. As a result, access to the object is implicitly denied. When an object has no DACL, on the other hand, no protection is assigned to the object, and any access request is granted.

There are three possible outcomes in different configurations of the bDaclPresent flag and the pDacl parameter:

  • When the pDacl parameter points to a discretionary ACL and the bDaclPresent flag is TRUE, a discretionary ACL is specified and it must contain access-allowed ACEs to allow access to the object.
  • When the pDacl parameter does not point to a discretionary ACL and the bDaclPresent flag is TRUE, a NULL discretionary ACL is specified. All access is allowed.
  • When the pDacl parameter does not point to a discretionary ACL and the bDaclPresent flag is FALSE, a discretionary ACL can be provided for the object through an inheritance or default mechanism.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, GetSecurityDescriptorDacl, InitializeSecurityDescriptor, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorGroup, SetSecurityDescriptorOwner, SetSecurityDescriptorSacl


SetSecurityDescriptorGroup

The SetSecurityDescriptorGroup function sets the primary group information of an absolute-format security descriptor, replacing any primary group information already present in the security descriptor.

BOOL SetSecurityDescriptorGroup(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
                         // address of security descriptor
  PSID pGroup,           // address of SID for group
  BOOL bGroupDefaulted   // flag for default
);

Parameters

pSecurityDescriptor
Points to the SECURITY_DESCRIPTOR structure whose primary group is set by this function. The function replaces any existing primary group with the new primary group.
pGroup
Points to a SID structure the function sets as the security descriptor's new primary group. The SID structure is referenced by, not copied into, the security descriptor. If this parameter is NULL, the function clears the security descriptor's primary group information. This marks the security descriptor as having no primary group.
bGroupDefaulted
Specifies a flag indicating whether the primary group information was derived from a default mechanism. If this flag is TRUE, it is default information, and the function stores this value as the SE_GROUP_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure. If this parameter is zero, the SE_GROUP_DEFAULTED flag is cleared.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetSecurityDescriptorGroup, InitializeSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorDacl, SetSecurityDescriptorOwner, SetSecurityDescriptorSacl, SID


SetSecurityDescriptorOwner

The SetSecurityDescriptorOwner function sets the owner information of an absolute-format security descriptor. It replaces any owner information already present in the security descriptor.

BOOL SetSecurityDescriptorOwner(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
                         // address of security descriptor
  PSID pOwner,           // address of SID for owner
  BOOL bOwnerDefaulted   // flag for default
);

Parameters

pSecurityDescriptor
Points to the SECURITY_DESCRIPTOR structure whose owner is set by this function. The function replaces any existing owner with the new owner.
pOwner
Points to a SID structure the function sets as the security descriptor's new primary owner. The SID structure is referenced by, not copied into, the security descriptor. If this parameter is NULL, the function clears the security descriptor's owner information. This marks the security descriptor as having no owner.
bOwnerDefaulted
Specifies a flag indicating whether the owner information is derived from a default mechanism. If this flag is TRUE, it is default information. The function stores this value as the SE_OWNER_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure. If this parameter is zero, the SE_OWNER_DEFAULTED flag is cleared.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetSecurityDescriptorOwner, InitializeSecurityDescriptor, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorDacl, SetSecurityDescriptorGroup, SetSecurityDescriptorSacl, SID


SetSecurityDescriptorSacl

The SetSecurityDescriptorSacl function sets information in a system access-control list (ACL). If there is already a system ACL present in the security descriptor, it is replaced.

BOOL SetSecurityDescriptorSacl(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
                        // address of security descriptor
  BOOL bSaclPresent,    // flag for presence of system ACL
  PACL pSacl,           // address of system ACL
  BOOL bSaclDefaulted   // flag for default system ACL
);

Parameters

pSecurityDescriptor
Points to the SECURITY_DESCRIPTOR structure to which the function adds the system ACL. This security descriptor must be in absolute format, meaning that its members must be pointers to other structures, rather than offsets to contiguous data.
bSaclPresent
Specifies a flag indicating the presence of a system ACL in the security descriptor. If this parameter is TRUE, the function sets the SE_SACL_PRESENT flag in the SECURITY_DESCRIPTOR_CONTROL structure and uses the values in the pSacl and bSaclDefaulted parameters. If it is FALSE, the function does not set the SE_SACL_PRESENT flag, and pSacl and bSaclDefaulted are ignored.
pSacl
Points to an ACL structure that specifies the system ACL for the security descriptor. If this parameter is NULL, a NULL system ACL is assigned to the security descriptor. The system ACL is referenced by, not copied into, the security descriptor.
bSaclDefaulted
Specifies a flag indicating the source of the system ACL. If this flag is TRUE, the system ACL has been retrieved by some default mechanism. If it is FALSE, the system ACL has been explicitly specified by a user. The function stores this value in the SE_SACL_DEFAULTED flag of the SECURITY_DESCRIPTOR_CONTROL structure. If this parameter is not specified, the SE_SACL_DEFAULTED flag is cleared.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, GetSecurityDescriptorSacl, InitializeSecurityDescriptor, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorDacl, SetSecurityDescriptorGroup, SetSecurityDescriptorOwner


SetServiceObjectSecurity

The SetServiceObjectSecurity function sets the security descriptor of a service object.

BOOL SetServiceObjectSecurity(
  SC_HANDLE hService,  // handle of service
  SECURITY_INFORMATION dwSecurityInformation,
                       // type of security information requested
  PSECURITY_DESCRIPTOR lpSecurityDescriptor
                       // address of security descriptor
);

Parameters

hService
Identifies the service. This handle is returned by the OpenService or CreateService function. The access required for this handle depends on the security information specified in the dwSecurityInformation parameter.
dwSecurityInformation
Specifies the components of the security descriptor to set. The value can be a combination of the following flags.
Value Meaning
OWNER_SECURITY_INFORMATION
Sets the object's owner security identifier (SID). The hService handle must have WRITE_OWNER access, or the calling process must be the object's owner or have the SE_TAKE_OWNERSHIP_NAME privilege enabled.
GROUP_SECURITY_INFORMATION
Sets the object's primary group SID. The hService handle must have WRITE_OWNER access, or the calling process must be the object's owner.
DACL_SECURITY_INFORMATION
Sets the object's discretionary access control list (DACL). The hService handle must have WRITE_DAC access, or the calling process must be the object's owner.
SACL_SECURITY_INFORMATION
Sets the object's system access control list (SACL). The hService handle must have ACCESS_SYSTEM_SECURITY access. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current access token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

lpSecurityDescriptor
Points to a SECURITY_DESCRIPTOR structure containing the new security information.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED
 | The specified handle was not opened with the required access, or the calling process is not the owner of the object.
ERROR_INVALID_HANDLE
 | The specified handle is invalid.
ERROR_INVALID_PARAMETER
 | The specified security information or security descriptor is invalid.
ERROR_SERVICE_MARKED_FOR_DELETE
 | The specified service has been marked for deletion.

Remarks

The SetServiceObjectSecurity function sets the specified portions of the service object's security descriptor, based on the information specified in the lpSecurityDescriptor buffer. This function replaces any or all of the security information associated with the service object, according to the flags set in the dwSecurityInformation parameter and subject to the calling process's access rights.

The initial security descriptor of a service object is created by the service control manager, based on the security descriptor of the process that called the CreateService function to create the service. You can change the security descriptor by calling the SetServiceObjectSecurity function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winsvc.h.
Import Library: Use advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, CreateService, OpenService, QueryServiceObjectSecurity, SECURITY_DESCRIPTOR


SetUserObjectSecurity

The SetUserObjectSecurity function sets the security of a user object. This can be, for example, a window or a DDE conversation.

BOOL SetUserObjectSecurity(
  HANDLE hObj,                // handle of user object
  PSECURITY_INFORMATION pSIRequested,
                              // address of security information
  PSECURITY_DESCRIPTOR pSD    // address of security descriptor
);

Parameters

hObj
Identifies a user object for which security information is set.
pSIRequested
Pointer to a value that indicates the components of the security descriptor to set. The value can be a combination of the following flags.
Value Meaning
OWNER_SECURITY_INFORMATION
Sets the object's owner security identifier (SID). The hObj handle must have WRITE_OWNER access, or the calling process must be the object's owner or have the SE_TAKE_OWNERSHIP_NAME privilege enabled.
GROUP_SECURITY_INFORMATION
Sets the object's primary group SID. The hObj handle must have WRITE_OWNER access, or the calling process must be the object's owner.
DACL_SECURITY_INFORMATION
Sets the object's discretionary access control list (DACL). The hObj handle must have WRITE_DAC access, or the calling process must be the object's owner.
SACL_SECURITY_INFORMATION
Sets the object's system access control list (SACL). The hObj handle must have ACCESS_SYSTEM_SECURITY access. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current access token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

pSD
Pointer to a SECURITY_DESCRIPTOR structure containing the new security information.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The SetUserObjectSecurity function applies changes specified in a security descriptor to the security descriptor assigned to a user object. The object's security descriptor must be in self-relative form. If necessary, this function allocates additional memory to increase the size of the security descriptor.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetUserObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetFileSecurity, SetKernelObjectSecurity, SetPrivateObjectSecurity


Low-Level Access Control Structures

The following structures are used with low-level access control.

ACCESS_ALLOWED_ACE
ACCESS_DENIED_ACE
ACCESS_ALLOWED_OBJECT_ACE
ACCESS_DENIED_OBJECT_ACE
ACL_REVISION_INFORMATION
ACL_SIZE_INFORMATION
SECURITY_DESCRIPTOR_CONTROL
SYSTEM_AUDIT_ACE
SYSTEM_AUDIT_OBJECT_ACE

The following structures are reserved for future use.

SYSTEM_ALARM_ACE
SYSTEM_ALARM_OBJECT_ACE


ACCESS_ALLOWED_ACE

The ACCESS_ALLOWED_ACE structure defines an access-control entry (ACE) for the discretionary access-control list (ACL) that controls access to an object. An access-allowed ACE allows access to an object for a specific subject identified by a security identifier (SID).

typedef struct _ACCESS_ALLOWED_ACE { // aaace
    ACE_HEADER Header;
    ACCESS_MASK Mask;
    DWORD SidStart;
} ACCESS_ALLOWED_ACE;

Members

Header
Specifies an ACE_HEADER structure.
Mask
Specifies an ACCESS_MASK structure that specifies the access rights granted by this ACE.
SidStart
Specifies a SID. The access rights specified by the Mask member are granted to any subject possessing an enabled SID matching this member.

Remarks

ACE structures must be aligned on DWORD boundaries. All Win32 memory-management functions return DWORD-aligned handles to memory.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, AddAccessAllowedAce, AddAce, GetAce, ACCESS_DENIED_ACE, ACCESS_MASK, ACE_HEADER, ACL, SID, SYSTEM_ALARM_ACE, SYSTEM_AUDIT_ACE


ACCESS_DENIED_ACE

The ACCESS_DENIED_ACE structure defines an access-control entry (ACE) for the discretionary access-control list (ACL) controlling access to an object. An access-denied ACE denies access to an object for a specific subject identified by a security identifier (SID).

typedef struct _ACCESS_DENIED_ACE { // adace
    ACE_HEADER Header;
    ACCESS_MASK Mask;
    DWORD SidStart;
} ACCESS_DENIED_ACE;

Members

Header
Specifies an ACE_HEADER structure.
Mask
Specifies an ACCESS_MASK structure specifying the access rights explicitly denied by this ACE.
SidStart
Specifies a SID. The access rights specified by the Mask member are denied to any subject possessing an enabled SID matching this member.

Remarks

ACE structures must be aligned on doubleword boundaries. All Win32 memory-management functions return doubleword-aligned handles to memory.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, AddAccessDeniedAce, ACCESS_ALLOWED_ACE, ACCESS_MASK, ACE_HEADER, ACL, SID, SYSTEM_ALARM_ACE, SYSTEM_AUDIT_ACE


ACCESS_ALLOWED_OBJECT_ACE

[This is preliminary documentation and subject to change.]

The ACCESS_ALLOWED_OBJECT_ACE structure defines an access-control entry (ACE). The ACE can control access to an object, or to a subobject of an object, such as a property set or property. The ACE contains a set of access rights, a GUID that identifies the type of object or subobject, and a SID that identifies the trustee to whom the system will grant access. The ACE also contains a GUID and a set of flags that control inheritance of the ACE by child objects.

typedef struct _ACCESS_ALLOWED_OBJECT_ACE {
    ACE_HEADER Header;
    ACCESS_MASK Mask;
    DWORD Flags;
    GUID ObjectType;
    GUID InheritedObjectType;
    DWORD SidStart;
} ACCESS_ALLOWED_OBJECT_ACE, *PACCESS_ALLOWED_OBJECT_ACE;

Members

Header
An ACE_HEADER structure that specifies the size and type of ACE. It also contains flags that control inheritance of the ACE by child objects.
Mask
An ACCESS_MASK that specifies the access rights the system will allow to the trustee. This mask must use the Windows NT access mask format, not the provider-independent access-mask format.
Flags
A set of bit flags that indicate whether the ObjectType and InheritedObjectType members contain GUIDs. This parameter can be a combination of the following values. Set all undefined bits to zero.
Value Meaning
ACE_OBJECT_TYPE_PRESENT
The ObjectType member contains a GUID.
ACE_INHERITED_OBJECT_TYPE_PRESENT
The InheritedObjectType member contains a GUID.

ObjectType
A GUID structure that identifies the type of object, property set, or property protected by the ACE. If this ACE is inherited, the GUID identifies the type of object, property set, or property protected by the inherited ACE.

If the ACE_OBJECT_TYPE_PRESENT bit is not set in the Flags member, the ObjectType member is ignored, and the ACE protects the object to which the ACL is assigned.

InheritedObjectType
A GUID structure that identifies the type of object that can inherit the ACE.

If the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is not set in the Flags member, the InheritedObjectType member is ignored, and all types of child objects can inherit the ACE. Otherwise, only the specified object type can inherit the ACE. In either case, inheritance is also controlled by the inheritance flags in the ACE_HEADER, as well as by any protection against inheritance placed on the child objects.

SidStart
Specifies the first DWORD of a SID that identifies the trustee to whom the access rights are granted.

Remarks

If neither the ObjectType nor InheritedObjectType GUID is specified, the ACCESS_ALLOWED_OBJECT_ACE structure has the same semantics as those used by the ACCESS_ALLOWED_ACE structure. In that case, use the ACCESS_ALLOWED_ACE structure because it is smaller and more efficient.

An ACL that contains an ACCESS_ALLOWED_OBJECT_ACE must specify the ACL_REVISION_DS revision number in its ACE_HEADER structure.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, ACCESS_ALLOWED_ACE, ACCESS_DENIED_OBJECT_ACE, ACCESS_MASK, ACE_HEADER, ACL, AddAccessAllowedObjectAce, GUID, SID, SYSTEM_AUDIT_OBJECT_ACE


ACCESS_DENIED_OBJECT_ACE

[This is preliminary documentation and subject to change.]

The ACCESS_DENIED_OBJECT_ACE structure defines an access-control entry (ACE). The ACE can control access to an object, or to a subobject of an object, such as a property set or property. The ACE contains a set of access rights, a GUID that identifies the type of object or subobject, and a SID that identifies the trustee to whom the system will deny access. The ACE also contains a GUID and a set of flags that control inheritance of the ACE by child objects.

typedef struct _ACCESS_DENIED_OBJECT_ACE {
    ACE_HEADER Header;
    ACCESS_MASK Mask;
    DWORD Flags;
    GUID ObjectType;
    GUID InheritedObjectType;
    DWORD SidStart;
} ACCESS_DENIED_OBJECT_ACE, *PACCESS_DENIED_OBJECT_ACE;

Members

Header
An ACE_HEADER structure that specifies the size and type of ACE. It contains flags that control inheritance of the ACE by child objects.
Mask
An ACCESS_MASK that specifies the access rights the system will deny to the trustee. This mask must use the Windows NT access mask format, not the provider-independent access-mask format.
Flags
A set of bit flags that indicate whether the ObjectType and InheritedObjectType members contain GUIDs. This parameter can be a combination of the following values. Set all undefined bits to zero.
Value Meaning
ACE_OBJECT_TYPE_PRESENT
The ObjectType member contains a GUID.
ACE_INHERITED_OBJECT_TYPE_PRESENT
The InheritedObjectType member contains a GUID.

ObjectType
A GUID structure that identifies the type of object, property set, or property protected by the ACE. If this ACE is inherited, the GUID identifies the type of object, property set, or property protected by the inherited ACE.

If the ACE_OBJECT_TYPE_PRESENT bit is not set in the Flags member, the ObjectType member is ignored and the ACE protects the object to which the ACL is assigned.

InheritedObjectType
A GUID structure that identifies the type of object that can inherit the ACE.

If the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is not set in the Flags member, the InheritedObjectType member is ignored and all types of child objects can inherit the ACE. Otherwise, only the specified object type can inherit the ACE. In either case, inheritance is also controlled by the inheritance flags in the ACE_HEADER, as well as by any protection against inheritance placed on the child objects.

SidStart
Specifies the first DWORD of a SID that identifies the trustee for whom the access rights are denied.

Remarks

If neither the ObjectType nor InheritedObjectType GUID is specified, the ACCESS_DENIED_OBJECT_ACE structure has the same semantics as those used by the ACCESS_DENIED_ACE structure. In that case, use the ACCESS_DENIED_ACE structure because it is smaller and more efficient.

An ACL that contains an ACCESS_DENIED_OBJECT_ACE must specify the ACL_REVISION_DS revision number in its ACE_HEADER structure.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, ACCESS_ALLOWED_OBJECT_ACE, ACCESS_DENIED_ACE, ACCESS_MASK, ACE_HEADER, ACL, AddAccessAllowedObjectAce, GUID, SID, SYSTEM_AUDIT_OBJECT_ACE


ACL_REVISION_INFORMATION

The ACL_REVISION_INFORMATION structure contains revision information about an ACL structure.

typedef struct _ACL_REVISION_INFORMATION {
    DWORD   AclRevision;
} ACL_REVISION_INFORMATION;

Members

AclRevision
Specifies a revision number. The current revision number is ACL_REVISION.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, GetAclInformation, SetAclInformation, ACL, ACL_INFORMATION_CLASS, ACL_SIZE_INFORMATION


ACL_SIZE_INFORMATION

The ACL_SIZE_INFORMATION structure contains information about the size of an ACL structure.

typedef struct _ACL_SIZE_INFORMATION {
    DWORD   AceCount;
    DWORD   AclBytesInUse;
    DWORD   AclBytesFree;
} ACL_SIZE_INFORMATION;

Members

AceCount
Specifies the number of access-control entries (ACEs) in the access-control list (ACL).
AclBytesInUse
Specifies the number of bytes in the ACL actually used to store the ACEs and ACL structure. This may be less than the total number of bytes allocated to the ACL.
AclBytesFree
Specifies the number of unused bytes in the ACL.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, GetAclInformation, SetAclInformation, ACL, ACL_INFORMATION_CLASS, ACL_REVISION_INFORMATION


SECURITY_DESCRIPTOR_CONTROL

The SECURITY_DESCRIPTOR_CONTROL type is a set of bit flags that qualify the meaning of a security descriptor or its components. Each security descriptor has a Control member that stores the SECURITY_DESCRIPTOR_CONTROL bits.

typedef WORD SECURITY_DESCRIPTOR_CONTROL;

Remarks

To get the control bits of a security descriptor, call the GetSecurityDescriptorControl function. To set the control bits of a security descriptor, use the Win32 functions for modifying security descriptors. These functions are listed in the See Also section.

For Windows NT versions 5.0 and later, applications can use the SetSecurityDescriptorControl function to set the control bits that relate to automatic inheritance of ACEs.

The control value retrieved by the GetSecurityDescriptorControl function can include a combination of the following SECURITY_DESCRIPTOR_CONTROL bit flags:

Value | Meaning
SE_DACL_AUTO_INHERITED Windows NT 5.0 and later: Indicates a security descriptor in which the DACL is set up to support automatic propagation of inheritable ACEs to existing child objects.

The system sets this bit when it performs the automatic inheritance algorithm for the object and its existing child objects. Protected servers can call the ConvertToAutoInheritPrivateObjectSecurity function to convert a security descriptor and set this flag.

This bit is not set in security descriptors for Windows NT versions 4.0 and earlier, which do not support automatic propagation of inheritable ACEs.
SE_DACL_DEFAULTED Indicates a security descriptor with a default DACL. For example, if an object's creator does not specify a DACL, the object receives the default DACL from the creator's access token. This flag can affect how the system treats the DACL, with respect to ACE inheritance. The system ignores this flag if the SE_DACL_PRESENT flag is not set.

To set this flag, use the SetSecurityDescriptorDacl function.
SE_DACL_PRESENT Indicates a security descriptor that has a DACL. If this flag is not set, or if this flag is set and the DACL is NULL, the security descriptor allows full access to everyone.

To set this flag, use SetSecurityDescriptorDacl.

SE_DACL_PROTECTED | Windows NT 5.0 and later: Prevents the DACL of the security descriptor from being modified by inheritable ACEs. To set this flag, use the SetSecurityDescriptorControl function.
SE_GROUP_DEFAULTED | A default mechanism, rather than the the original provider of the security descriptor, provided the security descriptor's group SID. To set this flag, use the SetSecurityDescriptorGroup function.
SE_OWNER_DEFAULTED | A default mechanism, rather than the the original provider of the security descriptor, provided the security descriptor's owner security identifier (SID). To set this flag, use the SetSecurityDescriptorOwner function.
SE_SACL_AUTO_INHERITED Windows NT 5.0 and later: Indicates a security descriptor in which the SACL is set up to support automatic propagation of inheritable ACEs to existing child objects.

The system sets this bit when it performs the automatic inheritance algorithm for the object and its existing child objects. Protected servers can call the ConvertToAutoInheritPrivateObjectSecurity function to convert a security descriptor and set this flag.

This bit is not set in security descriptors for Windows NT versions 4.0 and earlier, which do not support automatic propagation of inheritable ACEs.
SE_SACL_DEFAULTED | A default mechanism, rather than the the original provider of the security descriptor, provided the SACL. This flag can affect how the system treats the SACL, with respect to ACE inheritance. The system ignores this flag if the SE_SACL_PRESENT flag is not set. To set this flag, use the SetSecurityDescriptorSacl function.
SE_SACL_PRESENT | Indicates a security descriptor that has a SACL. To set this flag, use the SetSecurityDescriptorSacl function.
SE_SACL_PROTECTED | Windows NT 5.0 and later: Prevents the SACL of the security descriptor from being modified by inheritable ACEs. To set this flag, use the SetSecurityDescriptorControl function.
SE_SELF_RELATIVE | Indicates a security descriptor in self-relative format with all the security information in a contiguous block of memory. If this flag is not set, the security descriptor is in absolute format. For more information, see Absolute and Self-Relative Security Descriptors.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, ConvertToAutoInheritPrivateObjectSecurity, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, SetSecurityDescriptorControl, SetSecurityDescriptorDacl, SetSecurityDescriptorGroup, SetSecurityDescriptorOwner, SetSecurityDescriptorSacl


SYSTEM_ALARM_ACE

Reserved for future use.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures


SYSTEM_ALARM_OBJECT_ACE

Reserved for future use.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures


SYSTEM_AUDIT_ACE

The SYSTEM_AUDIT_ACE structure defines an access-control entry (ACE) for the system access-control list (ACL) specifying what types of access cause system-level notifications. A system-audit ACE causes an audit message to be logged when a specified user or group attempts to gain access to an object. The user or group is identified by a security identifier (SID).

typedef struct _SYSTEM_AUDIT_ACE { // sada
    ACE_HEADER  Header;
    ACCESS_MASK Mask;
    DWORD       SidStart;
} SYSTEM_AUDIT_ACE;

Members

Header
Specifies an ACE_HEADER structure.
Mask
Specifies an ACCESS_MASK structure that gives the access rights causing audit messages to be generated. The SUCCESSFUL_ACCESS_ACE_FLAG and FAILED_ACCESS_ACE_FLAG flags in the AceFlags member of the ACE_HEADER structure indicate whether messages are generated for successful access attempts, unsuccessful access attempts, or both.
SidStart
Specifies a SID. An access attempt of a kind specified by the Mask member by any user or group whose SID matches the SidStart member causes the system to generate an audit message. If an application does not specify a SID for this member, audit messages are generated for the specified access rights for all users and groups.

Remarks

Audit messages are stored in an event log that can be manipulated by using the Win32 API event-logging functions or by using Windows NT Event Viewer (EVENTVWR.EXE).

ACE structures should be aligned on doubleword boundaries. All Win32 memory-management functions return doubleword-aligned handles to memory.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, ACCESS_MASK, ACE_HEADER, ACL, SYSTEM_ALARM_ACE


SYSTEM_AUDIT_OBJECT_ACE

[This is preliminary documentation and subject to change.]

The SYSTEM_AUDIT_OBJECT_ACE structure defines an access-control entry (ACE) for a SACL. The ACE can audit access to an object, or to a subobject of an object, such as a property set or property. The ACE contains a set of access rights, a GUID that identifies the type of object or subobject, and a SID that identifies the trustee for whom the system will audit access. The ACE also contains a GUID and a set of flags that control inheritance of the ACE by child objects.

typedef struct _SYSTEM_ALARM_OBJECT_ACE {
    ACE_HEADER Header;
    ACCESS_MASK Mask;
    DWORD Flags;
    GUID ObjectType;
    GUID InheritedObjectType;
    DWORD SidStart;
} SYSTEM_ALARM_OBJECT_ACE, *PSYSTEM_ALARM_OBJECT_ACE;

Members

Header
An ACE_HEADER structure that specifies the size and type of ACE. It contains flags that control inheritance of the ACE by child objects. The structure also contains flags that indicate whether the ACE audits successful access attempts, failed access attempts, or both.
Mask
An ACCESS_MASK that specifies the access rights the system will audit for access attempts by the trustee. This mask must use the Windows NT access mask format, not the provider-independent access-mask format.
Flags
A set of bit flags that indicate whether the ObjectType and InheritedObjectType members contain GUIDs. This parameter can be a combination of the following values. Set all undefined bits to zero.
Value Meaning
ACE_OBJECT_TYPE_PRESENT
The ObjectType member contains a GUID.
ACE_INHERITED_OBJECT_TYPE_PRESENT
The InheritedObjectType member contains a GUID.

ObjectType
A GUID structure that identifies the type of object, property set, or property protected by the ACE. If this ACE is inherited, the GUID identifies the type of object, property set, or property protected by the inherited ACE.

If the ACE_OBJECT_TYPE_PRESENT bit is not set in the Flags member, the ObjectType member is ignored, and the ACE protects the object to which the ACL is assigned.

InheritedObjectType
A GUID structure that identifies the type of object that can inherit the ACE.

If the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is not set in the Flags member, the InheritedObjectType member is ignored, and all types of child objects can inherit the ACE. Otherwise, only the specified object type can inherit the ACE. In either case, inheritance is also controlled by the inheritance flags in the ACE_HEADER, as well as by any protection against inheritance placed on the child objects.

SidStart
Specifies the first DWORD of a SID that identifies the trustee for whom the access attempts are audited.

Remarks

If neither the ObjectType nor InheritedObjectType GUID is specified, the SYSTEM_AUDIT_OBJECT_ACE structure has the same semantics as the SYSTEM_AUDIT_ACE structure. In that case, use the SYSTEM_AUDIT_ACE structure because it is smaller and more efficient.

An ACL that contains an SYSTEM_AUDIT_OBJECT_ACE must specify the ACL_REVISION_DS revision number in its ACE_HEADER structure.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winnt.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, ACCESS_ALLOWED_OBJECT_ACE, ACCESS_DENIED_OBJECT_ACE, ACCESS_MASK, ACE_HEADER, ACL, AddAuditAccessObjectAce, GUID, SID, SYSTEM_AUDIT_ACE


Windows NT 4.0 Access Control

This overview describes the Microsoft® Windows NT® version 4.0 access-control functions for working with security descriptors and access-control lists (ACLs). These functions are also supported on later versions of Windows NT.

The Windows NT 4.0 access-control functions are one of three sets of Microsoft® Win32® access-control functions. For information about when to use each set of functions, see Access-Control Reference.


About Windows NT 4.0 Access Control

This overview describes the Windows NT version 4.0 security functions for working with security descriptors and access-control lists (ACLs).

The access control model is basically the same for all versions of Windows NT. For a description of the model, see Access-Control Model.


Windows NT 4.0 Security Descriptor Functions

Windows NT versions 4.0 and later supports a set of functions for getting and setting the components of the security descriptor associated with a securable object. Use the GetSecurityInfo and SetSecurityInfo functions with objects identified by a handle. Use the GetNamedSecurityInfo and SetNamedSecurityInfo functions with objects identified by a name.

These functions use the Windows NT access rights rather than the provider-independent access rights. Consequently, you cannot use these functions to manipulate the security information of objects created by operating systems other than Windows NT.

The SetSecurityInfo and SetNamedSecurityInfo functions can set any combination of the DACL, SACL, owner SID, and group SID in an object's security descriptor. The GetSecurityInfo and GetNamedSecurityInfo functions retrieve a pointer to the security descriptor of a specified object. You can also use these functions to get pointers to the SIDs and ACLs in the security descriptor.

The GetSecurityInfo and SetSecurityInfo functions use handles to identify objects. You can use these functions with the following types of objects:

  • Local or remote files or directories on an NTFS file system
  • Mailslots and named pipes
  • Local or remote printers
  • Local or remote Win32 services
  • Windows NT network shares
  • Registry keys
  • Semaphores, events, mutexes, and waitable timers
  • Processes, threads, file-mapping objects
  • Window stations and desktops

The GetNamedSecurityInfo and SetNamedSecurityInfo functions use names to identify objects. You can use these functions with the following types of objects:

  • Local or remote files or directories on an NTFS file system
  • Local or remote printers
  • Local or remote Win32 services
  • Windows NT network shares
  • Registry keys
  • Semaphores, events, mutexes, and waitable timers
  • File-mapping objects


Windows NT 4.0 Security Descriptor Creation

Windows NT versions 4.0 and later support a set of functions for building a security descriptor. Applications designed for Windows NT version 5.0 and later should use the functions described in Creating a Security Descriptor for a New Object.

The BuildSecurityDescriptor function allocates and initializes a new self-relative security descriptor. BuildSecurityDescriptor uses the EXPLICIT_ACCESS structure to specify information for the DACL and SACL; and it uses the TRUSTEE structure to specify the owner and primary group. BuildSecurityDescriptor can initialize the new security descriptor solely from the specified security information; or it can merge the specified security information with the information in an existing self-relative security descriptor.

The LookupSecurityDescriptorParts function retrieves information from an existing self-relative security descriptor. Like BuildSecurityDescriptor, the LookupSecurityDescriptorParts function uses the TRUSTEE and EXPLICIT_ACCESS structures. This makes it easy to call LookupSecurityDescriptorParts to extract security information from one security descriptor, and then call BuildSecurityDescriptor to use the extracted information in building another security descriptor.


Windows NT 4.0 ACL and ACE Functions

Windows NT versions 4.0 and later support a set of functions for creating an access-control list (ACL) or for modifying the access-control entries (ACEs) in an existing ACL. Applications designed for Windows NT version 5.0 and later should use the functions described in Modifying an Object's ACLs.

The SetEntriesInAcl function creates a new ACL. SetEntriesInAcl can specify a completely new set of ACEs for the ACL, or it can merge new ACEs with the ACEs of an existing ACL. SetEntriesInAcl uses an array of EXPLICIT_ACCESS structures to specify the information for the new ACEs. Each EXPLICIT_ACCESS structure contains information that describes a single ACE. This information includes the access rights, the type of ACE, the flags that control ACE inheritance, and a TRUSTEE structure that identifies the trustee.

To add a new ACE to an existing ACL
  1. Use the GetSecurityInfo or GetNamedSecurityInfo function to get the existing DACL or SACL from an object's security descriptor.
  2. Use the BuildExplicitAccessWithName function to fill EXPLICIT_ACCESS structures with the information needed to describe each new ACE.
  3. Call SetEntriesInAcl, specifying the existing ACL and the array of EXPLICIT_ACCESS structures. SetEntriesInAcl allocates and initializes the ACL and its ACEs.
  4. Call the SetSecurityInfo or SetNamedSecurityInfo function to attach the new ACL to the object's security descriptor.

For an example that uses the Windows NT 4.0 functions to merge a new ACE into an existing ACL, see Using Windows NT 4.0 Access Control.

If the caller specifies an existing ACL, SetEntriesInAcl merges the new ACE information with the existing ACEs in the ACL. Consider the case, for example, in which the existing ACL grants access to a specified trustee and an EXPLICIT_ACCESS structure denies access to the same trustee. In this case, SetEntriesInAcl adds a new access-denied ACE for the trustee and deletes or modifies the existing access-allowed ACE for the trustee.


Getting Information From an ACL

Windows NT versions 4.0 and later provide several functions for retrieving access-control information from an ACL. These include functions for determining the access rights that an ACL grants or audits for a specified trustee. Other functions enable you to extract ACE information from an ACL.

The GetEffectiveRightsFromAcl function enables you to determine the effective access rights that a DACL grants to a specified trustee. The trustee's effective access rights are the access rights that the ACL grants to the trustee or to any groups of which the trustee is a member. GetEffectiveRightsFromAcl checks all access-allowed and access-denied ACEs in the ACL to determine the effective rights for the trustee.

The GetAuditedPermissionsFromAcl function enables you to check a SACL to determine the audited access rights for a specified trustee or for any groups of which the trustee is a member. The audited rights indicate the types of access attempts that cause the system to generate an audit record in the security event log. The function returns two access masks: one containing the access rights monitored for failed access attempts, and another containing the access rights monitored for successful access. GetAuditedPermissionsFromAcl checks all system-audit ACEs in the ACL.

The GetExplicitEntriesFromAcl function retrieves an array of EXPLICIT_ACCESS structures that describe the ACEs in an ACL. This can be useful when you are copying ACE information from one ACL to another. For example, you can call GetExplicitEntriesFromAcl to get information about the ACEs in one ACL. Then pass the returned EXPLICIT_ACCESS structures in a call to the SetEntriesInAcl function to create equivalent ACEs in the new ACL.


Using Windows NT 4.0 Access Control

Following are some common tasks for the Windows NT 4.0 access-control functions:

  • Denying Access Using Windows NT 4.0 Functions
  • Allowing Access Using Windows NT 4.0 Functions


Denying Access Using Windows NT 4.0 Functions

These examples use the SetEntriesInAcl function to create an ACL. Then they use the SetNamedSecurityInfo function to attach the ACL as the DACL of an object. Note that these examples can work with a variety of named securable objects, such as files, registry keys, and synchronization objects.

The first example shows how to add an empty DACL to an object's security descriptor. The effect is to deny all access to the object.

DWORD SetEmptyDACL(LPTSTR lpObjectName, SE_OBJECT_TYPE ObjectType)
{
DWORD dwRes;
PACL pDacl;

if (NULL == lpObjectName)
    return ERROR_INVALID_PARAMETER;

// create an ACL with no ACEs

dwRes = SetEntriesInAcl(0, NULL, NULL, &pDacl);
if (ERROR_SUCCESS != dwRes)
    return dwRes;

// attach the emtpy ACL as the object's DACL

dwRes = SetNamedSecurityInfo(lpObjectName, ObjectType,
      DACL_SECURITY_INFORMATION,
      NULL, NULL, pDacl, NULL);

// free the buffer returned by SetEntriesInAcl

LocalFree(pDacl);

return dwRes;
}

You can modify this example to deny access to a specified trustee. The following variation uses the BuildExplicitAccessWithName function to initialize an EXPLICIT_ACCESS structure with the data for an access-denied ACE. Then it uses the SetEntriesInAcl and SetNamedSecurityInfo functions to create the ACL and attach it to the object.

#include <aclapi.h>

DWORD dwRes;
PACL pDacl;
EXPLICIT_ACCESS ea;

// initialize an EXPLICIT_ACCESS structure to deny access

ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
BuildExplicitAccessWithName(&ea,
    "ludwig",          // name of trustee
    GENERIC_ALL,       // type of access
    DENY_ACCESS,       // access mode
    NO_INHERITANCE);   // inheritance mode

// create an ACL with one access-denied ACE

dwRes = SetEntriesInAcl(1, &ea, NULL, &pDacl);
if (ERROR_SUCCESS != dwRes)
    return dwRes;

// attach the ACL as the object's DACL

dwRes = SetNamedSecurityInfo(TEXT("myfile"), SE_FILE_OBJECT,
      DACL_SECURITY_INFORMATION,
      NULL, NULL, pDacl, NULL);

// free the buffer returned by SetEntriesInAcl

LocalFree(pDacl);


Allowing Access Using Windows NT 4.0 Functions

This example adds an access-allowed ACE to the DACL of an object. The example uses the GetNamedSecurityInfo function to get the existing DACL. Then it uses the BuildExplicitAccessWithName and SetEntriesInAcl functions to merge a new ACE with any existing ACEs in the DACL. Finally, the example calls the SetNamedSecurityInfo function to attach the new DACL to the object's security descriptor.

DWORD AddAceToAcl (LPTSTR lpObjectName, SE_OBJECT_TYPE ObjectType)
{
DWORD dwRes;
PACL pOldDACL, pNewDACL;
PSECURITY_DESCRIPTOR pSD;
EXPLICIT_ACCESS ea;

if (NULL == lpObjectName)
    return ERROR_INVALID_PARAMETER;

// get a pointer to the existing DACL

dwRes = GetNamedSecurityInfo(lpObjectName, ObjectType,
      DACL_SECURITY_INFORMATION,
      NULL, NULL, &pOldDACL, NULL, &pSD);
if (ERROR_SUCCESS != dwRes)
    return dwRes;

// initialize an EXPLICIT_ACCESS structure to allow access

ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
BuildExplicitAccessWithName(&ea, "duke", GENERIC_READ,
        SET_ACCESS, NO_INHERITANCE);

// create an new ACL by merging the EXPLICIT_ACCESS structure
// with the existing DACL

dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
if (ERROR_SUCCESS != dwRes)
    goto Cleanup;

// attach the new ACL as the object's DACL

dwRes = SetNamedSecurityInfo(lpObjectName, ObjectType,
      DACL_SECURITY_INFORMATION,
      NULL, NULL, pNewDACL, NULL);

// free the buffers returned by SetEntriesInAcl
//   and GetNamedSecurityInfo

Cleanup:
    if(pSD != NULL)
        LocalFree((HLOCAL) pSD);
    if(pNewDACL != NULL)
        LocalFree((HLOCAL) pNewDACL);

return dwRes;
}


Windows NT 4.0 Access-Control Reference

The following elements are used with Windows NT 4.0 access control.

  • Windows NT 4.0 Access-Control Functions
  • Windows NT 4.0 Access-Control Structures


Windows NT 4.0 Access-Control Functions

The following functions are used to get and set the components of an object's security descriptor.

GetNamedSecurityInfo
GetSecurityInfo
SetNamedSecurityInfo
SetSecurityInfo

The following functions are used to manipulate access-control lists.

BuildExplicitAccessWithName
GetAuditedPermissionsFromAcl
GetEffectiveRightsFromAcl
GetExplicitEntriesFromAcl
SetEntriesInAcl


BuildExplicitAccessWithName

The BuildExplicitAccessWithName function initializes an EXPLICIT_ACCESS structure with data specified by the caller. The trustee is identified by a name string.

VOID BuildExplicitAccessWithName(
  PEXPLICIT_ACCESS pExplicitAccess,
                        // pointer to the structure to initialize
  LPTSTR pTrusteeName,  // name of the trustee to put in the
                        // structure
  DWORD AccessPermissions,  // access mask to put in the structure
  ACCESS_MODE AccessMode,  // access mode to put in the structure
  DWORD Inheritance     // inheritance type to put in the structure
);

Parameters

pExplicitAccess
Pointer to an EXPLICIT_ACCESS structure to initialize. BuildExplicitAccessWithName does not allocate any memory. If this parameter is NULL, the function does nothing.
pTrusteeName
Pointer to a null-terminated string that contains the name of the trustee for the ptstrName member of the TRUSTEE structure. The BuildExplicitAccessWithName function sets the other members of the TRUSTEE structure as follows:
Member | Value
pMultipleTrustee | NULL
MultipleTrusteeOperation | NO_MULTIPLE_TRUSTEE
TrusteeForm | TRUSTEE_IS_NAME
TrusteeType | TRUSTEE_IS_UNKNOWN

AccessPermissions
Specifies an access mask for the grfAccessPermissions member of the EXPLICIT_ACCESS structure. The mask is a set of bit flags that use the ACCESS_MASK format to specify the access rights that an ACE allows, denies, or audits for the trustee. The functions that use the EXPLICIT_ACCESS structure do not convert, interpret, or validate the bits in this mask.
AccessMode
Specifies an access mode for the grfAccessMode member of the EXPLICIT_ACCESS structure. The access mode indicates whether the ACE allows, denies, or audits the specified rights. This parameter contains values from the ACCESS_MODE enumeration.
Inheritance
Specifies an inheritance type for the grfInheritance member of the EXPLICIT_ACCESS structure. This value is a set of bit flags that determines whether other containers or objects can inherit the ACE from the primary object to which the ACL is attached. The value of this member corresponds to the inheritance portion (low-order byte) of the AceFlags member of the ACE_HEADER structure. This parameter can be NO_INHERITANCE to indicate that the ACE is not inheritable,or it can be a combination of the following values.
Value Meaning
CONTAINER_INHERIT_ACE
Other containers that are contained by the primary object inherit the ACE.
INHERIT_ONLY_ACE
The ACE does not apply to the primary object to which the ACL is attached, but objects contained by the primary object inherit the ACE.
NO_PROPAGATE_INHERIT_ACE
The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE flags are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE
Noncontainer objects contained by the primary object inherit the ACE.
SUB_CONTAINERS_ONLY_INHERIT
Other containers that are contained by the primary object inherit the ACE. This flag corresponds to the CONTAINER_INHERIT_ACE flag.
SUB_OBJECTS_ONLY_INHERIT
Noncontainer objects contained by the primary object inherit the ACE. This flag corresponds to the OBJECT_INHERIT_ACE flag.
SUB_CONTAINERS_AND_OBJECTS_INHERIT
Both containers and noncontainer objects that are contained by the primary object inherit the ACE. This flag corresponds to the combination of the CONTAINER_INHERIT_ACE and OBJECT_INHERIT_ACE flags.

Return Values

None.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Windows NT 4.0 Access Control Overview, Windows NT 4.0 Access-Control Functions, ACE, ACL, EXPLICIT_ACCESS, GetExplicitEntriesFromAcl, SetEntriesInAcl, TRUSTEE


GetAuditedPermissionsFromAcl

The GetAuditedPermissionsFromAcl function returns the audited access rights for a specified trustee. The audited rights are based on the access-control entries (ACEs) of a specified access-control list (ACL). The audited access rights indicate the types of access attempts that cause the system to generate an audit record in the system event log. The audited rights include those that the ACL specifies for the trustee or for any groups of which the trustee is a member. In determining the audited rights, the function does not consider the security privileges held by the trustee.

DWORD GetAuditedPermissionsFromAcl(
  PACL pacl,  // ACL to get trustee's audited rights from
  PTRUSTEE pTrustee,
              // trustee to get rights for
  PACCESS_MASK pSuccessfulAuditedRights,
              // receives rights audited for successful access
  PACCESS_MASK pFailedAuditRights
              // receives rights audited for failed access
);

Parameters

pacl
Pointer to an ACL from which to get the trustee's audited access rights.
pTrustee
Pointer to a TRUSTEE structure that identifies the trustee. A trustee can be a user, group, or program (such as a Win32 service). You can use a name or a security identifier (SID) to identify a trustee.
pSuccessfulAuditedRights
Pointer to an ACCESS_MASK variable that receives a set of access rights. The system generates an audit record when the trustee successfully uses any of these access rights.
pFailedAuditRights
Pointer to an ACCESS_MASK variable that receives a set of access rights based on the access-control entries in the specified ACL. The system generates an audit record when the trustee fails in an attempt to use any of these rights.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H.

Remarks

The GetAuditedPermissionsFromAcl function checks all system-audit ACEs in the ACL to determine the audited rights for the trustee. For all ACEs that specify audited rights for a group, GetAuditedPermissionsFromAcl enumerates the members of the group to determine whether the trustee is a member. The function returns an error if it cannot enumerate the members of a group.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Windows NT 4.0 Access Control Overview, Windows NT 4.0 Access-Control Functions, ACCESS_MASK, ACE, ACL, GetEffectiveRightsFromAcl, SID, SYSTEM_AUDIT_ACE, TRUSTEE


GetEffectiveRightsFromAcl

The GetEffectiveRightsFromAcl function retrieves the effective access rights that an ACL allows for a specified trustee. The trustee's effective access rights are the access rights that the ACL grants to the trustee or to any groups of which the trustee is a member. The function does not consider the security privileges held by the trustee in determining the effective access rights.

DWORD GetEffectiveRightsFromAcl(
  PACL pacl,                   // ACL to get trustee's rights from
  PTRUSTEE pTrustee,           // trustee to get rights for
  PACCESS_MASK pAccessRights  // receives trustee's access rights
);

Parameters

pacl
Pointer to an ACL structure from which to get the trustee's effective access rights.
pTrustee
Pointer to a TRUSTEE structure that identifies the trustee. A trustee can be a user, group, or program (such as a Win32 service). You can use a name or a security identifier (SID) to identify a trustee.
pAccessRights
Pointer to an ACCESS_MASK variable that receives the effective access rights of the trustee.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H.

Remarks

The GetEffectiveRightsFromAcl function checks all access-allowed and access-denied ACEs in the ACL to determine the effective rights for the trustee. For all ACEs that allow or deny rights to a group, GetEffectiveRightsFromAcl enumerates the members of the group to determine whether the trustee is a member. The function returns an error if it cannot enumerate the members of a group.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Windows NT 4.0 Access Control Overview, Windows NT 4.0 Access-Control Functions, ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, ACCESS_MASK, ACE, ACL, GetAuditedPermissionsFromAcl, SID, TRUSTEE


GetExplicitEntriesFromAcl

The GetExplicitEntriesFromAcl function retrieves an array of EXPLICIT_ACCESS structures that describe the access-control entries (ACEs) in an access-control list (ACL).

DWORD GetExplicitEntriesFromAcl(
  PACL pacl,  // pointer to the ACL from which to get entries
  PULONG pcCountOfExplicitEntries,
              // receives number of entries in the list
  PEXPLICIT_ACCESS *pListOfExplicitEntries
              // receives pointer to list of entries
);

Parameters

pacl
Pointer to an ACL from which to get ACE information.
pcCountOfExplicitEntries
Pointer to a variable that receives the number of EXPLICIT_ACCESS structures returned in the pListOfExplicitEntries array.
pListOfExplicitEntries
Pointer to a variable that receives a pointer to an array of EXPLICIT_ACCESS structures that describe the ACEs in the ACL. If the function succeeds, you must call the LocalFree function to free the returned buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H.

Remarks

Each entry in the array of EXPLICIT_ACCESS structures describes access control information from an ACE for a trustee. A trustee can be a user, group, or program (such as a Win32 service).

Each EXPLICIT_ACCESS structure specifies a set of access rights and an access mode flag that indicates whether the ACE allows, denies, or audits the specified rights.

For a discretionary ACL (DACL), the access mode flag can be one of the following values from the ACCESS_MODE enumeration.

Value | Meaning
SET_ACCESS | Indicates that an access-allowed ACE for the trustee allows the specified access rights.
DENY_ACCESS | Indicates that an access-denied ACE for the trustee denies the specified access rights.

For a system ACL (SACL), the access mode flag can be a combination of the following values from the ACCESS_MODE enumeration.

Value | Meaning
SET_AUDIT_SUCCESS | Indicates that a system-audit ACE for the trustee generates audit messages for successful attempts to use the specified access rights.
SET_AUDIT_FAILURE | Indicates that a system-audit ACE for the trustee generates audit messages for failed attempts to use the specified access rights.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Windows NT 4.0 Access Control Overview, Windows NT 4.0 Access-Control Functions, ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, ACE, ACL, EXPLICIT_ACCESS, LocalFree, SYSTEM_AUDIT_ACE


GetNamedSecurityInfo

The GetNamedSecurityInfo function retrieves a copy of the security descriptor for an object specified by name.

DWORD GetNamedSecurityInfo(
  LPTSTR pObjectName,
                     // name of the object
  SE_OBJECT_TYPE ObjectType,
                     // type of object
  SECURITY_INFORMATION SecurityInfo,
                     // type of security information to retrieve
  PSID *ppsidOwner,  // receives a pointer to the owner SID
  PSID *ppsidGroup,  // receives a pointer to the primary group SID
  PACL *ppDacl,      // receives a pointer to the DACL
  PACL *ppSacl,      // receives a pointer to the SACL
  PSECURITY_DESCRIPTOR *ppSecurityDescriptor
                     // receives a pointer to the security descriptor
);

Parameters

pObjectName
Pointer to a null-terminated string that specifies the name of the object from which to retrieve security information. For descriptions of the string formats for the different object types, see SE_OBJECT_TYPE.
ObjectType
Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object named by the pObjectName parameter.
SecurityInfo
A set of SECURITY_INFORMATION bit flags that indicate the type of security information to retrieve. This parameter can be a combination of the following values.
Value | Meaning
OWNER_SECURITY_INFORMATION | If this flag is set, the ppsidOwner parameter receives the security identifier (SID) of the object's owner.
GROUP_SECURITY_INFORMATION | If this flag is set, the ppsidGroup parameter receives the SID of the object's primary group.
DACL_SECURITY_INFORMATION | If this flag is set, the ppDacl parameter receives the object's discretionary access-control list (DACL).
SACL_SECURITY_INFORMATION | If this flag is set, the ppSacl parameter receives the object's system access-control list (SACL)..

ppsidOwner
Pointer to a variable that receives a pointer to the owner SID in the security descriptor returned in ppSecurityDescriptor. The returned pointer is valid only if you set the OWNER_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the owner SID.
ppsidGroup
Pointer to a variable that receives a pointer to the primary group SID in the returned security descriptor. The returned pointer is valid only if you set the GROUP_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the group SID.
ppDacl
Pointer to a variable that receives a pointer to the DACL in the returned security descriptor. The returned pointer is valid only if you set the DACL_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the DACL.
ppSacl
Pointer to a variable that receives a pointer to the SACL in the returned security descriptor. The returned pointer is valid only if you set the SACL_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the SACL.
ppSecurityDescriptor
Pointer to a variable that receives a pointer to the security descriptor of the object. You must call the LocalFree function to free the returned buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H.

Remarks

If the ppsidOwner, ppsidGroup, ppDacl, ppSacl parameters are non-NULL, and the SecurityInfo parameter specifies that they be retrieved from the object, those parameters will point to the corresponding parameters in the security descriptor returned in ppSecurityDescriptor.

To read the owner, group, or DACL from the object's security descriptor, the object's DACL must grant READ_CONTROL access to the caller or the caller must be the owner of the object.

To read the system access-control list (SACL) of the object, the SE_SECURITY_NAME privilege must be enabled for the calling process.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Windows NT 4.0 Access Control Overview, Windows NT 4.0 Access-Control Functions, ACL, GetSecurityInfo, LocalFree, SE_OBJECT_TYPE, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetNamedSecurityInfo, SetSecurityInfo, SID


GetSecurityInfo

The GetSecurityInfo function retrieves a copy of the security descriptor for an object specified by a handle.

DWORD GetSecurityInfo(
  HANDLE handle,     // handle to the object
  SE_OBJECT_TYPE ObjectType,
                     // type of object
  SECURITY_INFORMATION SecurityInfo,
                     // type of security information to retrieve
  PSID *ppsidOwner,  // receives a pointer to the owner SID
  PSID *ppsidGroup,  // receives a pointer to the primary group SID
  PACL *ppDacl,      // receives a pointer to the DACL
  PACL *ppSacl,      // receives a pointer to the SACL
  PSECURITY_DESCRIPTOR *ppSecurityDescriptor
                     // receives a pointer to the security descriptor
);

Parameters

handle
A handle to the object from which to retrieve security information.
ObjectType
Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object named by the pObjectName parameter.
SecurityInfo
A set of SECURITY_INFORMATION bit flags that indicate the type of security information to retrieve. This parameter can be a combination of the following values.
Value | Meaning
OWNER_SECURITY_INFORMATION | If this flag is set, the ppsidOwner parameter receives the security identifier (SID) of the object's owner.
GROUP_SECURITY_INFORMATION | If this flag is set, the ppsidGroup parameter receives the SID of the object's primary group.
DACL_SECURITY_INFORMATION | If this flag is set, the ppDacl parameter receives the object's discretionary access-control list (DACL).
SACL_SECURITY_INFORMATION | If this flag is set, the ppSacl parameter receives the object's system access-control list (SACL)..

ppsidOwner
Pointer to a variable that receives a pointer to the owner SID in the security descriptor returned in ppSecurityDescriptor. The returned pointer is valid only if you set the OWNER_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the owner SID.
ppsidGroup
Pointer to a variable that receives a pointer to the primary group SID in the returned security descriptor. The returned pointer is valid only if you set the GROUP_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the group SID.
ppDacl
Pointer to a variable that receives a pointer to the DACL in the returned security descriptor. The returned pointer is valid only if you set the DACL_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the DACL.
ppSacl
Pointer to a variable that receives a pointer to the SACL in the returned security descriptor. The returned pointer is valid only if you set the SACL_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the SACL.
ppSecurityDescriptor
Pointer to a variable that receives a pointer to the security descriptor of the object. You must call the LocalFree function to free the returned buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H.

Remarks

If the ppsidOwner, ppsidGroup, ppDacl, ppSacl parameters are non-NULL, and the SecurityInfo parameter specifies that they be retrieved from the object, those parameters will point to the corresponding parameters in the security descriptor returned in ppSecurityDescriptor.

To read the owner, group, or DACL from the object's security descriptor, the calling process must have been granted READ_CONTROL access when the handle was opened. To get READ_CONTROL access, the caller must be the owner of the object or the object's DACL must grant the access.

To read the SACL from the security descriptor, the calling process must have been granted ACCESS_SYSTEM_SECURITY access when the handle was opened. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.

See Also

Windows NT 4.0 Access Control Overview, Windows NT 4.0 Access-Control Functions, ACL, GetNamedSecurityInfo, LocalFree, SE_OBJECT_TYPE, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetNamedSecurityInfo, SetSecurityInfo, SID


SetEntriesInAcl

The SetEntriesInAcl function creates a new access-control list (ACL) by merging new access-control or audit-control information into an existing ACL.

DWORD SetEntriesInAcl(
  ULONG cCountOfExplicitEntries,
                 // number of entries in the list
  PEXPLICIT_ACCESS pListOfExplicitEntries,
                 // pointer to list of entries with new access data
  PACL OldAcl,   // pointer to the original ACL
  PACL *NewAcl   // receives a pointer to the new ACL
);

Parameters

cCountOfExplicitEntries
Specifies the number of EXPLICIT_ACCESS structures in the pListOfExplicitEntries array.
pListOfExplicitEntries
Pointer to an array of EXPLICIT_ACCESS structures that describe the access control information to merge into the existing ACL.
OldAcl
Pointer to the existing ACL. This parameter can be NULL, in which case, the function creates a new ACL based on the EXPLICIT_ACCESS entries.
NewAcl
Pointer to a variable that receives a pointer to the new ACL. If the function succeeds, you must call the LocalFree function to free the returned buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H.

Remarks

Each entry in the array of EXPLICIT_ACCESS structures specifies access-control or audit-control information for a specified trustee. A trustee can be a user, group, or other SID value, such as a logon identifier or logon type (for instance, a Win32 service or batch job). You can use a name or a security identifier (SID) to identify a trustee.

You can use the SetEntriesInAcl function to modify the list of ACEs in a DACL or a SACL. A DACL controls access to an object, and a SACL controls the system's auditing of attempts to access to an object. Note that SetEntriesInAcl does not prevent you from mixing access-control and audit-control information in the same ACL; however, the resulting ACL will contain meaningless entries.

For a DACL, the grfAccessMode member of the EXPLICIT_ACCESS structure specifies whether to allow, deny, or revoke access rights for the trustee. This member can specify one of the following values from the ACCESS_MODE enumeration.

Value | Meaning
GRANT_ACCESS | Creates a new access-allowed ACE that combines the specified rights with any existing rights of the trustee. The new ACE replaces any existing access-allowed ACE for the trustee. The function also modifies or deletes any existing access-denied ACE for the trustee that denies the specified rights.
SET_ACCESS | Similar to GRANT_ACCESS except that the new access-allowed ACE allows only the specified rights, discarding any existing rights. This flag also removes any existing access-denied ACE for the trustee.
DENY_ACCESS | Creates a new access-denied ACE that replaces any existing access-denied ACE for the trustee. The new ACE denies the specified rights in addition to any currently denied rights of the trustee. The function also modifies or deletes any existing access-allowed ACE for the trustee that allows the specified rights.
REVOKE_ACCESS | Removes any existing ACEs for the specified trustee. The function ignores the rights specified in the grfAccessPermissions member of the EXPLICIT_ACCESS structure.

The SetEntriesInAcl function places any new access-denied ACEs at the beginning of the list of ACEs for the new ACL. It places any new access-allowed ACEs just before any existing access-allowed ACEs.

For a SACL, the grfAccessMode member of the EXPLICIT_ACCESS structure can specify the following values.

Value | Meaning
REVOKE_ACCESS | Removes any existing ACEs for the specified trustee. The function ignores the rights specified in the grfAccessPermissions member of the EXPLICIT_ACCESS structure.
SET_AUDIT_SUCCESS | Creates a new system-audit ACE that replaces any existing system-audit ACE for the trustee. The new ACE generates audit messages when the specified trustee successfully uses the specified access rights. The new ACE combines the specified rights with any existing audited access rights for the trustee. You can combine this value with SET_AUDIT_FAILURE.
SET_AUDIT_FAILURE | Creates a new system-audit ACE that replaces any existing system-audit ACE for the trustee. The new ACE generates audit messages for failed attempts to use the specified access rights. The new ACE combines the specified rights with any existing audited access rights for the trustee. You can combine this value with SET_AUDIT_SUCCESS.

The SetEntriesInAcl function places any new system-audit ACEs at the beginning of the list of ACEs for the new ACL.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Windows NT 4.0 Access Control Overview, Windows NT 4.0 Access-Control Functions, ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, ACL, EXPLICIT_ACCESS, LocalFree, SYSTEM_AUDIT_ACE


SetNamedSecurityInfo

The SetNamedSecurityInfo function sets specified security information in the security descriptor of a specified object. The caller identifies the object by name.

DWORD SetNamedSecurityInfo(
  LPTSTR pObjectName,  // name of the object
  SE_OBJECT_TYPE ObjectType,
                       // type of object
  SECURITY_INFORMATION SecurityInfo,
                       // type of security information to set
  PSID psidOwner,      // pointer to the new owner SID
  PSID psidGroup,      // pointer to the new primary group SID
  PACL pDacl,          // pointer to the new DACL
  PACL pSacl           // pointer to the new SACL
);

Parameters

pObjectName
Pointer to a null-terminated string that specifies the name of the object for which to set security information. This can be the name of a local or remote file or directory on a NTFS file system, Windows NT network sharename, registry key, semaphore, event, mutex, file mapping, or waitable timer.

For descriptions of the string formats for the different object types, see SE_OBJECT_TYPE.

ObjectType
Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object named by the pObjectName parameter.
SecurityInfo
A set of SECURITY_INFORMATION bit flags that indicate the type of security information to set. This parameter can be a combination of the following values.
Value | Meaning
OWNER_SECURITY_INFORMATION | Set the owner security identifier (SID) in the object's security descriptor. The psidOwner parameter points to the new SID.
GROUP_SECURITY_INFORMATION | Set the primary group SID in the object's security descriptor. The psidGroup parameter points to the new SID.
DACL_SECURITY_INFORMATION | Set the discretionary access-control list (DACL) in the object's security descriptor. The pDacl parameter points to the new DACL.
SACL_SECURITY_INFORMATION | Set the system access-control list (SACL) in the object's security descriptor. The pSacl parameter points to the new SACL.

psidOwner
Pointer to a SID that identifies the object's owner. The SID must be one that can be assigned as the owner SID of a security descriptor. The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION flag. The caller must have WRITE_OWNER access to the object or have the SE_TAKE_OWNERSHIP_NAME privilege enabled. This parameter can be NULL if you are not setting the owner SID.
psidGroup
Pointer to a SID that identifies the object's primary group. The SecurityInfo parameter must include the GROUP_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the primary group SID.
pDacl
Pointer to the new DACL for the object. The SecurityInfo parameter must include the DACL_SECURITY_INFORMATION flag. The caller must have WRITE_DAC access to the object or be the object's owner. This parameter can be NULL if you are not setting the DACL.
pSacl
Pointer to the new SACL for the object. The SecurityInfo parameter must include the SACL_SECURITY_INFORMATION flag. The caller must have the SE_SECURITY_NAME privilege enabled. This parameter can be NULL if you are not setting the SACL.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Windows NT 4.0 Access Control Overview, Windows NT 4.0 Access-Control Functions, ACL, GetNamedSecurityInfo, GetSecurityInfo, SE_OBJECT_TYPE, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetSecurityInfo, SID


SetSecurityInfo

The SetSecurityInfo function sets specified security information in the security descriptor of a specified object. The caller identifies the object by a handle.

DWORD SetSecurityInfo(
  HANDLE handle,  // handle to the object
  SE_OBJECT_TYPE ObjectType,
                  // type of object
  SECURITY_INFORMATION SecurityInfo,
                  // type of security information to set
  PSID psidOwner, // pointer to the new owner SID
  PSID psidGroup, // pointer to the new primary group SID
  PACL pDacl,     // pointer to the new DACL
  PACL pSacl      // pointer to the new SACL
);

Parameters

handle
A handle to the object for which to set security information.
ObjectType
Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object identified by the handle parameter.
SecurityInfo
Specifies the components of the security descriptor to set. This parameter can be a combination of the following values.
Value Meaning
OWNER_SECURITY_INFORMATION
Sets the object's owner security identifier (SID). The psidOwner parameter points to the new SID. The handle parameter must have WRITE_OWNER access, or the calling process must be the object's owner or have the SE_TAKE_OWNERSHIP_NAME privilege enabled.
GROUP_SECURITY_INFORMATION
Sets the object's primary group SID. The psidGroup parameter points to the new SID. The handle parameter must have WRITE_OWNER access, or the calling process must be the object's owner.
DACL_SECURITY_INFORMATION
Sets the object's discretionary access control list (DACL). The pDacl parameter points to the new DACL. The handle parameter must have WRITE_DAC access, or the calling process must be the object's owner.
SACL_SECURITY_INFORMATION
Sets the object's system access control list (SACL). The pSacl parameter points to the new SACL. The handle parameter must have ACCESS_SYSTEM_SECURITY access. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current access token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

psidOwner
Pointer to a SID that identifies the object's owner. The SID must be one that can be assigned as the owner SID of a security descriptor. The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the owner SID.
psidGroup
Pointer to a SID that identifies the object's primary group. The SecurityInfo parameter must include the GROUP_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the primary group SID.
pDacl
Pointer to the new DACL for the object. The SecurityInfo parameter must include the DACL_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the DACL.
pSacl
Pointer to the new SACL for the object. The SecurityInfo parameter must include the SACL_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the SACL.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in aclapi.h.
Import Library: Use advapi32.lib.

See Also

Windows NT 4.0 Access Control Overview, Windows NT 4.0 Access-Control Functions, ACL, GetNamedSecurityInfo, GetSecurityInfo, SE_OBJECT_TYPE, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetNamedSecurityInfo, SID


Windows NT 4.0 Access-Control Structures

The following structures are used with security.

ACCESS_MODE
EXPLICIT_ACCESS


ACCESS_MODE

The ACCESS_MODE enumeration type contains values that indicate how the access rights in an EXPLICIT_ACCESS structure apply to the trustee. Functions such as SetEntriesInAcl and GetExplicitEntriesFromAcl use these values to set or retrieve information in an access-control entry (ACE).

typedef enum _ACCESS_MODE
{
    NOT_USED_ACCESS = 0,
    GRANT_ACCESS,
    SET_ACCESS,
    DENY_ACCESS,
    REVOKE_ACCESS,
    SET_AUDIT_SUCCESS,
    SET_AUDIT_FAILURE
} ACCESS_MODE;

Enumerator Value | Meaning
GRANT_ACCESS | An input flag that creates an ACCESS_ALLOWED_ACE. The new ACE combines the specified rights with any existing allowed or denied rights of the trustee.
SET_ACCESS | Indicates an ACCESS_ALLOWED_ACE that allows the specified rights. On input, this flag discards any existing access-control information for the trustee.
DENY_ACCESS | Indicates an ACCESS_DENIED_ACE that denies the specified rights. On input, this flag denies the specified rights in addition to any currently denied rights of the trustee. It also modifies or deletes any existing ACCESS_ALLOWED_ACE for the trustee that allows the specified rights.
REVOKE_ACCESS | An input flag that removes all existing ACCESS_DENIED_ACE, ACCESS_ALLOWED_ACE, or SYSTEM_AUDIT_ACE structures for the specified trustee.
SET_AUDIT_SUCCESS | Indicates a SYSTEM_AUDIT_ACE that generates audit messages for successful attempts to use the specified access rights. You can combine this value with SET_AUDIT_FAILURE. On input, this flag combines the specified rights with any existing audited access rights for the trustee.
SET_AUDIT_FAILURE | Indicates a SYSTEM_AUDIT_ACE that generates audit messages for failed attempts to use the specified access rights. You can combine this value with SET_AUDIT_SUCCESS. On input, this flag combines the specified rights with any existing audited access rights for the trustee.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.

See Also

Windows NT 4.0 Access Control Overview, Windows NT 4.0 Access-Control Structures, ACCESS_DENIED_ACE, ACCESS_ALLOWED_ACE, ACE, EXPLICIT_ACCESS, GetExplicitEntriesFromAcl, SetEntriesInAcl, SYSTEM_AUDIT_ACE


EXPLICIT_ACCESS

The EXPLICIT_ACCESS structure specifies access-control information for a specified trustee. Access control functions, such as SetEntriesInAcl and GetExplicitEntriesFromAcl, use this structure to describe the information in an access-control entry (ACE) of an access-control list (ACL).

typedef struct _EXPLICIT_ACCESS {
    DWORD        grfAccessPermissions;
    ACCESS_MODE  grfAccessMode;
    DWORD        grfInheritance;
    TRUSTEE      Trustee;
} EXPLICIT_ACCESS, *PEXPLICIT_ACCESS;

Members

grfAccessPermissions
A set of bit flags that use the ACCESS_MASK format to specify the access rights that an ACE allows, denies, or audits for the trustee. The functions that use the EXPLICIT_ACCESS structure do not convert, interpret, or validate the bits in this mask.
grfAccessMode
Specifies a value from the ACCESS_MODE enumeration. For a discretionary ACL (DACL), this flag indicates whether the ACL allows or denies the specified access rights. For a system ACL (SACL), this flag indicates whether the ACL generates audit messages for successful attempts to use the specified access rights, or failed attempts, or both. When modifying an existing ACL, you can specify the REVOKE_ACCESS flag to remove any existing ACEs for the specified trustee.
grfInheritance
A set of bit flags that determines whether other containers or objects can inherit the ACE from the primary object to which the ACL is attached. The value of this member corresponds to the inheritance portion (low-order byte) of the AceFlags member of the ACE_HEADER structure. This parameter can be NO_INHERITANCE to indicate that the ACE is not inheritable; or it can be a combination of the following values.
Value Meaning
CONTAINER_INHERIT_ACE
Other containers that are contained by the primary object inherit the ACE.
INHERIT_ONLY_ACE
The ACE does not apply to the primary object to which the ACL is attached, but objects contained by the primary object inherit the ACE.
NO_PROPAGATE_INHERIT_ACE
The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE flags are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE
Noncontainer objects contained by the primary object inherit the ACE.
SUB_CONTAINERS_ONLY_INHERIT
Other containers that are contained by the primary object inherit the ACE. This flag corresponds to the CONTAINER_INHERIT_ACE flag.
SUB_OBJECTS_ONLY_INHERIT
Noncontainer objects contained by the primary object inherit the ACE. This flag corresponds to the OBJECT_INHERIT_ACE flag.
SUB_CONTAINERS_AND_OBJECTS_INHERIT
Both containers and noncontainer objects that are contained by the primary object inherit the ACE. This flag corresponds to the combination of the CONTAINER_INHERIT_ACE and OBJECT_INHERIT_ACE flags.

Trustee
A TRUSTEE structure that identifies the user, group, or program (such as a Win32 service) to which the ACE applies.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in accctrl.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

Windows NT 4.0 Access Control Overview, Windows NT 4.0 Access-Control Structures, ACCESS_MODE, ACE, ACE_HEADER, ACL, BuildExplicitAccessWithName, BuildSecurityDescriptor, GetExplicitEntriesFromAcl, LookupSecurityDescriptorParts, SetEntriesInAcl, TRUSTEE


Legal Information

Security Support Provider Interface
for Microsoft Windows NT 4.0

Information in this document is subject to change without notice. Companies, names, and data used in examples herein are fictitious unless otherwise noted. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without the express written permission of Microsoft Corporation.

Microsoft may have patents or pending patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. The furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property rights except as expressly provided in any written license agreement from Microsoft.

©1996 Microsoft Corporation. All rights reserved.

Microsoft, MS, MS-DOS, Win32, Windows, and Windows NT are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.


Security Support Provider Interface

The Security Support Provider Interface is a common interface to security providers. Security providers export a set of functions that can be used to gain a certain level of security support. This interface is not specific to Microsoft® Windows NT™. It is supported by RPC (Remote Procedure Call) in Windows NT and Windows 95, as well as RPC on MS-DOS®, Windows® version 3.11, and Macintosh® (both MC680x0 and PowerPC).


About SSPI

The Security Support Provider Interface (SSPI) provides a common interface between transport-level applications, such as Microsoft RPC or a file system redirector, and security providers, such as Windows NT Distributed Security. SSPI provides a mechanism by which a transport application can call in to one of several security providers, and obtain an authenticated connection without knowledge of the details of the security protocol.

The functions defined fall into the following major categories:

  • Credential management
  • Context management
  • Message support
  • Package management

Assumptions

Several of the functions in this API return time stamps to represent the life span of various objects. All of these time stamps should be in local time. The provider is, of course, free to maintain time in any fashion, but the times provided at this API boundary should always be in local time to simplify the work of applications that make use of these functions.


SSPI Model

The Security Support Provider Interface (SSPI) allows an application to use any of the various security models available on a computer or network without changing the interface to the security system. SSPI does not establish credentials (logon), because that is generally a privileged operation handled by the operating system.

A security provider is a dynamic-link library that implements the Security Support Provider Interface to make one or more security packages available to applications. Each security package provides the necessary mapping between the SSPI and the actual security model, such as Kerberos or Microsoft LAN Manager.

An application can use the package management functions to list the security packages available and select one to support its needs. The application then uses the credential management functions to obtain a handle to the credentials of the user on whose behalf they are executing. With this handle, the application can use the context management functions to create a security context to a service. A security context is an opaque data structure that contains the security data relevant to a connection, such as a session key, the duration of the session, and so on. Finally, the application uses the security context with the message support functions to ensure message integrity and privacy during the connection.


Credential Management

The credential management functions of the Security Support Provider Interface enable applications to gain access to the credentials of a principal, or to free such access. This interface does not allow any other access to the credentials. A principal is an entity recognized by the security system. This includes human users as well as autonomous processes. Credentials are data, such as a password or a Kerberos ticket, used by a principal to establish the identity of the principal.

The AcquireCredentialsHandle function acquires a handle to the pre-existing logon credentials of a specified principal. Applications can use the credentials handle with the context management functions to create a security context.

The FreeCredentialsHandle function releases a credential handle and associated resources back to the security package.

The QueryCredentialsAttributes function queries attributes, such as the associated name, of the credential handle.

The credential management functions use a credential handle, which is a reference to an opaque security object. All references to security objects, such as credentials and contexts, are done through a handle. The security provider dereferences a handle to access the credentials. A credential handle with the value {0xFFFFFFFF, 0xFFFFFFFF} is always invalid.


Context Management

The context management functions of the Security Support Provider Interface enable applications to create and use security contexts. A security context is the security data relevant to a connection. A security context contains information such as a session key, duration of the session, and so on.

Both the client and server in a communication link must cooperate to create a security context. The client and server can then use the security context with the message support functions to ensure message integrity and privacy during the connection.

The context management functions use a context handle, which is an opaque object. The security provider dereferences a handle to access the security context. A context handle with the value {0xFFFFFFFF, 0xFFFFFFFF} is always invalid.

The following functions are used with context management.

Function | Description
AcceptSecurityContext | Create a security context based on an opaque message received from a client.
ApplyControlToken | Apply a supplemental security message to an existing security context.
DeleteSecurityContext | Free a security context and associated resources.
FreeContextBuffer | Free a memory buffer allocated by a security provider.
ImpersonateSecurityContext | Impersonate the security context to appear as the client to the system.
InitializeSecurityContext | Initiate a security context by generating an opaque message that can be passed to a server.
QueryContextAttributes | Query the attributes of a security context.
RevertSecurityContext | Cease impersonating a security context.


Message Support

The message support functions of the Security Support Provider Interface enable an application to transmit messages that cannot be tampered with. The functions work with one or more buffers that contain a message, and an associated security context created by the context management functions. The behavior can differ based on the type of context: connection, datagram, or stream. For a description of the differences, see Context Semantics.

The following functions provide security support for messages.

Function | Description
MakeSignature | Generate a secure signature based on a message and a security context.
VerifySignature | Verify that a signature matches a received message.


Package Management

The package management functions of the Security Support Provider Interface (SSPI) enumerate and query the attributes of the security packages of a security provider.

A security provider is a dynamic-link library that implements the SSPI to make one or more security packages available to applications. Each security package provides the necessary mapping between the SSPI and the actual security model, such as Kerberos or Microsoft LAN Manager.

The following functions provide management services for these packages.

Function | Description
EnumerateSecurityPackages | List available security packages and their capabilities.
InitSecurityInterface | Retrieve a pointer to a security provider dispatch table.
QuerySecurityPackageInfo | Query an individual security package for its capabilites.


Interface Model

The Security Support Provider Interface (SSPI) model provides a single interface through which a client-server transport application can use any of the various security packages available on a computer or network. SSPI allows an application to use a security package even though it does not "understand" the underlying security protocols of the package. SSPI is also flexible enough to allow more sophisticated security-aware applications to take advantage of the capabilities of a particular security package.

To use a security package, both the client and server components of a transport application can call the LoadLibrary function to load SECURITY.DLL. The client and server then use the GetProcAddress function to get a pointer to the InitSecurityInterface function, which returns a pointer to a SecurityFunctionTable dispatch table. The table contains pointers to the security provider's implementations of the various SSPI functions.


Initializing the Client and Server

Before using a specific security package, both client and server should call the EnumerateSecurityPackages function to enumerate the security packages that are available from the security provider. The EnumerateSecurityPackages function returns an array of SecPkgInfo structures that describe the attributes of the available security packages. A client or server can also use the QuerySecurityPackageInfo function to determine the attributes of the specified security package.

After selecting one or more security packages from those available, a server waits for a client to connect. When a client starts up, it also selects from the available security packages based on what it expects for the transaction with the server.


Authenticating a Connection

The client and server components of a transport application can use a security package to establish a secure connection for transmitting messages. The first step in establishing a secure connection is to create a security context, which is an opaque data structure that contains the security data relevant to a connection, such as a session key, the duration of the session, and so on. A security context is essentially a message from the security package associated with the client to the security package associated with the server. Consequently, creating a security context typically requires both client and server to make calls to their respective security packages.

The client starts the creation of a security context by calling the InitializeSecurityContext function. Typically, this call to InitializeSecurityContext returns a status code indicating partial success. The client then uses a socket, serial line, or other transport, to transmit the output of this call to the server.

The server calls the AcceptSecurityContext function, passing as input the output that it received from the client. The security package uses this input to generate the security context and authenticate the message. The AcceptSecurityContext function can generate a reply message that the server must send back to the client.

The client receives this reply from the server, and then passes it to the security package by making another call to InitializeSecurityContext. Depending on the security package and the context requirements, the InitializeSecurityContext and AcceptSecurityContext calls, and the transmission of messages between the client and server, can go on repeatedly. In general, the client and server should continue to exchange messages until either the context is successfully established, or there is a definite error.


Securing the Connection

After a security context is established, the application can use the message support functions to transmit messages that cannot be tampered with. The client or server can pass the security context and a message to the MakeSignature function to generate a secure signature that prevents the message from being modified while in transit. The receiver of the message then calls the VerifySignature function to verify that the message received is correct according to the information in the signature.


Memory Use and Buffers

Memory is handled through a list of descriptors for the buffers being passed to the functions. Because certain protocols, such as OSF DCE, require access to the entire message, the entire message is available. For integrity of the transport application, however, the packages can be prohibited from modifying some areas of the message.

The context functions use the SecBuffer and SecBufferDesc structures to pass memory buffers.

The transport application or client of this interface creates an array of SecBuffer structures that reference the buffers the transport application will be passing in to the package. Note that the security package may indicate that it will be looking at only the security portion of a message, and the client of this interface need not provide the other sections. This can increase performance.

The SecBufferDesc structure is a header that includes a pointer to the array of SecBuffer structures. This enables the client to allocate the header and buffers on the stack, as shown in the following example:

SecBuffer        Buffers[3];
SecBufferDesc    BufferDesc;
...
BufferDesc.ulVersion = SECBUFFER_VERSION;
BufferDesc.cBuffers = 3;
BufferDesc.pBuffers = &Buffers;

The application can then initialize the pointers and sizes in the buffer description to indicate where things may be found:

Buffers[0].cbBuffer = sizeof(Protocol_Header);
Buffers[0].BufferType = SECBUFFER_READONLY | SECBUFFER_DATA;
Buffers[0].pvBuffer = pHeader;

Buffers[1].cbBuffer = pHeader->MessageSize;
Buffers[1].BufferType = SECBUFFER_DATA;
Buffers[1].pvBuffer = pMessage;

Buffers[2].cbBuffer = pHeader->TrailerSize;
Buffers[2].BufferType = SECBUFFER_READONLY | SECBUFFER_TOKEN;
Buffers[2].pvBuffer = pSecurityTrailer;

For a description of the different buffer types, see SecBuffer.


Extended Error Information

Some security packages may support extended error messages, by which one side of a communication link could communicate to the other side the reasons for a failure. For example, Kerberos could fail because of a time skew. However, by returning the information to the client, the client could resynchronize its clock and generate a new connection message.

For security packages that support extended error messages, the security provider must set the SECPKG_FLAG_EXTENDED_ERROR flag in the fCapabilities member of the SecPkgInfo structure.

Applications that require extended error messages must specify the ISC_REQ_EXTENDED_ERROR flag when they call the InitializeSecurityContext function. When calling the AcceptSecurityContext function, the application must specify the ASC_REQ_EXTENDED_ERROR flag.


Context Semantics

The Security Support Provider Interface model supports three types of security contexts, summarized in the following table.

Type | Description
Connection | A connection-oriented context is the most common security context, and the simplest to use. The caller is responsible for the overall message format. The caller is responsible for the location of the data in the message. The caller is also responsible for the location of the security-relevant fields within a message, such as the location of the signature data.
Datagram | A datagram-oriented context has extra support for DCE style datagram communication. It can also be used generically for a datagram-oriented transport application.
Stream | A stream-oriented context is responsible for the blocking and message formatting within the security package. The caller is not interested in formatting, but rather a raw stream of data.


Connection-Oriented Contexts

With a connection-oriented context, the caller of the function is responsible for formatting messages. The caller also relies on the security provider to authenticate connections, and to ensure the integrity of specific parts of the message. Most of the range of context options are available to connection-oriented contexts. These options include mutual authentication, replay detection, and sequence detection, as described in Context Requirements.

A security package sets the SECPKG_FLAG_CONNECTION flag to indicate that it supports connection-oriented semantics.


Datagram Contexts

Datagram, or connectionless, contexts have slightly different semantics from connection-oriented contexts. A connectionless context implies that the server has no way of determining when the client has shut down or otherwise terminated the connection. In other words, no termination notice is passed from the transport application to the server, as would occur in a connection context. To better support some models, particularly DCE-style RPC, the following rules apply when the client specifies the ISC_REQ_DATAGRAM flag in its call to the InitializeSecurityContext function:

  1. The security package does not produce an authentication blob (binary large object) on the first call to the InitializeSecurityContext function. However, the client can immediately use the returned security context in a call to the MakeSignature function to generate a signature for a message.
  2. The security package must allow for the context to be re-established multiple times to allow the server to drop the connection without notice. This also implies that any keys used in the MakeSignature and VerifySignature functions can be reset to a consistent state.
  3. The security package must allow for the caller to specify sequence information, and must provide it back again at the other end. This is not exclusive of any sequence information maintained by the package, and can be viewed as a special payload.

A security package sets the SECPKG_FLAG_DATAGRAM flag to indicate that it supports datagram semantics.


Stream Contexts

Stream contexts are quite different from either connection or datagram contexts. Stream contexts were introduced to handle the secure streams-oriented protocols such as SSL or PCT.

In the interest of sharing the same interface, similar credential management, and so on, the Security Support Provider Interface has been extended to provide support for stream contexts. The security protocol incorporated both the authentication scheme, and the record formats. This posed a problem to the typical implementation, which required the blocking to be done by the caller.

To satisfy the requirements of the stream-oriented protocols, a security package that supports stream contexts has the following characteristics:

  1. The package sets the SECPKG_FLAG_STREAM flag to indicate that it supports stream semantics, just as it would set a flag to indicate support for connection and datagram semantics.
  2. A transport application requests stream semantics by setting the ISC_REQ_STREAM and ASC_REQ_STREAM flags in the calls to the InitializeSecurityContext and AcceptSecurityContext functions.
  3. The application calls the QueryContextAttributes function with a SecPkgContext_StreamSizes structure to query the security context for the number of buffers to provide, and the sizes to reserve for headers or trailers.
  4. The application provides buffer descriptors to spare during the actual processing of the data.

Obviously, item 4 is of the most interest. By specifying stream semantics, the caller is indicating a willingness to do extra so the security provider can handle the blocking of the messages.

In essence, for the MakeSignature and VerifySignature functions, the caller passes in a list of buffers. When a message is received from a channel that is stream-oriented (such as a TCP port), the caller passes in a buffer list as follows:

Buffer | Length | Buffer Type
1 | MessageLength | SECBUFFER_DATA
2 | 0 | SECBUFFER_EMPTY
3 | 0 | SECBUFFER_EMPTY
4 | 0 | SECBUFFER_EMPTY
5 | 0 | SECBUFFER_EMPTY

The security package then goes to work on the blob. If the function returns successfully, the buffer list looks like this:

Buffer | Length | Buffer Type
1 | Header Length | SECBUFFER_STREAM_HEADER
2 | Data Length | SECBUFFER_DATA
3 | Trailer Length | SECBUFFER_STREAM_TRAILER
4 | 0 | SECBUFFER_EMPTY
5 | 0 | SECBUFFER_EMPTY

The provider could have also returned buffer #4 as follows:

Buffer | Length | Buffer Type
4 | x | SECBUFFER_EXTRA

This indicates that the data in this buffer is part of the next record, and has not yet been processed.

Conversely, if the message function returns the SEC_E_INCOMPLETE_MESSAGE error code, the returned buffer list would look like this:

Buffer | Length | Buffer Type
1 | x | SECBUFFER_MISSING

This indicates that more data was needed to process the record. Unlike most errors returned from a message function, this buffer type does not indicate that the context has been compromised, just that more data is needed. Security providers must not update their state in this condition.

Similarly, on the send side of the communication, the caller can simply call the MakeSignature function, in which case the security package may need to reallocate the buffer, copy things around, and so on. Or the caller can be more efficient by providing a buffer list as follows:

Buffer | Length | Type
1 | Header Length | SECBUFFER_STREAM_HEADER
2 | Data Length | SECBUFFER_DATA
3 | Trailer Length | SECBUFFER_STREAM_TRAILER

This allows the caller to use the buffers more efficiently. By calling the QueryContextAttributes function to determine the amount of space to reserve before calling MakeSignature, the operation is more efficient for the application and the security package.


Context Requirements

Context requirements are expressed as a combination of bit flags, passed to either the InitializeSecurityContext or AcceptSecurityContext function. These flags affect the context in a number of ways, and are detailed following. Not all flags apply to all contexts; some are valid only for the server, others only for the client.

The caller uses the fContextReq parameter of the InitializeSecurityContext or AcceptSecurityContext call to specify a set of flags that indicate the required capabilities. When the function returns, the pfContextAttr parameter indicates the attributes of the established context. The caller is responsible for determining whether the final context attributes are acceptable. For example, if the caller requested mutual authentication, but the security package indicates that it was not or could not be performed, the caller must decide whether to cancel the context or continue on.

The following table describes the various context requirements.

Type | Description
DELEGATE | Indicates that the server in the transport application should be allowed simple delegation rights, that is, impersonation of the client on the node at which the server is executing.
MUTUAL_AUTH | Indicates that both parties must authenticate the identity of the peer.
REPLAY_DETECT | Indicates that the context should be established to allow detection of replayed packets later through the message support functions, MakeSignature and VerifySignature. Implies INTEGRITY.
SEQUENCE_DETECT | Indicates that the context should be established to allow detection of out-of-order delivery of packets later through the message support functions. Implies INTEGRITY.
CONFIDENTIALITY | Indicates that the context should be established to protect data while in transit. Reserved for future use.
USE_SESSION_KEY | Indicates that a new session key should be negotiated.
PROMPT_FOR_CREDS | Indicates that, if the client is an interactive user, the security package should prompt the user for the appropriate credentials to use, if possible.
USE_SUPPLIED_CREDS | Indicates that package-specific credential information is available in the input buffer. The security package should use these credentials to authenticate the connection.
ALLOCATE_MEMORY | Indicates that the security package should allocate the memory. The caller must eventually call the FreeContextBuffer function to free memory allocated by the security package.
USE_DCE_STYLE | Indicates that the caller expects a three-leg authentication transaction.
DATAGRAM | Indicates that datagram semantics should be used. For more information, see Datagram Contexts.
CONNECTION | Indicates that connection semantics should be used. For more information, see Connection-Oriented Contexts.
STREAM | Indicates that stream semantics should be used. For more information, see Stream Contexts.
EXTENDED_ERROR | Indicates that if the context fails (or failed), generate an error reply message for the peer.
INTEGRITY | Buffer integrity can be verified, but no sequencing or reply detection is enabled.


Using SSPI

  • Writing a security provider
  • Calling the NTLMSSP security provider
  • Server initialization
  • Client initialization
  • Server authentication
  • Using a security context


Writing a Security Provider

The design of the Security Support Provider Interface enables other security providers to be written and added to the system. A provider specific to a security model can be developed with relative ease or complexity, depending on the level of integration with the operating system. A client provider that allows connections to a new type of server could be done very quickly, while a full provider that provides local impersonation would require more effort.


Installing a Security Provider

Security providers are installed by updating a value in the registry, located as follows:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control
    SecurityProviders
        SecurityProviders = REG_SZ provider1.dll, provider2.dll,...

There can be multiple providers in a single DLL. PROVIDER1.DLL can contain two security "packages"; for example, "Protocol 1" and "Protocol 2."


Calling the NTLMSSP Security Provider

The Windows NT LAN Manager Security Support Provider (NTLMSSP) security provider is based on the NTLM (Windows NT LAN Manager) authentication protocol. NTLMSSP ships with the following products:

  • Windows NT versions 3.5 and later
  • Windows 95
  • The RPC SDK for Windows 3.1, MS-DOS, and Macintosh platforms

The following topics describe how to use the NTLMSSP security provider.


Server Initialization

The example in this topic shows the initialization code to add to a server so clients can connect using NTLMSSP authentication.

When the server starts, it calls the InitSecurityInterface function. If the server is directly binding to SECURITY.DLL, it can discard the returned function table. If the server dynamically loads SECURITY.DLL, it must call GetProcAddress(SECURITY_ENTRYPOINT) to get a pointer to the InitSecurityInterface function. The server uses the function table returned by InitSecurityInterface to make subsequent calls to the security provider functions.

Next, the server calls the QuerySecurityPackageInfo function to get the maximum length of the security token from the cbMaxToken member of the SecPkgInfo structure, as follows:

SECURITY_STATUS SecStatus;
PSecPkgInfo PackageInfo;
SecStatus = QuerySecurityPackageInfo(
    TEXT("NTLM"),
    &PackageInfo
);

The server then calls the AcquireCredentialsHandle function with the following parameters. The credential handle does not expire, so the server can ignore the expiration time.

CredHandle ServerCredential;  // global variable, used for the life
                              // of the process
TimeStamp Expiration;         // local variable, may be discarded
                              // after call returns

SecStatus = AcquireCredentialsHandle(
    NULL,                 // no principal name
    TEXT("NTLM"),         // package name
    SECPKG_CRED_INBOUND,  // credential use flag
    NULL,                 // no logon identifier
    NULL,                 // no package-specific data
    NULL,                 // no GetKey function
    NULL,                 // no GetKey function argument
    &ServerCredential,    // receives new credential handle
    &Expiration           // receives expiration time for the handle
);


Client Initialization

The example in this topic shows the initialization code to add to the client of a transport application to connect using NTLMSSP authentication.

The initialization when the client starts is similar to that described for the server in Server Initialization. The client calls the InitSecurityInterface function. As with the server, if the client is binding directly to SECURITY.DLL, it can discard the returned function table; otherwise, it must use the function table to make subsequent calls to the security provider functions. The client must also call the QuerySecurityPackageInfo function to get the maximum security buffer size.

When the client is ready to make a connection, it calls the AcquireCredentialsHandle function. The client must save the client credential handle for use when calling the InitializeSecurityContext function, but it can discard the other parameters after the call to AcquireCredentialsHandle.

If the client program needs to use additional credentials instead of the logon credentials (the user name, domain name, and password the user logged on with), it must provide them in the AcquireCredentialsHandle call. Note that the SEC_WINNT_AUTH_IDENTITY structure used to specify additional credentials in the following example is a package-specific structure defined in RPCDCE.H.

SEC_WINNT_AUTH_IDENTITY AdditionalCredentials;
BOOL SupplyCredentials;
CredHand ClientCredentials;
TimeStamp Expiration;

//
// If there are additional credentials stored in UserName,
// DomainName, and Password, fill them in here
//

#ifdef UNICODE
AdditionalCredentials.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE
#else
AdditionalCredentials.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI
#endif

//
// Set the flag indicating that we are supplying credentials to
// FALSE. We will set this to TRUE if a user name, domain name, or
// password has been supplied. If this is FALSE when we call
// AcquireCredentialsHandle, we will pass in NULL for the pAuthData
// parameter.
//

SupplyCredentials = FALSE;

if (UserName != NULL)
{
    AdditionalCredentials.User = UserName;
    AdditionalCredentials.UserLength = strlen(UserName);
    //
    // Set the flag to indicate that we are supplying credentials.
    //
    SupplyCredentials = TRUE;
}

//
// Do the same thing for the password and domain name.
//

SecStatus = AcquireCredentialsHandle(
    NULL,                       // no principal name
    TEXT("NTLM"),               // package name
    SECPKG_CRED_OUTBOUND,       // credential use flag
    NULL,                       // no logon identifier
    SupplyCredentials ?         // If we are supplying credentials,
      &AdditionalCredentials :  // pass in the additional credentials.
      NULL,
    NULL,                       // no GetKey function
    NULL,                       // no GetKey function argument
    &ClientCredential,          // receives the new credential
    &Expiration                 // receives the expiration time of
                                // the credential
    );

The credential handle does not expire, so the client can ignore the expiration time for this security package.

Next, the client calls the InitializeSecurityContext function to start setting up the security context.

CtxtHandle ClientContext;
TimeStamp Expiration;
SecBufferDesc OutputBufferDescriptor;
SecBuffer OutputSecurityToken;
ULONG ContextRequirements;
ULONG ContextAttributes;

//
// Build the output buffer descriptor.
//

OutputBufferDescriptor.cBuffers = 1
OutputBufferDescriptor.pBuffers = &OutputSecurityToken;
OutputBufferDescriptor.ulVersion = SECBUFFER_VERSION;

OutputSecurityToken.BufferType = SECBUFFER_TOKEN;
OutputSecurityToken.cbBuffer = PackageInfo->cbMaxToken;
OutputSecurityToken.pvBuffer =
    LocalAlloc(0, OutputSecurityToken.cbBuffer);

//
// Check for memory allocation failure here.
//

//
// Compute context requirements.
// If you want message integrity, ask for
//     replay or sequence detection.
// If you want message encryption, ask for confidentiality.
//

ContextRequirements = ISC_REQ_REPLAY_DETECT;

//
// Assume that TargetName is the name of the target server, or NULL.
// Make the call to InitializeSecurityContext.
//

SecStatus = InitializeSecurityContext(
      &ClientCredential
      NULL,                     // no context handle yet
      TargetName,               // target name, if available
      ContextRequirements,
      0,                        // reserved parameter
      SECURITY_NATIVE_DREP,     // target data representation
      NULL,                     // no input buffer
      0,                        // reserved parameter
      &ClientContext,           // receives new context handle
      &ContextAttributes,       // receives context attributes
      &OutputBufferDescriptor,  // receives output security token
      &Expiration               // receives context expiration time
      );

This InitializeSecurityContext call returns SEC_I_CONTINUE_NEEDED on success, or an error code on failure. If the function is successful, the client transmits the token buffer to the server. The token buffer is stored in the pvBuffer member of the OutputSecurityToken structure. The cbBuffer member of the structure specifies the length of the buffer.

To finish creating the security token, the server must call the AcceptSecurityContext function and send the output back to the client. The client calls InitializeSecurityContext again, followed by another call by the server to AcceptSecurityContext. Server Authentication describes this sequence of calls.


Server Authentication

The code in this topic describes the client and server interactions to create a security context.

The example begins after the client makes its initial call to the InitializeSecurityContext function and sends the output to the server. The example assumes that the security buffer produced by the client's call to InitializeSecurityContext is in InputSecurityBuffer, and the length of that buffer is in InputSecurityBufferSize.

The example begins with the server's first call to the AcceptSecurityContext function.

CtxtHandle ServerContext;
TimeStamp Expiration;
SecBufferDesc InputBufferDescriptor;
SecBuffer InputSecurityToken;
SecBufferDesc OutputBufferDescriptor;
SecBuffer OutputSecurityToken;
ULONG ContextRequirements;
ULONG ContextAttributes;

//
// Build the input buffer descriptor.
//

InputBufferDescriptor.cBuffers = 1
InputBufferDescriptor.pBuffers = &InputSecurityToken;
InputBufferDescriptor.ulVersion = SECBUFFER_VERSION;

InputSecurityToken.BufferType = SECBUFFER_TOKEN;
InputSecurityToken.cbBuffer = InputSecurityBufferSize;
InputSecurityToken.pvBuffer = InputSecurityBuffer;

//
// Build the output buffer descriptor. We need to allocate a buffer
// to hold this buffer.
//

OutputBufferDescriptor.cBuffers = 1
OutputBufferDescriptor.pBuffers = &OutputSecurityToken;
OutputBufferDescriptor.ulVersion = SECBUFFER_VERSION;

OutputSecurityToken.BufferType = SECBUFFER_TOKEN;
OutputSecurityToken.cbBuffer = PackageInfo->cbMaxToken;
OutputSecurityToken.pvBuffer = LocalAlloc(0, PackageInfo->cbMaxToken);

//
// Check for memory allocation failure here.
//

//
// We can pass zero for the context requirements because the buffer
// from the client will negotiate those requirements.
//

SecStatus = AcceptSecurityContext(
      &ServerCredential,
      NULL,                     // no context handle yet
      &InputBufferDescriptor,
      0,                        // no context requirements
      SECURITY_NATIVE_DREP,
      &ServerContext,           // receives new context handle
      &OutputBufferDescriptor,  // receives output security token
      &ContextAttributes,       // receives context attributes
      &Expiration               // receives context expiration time
      );

If this AcceptSecurityContext call is successful, it returns SEC_I_CONTINUE_NEEDED, and the server transmits the output security buffer and length back to the client. If it fails, it returns an error code.

The client makes a second call to the InitializeSecurityContext function. The parameters are similar to the first call. The example assumes that the security buffer returned from the server is in InputSecurityBuffer, and the length of that buffer is in InputSecurityBufferSize.

TimeStamp Expiration;
SecBufferDesc OutputBufferDescriptor;
SecBuffer OutputSecurityToken;
SecBufferDesc InputBufferDescriptor;
SecBuffer InputSecurityToken;
ULONG ContextAttributes;

//
// Build the input buffer descriptor.
//

InputBufferDescriptor.cBuffers = 1
InputBufferDescriptor.pBuffers = &InputSecurityToken;
InputBufferDescriptor.ulVersion = SECBUFFER_VERSION;

InputSecurityToken.BufferType = SECBUFFER_TOKEN;
InputSecurityToken.cbBuffer = InputSecurityBufferSize;
InputSecurityToken.pvBuffer = InputSecurityBuffer;

//
// Build the output buffer descriptor.
//

OutputBufferDescriptor.cBuffers = 1
OutputBufferDescriptor.pBuffers = &OutputSecurityToken;
OutputBufferDescriptor.ulVersion = SECBUFFER_VERSION;

OutputSecurityToken.BufferType = SECBUFFER_TOKEN;
OutputSecurityToken.cbBuffer = PackageInfo->cbMaxToken;
OutputSecurityToken.pvBuffer =
        LocalAlloc(0, OutputSecurityToken.cbBuffer);

//
// Check for memory allocation failure here.
//

//
// We can ignore the pszTargetName and fContextReq parameters on this
// call, because we passed them on the first call. This time,
// instead of passing NULL for phContext, we pass the context
// handle received on the first call.
//

SecStatus = InitializeSecurityContext(
      &ClientCredential
      &ClientContext,
      NULL,                     // no target name this time
      0,                        // no context requirements
      0,                        // reserved parameter
      SECURITY_NATIVE_DREP,     // target data representation
      &InputBufferDescriptor,   // input buffer
      0,                        // reserved parameter
      &ClientContext,           // same as the old context
      &ContextAttributes,       // receives context attributes
      &OutputBufferDescriptor,  // receives output security token
      &Expiration               // receives context expiration time
      );

If this InitializeSecurityContext call is successful, it returns SEC_E_OK, and the client transmits the output security buffer and buffer length to the server, as it did after the first call to InitializeSecurityContext. If it fails, it returns an error code.

The client has now finished setting up the security context. The client can begin using the security context in calls to the MakeSignature and VerifySignature functions to make and verify message signatures, even though the server has not yet finished authenticating the client.

The server makes the final call to AcceptSecurityContext. The input buffer and buffer size are assumed to be in InputSecurityBuffer and InputSecurityBufferSize. On this call, there is no output message, so we pass NULL for the pOutput parameter.

TimeStamp Expiration;
SecBufferDesc InputBufferDescriptor;
SecBuffer InputSecurityToken;
ULONG ContextAttributes;

//
// Build the input buffer descriptor.
//

InputBufferDescriptor.cBuffers = 1
InputBufferDescriptor.pBuffers = &InputSecurityToken;
InputBufferDescriptor.ulVersion = SECBUFFER_VERSION;

InputSecurityToken.BufferType = SECBUFFER_TOKEN;
InputSecurityToken.cbBuffer = InputSecurityBufferSize;
InputSecurityToken.pvBuffer = InputSecurityBuffer;

//
// This time, instead of passing NULL for phContext, we pass the
// context handle we received on the first call.
//

SecStatus = AcceptSecurityContext(
      &ServerCredential
      &ServerContext,
      &InputBufferDescriptor,  // input buffer
      0,                       // no context requirements.
      SECURITY_NATIVE_DREP,    // target data representation
      &ServerContext,          // same as the old context
      &ContextAttributes,      // receives context attributes
      NULL,                    // no output security token
      &Expiration              // receives context expiration time
      );

This AcceptSecurityContext call returns SEC_E_OK if successful, or an error code if it fails. If this succeeds, the client was successfully authenticated. The server can now call the ImpersonateSecurityContext function to impersonate the caller, the QueryContextAttributes function to obtain the caller's identity, as well as the MakeSignature and VerifySignature functions to make and verify message signatures.


Using a Security Context

Both the client side and the server side of a transport application can use the MakeSignature function to generate a signed message to send to the other side. The receiving side then uses the VerifySignature function to verify that a signature matches the received message. If the application wants to generate signed messages, the client must have specified the ISC_REQ_REPLAY_DETECT or ISC_REQ_SEQUENCE_DETECT flag in its first call to the InitializeSecurityContext function.

When the client calls MakeSignature or VerifySignature, it uses the ClientContext handle it obtained from its first call to the InitializeSecurityContext function. When the server calls these functions, it uses the ServerContext handle it obtained from its call to the AcceptSecurityContext function.

The following example shows the client side generating a signed message to send to the server. Before calling MakeSignature, the client calls the QueryContextAttributes function with a SecPkgContext_Sizes structure to determine the length of the buffer needed to hold the message signature. If the cbMaxSignature member is zero, the security package does not support signing messages; otherwise, this member indicates the size of the buffer to allocate to receive the signature.

SecPkgContext_Sizes ContextSizes;

SecStatus = QueryContextAttributes(
    &ClientContext,
    SECPKG_ATTR_SIZES,
    &ContextSizes
    );

//
// Now, assume that the message is in the variable MessageBuffer, and
// its length is in MessageBufferSize. Build up the buffer descriptors
// to pass to the MakeSignature call.
//

SecBufferDesc InputBufferDescriptor;
SecBuffer InputSecurityToken[2];

//
// Build the input buffer descriptor.
//

InputBufferDescriptor.cBuffers = 2
InputBufferDescriptor.pBuffers = InputSecurityToken;
InputBufferDescriptor.ulVersion = SECBUFFER_VERSION;

//
// Build a security buffer for the message itself. If we added
// the SECBUFFER_READONLY attribute, this buffer would not get
// signed.
//

InputSecurityToken[0].BufferType = SECBUFFER_DATA;
InputSecurityToken[0].cbBuffer = MessageBufferSize;
InputSecurityToken[0].pvBuffer = MessageBuffer;

//
// Allocate and build a security buffer for the message
// signature.
//

InputSecurityToken[1].BufferType = SECBUFFER_TOKEN;
InputSecurityToken[1].cbBuffer = ContextSizes.cbMaxSignature;
InputSecurityToken[1].pvBuffer =
        LocalAlloc(0, ContextSizes.cbMaxSignature);

//
// Check for memory allocation failure here
//

//
// Call MakeSignature now.
// You need not specify the sequence number because NTLM will
// provide one.
// The quality of service is ignored.
//

SecStatus = MakeSignature(
    &ClientContext,
    0,                       // no quality of service
    &InputBufferDescriptor,  // input message descriptor
    0                        // no sequence number
    );

The MakeSignature function returns successfully if the context was set up to allow signing messages and the input buffer descriptor is correctly formatted. If the function is successful, the client sends the message buffer and its size, along with the signature buffer and its size, to the server.

The server calls the the QueryContextAttributes function with a SecPkgContext_Sizes structure to determine whether the client wants messages to be signed and verified. A nonzero value for the cbMaxSignature member indicates that messages need to be verified.

The following example shows the server code to verify a signed message. The example is built on the assumption that the signature buffer and size are in SignatureBuffer and SignatureBufferSize, and the message buffer and size are in MessageBuffer and MessageBufferSize.

SecBufferDesc InputBufferDescriptor;
SecBuffer InputSecurityToken[2];
ULONG fQOP;

//
// Build the input buffer descriptor.
//

IputBufferDescriptor.cBuffers = 2
InputBufferDescriptor.pBuffers = InputSecurityToken;
InputBufferDescriptor.ulVersion = SECBUFFER_VERSION;

//
// Build a security buffer for the message itself. If we added
// the SECBUFFER_READONLY attribute, this buffer would not get
// signed.
//

InputSecurityToken[0].BufferType = SECBUFFER_DATA;
InputSecurityToken[0].cbBuffer = MessageBufferSize;
InputSecurityToken[0].pvBuffer = MessageBuffer;

//
// Allocate and build a security buffer for the message
// signature.
//

InputSecurityToken[1].BufferType = SECBUFFER_TOKEN;
InputSecurityToken[1].cbBuffer = SignatureBufferSize;
InputSecurityToken[1].pvBuffer = SignatureBuffer;

//
// Call VerifySignature now.
// You need not specify the sequence number because NTLM will
// provide one.
// The quality of service is ignored.
//

SecStatus = VerifySignature(
      &ServerContext,
      &InputBufferDescriptor,  // input message descriptor
      0,                       // no sequence number
      &fQOP                    // Quality of protection
      );

NTLMSSP does not fill in the fQOP parameter, so it should be ignored. If the messages have been received in the correct order and have not been modified, the VerifySignature function returns SEC_E_OK. Otherwise, VerifySignature may return SEC_E_OUT_OF_SEQUENCE or SEC_E_MESSAGE_ALTERED.

To delete the security contexts after the client and server have finished communicating, both sides can call the DeleteSecurityContext function with their respective context handles. The client should also call the FreeCredentialsHandle function when it has finished communicating with any server or has finished using the additional credentials passed to the AcquireCredentialsHandle function. The server should call DeleteSecurityContext when it is ready to shut down, but before unloading the DLL.


SSPI Reference

SSPI Functions

SSPI Structures

SSPI Status Codes


SSPI Functions

The following is a complete, alphabetic listing of functions used with SSPI. Functional groupings follow.

AcceptSecurityContext
AcquireCredentialsHandle
ApplyControlToken
DeleteSecurityContext
EnumerateSecurityPackages
FreeContextBuffer
FreeCredentialsHandle
ImpersonateSecurityContext
InitializeSecurityContext
InitSecurityInterface
MakeSignature
QueryContextAttributes
QueryCredentialsAttributes QuerySecurityPackageInfo
RevertSecurityContext VerifySignature

Credential Management Functions

AcquireCredentialsHandle
FreeCredentialsHandle
QueryCredentialsAttributes

Context Management Functions

AcceptSecurityContext
ApplyControlToken
DeleteSecurityContext
FreeContextBuffer
ImpersonateSecurityContext
InitializeSecurityContext
QueryContextAttributes
RevertSecurityContext

Message Support Functions

MakeSignature
VerifySignature

Package Management Functions

EnumerateSecurityPackages
InitSecurityInterface
QuerySecurityPackageInfo


AcceptSecurityContext

The AcceptSecurityContext function enables the server component of a transport application to establish a security context between the server and a remote client. The remote client uses the InitializeSecurityContext function to start the process of establishing a security context. The server may need one or more reply tokens from the remote client to complete the establishment of the security context.

SECURITY_STATUS AcceptSecurityContext(
  PCredHandle phCredential,  // handle to the credentials
  PCtxtHandle phContext,     // handle of partially formed context
  PSecBufferDesc pInput,     // pointer to the input buffers
  ULONG fContextReq,         // required context attributes
  ULONG TargetDataRep,       // data representation on the target
  PCtxtHandle phNewContext,  // receives the new context handle
  PSecBufferDesc pOutput,    // pointer to the output buffers
  PULONG pfContextAttr,      // receives the context attributes
  PTimeStamp ptsExpiry       // receives the life span of the security
                             // context
);

Parameters

phCredential
Handle to the server's credentials. The server calls the AcquireCredentialsHandle function to retrieve this handle.
phContext
Pointer to a CtxtHandle structure. On the first call to AcceptSecurityContext, this pointer is NULL. On the second call, this the handle to the partially formed context that was returned in the phNewContext parameter by the first call.
pInput
Pointer to a SecBufferDesc structure that contains the input buffer descriptor. Depending on the security package, this parameter may be NULL if no initial token is ready.
fContextReqs
A set of bit flags that specify the attributes that the server requires for the context to be established. This value can include a combination of the following flags:

ASC_REQ_DELEGATE
ASC_REQ_MUTUAL_AUTH
ASC_REQ_REPLAY_DETECT
ASC_REQ_SEQUENCE_DETECT
ASC_REQ_CONFIDENTIALITY
ASC_REQ_USE_SESSION_KEY
ASC_REQ_ALLOCATE_MEMORY
ASC_REQ_USE_DCE_STYLE
ASC_REQ_DATAGRAM
ASC_REQ_CONNECTION
ASC_REQ_CALL_LEVEL
ASC_REQ_EXTENDED_ERROR
ASC_REQ_STREAM
ASC_REQ_INTEGRITY

TargetDataRep
Indicates the data representation (byte ordering, and so on) on the target. You can specify SECURITY_NATIVE_DREP to indicate that the native format is in use.
phNewContext
Pointer to a CtxtHandle structure. On the first call to AcceptSecurityContext, this pointer receives the new context handle. On the second call, this parameter can be the same as the handle specified in the phContext parameter.
pOutput
Pointer to a SecBufferDesc structure that contains the output buffer descriptor.
pfContextAttributes
Pointer to a variable that receives a set of bit flags indicating the attributes of the established context. For a description of the various attributes, see Context Requirements. This value can include any of the following flags:

ASC_RET_DELEGATE
ASC_RET_MUTUAL_AUTH
ASC_RET_REPLAY_DETECT
ASC_RET_SEQUENCE_DETECT
ASC_RET_CONFIDENTIALITY
ASC_RET_USE_SESSION_KEY
ASC_RET_ALLOCATED_MEMORY
ASC_RET_USED_DCE_STYLE
ASC_RET_DATAGRAM
ASC_RET_CONNECTION
ASC_RET_CALL_LEVE
ASC_RET_THIRD_LEG_FAILED
ASC_RET_EXTENDED_ERROR
ASC_RET_STREAM
ASC_RET_INTEGRITY

ptsExpiry
Pointer to a PTimeStamp variable that receives the expiration time of the context. The security provider should always return this value in local time.

Return Values

If the function succeeds, the return value is one of the following success codes.

Value | Meaning
SEC_E_OK | The security context was successfully established.
SEC_I_CONTINUE_NEEDED |
SEC_I_COMPLETE_NEEDED |
SEC_I_COMPLETE_AND_CONTINUE |

If the function fails, the return value is one of the following error codes.

Value | Meaning
SEC_E_INVALID_TOKEN | The token passed to the function is invalid.
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.
SEC_E_LOGON_DENIED | The logon failed.
SEC_E_INTERNAL_ERROR | The Local Security Authority cannot be contacted.
SEC_E_NO_AUTHENTICATING_AUTORITY | No authority could be contacted for authentication.

Remarks

The AcceptSecurityContext function is the server counterpart to the InitializeSecurityContext function.

When a request comes in, the server uses the fContextReq parameter to specify what it requires of the session. In this fashion, a server can specify that clients must be capable of using a confidential or integrity-checked session, and it can fail clients that cannot meet that demand. As an alternative, a server can require nothing, and whatever the client can provide or requires is returned in the pfContextAttr parameter.

For a package that supports three-leg mutual authentication, the calling sequence is as follows:

  • The client transmits a token to the server.
  • The server calls AcceptSecurityContext the first time, generating a reply token.
  • The client passes this token in a second call to InitializeSecurityContext, which generates a final token.
  • The server uses this token in the final call to AcceptSecurityContext to complete the session.

LAN Manager and Windows NT use another authentication style.

  • The client connects to negotiate a protocol.
  • The server calls AcceptSecurityContext to set up a context and generate a challenge to the client.
  • The client calls InitializeSecurityContext and creates the response.
  • The server then calls AcceptSecurityContext the final time to allow the security package to verify that the response is appropriate for the challenge.

See Also

InitializeSecurityContext


AcquireCredentialsHandle

The AcquireCredentialsHandle function allows applications to acquire a handle to pre-existing credentials associated with the user on whose behalf the call is made. These pre-existing credentials are established through a system logon not described here.

Note that this is different from "login to the network" and does not imply gathering of credentials.

SECURITY_STATUS AcquireCredentialsHandle(
  SEC_CHAR * pszPrincipal,  // name of principal
  SEC_CHAR * pszPackage, // name of package
  ULONG fCredentialUse,  // flags indicating use
  PLUID pvLogonID,       // pointer to logon identifier
  PVOID pAuthData,       // package-specific data
  PVOID pGetKeyFn,       // pointer to GetKey function
  PVOID pvGetKeyArgument,  // value to pass to GetKey
  PCredHandle phCredential,  // credential handle
  PTimeStamp ptsExpiry   // life time of the returned credentials
);

Parameters

pszPrincipal
Pointer to a null-terminated string the specifies the name of the principal whose credentials the handle will reference. Note that if the process requesting the handle does not have access to the credentials, the function returns an error. A null string indicates that the process requires a handle to the credentials of the user under whose security context it is executing.
pszPackage
Pointer to a null-terminated string the specifies the name of the security package with which these credentials will be used. This is a security package name returned in the Name member of a SecPkgInfo structure returned by the EnumerateSecurityPackages function.
fCredentialUse
A flag that indicates how these credentials will be used. This parameter can one of the following values:

CRED_INBOUND
CRED_OUTBOUND
CRED_BOTH

The credentials created with the CRED_INBOUND option can be used only for validating incoming calls. They cannot be used for accessing objects.

pvLogonId
Pointer to a Windows NT–style logon identifier, an LUID. This parameter is provided for file-system processes such as network redirectors. This parameter can be NULL.
pAuthData
Pointer to package-specific data. This parameter can be NULL, indicating that the default credentials for that package should be used. The RPC run time passes whatever was provided in the RpcBindingSetAuthInfo function.
pGetKeyFn
Pointer to a SEC_GET_KEY_FN function to retrieve the key for the function. The security package can call this function, as provided by the RPC run-time transport application. This parameter can be NULL if the transport application does not support callbacks to retrieve credentials.
pvGetKeyArgument
Specifies the pointer argument that the security provider should pass to the GetKey function. This parameter can be NULL.
phCredential
Pointer to CredHandle structure that receives the credential handle.
ptsExpiry
Pointer to a TimeStamp variable that receives the time at which the returned credentials expire. The value returned in this member depends on the security package. The security provider should always return this value in local time.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value may be one of the following error codes.

Value | Meaning
SEC_E_UNKNOWN_CREDENTIALS | The credentials supplied to the package were not recognized.
SEC_E_NO_CREDENTIALS | No credentials are available in the security package.
SEC_E_NOT_OWNER | The caller of the function does not own the necessary credentials.
SEC_E_INSUFFICIENT_MEMORY | Not enough memory is available to complete this request.
SEC_E_INTERNAL_ERROR | The Local Security Authority cannot be contacted.
SEC_E_SECPKG_NOT_FOUND | The requested security package does not exist.

Remarks

The AcquireCredentialsHandle function returns a handle to the credentials of a principal (user, client) as used by a specific security package. The handle returned can be used in subsequent calls to the AcceptSecurityContext and InitializeSecurityContext functions.

The AcquireCredentialsHandle function will not let a process obtain a handle to credentials that are not related to the process; in other words, a process cannot get the credentials of another user who is logged on to the same computer. There is no way to determine whether a process is a Trojan horse if it is executed by the user.

The AcquireCredentialsHandle function uses the following algorithm to determine whether to grant the request for a handle to the credentials.

If the caller is a system process with the SE_TCB_NAME privilege (for example, an FSP), and the caller provides both the name and logon identifier, the function verifies that they match before returning the credentials. If only one is provided, the function returns a handle to that identifier.

If the caller is not a system process, the caller can only obtain a handle to the credentials under which it is running The caller can provide the name or the logon identifier, but it must be for the current session or the request fails.

When you no longer need the returned credentials, call the FreeCredentialsHandle function.

See Also

FreeCredentialsHandle


ApplyControlToken

The ApplyControlToken function provides a way to apply a control token to a security context. A token can be received when the security context is being established (InitializeSecurityContext), or with a per-message security service (verify, unseal).

This function allows additional or replacement tokens to be applied to a context.

SECURITY_STATUS ApplyControlToken(
  PCtxtHandle phContext, // handle of the context to modify
  PSecBufferDesc pInput  // input token to apply
);

Parameters

phContext
Handle to the context to which the token is applied.
pInput
Pointer to a SecBufferDesc structure with a pointer to a SecBuffer structure that contains the input token to apply to the context.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

The ApplyControlToken function may modify the context based on this token.

See Also

ImpersonateSecurityContext, SecBufferDesc


CompleteAuthToken

The CompleteAuthToken function completes an authentication token. This function is used by protocols, like DCE, that need to revise the security information after the transport application has updated some message parameters.

SECURITY_STATUS CompleteAuthToken(
  PCtxtHandle phContext, // handle of the context to complete
  PSecBufferDesc pToken  // token to complete
);

Parameters

phContext
Handle of the context that needs to be completed.
pToken
Pointer to a SecBufferDesc structure that contains the buffer descriptor for the entire message.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.
SEC_E_INVALID_TOKEN | The token pased to the function is invalid.
SEC_E_INTERNAL_ERROR |

Remarks

The client of a transport application calls the CompleteAuthToken function to allow the security package to update a checksum or similar operation after all the protocol headers have been updated by the transport application. The client should call this function only if the InitializeSecurityContext call returned SEC_I_COMPLETE_NEEDED or SEC_I_COMPLETE_AND_CONTINUE.

See Also

InitializeSecurityContext


DeleteSecurityContext

The DeleteSecurityContext function deletes the local data structures associated with the specified security context.

SECURITY_STATUS DeleteSecurityContext(
  PCtxtHandle phContext  // handle of the context to delete
);

Parameters

phContext
Handle of the context to delete.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value can be the following error code.

Value | Meaning
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.

Remarks

The DeleteSecurityContext function terminates a security context. No further use of the context is permitted.


EnumerateSecurityPackages

The EnumerateSecurityPackages function returns an array of SecPkgInfo structures that describe the security packages available to the client.

SECURITY_STATUS EnumerateSecurityPackages(
  PULONG pcPackages,          // receives the number of packages
  PSecPkgInfo *ppPackageInfo  // receives array of information
);

Parameters

pcPackages
Pointer to a ULONG variable that receives the number of packages returned.
ppPackageInfo
Pointer to a variable that receives a pointer to an array of SecPkgInfo structures. Each structure contains information that describes a security package available from the security provider.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

The SecPkgInfo structures provide information that the caller can use to determine which security package best satisfies the requirements of the caller.

The caller can use the Name member of a SecPkgInfo structure to specify a security package in a call to the AcquireCredentialsHandle function.

The caller must assume that the security provider includes all available security packages in the single call to EnumerateSecurityPackages.

The caller must call the FreeContextBuffer function to free the buffer returned in ppPackageInfo.

See Also

AcquireCredentialsHandle, FreeContextBuffer, SecPkgInfo


FreeContextBuffer

The FreeContextBuffer function enables callers of security provider functions to free a memory buffer allocated by the security provider. For example, the InitializeSecurityContext function may allocate a buffer for returning the outbound context token.

SECURITY_STATUS FreeContextBuffer(
  PVOID pvContextBuffer  // buffer to free
);

Parameters

pvContextBuffer
Pointer to memory allocated by the security provider.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

The FreeContextBuffer function can free any memory allocated by a security package.

See Also

InitializeSecurityContext


FreeCredentialsHandle

The FreeCredentialsHandle function notifies the security system that the credentials are no longer needed. An application calls this function to free the credential handle acquired in the call to the AcquireCredentialsHandle function. When all references to this credential set have been removed, the credentials themselves can be removed.

SECURITY_STATUS FreeCredentialsHandle(
  PCredHandle  phCredential  // handle to free
);

Parameters

phCredential
Pointer to the credential handle obtained by using the AcquireCredentialsHandle function.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value may be the following error code.

Value | Meaning
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.

Remarks

The FreeCredentialsHandle function allows the security system to free any resources associated with the credential handle.

See Also

AcquireCredentialsHandle


ImpersonateSecurityContext

The ImpersonateSecurityContext function allows service providers to impersonate the caller. This function allows the application server to act as the client, and thus all necessary access controls are enforced.

SECURITY_STATUS ImpersonateSecurityContext(
  PCtxtHandle phContext  // handle of context to impersonate
);

Parameters

phContext
Handle of the context to impersonate. This handle must have been obtained in a call to the AcceptSecurityContext function.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value can be the following error code.

Value | Meaning
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.

Remarks

The service provider or application server calls the ImpersonateSecurityContext function when it needs to impersonate the caller. The server must have obtained a valid context handle by submitting to the security system the incoming security token from the client through the AcceptSecurityContext function. The server ends up with a context handle if the inbound context was validated successfully. The function creates an impersonation token and allows the thread or process to run with the impersonation context.

The application server must call the RevertSecurityContext function when it has finished or when it needs to restore its own security context.

Typically, ImpersonateSecurityContext is implemented only on security packages for which a call to the QuerySecurityPackageInfo function indicates impersonation support. The caller must also specify ASC_REQ_DELEGATION in the AcceptSecurityContext function.

See Also

AcceptSecurityContext, QuerySecurityPackageInfo, RevertSecurityContext


InitializeSecurityContext

The InitializeSecurityContext function initiates the outbound security context from a credential handle. The function establishes a security context between the client application and a remote peer. InitializeSecurityContext returns a token that the client must pass to the remote peer, which in turn submits it to the local security implementation through the AcceptSecurityContext call. The token generated should be considered opaque by all callers.

SECURITY_STATUS InitializeSecurityContext(
  PCredHandle phCredential,  // handle to the credentials
  PCtxtHandle phContext, // handle of partially formed context
  SEC_CHAR * pszTargetName,  // name of the target of the context
  ULONG fContextReq,     // required context attributes
  ULONG Reserved1,       // reserved; must be zero
  ULONG TargetDataRep,   // data representation on the target
  PSecBufferDesc pInput, // pointer to the input buffers
  ULONG Reserved2,       // reserved; must be zero
  PCtxtHandle phNewContext,  // receives the new context handle
  PSecBufferDesc pOutput,  // pointer to the output buffers
  PULONG pfContextAttr,  // receives the context attributes
  PTimeStamp ptsExpiry   // receives the life span of the security
                         // context
);

Parameters

phCredential
Handle to the credentials to use to create the context. The client retrieves this handle by calling the AcquireCredentialsHandle function.
phContext
Pointer to a CtxtHandle structure. On the first call to InitializeSecurityContext, this pointer is NULL. On the second call, this parameter is the handle to the partially formed context returned in the phNewContext parameter by the first call.
pszTargetName
Pointer to a null-terminated string that indicates the target of the context. The name is security-package specific.
fContextReq
A set of bit flags that indicate the requirements of the context. Not all packages can support all requirements. For a description of the various attributes, see Context Requirements. This parameter can include any of the following values:

ISC_REQ_DELEGATE
ISC_REQ_MUTUAL_AUTH
ISC_REQ_REPLAY_DETECT
ISC_REQ_SEQUENCE_DETECT
ISC_REQ_CONFIDENTIALITY
ISC_REQ_USE_SESSION_KEY
ISC_REQ_PROMPT_FOR_CREDS
ISC_REQ_USE_SUPPLIED_CREDS
ISC_REQ_ALLOCATE_MEMORY
ISC_REQ_USE_DCE_STYLE
ISC_REQ_DATAGRAM
ISC_REQ_CONNECTION
ISC_REQ_CALL_LEVEL
ISC_REQ_EXTENDED_ERROR
ISC_REQ_STREAM
ISC_REQ_INTEGRITY

Reserved1
Reserved value; must be zero.
TargetDataRep
Indicates the data representation (byte ordering, and so on) on the target. The constant SECURITY_NATIVE_DREP may be supplied by the transport application, indicating that the native format is in use.
pInput
Pointer to a SecBufferDesc structure that contains pointers to the buffers supplied as input to the package. The transport application should provide as much input as possible, although some packages may not be interested in the nonsecurity portions. This parameter is optional, particularly on the first call to InitializeSecurityContext.
Reserved2
Reserved value; must be zero.
phNewContext
Pointer to a CtxtHandle structure. On the first call to InitializeSecurityContext, this pointer receives the new context handle. On the second call, this can be the same as the handle specified in the phContext parameter.
pOutput
Pointer to a SecBufferDesc structure that contains pointers to the buffers that receive the output data. If a buffer was typed as READWRITE in the input, it will be there on output. The system will allocate a buffer for the security token if requested (through ISC_REQ_ALLOCATE_MEMORY), and fill in the address in the buffer descriptor for the security token.
pfContextAttributes
Pointer to a variable that receives a set of bit flags indicating the attributes of the established context. For a description of the various attributes, see Context Requirements. This value can include any of the following flags.

ISC_RET_DELEGATE
ISC_RET_MUTUAL_AUTH
ISC_RET_REPLAY_DETECT
ISC_RET_SEQUENCE_DETECT
ISC_RET_CONFIDENTIALITY
ISC_RET_USE_SESSION_KEY
ISC_RET_USED_COLLECTED_CREDS
ISC_RET_USED_SUPPLIED_CREDS
ISC_RET_ALLOCATED_MEMORY
ISC_RET_USED_DCE_STYLE
ISC_RET_DATAGRAM
ISC_RET_CONNECTION
ISC_RET_INTERMEDIATE_RETURN
ISC_RET_CALL_LEVEL
ISC_RET_EXTENDED_ERROR
ISC_RET_STREAM
ISC_RET_INTEGRITY

ptsExpiry
Pointer to a TimeStamp variable that receives the expiration time of the context. The security provider should always return this value in local time.

Return Values

If the function succeeds, the return value is one of the following success codes.

Value | Meaning
SEC_E_OK | The security context was successfully initialized. There is no need for another InitializeSecurityContext call, and no response from the server is expected.
SEC_I_CONTINUE_NEEDED | The client must send the output token to the server, and then pass the token returned by the server in a second call to InitializeSecurityContext.
SEC_I_COMPLETE_NEEDED | The client must finish building the message, and then call the CompleteAuthToken function.
SEC_I_COMPLETE_AND_CONTINUE | The client must call CompleteAuthToken, then pass the output to the server, and finally make a second call to InitializeSecurityContext.

If the function fails, the return value is one of the following error codes.

Value | Meaning
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.
SEC_E_TARGET_UNKNOWN | The target was not recognized.
SEC_E_LOGON_DENIED | The logon failed.
SEC_E_INTERNAL_ERROR | The Local Security Authority cannot be contacted.
SEC_E_NO_CREDENTIALS | No credentials are available in the security package.
SEC_E_NO_AUTHENTICATING_AUTHORITY | No authority could be contacted for authentication.

Remarks

The InitializeSecurityContext function is used by a client to initialize an outbound context.

For a two-leg security package, the calling sequence is as follows:

  1. The client calls the function with phContext set to NULL and fills in the buffer descriptor with the input message.
  2. The security package examines the parameters and constructs an opaque token, placing it in the TOKEN element in the buffer array. If the fContextReq parameter includes the ISC_REQ_ALLOCATE_MEMORY flag, the security package allocates the memory and returns the pointer in the TOKEN element.
  3. The client sends the token returned in the pOutput buffer to the target server. The server then passes the token as an input argument in a call to the AcceptSecurityContext function.
  4. AcceptSecurityContext may return a token, which the server sends to the client for a second call to InitializeSecurityContext.

For a three-leg (mutual authentication) security package, the calling sequence is as follows:

  1. The client calls the function as described earlier, but the package will return the SEC_I_CONTINUE_NEEDED success code.
  2. The client then sends the output token to the server and waits for the server's reply.
  3. Upon receipt of the server's response, the client calls InitializeSecurityContext again, with phContext set to the handle that was returned from the first call. The token received from the server is supplied in the pInput parameter. If the server has successfully responded, then the security package will respond with success, otherwise, it will invalidate the context.

To initialize a security context, more than one call to this function may be required, depending on the underlying authentication mechanism as well as the "choices" specified in the fContextReq parameter.

The fContextReq and pfContextAttributes are bit masks representing various context attributes. For a description of the various attributes, see Context Requirements. The pfContextAttributes parameter is valid on any successful return, but only on the final successful return should you examine the flags pertaining to security aspects of the context. Intermediate returns can set, for example, the ISC_RET_ALLOCATED_MEMORY flag.

The caller is responsible for determining whether the final context attributes are sufficient; if, for example, confidentiality was requested, but could not be established, some applications may choose to shut down the connection immediately.

When the ISC_REQ_PROMPT_FOR_CREDS flag is set, the security package attempts to prompt the user for the credentials to use for the connection. If the caller is not an interactive user (for example, a noninteractive service), this flag is ignored. During the prompt, the package may inquire if the supplied credentials should be retained; if so, the package can store them away for future use, relieving the user of having to enter credentials later. This behavior, if supported, should be configurable for environments in which the credentials cannot or should not be stored away.

If the ISC_REQ_USE_SUPPLIED_CREDS flag is set, the security package should look for a SECBUFFER_PKG_PARAMS buffer type in the pInput input buffer. This is not a generic solution, but it allows for a strong pairing of security package and application when appropriate.

If the ISC_REQ_ALLOCATE_MEMORY was specified, the caller must free the memory by calling the FreeContextBuffer function.

For example, the input token could be the challenge from a LAN Manager or Windows NT file server. In this case, the output token would be the NTLM encrypted response to the challenge.

The action the client takes depends on the return code from this function. If the return code is SEC_E_OK, there will be no second InitializeSecurityContext call, and no response from the server is expected. If the return code is SEC_I_CONTINUE_NEEDED, the client expects a token in response from the server, and passes it in a second call to InitializeSecurityContext. The SEC_I_COMPLETE_NEEDED return code indicates that the client must finish building the message, and call the CompleteAuthToken function. The SEC_I_COMPLETE_AND_CONTINUE code, of course, incorporates both of these actions.

If the connection is rejected by the server, the client must call the DeleteSecurityContext function at that time to free any resources.

See Also

AcceptSecurityContext, CompleteAuthToken, DeleteSecurityContext, FreeContextBuffer


InitSecurityInterface

The InitSecurityInterface function returns a pointer to a Security Service Provider Interface (SSPI) dispatch table. This function enables clients to use SSPI without binding directly to an implementation of the interface.

PSecurityFunctionTable InitSecurityInterface(VOID)

Return Values

If the function succeeds, the return value is a pointer to a SecurityFunctionTable structure.

If the function fails, the return value is NULL.

See Also

SecurityFunctionTable


MakeSignature

The MakeSignature function generates a cryptographic checksum of the message, and also includes sequencing information to prevent message loss or insertion. MakeSignature allows the application to choose between several cryptographic algorithms, if supported by the chosen mechanism. The MakeSignature function uses the security context referenced by the context handle.

SECURITY_STATUS MakeSignature(
  PCtxtHandle phContext,  // context to use
  ULONG fQOP,             // quality of protection
  PSecBufferDesc pMessage,  // message to sign
  ULONG MessageSeqNo      // message sequence number
);

Parameters

phContext
Handle to the context to use for the message.
fQOP
Specifies package-specific flags that indicate the quality of protection. A security package can use this parameter to enable the selection of cryptographic algorithms.
pMessage
Pointer to a SecBufferDesc structure. On input, the structure references one or more SecBuffer structures that contain the message to be signed. The function does not process buffers with the SECBUFFER_READONLY attribute.

The SecBufferDesc structure also references a SecBuffer structure of type SECBUFFER_TOKEN that receives the signature.

MessageSeqNo
Specifies a sequence number that the transport application assigned to the message. If the transport application does not maintain sequence numbers, this parameter is zero.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

The MakeSignature function generates a signature that is based on the message and the session key for the context.

If the transport application created the security context to support sequence detection and the caller provides a sequence number, the function includes this information in the signature. This protects against reply, insertion, and suppression of messages. The security package will incorporate the sequence number passed down from the transport application.

See Also

VerifySignature


QueryContextAttributes

The QueryContextAttributes function enables a transport application to query a security package for certain attributes of a security context.

SECURITY_STATUS QueryContextAttributes(
  PCtxtHandle phContext,   // handle of the context to query
  ULONG ulAttribute,   // attribute to query
  PVOID pBuffer        // buffer for attributes
);

Parameters

phContext
Handle to the context to be queried.
ulAttribute
Specifies the attribute of the context to be returned. This parameter can be one of the following values.
Value | Meaning
SECPKG_ATTR_SIZES | Query the sizes of the structures used in the per-message functions. The pBuffer parameter is a pointer to a SecPkgContext_Sizes structure.
SECPKG_ATTR_NAMES | Query the name associated with the context. The pBuffer parameter is a pointer to a SecPkgContext_Names structure.
SECPKG_ATTR_LIFESPAN | Query the life span of the context. pBuffer is a pointer to a SecPkgContext_Lifespan structure.
SECPKG_ATTR_DCE_INFO | Query for authorization data used by DCE services. pBuffer is a pointer to a SecPkgContext_DceInfo structure.
SECPKG_ATTR_STREAM_SIZES | Query the sizes of the various stream components used in the per-message functions. The pBuffer parameter is a pointer to a SecPkgContext_StreamSizes structure.
SECPKG_ATTR_AUTHORITY | Query the name of the authenticating authority. The pBuffer parameter is a pointer to a SecPkgContext_Authority structure.
SECPKG_ATTR_KEY_INFO | Query information about the keys used in a security context. The pBuffer parameter is a pointer to a SecPkgContext_KeyInfo structure.

pBuffer
Pointer to a structure that receives the attributes. The type of structure pointed to depends on the value specified in the ulAttribute parameter.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

The structure pointed to by the pBuffer parameter varies, depending on the attribute being queried. The caller must allocate the structure itself, but the package allocates other pointers that are returned in the structure. Any pointers allocated by the package can be freed by calling the FreeContextBuffer function.

See Also

FreeContextBuffer, SecPkgContext_DceInfo, SecPkgContext_Lifespan, SecPkgContext_Names, SecPkgContext_Sizes, SecPkgContext_StreamSizes


QueryCredentialsAttributes

The QueryCredentialsAttributes function retrieves the attributes of a credential, such as the name associated with the credential.

SECURITY_STATUS QueryCredentialsAttributes(
  PCredHandle phCredential,  // credential to query
  ULONG ulAttribute,         // attribute to query
  PVOID pBuffer              // buffer that receives attributes
);

Parameters

phCredential
Handle to the credentials to be queried.
ulAttribute
Specifies the attribute to query. This parameter must be SECPKG_CRED_ATTR_NAMES.
pBuffer
Pointer to a buffer that receives the requested attribute. For the SECPKG_CRED_ATTR_NAMES attribute, pBuffer must point to a SecPkgCredentials_Names structure.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value may be one of the following error codes.

Value | Meaning
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.
SEC_E_INSUFFICIENT_MEMORY | Insufficient memory.

Remarks

The QueryCredentialsAttributes function allows a customer of the security services to determine the name associated with the specified credentials.

The caller must allocate the structure pointed to by the pBuffer parameter. The security provider allocates the buffer for any pointer returned in the pBuffer structure. The caller can call the FreeContextBuffer function to free any pointers allocated by the security provider.

See Also

FreeContextBuffer


QuerySecurityPackageInfo

The QuerySecurityPackageInfo function retrieves information about a specified security package. This information includes the bounds on sizes of authentication information, credentials, and contexts.

SECURITY_STATUS QuerySecurityPackageInfo(
  SEC_CHAR * pszPackageName,   // name of package
  PSecPkgInfo *ppPackageInfo   // receives package information
);

Parameters

pszPackageName
Pointer to a null-terminated string that specifies the name of the security package.
ppPackageInfo
Pointer to a variable that receives a pointer to a SecPkgInfo structure containing information about the specified security package.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

The caller must call the FreeContextBuffer function to free the buffer returned in ppPackageInfo.

See Also

FreeContextBuffer, SecPkgInfo


RevertSecurityContext

The RevertSecurityContext function allows a service provider to discontinue the impersonation of the caller and restore its own security context.

SECURITY_STATUS RevertSecurityContext(
  PCtxtHandle phContext  // handle of the context being impersonated
);

Parameters

hContext
Handle of the context being impersonated. This handle must have been obtained in the call to the AcceptSecurityContext function and used in the call to the ImpersonateSecurityContext function.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value can be the following error code.

Value | Meaning
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.

Remarks

The service provider or an application server calls the RevertSecurityContext function when it needs to stop impersonating the caller. The server must have used this handle in the ImpersonateSecurityContext function.

See Also

AcceptSecurityContext, ImpersonateSecurityContext


VerifySignature

The VerifySignature function verifies the signature of a message at the other end.

SECURITY_STATUS VerifySignature(
  PCtxtHandle phContext,  // context to use
  PSecBufferDesc pMessage,  // message to verify
  ULONG MessageSeqNo,     // sequence number
  PULONG pfQOP            // quality of protection
);

Parameters

phContext
Handle to the context to use for the message.
pMessage
Pointer to a SecBufferDesc structure that references a set of SecBuffer structures that contain the message and signature to verify. The signature is in a SecBuffer structure of type SECBUFFER_TOKEN.
MessageSeqNo
Specifies the sequence number expected by the transport application, if any. If the transport application does not maintain sequence numbers, this parameter is zero.
pfQOP
Pointer to a ULONG variable that receives package-specific flags that indicate the quality of protection.

Return Values

If the function verifies that the message was received in the correct sequence and has not been modified, the return value is SEC_E_OK.

If the function determines that the message is not correct according to the information in the signature, the return value can be one of the following error codes.

Value | Meaning
SEC_E_OUT_OF_SEQUENCE | The message was not received in the correct sequence.
SEC_E_MESSAGE_ALTERED | The message has been altered.

Remarks

The VerifySignature function verifies that the message received was correct according to the information in the signature.

See Also

MakeSignature


SSPI Structures

The following structures (and portable types) are used in SSPI.

Portable Types


Portable Types

In the interest of portability to other platforms, the following types are used on the following platforms.

Win32

Win32 is a flat, 32-bit environment, which supports the Unicode character set. As such, the following types are defined:

typedef wchar_t      SEC_CHAR;

typedef struct _SECURITY_INTEGER {
      unsigned long      LowPart;
      long            HighPart;
} SECURITY_INTEGER;

typedef SECURITY_INTEGER      TimeStamp, * PTimeStamp;

Win16, MS-DOS

These environments are segmented, 16-bit real-mode environments.

typedef unsigned char      SEC_CHAR;

typedef unsigned long      TimeStamp, __far * PTimeStamp;

Handles

Handles are defined as follows:

typedef struct _SecHandle {
      unsigned long      dwLower;
      unsigned long      dwUpper;
} SecHandle, * PSecHandle;

typedef SecHandle      CredHandle;
typedef PSecHandle     PCredHandle;

typedef SecHandle      CtxtHandle;
typedef PSecHandle     PCtxtHandle;

Note that for 16-bit environments, the PSecHandle type is actually a __far pointer.


SecurityFunctionTable

The SecurityFunctionTable structure is a dispatch table that contains pointers to the functions defined in the Security Service Provider Interface .

typedef struct _SECURITY_FUNCTION_TABLE {
  unsigned long                       dwVersion;
  ENUMERATE_SECURITY_PACKAGES_FN      EnumerateSecurityPackages;
  void SEC_FAR *                      Reserved1;
  ACQUIRE_CREDENTIALS_HANDLE_FN       AcquireCredentialsHandle;
  FREE_CREDENTIALS_HANDLE_FN          FreeCredentialHandle;
  void SEC_FAR *                      Reserved2;
  INITIALIZE_SECURITY_CONTEXT_FN      InitializeSecurityContextA;
  ACCEPT_SECURITY_CONTEXT_FN          AcceptSecurityContext;
  COMPLETE_AUTH_TOKEN_FN              CompleteAuthToken;
  DELETE_SECURITY_CONTEXT_FN          DeleteSecurityContext;
  APPLY_CONTROL_TOKEN_FN              ApplyControlToken;
  QUERY_CONTEXT_ATTRIBUTES_FN         QueryContextAttributesA;
  IMPERSONATE_SECURITY_CONTEXT_FN     ImpersonateSecurityContext;
  REVERT_SECURITY_CONTEXT_FN          RevertSecurityContext;
  MAKE_SIGNATURE_FN                   MakeSignature;
  VERIFY_SIGNATURE_FN                 VerifySignature;
  FREE_CONTEXT_BUFFER_FN              FreeContextBuffer;
  QUERY_SECURITY_PACKAGE_INFO_FN      QuerySecurityPackageInfoA;
  void SEC_FAR *                      Reserved3;
  void SEC_FAR *                      Reserved4;
} SecurityFunctionTable, * PSecurityFunctionTable;

#define SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION

See Also

InitSecurityInterface


SecBuffer

The SecBuffer structure describes a buffer that is allocated by a transport application to pass to a security package.

typedef struct _SecBuffer {
    ULONG        cbBuffer;
    ULONG        BufferType;
    PVOID        pvBuffer;
} SecBuffer, *PSecBuffer;

Members

cbBuffer
Specifies the size, in bytes, of the buffer pointed to by the pvBuffer member.
BufferType
A set of bit flags that indicate the type of buffer. BufferType must be one of the following flags.
Flag | Meaning
SECBUFFER_EMPTY | This is a placeholder in the buffer array. The caller can supply several such entries in the array, and the security package can return information in them. For more information, see Context Semantics.
SECBUFFER_DATA | Used for common data. The security package can read this data, and write it, for example, to encrypt some or all of it.
SECBUFFER_TOKEN | This buffer is used to indicate the security token portion of the message. This is "read-only" for input parameters, or "read/write" for output parameters.
SECBUFFER_PKG_PARAMS | These are transport-to-package–specific parameters. For example, the Netware redirector may supply the server object identifier, while DCE RPC can supply an association UUID, and so on.
SECBUFFER_MISSING | The security package uses this value to indicate the number of missing bytes in a particular message. The pvBuffer member is ignored in this type.
SECBUFFER_EXTRA | The security package uses this value to indicate the number of extra, or unprocessed bytes in a message.
SECBUFFER_STREAM_TRAILER | Indicates a protocol-specific trailer for a particular record. Not usually of interest to callers.
SECBUFFER_STREAM_HEADER | Indicates a protocol-specific header for a particular record. Not usually of interest to callers.

In addition, BufferType can combine the following flag with any of the flags in the preceding table.
Flag | Meaning
SECBUFFER_READONLY | The buffer is read-only. This flag is intended for sending header information to the security package for checksumming or the like. The package can read this buffer, but cannot modify it.

pvBuffer
Pointer to a buffer.

See Also

SecBufferDesc


SecBufferDesc

The SecBufferDesc structure describes an array of SecBuffer structures to pass from a transport application to a security package.

typedef struct _SecBufferDesc {
    ULONG        ulVersion;
    ULONG        cBuffers;
    PSecBuffer   pBuffers;
} SecBufferDesc, * PSecBufferDesc;

Members

ulVersion
Specifies the version number of this structure. This member must be SECBUFFER_VERSION.
cBuffers
Indicates the number of SecBuffer structures in the pBuffers array.
pBuffers
Pointer to an array of SecBuffer structures.

See Also

SecBuffer


SecPkgInfo

The SecPkgInfo structure provides general information about a security package, such as its name and its capabilities.

typedef struct _SecPkgInfo {
      ULONG fCapabilities;  // capability of bit mask
      USHORT wVersion;      // version of driver
      USHORT wRPCID;        // identifier for RPC run time
      ULONG cbMaxToken;     // size of authentication token
      SEC_CHAR * Name;      // text name
      SEC_CHAR * Comment;   // comment
} SecPkgInfo, * PSecPkgInfo;

Members

fCapabilities
A set of bit flags that describe the capabilities of the security package. This member can be a combination of the following flags.
Value | Meaning
SECPKG_FLAG_INTEGRITY | Verify that all messages exchanged have not been tampered with or exchanged out of sequence.
SECPKG_FLAG_PRIVACY | All messages are tamper proof and are not passed in cleartext. Reserved for future use.
SECPKG_FLAG_TOKEN_ONLY | The package is interested only in the security-token portion of messages, and will ignore any other buffers. This is a performance-related issue.
SECPKG_FLAG_DATAGRAM | Supports datagram-style authentication. For more information, see Context Semantics.
SECPKG_FLAG_CONNECTION | Supports connection-oriented style authentication. For more information, see Context Semantics.
SECPKG_FLAG_MULTI_REQUIRED | Multiple legs are required for authentication.
SECPKG_FLAG_CLIENT_ONLY | Server authentication support is not provided.
SECPKG_FLAG_EXTENDED_ERROR | Supports extended error handling. For more information, see Extended Error Information.
SECPKG_FLAG_IMPERSONATION | Supports Win32 impersonation in server contexts.
SECPKG_FLAG_ACCEPT_WIN32_NAME | Understands Win32 principal and target names.
SECPKG_FLAG_STREAM | Supports stream semantics. For more information, see Context Semantics.

wVersion
Specifies the version of the package protocol. Must be 1.
wRPCID
Specifies a DCE RPC identifier, if appropriate. If the package does not implement one of the DCE registered security systems, the reserved value SECPKG_ID_NONE is used.
cbMaxToken
Specifies the maximum size, in bytes, of the token.
Name
Pointer to a null-terminated string that contains the name of the security package.
Comment
Pointer to a null-terminated string. This can be any additional string passed back by the package.

See Also

EnumerateSecurityPackages, QuerySecurityPackageInfo


SecPkgContext_Sizes

The SecPkgContext_Sizes structure indicates the sizes of important structures used in the message support functions. The QueryContextAttributes function uses this structure.

typedef struct _SecPkgContext_Sizes {
  ULONG    cbMaxToken;
  ULONG    cbMaxSignature;
  ULONG    cbBlockSize;
  ULONG    cbSecurityTrailer;
} SecPkgContext_Sizes, * PSecPkgContext_Sizes;

Members

cbMaxToken
Specifies the maximum size of the security token used in the authentication exchanges.
cbMaxSignature
Specifies the maximum size of the signature created by the MakeSignature function. This member should be zero if integrity services are not requested or available.
cbBlockSize
Specifies the preferred integral size of the messages — for example, 8 indicates that messages should be of size 0 mod 8 for optimal performance. Messages other than this block size can be padded.
cbSecurityTrailer
Size of the security trailer to be appended to messages. This member should be zero if the relevant services are not requested or available.

See Also

MakeSignature, QueryContextAttributes


SecPkgContext_Names

The SecPkgContext_Names structure indicates the name of the user associated with a security context. The QueryContextAttributes function uses this structure.

typedef struct _SecPkgContext_Names {
      SEC_CHAR *  sUserName;
} SecPkgContext_Names, * pSecPkgContext_Names;

Members

sUserName
Pointer to a null-terminated string that contains the name of the user represented by the context. If the security package indicates that it understands Win32 names (by setting the SECPKG_FLAG_ACCEPT_WIN32_NAME flag), you can use this name in other Win32 calls.

See Also

QueryContextAttributes


SecPkgContext_StreamSizes

The SecPkgContext_StreamSizes structure indicates the sizes of the various stream components, for use with the message support functions. The QueryContextAttributes function uses this structure.

typedef struct _SecPkgContext_StreamSizes {
    ULONG        cbHeader;
    ULONG        cbTrailer;
    ULONG        cbMaximumMessage;
    ULONG        cBuffers;
    ULONG        cbBlockSize;
} SecPkgContext_StreamSizes, * PSecPkgContext_StreamSizes;

Members

cbHeader
Specifies the size, in bytes, of the header portion. If zero, no header is used.
cbTrailer
Specifies the size, in bytes, of the trailer portion. If zero, no trailer is used.
cbMaximumMessage
Specifies the size, in bytes, of the largest message that can be encapsulated.
cBuffers
Specifies the number of buffers to pass.
cbBlockSize
Specifies the preferred integral size of the messages — for example, 8 indicates that messages should be of size 0 mod 8 for optimal performance. Messages other than this block size can be padded.

See Also

QueryContextAttributes


SecPkgContext_Lifespan

The SecPkgContext_Lifespan structure indicates life span of a security context. The QueryContextAttributes function uses this structure.

typedef struct _SecPkgContext_Lifespan {
      TimeStamp      tsStart;
      TimeStamp      tsExpiry;
} SecPkgContext_Lifespan, * PSecPkgContext_Lifespan;

Members

tsStart
Time at which the context was established.
tsExpiry
Time at which the context will expire.

Remarks

The security provider should always return these values in local time.

See Also

QueryContextAttributes


SecPkgContext_DceInfo

The SecPkgContext_DceInfo structure contains authorization data used by DCE services. The QueryContextAttributes function uses this structure.

typedef struct _SecPkgContex_DceInfo {
      ULONG  AuthzSvc;
      PVOID  pPac;
} SecPkgContext_DceInfo, * PSecPkgContext_DceInfo;

Members

AuthzSvc
Specifies the authorization service used. DCE use only.
pPac
Pointer to package-specific authorization data.

See Also

QueryContextAttributes


SecPkgContext_KeyInfo

The SecPkgContext_KeyInfo structure contains information about the keys used in a security context. Note that it does not return the actual key values, merely information about them. The QueryContextAttributes function uses this structure.

typedef struct _SecPkgContext_KeyInfo {
    SEC_CHAR   * sSignatureAlgorithmName;
    SEC_CHAR   * sEncryptAlgorithmName;
    ULONG        KeySize;
    ULONG        SignatureAlgorithm;
    ULONG        EncryptAlgorithm;
} SecPkgContext_KeyInfo, * PSecPkgContext_KeyInfo;

Members

sSignatureAlgorithmName
Pointer to a null-terminated string containing the name, if available, of the algorithm used for generating signatures, such as "MD5", "SHA-2", and so on.
sEncryptAlgorithmName
Pointer to a null-terminated string containing the name, if available, of the algorithm used for encrypting messages. Reserved for future use.
KeySize
Specifies the size, in bits, of the key used for encrypting messages. Reserved for future use.
SignatureAlgorithm
Specifies the CryptoAPI algorithm identifier (ALG_ID, documented in the Platform SDK) in use for the signature, if available.
EncryptAlgorithm
Specifies the CryptoAPI algorithm identifier (ALG_ID) in use for encrypting messages. Reserved for future use.

See Also

QueryContextAttributes


SecPkgContext_Authority

The SecPkgContext_Authority structure contains the name of the authenticating authority, if one is available. It can be a Certification Authority, or the name of a server or domain that authenticated the connection. The QueryContextAttributes function uses this structure.

typedef struct _SecPkgContext_Authority {
    SEC_CHAR *    sAuthorityName;
} SecPkgContext_Authority, * PSecPkgContext_Authority;

Members

sAuthorityName
Pointer to a null-terminated string containing the name of the authenticating authority, if available.

See Also

QueryContextAttributes


SecPkgCredentials_Names

The SecPkgCredentials_Names structure indicates the name of the user associated with a context. The QueryCredentialsAttributes function uses this structure.

typedef struct _SecPkgCredentials_Names {
      SEC_CHAR *  sUserName;
} SecPkgCredentials_Names, * PSecPkgCredentials_Names;

Members

sUserName
Pointer to a null-terminated string containing the name of the user represented by the credential. If the security package sets the SECPKG_FLAG_ACCEPT_WIN32_NAME flag to indicate that it can process Win32 names, you can use this name in other Win32 calls.

See Also

QueryCredentialsAttributes


SSPI Status Codes

The following status codes are described in the SSPI documentation.

Status Code | Meaning
SEC_E_NOT_OWNER | The caller of the function does not own the credentials.
SEC_E_CANNOT_INSTALL | The security package cannot initialize successfully, and should not be installed.
SEC_I_PACKAGE_INSTALLED | Informational return indicating that the package installed itself successfully.
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.
SEC_E_CANNOT_PACK | The package is unable to pack the context.
SEC_E_INVALID_TOKEN | The token passed to the function is invalid.
SEC_E_NOT_SUPPORTED | The request is not supported.
SEC_E_QOP_NOT_SUPPORTED | The quality of protection attribute is not supported by this package.
SEC_E_NO_TOKEN | The context does not possess an impersonation token.
SEC_E_TARGET_UNKNOWN | The target was not recognized.
SEC_E_SECPKG_NOT_FOUND | The security package was not recognized.
SEC_E_NO_IMPERSONATION | No impersonation is allowed for this context.
SEC_E_LOGON_DENIED | This status code is obsolete.
SEC_E_UNKNOWN_CREDENTIALS | The credentials provided were not recognized.
SEC_E_NO_CREDENTIALS | No credentials are available.
SEC_E_MESSAGE_ALTERED | The message supplied for verification has been altered.
SEC_E_OUT_OF_SEQUENCE | The message supplied for verification is out of sequence.
SEC_E_NO_AUTHENTICATING_AUTHORITY | No authority could be contacted for authentication.
SEC_E_BAD_PKGID | The requested package identifier does not exist.
SEC_E_CONTEXT_EXPIRED | The context has expired, and can no longer be used.
SEC_E_INCOMPLETE_MESSAGE | The message supplied was incomplete. The signature was not verified.
SEC_I_CONTINUE_NEEDED | The function completed successfully, but you must call this function again to complete the context.
SEC_I_COMPLETE_NEEDED | The function completed successfully, but you must call the CompleteAuthToken function on the final message.
SEC_I_COMPLETE_AND_CONTINUE | The function completed successfully, but the application must call both CompleteAuthToken and this function to complete the context.


Window Stations and Desktops

This overview describes the new window station and desktop functionality, and is primarily intended for developers of Win32 services. Developers of typical applications that will be run by the logged-on user do not need to be concerned about window stations and desktops.


About Window Stations and Desktops

Microsoft® Windows NT® version 3.5 and later provides new window station and desktop functionality that enables Win32 services to call USER32 and GDI32 functions regardless of the logon account in which the service is running. This new functionality enables Win32 services to make these calls while maintaining the security of applications running in the account of the logged-on interactive user.

For more information on how Win32 services use the window station and desktop support, see Interactive Services.


Window Stations

A window station is a secure object that contains a clipboard, a set of global atoms and a group of desktop objects. The interactive window station assigned to the logon session of the interactive user also contains the keyboard, mouse, and display device. The interactive window station is visible to the user and can receive input from the user. All other window stations are noninteractive, which means that they cannot be made visible to the user, and cannot receive user input.

Applications can use the following functions for manipulating window station objects:

Function | Description
CloseWindowStation | Closes a specified window station.
CreateWindowStation | Creates a new window station.
EnumWindowStations | Enumerates the window stations in the system by repeatedly calling an application-defined EnumWindowStationProc callback function.
GetProcessWindowStation | Returns a handle to the window station assigned to the calling process.
GetUserObjectInformation | Gets information about a window station or desktop object.
GetUserObjectSecurity | Gets security information for a window station or desktop object.
OpenWindowStation | Opens a handle to an existing window station.
SetProcessWindowStation | Assigns a specified window station to the calling process.
SetUserObjectInformation | Sets information about a window station or desktop object.
SetUserObjectSecurity | Sets security information for a window station or desktop object.


Desktops

A desktop is a secure object contained within a window station. A desktop has a logical display surface and contains windows, menus, and hooks. A window station can have multiple desktops. Only the desktops of the interactive window station can be visible and receive user input. On the interactive window station, only one desktop at a time is active. This active desktop, also known as the input desktop, is the one that is currently visible to the user and that receives user input. Applications can use the OpenInputDesktop function to get a handle to the input desktop. Applications that have the necessary access can use the SwitchDesktop function to specify a different input desktop.

Invisible, noninteractive window stations enable Win32 services that do not have access to the interactive window station to start GUI applications. Applications running in a noninteractive window station cannot receive input or be visible. For example, the schedule service could use this support to start a GUI backup application on a remote computer on which the interactive window station was not accessible. For more information, see Interactive Services.

Applications can use the following functions for manipulating desktop objects:

Function | Description
CloseDesktop | Closes a specified desktop.
CreateDesktop | Creates a new desktop on a specified window station.
EnumDesktops | Enumerates the desktops on a specified window station by repeatedly calling an application-defined EnumDesktopProc callback function.
EnumDesktopWindows | Enumerates the windows on a specified desktop by repeatedly calling an application-defined EnumWindowsProc callback function.
GetThreadDesktop | Returns a handle to the desktop assigned to the calling thread.
GetUserObjectInformation | Gets information about a window station or desktop object.
GetUserObjectSecurity | Gets security information for a window station or desktop object.
OpenDesktop | Opens a handle to an existing desktop.
SetThreadDesktop | Assigns a specified desktop to the calling thread.
SetUserObjectInformation | Sets information about a window station or desktop object.
SetUserObjectSecurity | Sets security information for a window station or desktop object.


Window Station and Desktop Creation

The system automatically creates the interactive window station. When an interactive user logs on, the system associates the interactive window station with the user's logon session. The system also creates the default input desktop for the interactive window station.

When a noninteractive process such as a Win32 service attempts to connect to Win32 and no window station exists for the process' logon session, Win32 attempts to create a window station and desktop for the session. The name of the created window station is based on the logon session identifier, and the desktop is named "Default." The discretionary access control lists (DACLs) for the window station and desktop grant the following accesses to the service's user account:

Window Station: WINSTA_READATTRIBUTES | WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS | STANDARD_RIGHTS_REQUIRED

Desktop: DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | DESKTOP_ENUMERATE | STANDARD_RIGHTS_REQUIRED

A process can use the CreateWindowStation function to create a new window station, and the CreateDesktop function to create a new desktop.


Process Connection to a Window Station

A process automatically establishes a connection to a window station and desktop when it first calls a USER32 or GDI32 function (other than the window station or desktop functions) that must go to the Win32 server. The Win32 server determines the window station to which a process connects according to the following rules:

  1. If the process has called the SetProcessWindowStation function, it connects to the window station specified in that call.
  2. If the process did not call SetProcessWindowStation, it connects to the window station inherited from the parent process.
  3. If the process did not call SetProcessWindowStation and did not inherit a window station, the Win32 server attempts to open for MAXIMUM_ALLOWED access and connect to a window station as follows:
    1. If a window station name was specified in the lpDesktop member of the STARTUPINFO structure that was passed to the CreateProcess function when the process was created, the process connects to the specified window station.
    2. Otherwise, if the process is running in the logon session of the interactive user, the process connects to the interactive window station.
    3. If the process is running in a noninteractive logon session, the window station name is formed based on the logon session identifier and an attempt is made to open that window station. If the open operation fails because this window station does not exist, Win32 tries to create the window station and a default desktop.


Thread Connection to a Desktop

After a process connects to a window station, the Win32 server assigns a desktop to the thread making the connection to Win32. The desktop assigned during this connection process cannot be closed by calling the CloseDesktop function. The Win32 server determines the desktop to assign to the thread according to the following rules:

  1. If the thread has called the SetThreadDesktop function, it connects to the specified desktop.
  2. If the thread did not call SetThreadDesktop, it connects to the desktop inherited from the parent process.
  3. If the thread did not call SetThreadDesktop and did not inherit a desktop, the Win32 server attempts to open for MAXIMUM_ALLOWED access and connect to a desktop as follows:
    1. If a desktop name was specified in the lpDesktop member of the STARTUPINFO structure that was passed to the CreateProcess function when the process was created, the thread connects to the specified desktop.
    2. Otherwise, the thread connects to the default desktop of the window station to which the process connected.

The desktop assigned during this connection process cannot be closed by calling the CloseDesktop function.


Inherited Handles

When a process is connecting to a window station or desktop, the Win32 server searches the process's handle table for inherited handles. The Win32 server uses the first window station and desktop handles that it finds. If you want a child process to connect to a particular inherited window station or desktop, you must ensure that the only the desired handles are marked inheritable. If a child process inherits multiple window station or multiple desktop handles, the results of the window station and desktop connection are undefined.

Handles to a window station and desktop that the Win32 server opens while connecting a process to a window station or desktop are not inheritable.


Logoff Events

A logoff event occurs when a process calls the ExitWindows or ExitWindowsEx function. The logoff event is identified by the window station of the process calling ExitWindowsEx.

When a logoff event occurs, the system notifies all processes in the system as follows:

  • All windows of processes in the logon session being logged off receive the WM_QUERYENDSESSION and WM_ENDSESSION messages. All windows on the desktops of the window station being logged off receive these messages, even if the windows belong to processes running in another logon session.
  • Every process in the system receives the CTRL_LOGOFF_EVENT control signal. This signal does not indicate which session is being logged off. The system sends this signal after sending the window messages. For more information on control signals, see the SetConsoleCtrlHandler function.

If the process that called ExitWindowsEx is running in the logon session of the interactive user, all processes in the logon session are terminated. If the process calling ExitWindowsEx is in some other logon session, only the notifications are made; no processes are terminated.


Using Window Stations and Desktops

  • Creating an interactive process
  • Interacting with the user by a win32 service
  • Handling logoff events


Creating an Interactive Process

The following code fragment shows how a Win32 service process could use the STARTUPINFO structure in a CreateProcess call to create a process that has access to the user's interactive window station and default desktop. A noninteractive Win32 service could use this technique to interact with the logged on user. The new process could then use a named pipe or some other means of interprocess communication to communicate with the Win32 service.

To create an interactive process as shown in this example, a Win32 service must be logged in to the LocalSystem account.

#include <windows.h>

STARTUPINFO si;
PROCESS_INFORMATION ProcessInformation;

si.cb = sizeof(STARTUPINFO);
si.lpReserved = NULL;
si.lpTitle = NULL;
si.lpDesktop = "WinSta0\\Default";
si.dwX = si.dwY = si.dwXSize = si.dwYSize = 0L;
si.dwFlags = 0;;
si.wShowWindow = SW_SHOW;
si.lpReserved2 = NULL;
si.cbReserved2 = 0;
if (CreateProcess(NULL, lpszCmdLine, NULL, NULL, FALSE,
                   0, NULL, NULL, &si, &ProcessInformation))
{
    CloseHandle(ProcessInformation.hProcess);
    CloseHandle(ProcessInformation.hThread);
}


Interacting with the User by a Win32 Service

For a noninteractive Win32 service to interact with the user, it must open the user's window station ("WinSta0") and desktop ("Default"). By default, only the logged-on user and Win 32 services running in the LocalSystem account are granted access to the user's window station and desktop. This means that services running in other accounts must either impersonate the user when opening the interactive window station and desktop, or have access granted to those accounts by the user.

For compatibility with versions of Windows NT that support multiple users and/or multiple desktops per user, the user's window station and desktop names should not be hard-coded. Client applications should pass the names of their window station and desktop to the service as part of the request to the service.

This code sample displays a message on the user's desktop in response to an RPC request from one of the user's applications. Note that a global variable dwGuiThreadId in this example is also used in the logoff handling example. If the thread that displays the message box terminates after it is done with the message box, it is not necessary to save and restore the thread's desktop. It is necessary to restore the process's window station.

DWORD dwGuiThreadId = 0;

int
UserMessageBox(
    RPC_BINDING_HANDLE h,
    LPSTR lpszWindowStation,
    LPSTR lpszDesktop,
    LPSTR lpszText,
    LPSTR lpszTitle,
    UINT fuStyle)
{
    DWORD dwThreadId;
    HWINSTA hwinstaSave;
    HDESK hdeskSave;
    HWINSTA hwinstaUser;
    HDESK hdeskUser;
    int result;

    // Ensure connection to service window station and desktop, and
    // save their handles.

    GetDesktopWindow();
    hwinstaSave = GetProcessWindowStation();
    dwThreadId = GetCurrentThreadId();
    hdeskSave = GetThreadDesktop(dwThreadId);

    // Impersonate the client and connect to the User's
    // window station and desktop.

    RpcImpersonateClient(h);
    hwinstaUser = OpenWindowStation(lpszWindowStation, FALSE, MAXIMUM_ALLOWED);
    if (hwinstaUser == NULL)
    {
        RpcRevertToSelf();
        return 0;
    }
    SetProcessWindowStation(hwinstaUser);
    hdeskUser = OpenDesktop(lpszDesktop, 0, FALSE, MAXIMUM_ALLOWED);
    RpcRevertToSelf();
    if (hdeskUser == NULL)
    {
        SetProcessWindowStation(hwinstaSave);
        CloseWindowStation(hwinstaUser);
        return 0;
    }
    SetThreadDesktop(hdeskUser);

    // Display message box.

    dwGuiThreadId = dwThreadId;
    result = MessageBox(NULL, lpszText, lpszTitle, fuStyle);
    dwGuiThreadId = 0;

    // Restore window station and desktop.

    SetThreadDesktop(hdeskSave);
    SetProcessWindowStation(hwinstaSave);
    CloseDesktop(hdeskUser);
    CloseWindowStation(hwinstaUser);

    return result;
}


Handling Logoff Events

Win32 services that interact with the user should be prepared to handle logoff events. When a logoff event occurs, the Win32 service must close all handles to the user's window station and desktop.

This sample demonstrates how the message box in the interaction example code should be dismissed at logoff. The ConsoleCtrlHandler function in this example is a HandlerRoutine that was specified by a call to the SetConsoleCtrlHandler function.

BOOL CALLBACK EnumProc(
    HWND hwnd,
    LPARAM lParam)
{
    // Send a WM_CLOSE to destroy the window, because DestroyWindow
    // does not work across threads.

    SendMessage(hwnd, WM_CLOSE, 0, 0);
    return TRUE;
}

BOOL ConsoleCtrlHandler(
    DWORD dwCtrlType)
{
    if (dwCtrlType == CTRL_LOGOFF_EVENT && dwGuiThreadId != 0)
    {
        SetThreadDesktop(GetThreadDesktop(dwGuiThreadId));
        EnumThreadWindows(dwGuiThreadId, EnumProc, 0);
    }
    return FALSE;
}


Window Station and Desktop Reference

The following elements are associated with window station and desktop features.

  • Window Station and Desktop Functions
  • Window Station and Desktop Structures


Window Station and Desktop Functions

Use the following functions to implement window station and desktop features.

CloseDesktop
CloseWindowStation
CreateDesktop
CreateWindowStation
EnumDesktopProc
EnumDesktops
EnumDesktopWindows
EnumWindowStationProc
EnumWindowStations
GetProcessWindowStation
GetThreadDesktop
GetUserObjectInformation
GetUserObjectSecurity
OpenDesktop
OpenInputDesktop
OpenWindowStation
SetProcessWindowStation
SetThreadDesktop
SetUserObjectInformation
SetUserObjectSecurity
SwitchDesktop


CloseDesktop

The CloseDesktop function closes an open handle to a desktop object. A desktop is a secure object contained within a window station object. A desktop has a logical display surface and contains windows, menus and hooks.

BOOL CloseDesktop(
  HDESK hDesktop  // handle to desktop to close
);

Parameters

hDesktop
Handle to the desktop to close. This can be a handle returned by the CreateDesktop, OpenDesktop, or OpenInputDesktop functions.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The CloseDesktop function will fail if any thread in the calling process is using the specified desktop handle or if the handle refers to the initial desktop of the calling process.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, CreateDesktop, OpenDesktop, OpenInputDesktop


CloseWindowStation

The CloseWindowStation function closes an open window station handle.

BOOL CloseWindowStation(
  HWINSTA hWinSta  // handle to window station to close
);

Parameters

hWinSta
Handle to the window station to be closed. This handle is returned by the CreateWindowStation and OpenWindowStation functions.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The CloseWindowStation function will fail if the handle being closed is for the window station assigned to the calling process.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, SetProcessWindowStation


CreateDesktop

The CreateDesktop function creates a new desktop on the window station associated with the calling process. It returns a handle that can be used to access the new desktop. The calling process must have an associated window station, either assigned by the system at process creation time or set by SetProcessWindowStation. A desktop is a secure object contained within a window station object. A desktop has a logical display surface and contains windows, menus, and hooks.

HDESK CreateDesktop(
  LPCTSTR lpszDesktop,    // name of the new desktop
  LPCTSTR lpszDevice,     // reserved; must be NULL.
  LPDEVMODE pDevMode,     // reserved; must be NULL
  DWORD dwFlags,          // flags to control interaction with other
                          // applications
  DWORD dwDesiredAccess,  // specifies access of returned handle
  LPSECURITY_ATTRIBUTES lpsa  // specifies security attributes of
                              // the desktop
);

Parameters

lpszDesktop
Pointer to a null-terminated string specifying the name of the desktop to be created. Desktop names are case-insensitive and may not contain backslash characters (\).
lpszDevice
Reserved; must be NULL. The desktop uses the default display driver loaded at boot time.
pDevMode
Reserved; must be NULL.
dwFlags
A bit flag parameter that controls how the calling application will cooperate with other applications on the desktop. This parameter can specify zero or the following value:
Value | Description
DF_ALLOWOTHERACCOUNTHOOK | Allows processes running in other accounts on the desktop to set hooks in this process.

dwDesiredAccess
Specifies the access rights the returned handle has to the desktop. This parameter must include the DESKTOP_CREATEWINDOW flag because internally CreateDesktop uses the handle to create a window. In addition, you can specify any of the standard access rights, such as READ_CONTROL or WRITE_DAC, and a combination of the following desktop-specific access rights.
Value | Description
DESKTOP_CREATEMENU | Required to create a menu on the desktop.
DESKTOP_CREATEWINDOW | Required to create a window on the desktop.
DESKTOP_ENUMERATE | Required for the desktop to be enumerated.
DESKTOP_HOOKCONTROL | Required to establish any of the window hooks.
DESKTOP_JOURNALPLAYBACK | Required to perform journal playback on the desktop.
DESKTOP_JOURNALRECORD | Required to perform journal recording on the desktop.
DESKTOP_READOBJECTS | Required to read objects on the desktop.
DESKTOP_SWITCHDESKTOP | Required to activate the desktop using the SwitchDesktop function.
DESKTOP_WRITEOBJECTS | Required to write objects on the desktop.

lpsa
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpsa is NULL, the handle cannot be inherited.

The lpSecurityDescriptor member of the structure specifies a security descriptor for the new desktop. If lpsa is NULL, the desktop inherits its security descriptor from the parent window station.

Return Values

If the function succeeds, the return value is a handle to the newly created desktop. If the specified desktop already exists, the function succeeds and returns a handle to the existing desktop. When you are finished using the handle, call the CloseDesktop function to close it.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The CreateDesktop function returns a handle that can be used to access the desktop.

If the dwDesiredAccess parameter specifies the READ_CONTROL, WRITE_DAC, or WRITE_OWNER standard access rights to access the security descriptor of the desktop object, you must also request the DESKTOP_READOBJECTS and DESKTOP_WRITEOBJECTS access rights.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, CloseDesktop, SECURITY_ATTRIBUTES, SetProcessWindowStation, SwitchDesktop


CreateWindowStation

The CreateWindowStation function creates a window station object. It returns a handle that can be used to access the window station. A window station is a secure object that contains a set of global atoms, a clipboard, and a set of desktop objects.

HWINSTA CreateWindowStation(
  LPTSTR lpwinsta,        // name of the new window station
  DWORD dwReserved,       // reserved; must be NULL
  DWORD dwDesiredAccess,  // specifies access of returned handle
  LPSECURITY_ATTRIBUTES lpsa  // specifies security attributes of
                              // the window station
);

Parameters

lpwinsta
Optionally points to a null-terminated string specifying the name of the window station to be created. Window station names are case-insensitive and cannot contain backslash characters (\). Only members of the Administrators group are allowed to specify a name. If lpwinsta is NULL, the system forms a window station name using the logon session identifier for the calling process. To get this name, call the GetUserObjectInformation function.
dwReserved
Reserved; must be NULL.
dwDesiredAccess
Specifies the type of access to the window station. This parameter can be one or more of the following values:
Value | Description
WINSTA_ACCESSCLIPBOARD | Required to use the clipboard.
WINSTA_ACCESSGLOBALATOMS | Required to manipulate global atoms.
WINSTA_CREATEDESKTOP | Required to create new desktop objects on the window station.
WINSTA_ENUMDESKTOPS | Required to enumerate existing desktop objects.
WINSTA_ENUMERATE | Required for the window station to be enumerated.
WINSTA_EXITWINDOWS | Required to successfully call the ExitWindows or ExitWindowsEx functions.
WINSTA_READATTRIBUTES | Required to read the attributes of a window station object.
WINSTA_READSCREEN | Required to access screen contents.
WINSTA_WRITEATTRIBUTES | Required to modify the attributes of a window station object.

lpsa
Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpsa is NULL, the handle cannot be inherited.

The lpSecurityDescriptor member of the structure specifies a security descriptor for the new window station. If lpsa is NULL, the window station (and any desktops created within the window) gets a security descriptor that grants GENERIC_ALL access to all users.

Return Values

If the function succeeds, the return value is a handle to the newly created window station. If the specified window station already exists, the function succeeds and returns a handle to the existing window station.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, GetUserObjectInformation, OpenWindowStation


EnumDesktopProc

The EnumDesktopProc function is an application-defined callback function used with the EnumDesktops function. It receives a desktop name. The DESKTOPENUMPROC type defines a pointer to this callback function. EnumDesktopProc is a placeholder for the application-defined function name.

BOOL CALLBACK EnumDesktopProc(
  LPTSTR lpszDesktop,  // name of a desktop
  LPARAM lParam        // value specified in EnumDesktops call
);

Parameters

lpszDesktop
Pointer to the null-terminated name of a desktop.
lParam
Specifies the application-defined value given in the EnumDesktops function.

Return Values

To continue enumeration, the callback function must return TRUE. To stop enumeration, it must return FALSE.

Remarks

An application registers an EnumDesktopProc function by passing its address to the EnumDesktops function.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.
Unicode: Defined as Unicode and ANSI prototypes.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, EnumDesktops


EnumDesktops

The EnumDesktops function enumerates all desktops in the window station assigned to the calling process. The function does so by passing the name of each desktop, in turn, to an application-defined callback function.

BOOL EnumDesktops(
  HWINSTA hwinsta,            // handle to window station to enumerate
  DESKTOPENUMPROC lpEnumFunc, // points to application's callback function
  LPARAM lParam               // value to pass to the callback function
);

Parameters

hwinsta
Handle to the window station whose desktops are to be enumerated. The CreateWindowStation, GetProcessWindowStation, and OpenWindowStation functions return a window station handle.
lpEnumFunc
Pointer to an application-defined EnumDesktopProc callback function.
dwDesiredAccess
Specifies a 32-bit application-defined value to be passed to the callback function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The calling process must have WINSTA_ENUMDESKTOPS access to the window station. The EnumDesktops function enumerates only those desktops for which the calling process has DESKTOP_ENUMERATE access.

The EnumDesktops function repeatedly invokes the lpEnumFunc callback function until the last desktop is enumerated or the callback function returns FALSE.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, CreateWindowStation, EnumDesktopProc, GetProcessWindowStation, OpenWindowStation


EnumDesktopWindows

The EnumDesktopWindows function enumerates all windows in a desktop by passing a handle to each window, in turn, to an application-defined callback function.

BOOL EnumDesktopWindows(
  HDESK hDesktop,   // handle to desktop to enumerate
  WNDENUMPROC lpfn, // points to application's callback function
  LPARAM lParam     // 32-bit value to pass to the callback function
);

Parameters

hDesktop
Handle to the desktop whose windows are to be enumerated. The CreateDesktop, OpenDesktop, and GetThreadDesktop functions return a desktop handle. If this parameter is NULL, the current desktop is used.
lpfn
Pointer to an application-defined EnumWindowsProc callback function.
lParam
Specifies a 32-bit application-defined value to be passed to the callback function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The EnumDesktopWindows function repeatedly invokes the lpfn callback function until the last window is enumerated or the callback function returns FALSE.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, CreateDesktop, EnumWindowsProc, GetThreadDesktop, OpenDesktop


EnumWindowStationProc

The EnumWindowStationProc function is an application-defined callback function used with the EnumWindowStations function. It receives a window station name. The WINSTAENUMPROC type defines a pointer to this callback function. EnumWindowStationProc is a placeholder for the application-defined function name.

BOOL CALLBACK EnumWindowStationProc(
  LPTSTR lpszWindowStation
                 // name of a window station
  LPARAM lParam  // value specified in EnumWindowStations call
);

Parameters

lpszWindowStation
Pointer to the null-terminated name of a window station.
lParam
Specifies the application-defined value given in the EnumWindowStations function.

Return Values

To continue enumeration, the callback function must return TRUE. To stop enumeration, it must return FALSE.

Remarks

An application must register this callback function by passing its address to EnumWindowStations.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: User-defined.
Unicode: Defined as Unicode and ANSI prototypes.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, EnumWindowStations


EnumWindowStations

The EnumWindowStations function enumerates all window stations in the system by passing the name of each window station, in turn, to an application-defined callback function.

BOOL EnumWindowStations(
  WINSTAENUMPROC lpEnumFunc, // pointer to the callback function
  LPARAM lParam              // value to pass to the callback function
);

Parameters

lpEnumFunc
Pointer to an application-defined EnumWindowStationProc callback function.
lParam
Specifies a 32-bit application-defined value to be passed to the callback function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The EnumWindowStations function enumerates only those window stations for which the calling process has WINSTA_ENUMERATE access.

EnumWindowStations repeatedly invokes the lpEnumFunc callback function until the last window station is enumerated or the callback function returns FALSE.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, EnumWindowStationProc


GetProcessWindowStation

The GetProcessWindowStation function returns a handle to the window station associated with the calling process.

HWINSTA GetProcessWindowStation(VOID)

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is a handle to the window station associated with the calling process.

If the function fails, the return value is NULL. This can occur if the calling process is not an application written for Windows NT. To get extended error information, call GetLastError.

Remarks

The system associates a window station with a process when the process is created. A process can use the SetProcessWindowStation function to change its window station.

The calling process can use the returned handle in calls to the GetUserObjectInformation, GetUserObjectSecurity, SetUserObjectInformation, and SetUserObjectSecurity functions.

Windows NT version 3.51: A Win32 service does not have an associated window station or desktop until the service calls a USER or GDI function that interacts with the desktop. If a service calls GetProcessWindowStation before it has an associated window station, the return value is NULL. After a service interacts with the desktop, the return value is a valid window station handle.

Windows NT version 4.0: A Win32 service is created with an associated window station and desktop, so there is no need to call a USER or GDI function to connect the service to a window station and desktop.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, GetThreadDesktop, GetUserObjectInformation, GetUserObjectSecurity, SetProcessWindowStation, SetUserObjectInformation, SetUserObjectSecurity


GetThreadDesktop

The GetThreadDesktop function returns a handle to the desktop associated with a specified thread.

HDESK GetThreadDesktop(
  DWORD dwThreadId   // thread identifier
);

Parameters

dwThreadId
Handle to the thread for which to return the desktop handle. The GetCurrentThreadId and CreateProcess functions return thread identifiers.

Return Values

If the function succeeds, the return value is a handle to the desktop associated with the specified thread. You do not need to call the CloseDesktop function to close the returned handle.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The system associates a desktop with a thread when that thread is created. A thread can use the SetThreadDesktop function to change its desktop. The desktop associated with a thread must be on the window station associated with the thread's process.

The calling process can use the returned handle in calls to the GetUserObjectInformation, GetUserObjectSecurity, SetUserObjectInformation, and SetUserObjectSecurity functions.

Windows 95 and Windows 98: The system does not support multiple desktops, so GetThreadDesktop always returns the same value.

Windows NT version 3.51: A Win32 service does not have an associated window station or desktop until the service calls a USER or GDI function that interacts with the desktop. If a service calls GetThreadDesktop before it has an associated desktop, the return value is NULL. After a service interacts with the desktop, the return value is a valid desktop handle.

Windows NT: A Win32 service is created with an associated window station and desktop, so there is no need to call a USER or GDI function to connect the service to a window station and desktop.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, GetCurrentThreadId, GetProcessWindowStation, GetUserObjectInformation, GetUserObjectSecurity, SetProcessWindowStation, SetThreadDesktop, SetUserObjectInformation, SetUserObjectSecurity


GetUserObjectInformation

The GetUserObjectInformation function returns information about a window station or desktop object.

BOOL GetUserObjectInformation(
  HANDLE hObj,            // handle to object to get information for
  int nIndex,             // type of information to retrieve
  PVOID pvInfo,           // points to buffer that receives the information
  DWORD nLength,          // size of the pvInfo buffer
  LPDWORD lpnLengthNeeded // receives required size of the pvInfo buffer
);

Parameters

hObj
Handle to the window station or desktop object for which to return information. This can be an HDESK or HWINSTA handle (for example, a handle returned by CreateWindowStation, OpenWindowStation, CreateDesktop, or OpenDesktop).
nIndex
Specifies the object information to be retrieved. The parameter must be one of the following values:
Value | Description
UOI_FLAGS | Returns handle flags. The pvInfo parameter must point to a USEROBJECTFLAGS structure.
UOI_NAME | Returns a string containing the name of the object.
UOI_TYPE | Returns a string containing the type name of the object.
UOI_USER_SID | Returns the SID structure that identifies the user that is currently associated with the specified object. If no user is associated with the object, the value returned in the buffer pointed to by lpnLengthNeeded is zero. Note that SID is a variable length structure. You will usually make a call to GetUserObjectInformation to determine the length of the SID before retrieving its value.

pvInfo
Pointer to a buffer to receive the object information.
nLength
Specifies the size, in bytes, of the buffer pointed to by the pvInfo parameter.
lpnLengthNeeded
Pointer to a variable receiving the number of bytes required to store the requested information. If this variable's value is greater than the value of the nLength parameter when the function returns, the function returns FALSE, and none of the information is copied to the pvInfo buffer. If the value of the variable pointed to by lpnLengthNeeded is less than or equal to the value of nLength, the entire information block is copied.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, CreateDesktop, CreateWindowStation, GetUserObjectSecurity, OpenDesktop, OpenWindowStation, SetUserObjectInformation, SetUserObjectSecurity, SID, USEROBJECTFLAGS


OpenDesktop

The OpenDesktop function returns a handle to an existing desktop. A desktop is a secure object contained within a window station object. A desktop has a logical display surface and contains windows, menus and hooks.

HDESK OpenDesktop(
  LPTSTR lpszDesktop,    // name of the desktop to open
  DWORD dwFlags,         // flags to control interaction with other applications
  BOOL fInherit,         // specifies whether returned handle is inheritable
  DWORD dwDesiredAccess  // specifies access of returned handle
);

Parameters

lpszDesktop
Pointer to null-terminated string specifying the name of the desktop to be opened. Desktop names are case-insensitive.
dwFlags
A bit flag parameter that controls how the calling application will cooperate with other applications on the desktop. This parameter can specify zero or the following value:
Value | Description
DF_ALLOWOTHERACCOUNTHOOK | Allows processes running in other accounts on the desktop to set hooks in this process.

fInherit
Specifies whether the returned handle is inherited when a new process is created. If this value is TRUE, new processes will inherit the handle.
dwDesiredAccess
Specifies the access rights the returned handle has to the desktop. This parameter can include any of the standard access rights, such as READ_CONTROL or WRITE_DAC, and a combination of the following desktop-specific access rights.
Value | Description
DESKTOP_CREATEMENU | Required to create a menu on the desktop.
DESKTOP_CREATEWINDOW | Required to create a window on the desktop.
DESKTOP_ENUMERATE | Required for the desktop to be enumerated.
DESKTOP_HOOKCONTROL | Required to establish any of the window hooks.
DESKTOP_JOURNALPLAYBACK | Required to perform journal playback on the desktop.
DESKTOP_JOURNALRECORD | Required to perform journal recording on the desktop.
DESKTOP_READOBJECTS | Required to read objects on the desktop.
DESKTOP_SWITCHDESKTOP | Required to activate the desktop using SwitchDesktop.
DESKTOP_WRITEOBJECTS | Required to write objects on the desktop.

Return Values

If the function succeeds, the return value is a handle to the opened desktop. When you are finished using the handle, call the CloseDesktop function to close it.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The calling process must have an associated window station, either assigned by the system at process creation time or set by the SetProcessWindowStation function.

If the dwDesiredAccess parameter specifies the READ_CONTROL, WRITE_DAC, or WRITE_OWNER standard access rights to access the security descriptor of the desktop object, you must also request the DESKTOP_READOBJECTS and DESKTOP_WRITEOBJECTS access rights.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, CloseDesktop, CreateDesktop, SetProcessWindowStation, SetThreadDesktop, SwitchDesktop


OpenInputDesktop

The OpenInputDesktop function returns a handle to the desktop that receives user input. The input desktop is a desktop on the window station associated with the logged-on user.

HDESK OpenInputDesktop(
  DWORD dwFlags,         // flags to control interaction with other applications
  BOOL fInherit,         // specifies whether returned handle is inheritable
  DWORD dwDesiredAccess  // specifies access of returned handle
);

Parameters

dwFlags
A bit flag parameter that controls how the calling application will cooperate with other applications on the desktop. This parameter can specify zero or the following value:
Value | Description
DF_ALLOWOTHERACCOUNTHOOK | Allows processes running in other accounts on the desktop to set hooks in this process.

fInherit
Specifies whether the returned handle is inherited when a new process is created. If this value is TRUE, new processes will inherit the handle.
dwDesiredAccess
Specifies the access rights the returned handle has to the desktop. This parameter can include any of the standard access rights, such as READ_CONTROL or WRITE_DAC, and a combination of the following desktop-specific access rights.
Value | Description
DESKTOP_CREATEMENU | Required to create a menu on the desktop.
DESKTOP_CREATEWINDOW | Required to create a window on the desktop.
DESKTOP_ENUMERATE | Required for the desktop to be enumerated.
DESKTOP_HOOKCONTROL | Required to establish any of the window hooks.
DESKTOP_JOURNALPLAYBACK | Required to perform journal playback on the desktop.
DESKTOP_JOURNALRECORD | Required to perform journal recording on the desktop.
DESKTOP_READOBJECTS | Required to read objects on the desktop.
DESKTOP_SWITCHDESKTOP | Required to activate the desktop using SwitchDesktop.
DESKTOP_WRITEOBJECTS | Required to write objects on the desktop.

Return Values

If the function succeeds, the return value is a handle to the desktop that receives user input. When you are finished using the handle, call the CloseDesktop function to close it.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

The calling process must have an associated window station, either assigned by the system at process creation time or set by SetProcessWindowStation The window station associated with the calling process must be capable of receiving input.

An application can use the SwitchDesktop function to change the input desktop.

If the dwDesiredAccess parameter specifies the READ_CONTROL, WRITE_DAC, or WRITE_OWNER standard access rights to access the security descriptor of the desktop object, you must also request the DESKTOP_READOBJECTS and DESKTOP_WRITEOBJECTS access rights.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, CloseDesktop, SetProcessWindowStation, SwitchDesktop


OpenWindowStation

The OpenWindowStation function returns a handle to an existing window station.

HWINSTA OpenWindowStation(
  LPTSTR lpszWinSta,     // name of the window station to open
  BOOL fInherit,         // specifies whether returned handle is inheritable
  DWORD dwDesiredAccess  // specifies access of returned handle
);

Parameters

lpszWinSta
Pointer to a null-terminated string specifying the name of the window station to be opened. Window station names are case-insensitive.
fInherit
Specifies whether the returned handle is inherited when a new process is created. If this value is TRUE, new processes will inherit the handle.
dwDesiredAccess
Specifies the type of access to the window station. This parameter can be one or more of the following values:
Value | Description
WINSTA_ACCESSCLIPBOARD | Required to use the clipboard.
WINSTA_ACCESSGLOBALATOMS | Required to manipulate global atoms.
WINSTA_CREATEDESKTOP | Required to create new desktop objects on the window station.
WINSTA_ENUMDESKTOPS | Required to enumerate existing desktop objects.
WINSTA_ENUMERATE | Required for the window station to be enumerated.
WINSTA_EXITWINDOWS | Required to successfully call the ExitWindows and ExitWindowsEx functions.
WINSTA_READATTRIBUTES | Required to read the attributes of a window station object.
WINSTA_READSCREEN | Required to access screen contents.
WINSTA_WRITEATTRIBUTES | Required to modify the attributes of a window station object.

Return Values

If the function succeeds, the return value is the handle to the specified window station.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, ExitWindows, ExitWindowsEx


SetProcessWindowStation

The SetProcessWindowStation function assigns a window station to the calling process. This enables the process to access objects in the window station such as desktops, the clipboard, and global atoms. All subsequent operations on the window station use the access rights granted to hWinSta.

BOOL SetProcessWindowStation(
  HWINSTA hWinSta  // handle to window station to assign to this process
);

Parameters

hWinSta
Handle to the window station to be assigned to the calling process. This can be a handle returned by the CreateWindowStation, OpenWindowStation, or GetProcessWindowStation functions.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, CreateWindowStation, GetProcessWindowStation, OpenWindowStation, SetThreadDesktop


SetThreadDesktop

The SetThreadDesktop function assigns a desktop to the calling thread. All subsequent operations on the desktop use the access rights granted to hDesktop.

BOOL SetThreadDesktop(
  HDESK hDesktop  // handle to the desktop to assign to this thread
);

Parameters

hDesktop
Handle to the desktop to be assigned to the calling thread. This handle is returned by the CreateDesktop, GetThreadDesktop, and OpenDesktop functions.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The SetThreadDesktop function will fail if the calling thread has any windows or hooks on its current desktop (unless the hDesktop parameter is a handle to the current desktop).

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, CreateDesktop, GetThreadDesktop, OpenDesktop, SetProcessWindowStation


SetUserObjectInformation

The SetUserObjectInformation function sets information about a window station or desktop object.

BOOL SetUserObjectInformation(
  HANDLE hObj,  // handle to the object for which to set information
  int nIndex,   // type of information to set
  PVOID pvInfo, // pointer to a buffer that contains the information
  DWORD nLength // size, in bytes, of pvInfo buffer
);

Parameters

hObj
Handle to the window station or desktop object for which to set object information. This value can be an HDESK or HWINSTA handle (for example, a handle returned by CreateWindowStation, OpenWindowStation, CreateDesktop, or OpenDesktop).
nIndex
Specifies the object information to be set. This parameter must specify the following value:
Value | Description
UOI_FLAGS | Sets the object's handle flags. The pvInfo parameter must point to a USEROBJECTFLAGS structure.

pvInfo
Pointer to a buffer containing the object information.
nLength
Specifies the size, in bytes, of the information contained in the buffer pointed to by pvInfo.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails the return value is zero. To get extended error information, call GetLastError.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, CreateDesktop, CreateWindowStation, GetUserObjectInformation, OpenDesktop,.OpenWindowStation, USEROBJECTFLAGS


SwitchDesktop

The SwitchDesktop function makes a desktop visible and activates it. This enables the desktop to receive input from the user. The calling process must have DESKTOP_SWITCHDESKTOP access to the desktop for the SwitchDesktop function to succeed.

BOOL SwitchDesktop(
  HDESK hDesktop  // handle to desktop to activate
);

Parameters

hDesktop
Handle to the desktop to be made visible and active. This handle is returned by the CreateDesktop and OpenDesktop functions.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The SwitchDesktop function will fail if the desktop belongs to an invisible window station.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.
Import Library: Use user32.lib.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Functions, CreateDesktop, OpenDesktop


Window Station and Desktop Structures

Use the following structure to manipulate window station and desktop objects.

USEROBJECTFLAGS


USEROBJECTFLAGS

The USEROBJECTFLAGS structure contains information about a window station or desktop handle.

typedef struct tagUSEROBJECTFLAGS {
    BOOL fInherit;
    BOOL fReserved;
    DWORD dwFlags;
} USEROBJECTFLAGS;

Members

fInherit
Specifies whether the handle is inherited when a new process is created. If this member is TRUE, new processes will inherit the handle.
fReserved
Reserved for future use. This member must be FALSE.
dwFlags
For window stations, this member can contain the following window station attribute flag:
Value | Description
WSF_VISIBLE | Window station has visible display surfaces.

For desktops, the dwFlags member can contain the following desktop control flag:
Value | Description
DF_ALLOWOTHERACCOUNTHOOK | Allows processes running in other accounts on the desktop to set hooks in this process.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winuser.h.

See Also

Window Stations and Desktops Overview, Window Station and Desktop Structures, CreateDesktop, GetUserObjectInformation, OpenDesktop, OpenInputDesktop, SetUserObjectInformation


WinTrust

TBD


WinTrust Reference

The following elements are used with WinTrust:

  • WinTrust Functions
  • WinTrust Structures


WinTrust Functions

The following function is used with WinTrust.

WinVerifyTrust


WinVerifyTrust

The WinVerifyTrust function performs a specified verification action on a specified subject. The function passes the inquiry to the trust provider, if any, that supports the action identifier.

LONG WinVerifyTrust(
  HWND hwnd,        // handle to a window for interacting with the user
  GUID *ActionID,   // pointer to a trust provider action identifier
  LPVOID ActionData // pointer to a buffer containing action-specific data
);

Parameters

hwnd
Handle to the caller's window. The trust provider can use this value to determine whether it can interact with the user. However, trust providers typically perform verification actions with input from the user.

This parameter can be one of the following values.
Value | Meaning
INVALID_HANDLE_VALUE | There is no interactive user. The trust provider performs the verification action without the user's assistance.
Zero | The trust provider can use the interactive desktop to display its user interface.
A valid window handle | A trust provider can treat any value other than INVALID_HANDLE_VALUE or zero as a valid window handle that it can use to interact with the user.

ActionID
Pointer to a GUID structure that identifies an action, and implicitly, the trust provider that supports the action identifier. This value indicates the type of verification action to perform on the subject identified by the ActionData parameter.

The WinTrust service is designed to work with trust providers implemented by third parties. Each trust provider provides its own unique set of action identifiers. For information about the action identifiers supported by a trust provider, see the documentation for that trust provider.

For example, Microsoft provides a Software Publisher Trust Provider that can establish the trustworthiness of software being downloaded from a public network, such as the internet. The Software Publisher Trust Provider supports the following action identifiers.
Value Description
WIN_SPUB_ACTION_TRUSTED_PUBLISHER
The ActionData parameter is a pointer to a WIN_SPUB_TRUSTED_PUBLISHER_DATA structure.
WIN_SPUB_ACTION_NT_ACTIVATE_IMAGE
The ActionData parameter is a pointer to a WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT structure.
WIN_SPUB_ACTION_PUBLISHED_SOFTWARE
The ActionData parameter is a pointer to a WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT structure.

ActionData
Pointer to a buffer that contains information that the trust provider needs to process the specified action identifier. Typically, the data in the buffer includes information that identifies the subject that the trust provider must evaluate.

The format of the data depends on the action identifier. For information about the data required for a specific action identifier, see the documentation for the trust provider that supports that action.

Return Values

If the trust provider verifies that the subject is trusted for the specified action, the return value is ERROR_SUCCESS.

Otherwise, the return value is the status code returned by the trust provider. For example, a trust provider might indicate that the subject is not trusted, or is trusted but with limitations or warnings. The return value can be a trust-provider-specific value described in the documentation for an individual trust provider, or it can be one of the following error codes.

Value | Meaning
TRUST_E_SUBJECT_NOT_TRUSTED | The subject failed the specified verification action. Most trust providers return a more detailed error code that describes the reason for the failure.
TRUST_E_PROVIDER_UNKNOWN | The trust provider is not recognized on this system.
TRUST_E_ACTION_UNKNOWN | The trust provider does not support the specified action.
TRUST_E_SUBJECT_FORM_UNKNOWN | The trust provider does not support the form specified for the subject.

Remarks

The WinVerifyTrust function enables applications to invoke a trust provider to verify that a specified subject satisfies the criteria of a specified verification operation. The ActionID parameter identifies the verification operation, and the ActionData parameter identifies the subject. A trust provider is a DLL registered with WinTrust. When you call WinVerifyTrust, the WinTrust service forwards the call to the registered trust provider, if there is one, that supports the specified action identifier.

For example, the Software Publisher Trust Provider can verify that an executable image file comes from a trusted software publisher and that the file has not been modified since it was published. In this case, the ActionData parameter specifies the name of the file and the type of file, such as a Microsoft Portable Executable image file or a Java class file.

Each trust provider supports a specific set of actions that it can evaluate. Each action has a globally unique identifier (GUID) that identifies it. A trust provider can support any number of action identifiers, but two trust providers cannot support the same action identifier.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Import Library: Use wintrust.lib.

See Also

WinTrust Overview, WinTrust Functions, GUID, WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT


WinTrust Structures

Use the following structures to implement WinTrust functionality.

WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT
WIN_TRUST_ACTDATA_SUBJECT_ONLY
WIN_TRUST_SUBJECT_FILE


WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT NT]

WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT

The WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT structure identifies the subject to be evaluated in some WinVerifyTrust verification operations. For example, Microsoft's Software Publisher Trust Provider uses this structure with some of its action identifiers.

typedef struct _WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT {
    HANDLE            hClientToken;
    GUID *            SubjectType;
    WIN_TRUST_SUBJECT Subject;

} WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT, *LPWIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT ;

Members

hClientToken
Handle to the access token of the calling process.
SubjectType
Pointer to a GUID structure that identifies the type of subject that a trust provider must evaluate. The value of this member determines the type of data pointed to by the Subject member.

The WinTrust service is designed to work with trust providers and subject interface packages (SIPs) implemented by third parties. Each SIP provides its own unique set of subject type identifiers, and each trust provider specifies the set of subject types that it can evaluate for a specified action identifier. For information about the subject and action identifiers supported by a trust provider, see the documentation for that trust provider.

For example, for the WIN_SPUB_ACTION_PUBLISHED_SOFTWARE action, Microsoft's Software Publisher Trust Provider supports the following subject types.
Value Description
WIN_TRUST_SUBJTYPE_PE_IMAGE
Microsoft Portable Executable image files.
WIN_TRUST_SUBJTYPE_JAVA_CLASS
Java class files.
WIN_TRUST_SUBJTYPE_CABINET
WIN_TRUST_SUBJTYPE_RAW_FILE

Subject
Pointer to a buffer that a trust provider uses to access the subject. The format of this data depends on the type of subject. For example, the subject types supported by the WIN_SPUB_ACTION_PUBLISHED_SOFTWARE action use a WIN_TRUST_SUBJECT_FILE structure that contains a handle or a path to the file to be evaluated.

Remarks

The WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT structure is one of the data structures defined in WINBASE.H for use with the ActionData parameter of the WinVerifyTrust function. Trust providers can use one of the predefined structures, or define their own.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

WinTrust Overview, WinTrust Structures, GUID, WIN_TRUST_ACTDATA_SUBJECT_ONLY, WIN_TRUST_SUBJECT_FILE, WinVerifyTrust


WIN_TRUST_ACTDATA_SUBJECT_ONLY

The WIN_TRUST_ACTDATA_SUBJECT_ONLY structure is one of the structures defined in WINBASE.H for use with the ActionData parameter of the WinVerifyTrust function. Trust providers can use one of the predefined structures, or define their own.

typedef struct _WIN_TRUST_ACTDATA_SUBJECT_ONLY {
    GUID *            SubjectType;
    WIN_TRUST_SUBJECT Subject;

} WIN_TRUST_ACTDATA_SUBJECT_ONLY, *LPWIN_TRUST_ACTDATA_SUBJECT_ONLY;

Members

SubjectType
Pointer to a GUID structure that identifies the type of subject that a trust provider must evaluate. The value of this member determines the type of data pointed to by the Subject member.

The WinTrust service is designed to work with trust providers and subject interface packages (SIPs) implemented by third parties. Each SIP provides its own unique set of subject type identifiers, and each trust provider specifies the set of subject types that it can evaluate for a specified action identifier. For information about the subject and action identifiers supported by a trust provider, see the documentation for that trust provider.

Subject
Pointer to a buffer that a trust provider uses to access the subject. The format of this data depends on the type of subject.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

WinTrust Overview, WinTrust Structures, GUID, WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT, WinVerifyTrust


WIN_TRUST_SUBJECT_FILE

The WIN_TRUST_SUBJECT_FILE structure identifies a file to be evaluated in a WinVerifyTrust verification operation. For example, Microsoft's Software Publisher Trust Provider uses this structure for verification operations that require access to the software image to be evaluated.

typedef struct _WIN_TRUST_SUBJECT_FILE {
    HANDLE  hFile;
    LPCWSTR lpPath;

} WIN_TRUST_SUBJECT_FILE, *LPWIN_TRUST_SUBJECT_FILE;

Members

hFile
Handle to the file to evaluate in a WinVerifyTrust operation. The handle must have FILE_READ_DATA access to the file.
lpPath
Pointer to a null-terminated Unicode string that specifies the complete path of the file to evaluate.

Remarks

The WIN_TRUST_SUBJECT_FILE structure is one of the structures defined for use by trust providers to specify information about a subject to be evaluated in a trust inquiry. Trust providers can use this structure, or define their own.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.

See Also

WinTrust Overview, WinTrust Structures, WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT, WinVerifyTrust


Windows 95 Features

This overview covers programming issues specific to the Windows 95 operating system. It provides conceptual and reference information that is not available in any other document. It is divided into the following sections:

  • "About Windows 95" discusses the Windows 95 architecture, Windows 95 system limits, and the API differences between version 3.x–based and Windows 95–based applications.
  • "Using Windows 95 Features" discusses device I/O control, exclusive volume locking, long filenames, MS-DOS extensions, system policies, thunk compiler, ToolHelp functions, and virtual machine services.
  • "Windows 95 Reference" contains complete reference information for the functions, structures, messages, and interfaces that are specific to Windows 95.


Windows 95 Architecture

The operating environment for Windows 95 consists of a computer's hardware devices and the following software components:

  • Virtual machine manager (VMM).
  • Virtual devices (VxDs).
  • Device drivers.
  • 16- and 32-bit Windows dynamic-link libraries (DLLs).
  • MS-DOS – based applications.
  • 16- and 32-bit Windows-based applications.


Virtual Machine Manager

The virtual machine manager (VMM) is the 32-bit protected-mode operating system at the core of Windows 95. Its primary responsibility is to create, run, monitor, and terminate virtual machines. The VMM provides services that manage memory, processes, interrupts, and exceptions such as general protection faults. The VMM works with virtual devices, 32-bit protected-mode modules, to allow the virtual devices to intercept interrupts and faults to control the access that an application has to hardware devices and installed software.

Both the VMM and virtual devices run in a single, 32-bit, flat model address space at privilege level 0 (also called ring 0). The system creates two global descriptor table (GDT) selectors, one for code and the other for data, and uses the selectors in the CS, DS, SS, and ES segment registers. Both selectors have a base address of zero and a limit of 4 gigabytes (GBs), so all the segment registers point to the same range of addresses. The VMM and virtual devices never change these registers.

The VMM provides multiple-threaded, preemptive multitasking. It runs multiple applications simultaneously by sharing CPU (central processing unit) time between the virtual machines in which the applications run. The VMM is also nonreentrant. This means that virtual devices must synchronize access to the VMM services. The VMM provides services, such as semaphores and events, to help virtual devices prevent reentering the VMM.

For more information about the VMM, including descriptions of the services that it provides to virtual devices, see the documentation included in the Microsoft Windows 95 Device Driver Kit (DDK).


Virtual Devices

Virtual devices (VxDs) are 32-bit programs that support the device-independent VMM by managing the computer's hardware devices and supporting software. VxDs support all hardware devices for a typical computer, including the programmable interrupt controller (PIC), timer, direct memory access (DMA) device, disk controller, serial ports, parallel ports, keyboard, and display adapter. A VxD is required for any hardware device that has settable operating modes or retains data over any period of time. In other words, if the state of the hardware device can be disrupted by switching between multiple virtual machines or applications, the device must have a corresponding VxD.

Some VxDs support software, but no corresponding hardware device. In general, a VxD can provide any kind of services for the VMM and other virtual devices. Windows 95 allows the user to install new virtual device drivers to support an add-on hardware device or provide some system-wide software service.

A VxD can also provide application programming interface (API) functions for applications running in virtual 8086 mode or protected mode. These functions can give applications direct access to the features of the VxD.

Windows 95 includes a device input and output control (IOCTL) interface that allows Microsoft® Win32® – based applications to communicate directly with VxDs. Applications typically use this interface to carry out selected MS-DOS system functions, to obtain information about a device, or to carry out input and output (I/O) operations that are not available through standard Win32 functions. For more information about the device IOCTL interface, see Device I/O Control.

For more information about virtual devices, see the documentation included in the Windows 95 DDK.


Device Drivers

A Windows device driver is a DLL that Windows uses to interact with a hardware device, such as a display or keyboard. Rather than access devices directly, Windows loads device drivers and calls functions in the drivers to carry out actions on the device. Each device driver exports a set of functions; Windows calls these functions to complete an action, such as drawing a circle or translating a keyboard scan code. The driver functions also contain the device-specific code needed to carry out actions on the device.

Windows requires device drivers for the display, keyboard, and communication ports. Other drivers may also be required if the user adds optional devices to the system.

The Windows 95 DDK provides independent hardware and software vendors (IHVs and ISVs) with the resources to build device drivers and VxDs that are compatible with the Windows 95 operating system. The resources include a configurable development environment, documentation, tools, and header files and libraries for several device types. The Windows 95 DDK contains the following components:

  • Header files and libraries for building device drivers and VxDs.
  • Sample source code for device drivers and VxDs.
  • 16- and 32-bit versions of the driver development tools.


Dynamic-Link Libraries

Dynamic linking provides a mechanism for linking applications to libraries of functions at run time. The libraries reside in their own executable files and are not copied into an application's executable file as with static linking. These libraries are "dynamically linked" because they are linked to an application when it is loaded and executed rather than when it is linked. When an application uses a DLL, the operating system loads the DLL into memory, resolves references to functions in the DLL so that they can be called by the application, and unloads the DLL when it is no longer needed. Dynamic linking can be performed explicitly by applications or implicitly by the operating system.

DLLs are designed to provide resources to applications. Many applications can use the code in a DLL, meaning that only one copy of the code is resident in the system. Also, it is possible to update a DLL without changing applications that use the DLL, as long as the interface to the functions in the DLL does not change.

Software developers can extend the Windows environment by creating a DLL that contains routines for performing operations and then making the DLL available to other Windows-based applications (in addition to internal Windows routines). DLLs most often appear as files with a .DLL filename extension; however, they may also have an .EXE or other filename extension.

For more information about dynamic-link libraries, see Dynamic-Link Libraries.

Windows 95 supports 32-bit DLLs as well as 16-bit DLLs that were written for Windows version 3.x. For a discussion of the issues involved in mixing 16- and 32-bit components in the Windows 95 environment, see Thunk Compiler.


MS-DOS - Based Applications

MS-DOS – Based Applications

Windows 95 supports applications written for MS-DOS. Each MS-DOS – based application can run as a full-screen application, or it can run in a window on the Windows 95 desktop.

The system can run multiple MS-DOS – based applications at the same time. To do so, it creates a separate virtual machine (VM) for each MS-DOS – based application and shares the microprocessor among the MS-DOS VMs and the system VM (which contains all Windows-based applications). A VM can run an MS-DOS – based application in either the virtual 8086 mode or protected mode of the microprocessor.

Although most MS-DOS – based applications run fine in a window or as a full-screen application, some may not. To ensure absolute backward compatibility for all MS-DOS – based applications, Windows 95 provides a separate operating mode called "single MS-DOS application mode." When in this mode, Windows 95 runs only one MS-DOS – based application at a time. No Windows-based applications run in that mode; in fact, none of the graphical user interface (GUI) components of the system are even loaded.

Windows 95 supports the complete set of MS-DOS system functions and interrupts and provides extensions that permit MS-DOS – based applications to take advantage of features such as long filenames, and exclusive volume locking. For more information, see MS-DOS Extensions, Long Filenames, and Exclusive Volume Locking.

Disk utilities and other applications that directly modify file system structures, such as directory entries, must request exclusive use of the volume before making modifications to the structures. Windows 95 provides a set of input and output control (IOCTL) functions to manage exclusive volume use. Exclusive use prevents applications from inadvertently changing the file system while a disk utility is trying modify it.

Virtual machine services let Microsoft MS-DOS – based applications take advantage of features provided by Windows 95 when the applications run in a window. MS-DOS – based applications can retrieve and, optionally, set the title of the window in which they run. Virtual machine services also allow MS-DOS – based applications to periodically check the state of an internal close flag and terminate if the flag is set. Windows 95 sets this flag when the user chooses the Close command from the system menu of the window in which the MS-DOS – based application runs. Close-aware applications enable the Close command, which gives the user an alternate way to exit the application and close the window. For more information, see Virtual Machine Services.


Windows-Based Applications

Windows 95 supports 16-bit applications written for Windows version 3.x as well as 32-bit applications that use the Win32 or Microsoft® Win32s® API. For 16-bit applications, Windows 95 preserves the cooperative multitasking model used in Windows version 3.x; that is, all 16-bit applications share the same virtual address space, the same message queue, and the same thread of execution. By contrast, each 32-bit Windows-based application has its own address space, a private message queue, and one or more threads of execution. In addition, each 32-bit thread is preemptively multitasked.

All new applications should be 32-bit applications developed using the Win32 API. For information about porting a 16-bit application to Win32, see Version Differences.


Windows 95 System Limitations

Microsoft® Windows® 95 implements some functions and messages differently than Microsoft® Windows NT®.


About Windows 95 System Limitations

To minimize development and debugging time when you target both Windows 95 and Windows NT, you need to understand the differences in the following areas:

  • Windows 95 General Limitations
  • Windows 95 Window Management
  • Windows 95 Graphics Device Interface
  • Windows 95 System Services
  • Windows 95 Multimedia


Windows 95 General Limitations

Certain functions and classes of functions, such as for security and event logging, are not supported by Windows 95. Windows 95 provides stub routines for these unsupported functions so that applications designed for other operating systems that fully support the Win32 application programming interface (API) can run on Windows 95 without errors.

The extended error codes returned by the GetLastError function are not guaranteed to be the same in Windows 95 and Windows NT. This difference applies to extended error codes generated by calls to window management, GDI, and system services functions. For example, the ActivateKeyboardLayout, GetKeyboardLayoutName, and UnloadKeyboardLayout functions do not support extended error code values; that is, you cannot retrieve errors for these functions by using the GetLastError function.

By design, functions that take string parameters can handle either Unicode™ (wide character) or ANSI strings. However, Windows 95 does not implement the Unicode (or wide character) version of most functions. With few exceptions, these functions are implemented as stubs that simply return an error value. However, Windows 95 does provide Unicode implementations of the following functions.

ExtTextOut
GetCharWidth
GetTextExtentExPoint
GetTextExtentPoint 		MessageBox
MessageBoxEx
TextOut

In addition, Windows 95 implements the MultiByteToWideChar and WideCharToMultiByte functions for converting strings to and from Unicode.


Windows 95 Window Management

Windows 95 implements some window management features in 16 bits. The use of 16 bits imposes some restrictions on parameters in functions and messages and places limits on internal storage. In some cases, Windows 95 provides features that can be used to avoid these restrictions and limitations. For example, the standard edit control is limited to somewhat less than 64 kilobytes (K) of text; however, the text in a rich edit control is limited only by available memory.

Handles

Windows 95 permits up to 16,364 window handles and 16,364 menu handles. Although Windows NT supports more handles than this, Windows 95 does support significantly more handles than Windows version 3.1.

Messages

The wParam parameter for the SendMessageCallback, SendMessageTimeout, and SendNotifyMessage functions is limited to a 16-bit value.

In Windows 95, the wParam parameter in list box messages, such as LB_INSERTSTRING or LB_SETITEMDATA, is limited to a 16-bit value. One effect of this limit is that list boxes cannot contain more than 32,767 items. Although the number of items is restricted, the total size, in bytes, of the items in a list box is limited only by available memory. In contrast, a 64K data limit is imposed by Windows version 3.1.

Any private application message must be defined above WM_USER + 0x100. A value above this will ensure that there is no collision between private messages and dialog box control messages.

Three-Dimensional Look

Windows 95 automatically applies the standard three-dimensional shading and color scheme to dialog boxes created by applications marked as version 4.0 or later. Applications that are marked for earlier versions can still get the three-dimensional appearance by applying the DS_3DLOOK style to dialog boxes. If this style is used, the system automatically applies the three-dimensional look without requiring the application to check the operating system version. This is useful, for example, in applications developed for Windows NT version 3.5. The DS_3DLOOK style is ignored in Windows NT version 3.1.

Message-box Styles

In Windows 95, the MB_ICONQUESTION style used with the MessageBox, MessageBoxEx, and MessageBoxIndirect functions is obsolete. Win32-based applications should use the MB_ICONEXCLAMATION style instead. Similarly, applications should use the MB_ICONINFORMATION style instead of the MB_ICONASTERISK style and the MB_ICONSTOP style instead of the MB_ICONHAND style.

Cursors

The IDC_SIZE and IDC_ICON values used with the LoadCursor function are obsolete and should not be used in a Windows 95 – based application or in a Win32-based application that is marked as version 4.0.

Desktop

In Windows 95, only one desktop is available while the system runs. Although the thread desktop functions, GetThreadDesktop and SetThreadDesktop, are available under Windows 95, they do not do anything.


Windows 95 Graphics Device Interface

Windows 95 implements some GDI features in 16 bits. The use of 16 bits imposes some restrictions on parameters in functions and places limits on internal storage.

Coordinate System

Windows 95 uses a 16-bit world coordinate system and restricts x- and y- coordinates for text and graphics to the range ±32K. Windows NT uses a 32-bit world coordinate system and allows coordinates in the range ±2 gigabytes (GB). If you pass full 32-bit coordinates to text and graphics functions in Windows 95, the system truncates the upper 16 bits of the coordinates before carrying out the requested operation.

Because Windows 95 uses a 16-bit coordinate system, the sum of the coordinates of the bounding rectangle specified by the Arc, Chord, Pie, Ellipse, and RoundRect functions cannot exceed 32K. In addition, the sum of the nLeftRect and nRightRect parameters or the nTopRect and nBottomRect parameters cannot exceed 32K.

World Transformations

Windows 95 does not support world transformations that involve either shearing or rotations. The ExtCreateRegion function fails if the transformation matrix is anything other than a scaling or translation of the region.

Bitmaps

Windows 95 does not support the CBM_CREATEDIB value for the CreateDIBitmap function. The CreateDIBSection function should be used instead to create a DIB. CreateDIBSection is also available in Windows NT version 3.5.

If the biCompression member of the BITMAPINFOHEADER structure is the BI_BITFIELDS value, the bmiColors member of the BITMAPINFO structure contains three doubleword color masks that specify the red, green, and blue components, respectively, of each pixel. Windows 95 only supports the following color masks for 16 and 32 bits per pixel (bpp).

16bpp | The blue mask is 0x001F, the green mask is 0x03E0, and the red mask is 0x7C00.
16bpp | The blue mask is 0x001F, the green mask is 0x07E0, and the red mask is 0xF800.
32bpp | The blue mask is 0x000000FF, the green mask is 0x0000FF00, and the red mask is 0x00FF0000.

If the lpvBits parameter is NULL, the GetDIBits function fills in the dimensions and format of the bitmap in the BITMAPINFO structure pointed to by the lpbi parameter. In this case, if the function is successful, the return value in Windows 95 is the total number of scan lines in the bitmap. In Windows NT versions 3.1 and 3.5, however, the return value is 1 (TRUE), indicating success.

Pens and Brushes

In Windows 95, pens and brushes have several limitations. The ExtCreatePen function supports solid colors only (the PS_SOLID style), and the PS_ALTERNATE and PS_USERSTYLE styles are not supported. Geometric pens (the PS_GEOMETRIC style) are limited to the BS_SOLID brush style specified in the LOGBRUSH structure passed to ExtCreatePen. In addition, the following pen styles are supported in paths only.

PS_ENDCAP_FLAT
PS_ENDCAP_ROUND
PS_ENDCAP_SQUARE 		PS_JOIN_BEVEL
PS_JOIN_MITER
PS_JOIN_ROUND

Windows 95 does not support the dashed or dotted pen styles, such as PS_DASH or PS_DOT, in wide lines. The BS_DIBPATTERN brush style is limited to an 8- by 8-pixel brush.

Windows 95 does not support brushes from bitmaps or device independent bitmaps (DIBs) that are larger than 8 by 8 pixels. Although bitmaps larger than 8 by 8 pixels can be passed to the CreatePatternBrush or CreateDIBPatternBrush function, only a portion of the bitmap is used to create the brush.

Windows 95 does not provide automatic tracking of the brush origin. An application is responsible for using the UnrealizeObject, SetBrushOrgEx, and SelectObject functions each time it paints using a pattern brush.

Logical Objects

In Windows 95, regions are allocated from the 32-bit heap and can, therefore, be as large as available memory. All other logical objects, however, share the 64K local heap. In addition, the number of region handles cannot exceed 16K.

To ensure that adequate space is always available for logical objects, applications should always delete objects when no longer needed. The following functions create objects that are placed in the local heap and have corresponding functions used to delete the objects.

Object | Create with | Delete with
Bitmap | CreateBitmap, CreateBitmapIndirect, CreateCompatibleBitmap, CreateDIBitmap, CreateDIBSection, CreateDiscardableBitmap | DeleteObject
Brush | CreateBrushIndirect, CreateDIBPatternBrush, CreateDIBPatternBrushPt, CreateHatchBrush, CreatePatternBrush, CreateSolidBrush | DeleteObject
Color space | CreateColorSpace | DeleteColorSpace
Device context (DC) CreateDC,
GetDC 		DeleteDC, ReleaseDC
Enhanced metafile | CloseEnhMetaFile, CopyEnhMetaFile, GetEnhMetaFile, SetEnhMetaFileBits | DeleteEnhMetaFile
Enhanced metafile DC | CreateEnhMetaFile | CloseEnhMetaFile
Extended pen | ExtCreatePen | DeleteObject
Font | CreateFont, CreateFontIndirect | DeleteObject
Memory DC | CreateCompatibleDC | DeleteDC
Metafile CloseMetaFile, CopyMetaFile,
GetMetaFile, SetMetaFileBitsEx 		DeleteMetaFile
Metafile DC | CreateMetafile | CloseMetaFile
Palette | CreatePalette | DeleteObject
Pen | CreatePen, CreatePenIndirect | DeleteObject
Region | CombineRgn, CreateEllipticRgn, CreateEllipticRgnIndirect, CreatePolygonRgn, CreatePolyPolygonRgn, CreateRectRgn, CreateRectRgnIndirect, CreateRoundRectRgn, ExtCreateRegion, PathToRegion | DeleteObject

Physical objects have always existed in global memory and are, therefore, not limited.

Object Deletion

Deletion of drawing objects is slightly different in Windows 95 than in Windows NT. In Windows NT, if a drawing object (pen or brush) is deleted while it is still selected into a DC, the DeleteObject function fails. In Windows 95, the function succeeds, but the result is a nonfunctioning object. This nonfunctioning object is automatically destroyed when the DC is deleted.

Paths

When a path is constructed in Windows 95, only the following functions are recorded: ExtTextOut, LineTo, MoveToEx, PolyBezier, PolyBezierTo, Polygon, Polyline, PolylineTo, PolyPolygon, PolyPolyline, and TextOut.

Graphics Mode and Device Capabilities

In Windows 95, the GetGraphicsMode and SetGraphicsMode functions support the GM_COMPATIBLE value only. The GM_ADVANCED value is not supported.

In Windows 95, the DeviceCapabilities function returns – 1 when called with the DC_FILEDEPENDENCIES value because that capability is not supported. In Windows 95, DeviceCapabilities supports the following additional capabilities.

DC_DATATYPE_PRODUCED | Retrieves an array of strings containing the data types that the printer driver supports. A return value of – 1 indicates that the printer driver only understands device-specific commands (in other words, "RAW" data) that are native to the printer. A return value of 2 or more indicates the number of strings in the array.
DC_EMF_COMPLIANT | Returns a flag that indicates if the specified printer driver is capable of accepting an enhanced metafile (EMF) spooled by the system (that is, the printer driver is EMF-compliant). The function returns 1 if the printer driver is EMF-compliant and – 1 if the printer driver is not.

Enhanced Metafiles

Although Windows 95 imposes no restrictions on the PlayEnhMetaFile and PlayEnhMetaFileRecord functions, the files and records that these functions execute are subject to the limitations described in this section. For example, the functions ignore records that attempt to draw outside of the 16-bit coordinate space or that apply shearing or rotation to world transformations.

In Windows 95, the maximum length of the description string for an enhanced metafile is 16K. This limit applies to the GetEnhMetaFileDescription, GetEnhMetaFileHeader, and GetEnhMetaFile functions.

In Windows 95, the dmDeviceName member of the DEVMODE structure specifies the "friendly" name of the printer, which may be set to any user-defined value. Windows 95, however, does not support the the following members; they are included for compatibility with Windows NT.

dmBitsPerPel
dmDisplayFlags
dmDisplayFrequency 		dmFormName
dmPelsHeight
dmPelsWidth

Printing and Print Spooler

Windows 95 does not support print monitor dynamic-link libraries (DLLs) that have been developed for Windows NT. To add a monitor using the AddMonitor function, you must specify a monitor DLL that has been explicitly created for Windows 95. The following printing and print spooling functions are not available in Windows 95.

AddForm
AddPrinterConnection
ConnectToPrinterDlg
DeleteForm
DeletePrinterConnection
EnumForms
FindClosePrinterChangeNotification 		FindFirstPrinterChangeNotification
FindNextPrinterChangeNotification
GetForm
ResetPrinter
SetForm
WaitForPrinterChange

In Windows 95, the SetPrinter function ignores the pShareName member of the PRINTER_INFO_2 structure. The PRINTER_INFO_3 and PRINTER_INFO_4 structures used with the SetPrinter, GetPrinter, and EnumPrinters functions are not supported in Windows 95. The PRINTER_INFO_5 structure, which is available in Windows 95, is not supported in Windows NT versions 3.1 and 3.5.

The PRINTER_ENUM_CONNECTIONS value used with the EnumPrinters function is not supported in Windows 95. The DOC_INFO_2 structure used with the StartDocPrinter function and the PORT_INFO_2 structure used with the EnumPorts function are not supported in Windows NT versions 3.1 and 3.5.

Windows 95 supports the DRAWPATTERNRECT printer escape.

Win32-based applications that send output to PostScript™ printers should use the GetDeviceCaps function to check for the PC_PATHS value to determine whether to use path functions or printer escapes to draw paths. Applications should use paths functions whenever possible. The following example shows how to check for this capability.

// Determine whether to use path functions on the device.
// hDC is the output device.

OSVERSIONINFO osvi;

osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionEx(&osvi);

if ((osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) ||
     ((osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
       (GetDeviceCaps(hDC, POLYCAPS) & PC_PATHS)))
    bUsePaths = TRUE;
else
    bUsePaths = FALSE;

In Windows 95, printer drivers typically set this capability to zero. This means that Win32-based applications sending output to Postscript printers need to use the ExtEscape function and the printer-specific escapes to draw paths at the printer. (The Escape function cannot be used for this.)

In Windows NT, the string specified in the lpszDeviceName parameter of the EnumDisplaySettings function must be of the form "\\.\DisplayX", where X can be 1, 2, or 3. In Windows 95, lpszDeviceName must be NULL.


Windows 95 System Services

File I/O

Windows 95 does not support asynchronous file input and output (I/O), except on serial devices. Therefore, the ReadFile and WriteFile functions will fail if you pass in an overlapped region on anything other than a serial device. The GetOverlappedResult function works only on serial devices or on files opened by using the DeviceIoControl function.

In Windows 95, the ReadFileEx and WriteFileEx functions will fail if you pass in the handle of a serial device (for example, COM2). ReadFile and WriteFile, however, accept the handle of a serial device.

In Windows 95, the CreateFile function does not support the standard "\\.\C:" and "\\.\PhysicalDrive0" formats used to gain access to the logical or physical drives. To gain access, applications must specify a virtual device (VxD) name instead and use the DeviceIoControl function to send requests through the VxD to the logical and physical drives. For more information, see Device I/O Control.

In Windows NT, the DeleteFile function fails if you attempt to delete a file that is open for normal I/O or is opened as a memory mapped file. In Windows 95, DeleteFile deletes such files. Because deleting open files may cause loss of data and application failure, you must take every precaution to close files before attempting to delete them by using DeleteFile.

Time

In Windows NT, the FileTimeToDosDateTime and DosDateTimeToFileTime functions allow dates up to 12/31/2107. In Windows 95, these functions allow dates up to 12/31/2099.

The precision of the time for a file on a file allocation table (FAT) file system volume is 2 seconds. If Windows 95 is connected through a network to a different file system, the time precision is limited only by the remote device.

Memory Management

In Windows 95, fixed memory blocks cannot be reallocated to be movable. The GMEM_MODIFY and GMEM_MOVEABLE combination of values has no effect when a memory block is reallocated by using the GlobalReAlloc function. Similarly, the LMEM_MODIFY and LMEM_MOVEABLE combination has no effect when a memory block is reallocated by using the LocalReAlloc function.

In Windows 95, committing memory for a page that is already committed is an expensive operation that has no ultimate effect (it is expensive because additional storage is allocated and subsequently freed for each committed page). When committing memory by using the VirtualAlloc function, an application should specify only the pages that actually need to be committed.

Although applications can request that memory allocation be at a specific virtual address, applications must not depend on any given address range always being available on every operating system. Applications can query the address space by using the GetSystemInfo function.

In Windows 95, memory allocated by Win32-based applications falls in the address range 4 megabytes (MB) – 2GB for private memory and 2GB – 3GB for shared memory (shared mapped files). The PAGE_WRITECOPY and PAGE_GUARD access protection values are not supported. Instead of using the PAGE_GUARD value and handling the EXCEPTION_GUARD_PAGE exception, applications can use the PAGE_NOACCESS value and handle the EXCEPTION_ACCESS_VIOLATION exception.

File Mapping

The SEC_IMAGE and SEC_NOCACHE values for the fdwProtect parameter of the CreateFileMapping function are not supported in Windows 95. In addition, the dwMaximumSizeHigh parameter of CreateFileMapping is ignored in Windows 95, so applications should specify zero for the parameter.

In Windows 95, shared memory mapped files that are created by using the MapViewOfFileEx function appear in the same address space across all 32-bit processes in the system. If you pass in a specific base offset in the lpvBase parameter of MapViewOfFileEx and the function succeeds, you are guaranteed that the same memory region is available in every process. This is not true in Windows NT because MapViewOfFileEx fails for any process that already has the given memory region in use.

Coherence guarantees that the data accessible in a file view is an identical copy of the file's contents on disk. In Windows 95, file views derived from a single file-mapping object are coherent only if the file is accessed through one of the views. A view of a file is not guaranteed to be coherent if the file is accessed by normal file I/O functions, such as ReadFile or WriteFile, or by views created from a different file-mapping object.

If you close a file handle that was used to create a file mapping object, both Windows NT and Windows 95 hold the file open until you unmap the last view of the file by using the UnmapViewOfFile function. However, Windows NT holds the file open with no sharing restrictions, whereas Windows 95 holds it open using the sharing restrictions of the original file handle. To ensure exclusive access to a file in Windows NT, the file handle must remain open for the life of the file-mapping object. Because Windows 95 retains the sharing restrictions, both the file handle and the handle to the file-mapping object may be closed after calling MapViewOfFile and exclusive access to the file is ensured.

In Windows 95, if the FILE_MAP_COPY value is specified for the fdwAccess parameter of MapViewOfFile (or MapViewOfFileEx), the hMapObject parameter must have been created with the PAGE_WRITECOPY value. In addition, the dwOffsetHigh parameter of MapViewOfFile (or MapViewOfFileEx) is ignored, so applications should specify zero for the parameter.

Windows 95 implements copy-on-write file mappings slightly differently than Windows NT. In Windows 95, a call to MapViewOfFile with FILE_MAP_COPY returns an error unless PAGE_WRITECOPY was used with the CreateFileMapping function. In both Windows NT and Windows 95, creating the map with PAGE_WRITECOPY and the view with FILE_MAP_COPY produces a view to the file that makes the pages swappable and prevents modifications from going to the original data file. In Windows 95, PAGE_WRITECOPY must be passed to CreateFileMapping, but this is optional in Windows NT.

If you share the mapping between multiple processes by using the DuplicateHandle or OpenFileMapping function and one process writes to a view, the modifications will not be propagated to the other process in Windows NT. However, the modifications will be propagated in Windows 95. The original file, though, will not change on either platform.

Registry

The Windows 95 registry does not allow key names containing control characters. In addition, if the lpszSubKey parameter is an empty string (""), the RegDeleteKey function deletes the key identified by the hKey parameter.

In Windows 95, the RegCreateKeyEx function creates a non-volatile key even if the REG_OPTION_VOLATILE value is specified.

Handle Duplication

In Windows 95, the DuplicateHandle function cannot duplicate handles of registry keys as it can in Windows NT. The function returns an error if an application attempts to duplicate the handle of a registry key. In addition, when a file handle is duplicated, the duplicated handle will not be granted more access than the original.

Thread Locales

Thread locales, retrieved and set by using the GetThreadLocale and SetThreadLocale functions, are static and can only be changed at system boot time.

Instruction Cache

In Windows 95, the FlushInstructionCache function always returns TRUE. Windows 95 supports single processor machines only.

Resources

In Windows 95, a call to the FreeResource function must be included for every call to the LoadResource function. The call to FreeResource allows the system to discard a resource that an application no longer needs. Windows NT automatically frees resources, so a call to FreeResource is not required.

Access Rights

The SYNCHRONIZE standard access rights flag is not supported in Windows 95. The following functions are affected.

DuplicateHandle | OpenSemaphore
MsgWaitForMultipleObjects | WaitForMultipleObjects
OpenEvent | WaitForMultipleObjectsEx
OpenMutex | WaitForSingleObject
OpenProcess | WaitForSingleObjectEx


Windows 95 Multimedia

The sndAlias macro is not supported in Windows 95. In addition, the SND_ALIAS and SND_ALIAS_ID values for the PlaySound function are not supported in Windows 95.

The Windows 95 multimedia functions are not designed to be used by two or more threads in the same process. Although most multimedia functions will work if they are called by multiple threads, some are likely to fail. Functions that are particularly likely to fail include PlaySound, any of the functions that prepare or unprepare headers, and any of the open and close functions. PlaySound can never be used simultaneously by multiple threads in the same process. The functions that prepare or unprepare headers and the open and close functions can be used simultaneously by multiple threads in the same process, but only if they do not pass the same structure.


Version Differences

The Microsoft® Windows® 95 operating system supports Windows-based applications that have a subsystem version number of either 3.x or 4.0. An application's subsystem version number is set by the linker.

This overview describes the differences in the way Windows 95 treats applications based on their subsystem version numbers. It is intended to help you identify areas in an application written for Windows version 3.x that you must revise to take advantage of the new features provided by Windows 95. It is divided into the following sections:

  • Window Management Differences
  • Dialog Box Differences
  • Button Differences
  • Edit Control Differences
  • List Box Differences
  • Combo Box Differences
  • Menu Differences
  • System Bitmap and Color Differences
  • System Metrics Differences
  • Parameter Validation Differences


Window Management Differences

When a version 4.0 application uses the SetWindowLong function (with GWL_STYLE) to change a window's style, Windows 95 sends the window a WM_STYLECHANGING message before changing the style. The message's lParam parameter is the address of a STYLESTRUCT structure. The styleOld and styleNew members of the structure specify the old and new styles. By processing WM_STYLECHANGING, an application can inspect the styles and perhaps change them.

Windows 95 sends the WM_STYLECHANGED message after changing the style. Again, the lParam parameter is the address of a STYLESTRUCT structure that specifies the new styles. The application can use WM_STYLECHANGED to update any style-dependent information stored in the application's internal data structures.

Windows 95, however, does not send the WM_STYLECHANGING and WM_STYLECHANGED messages to a version 3.x application.

A version 4.0 application cannot use the SetWindowLong function to set the WS_EX_TOPMOST style for a window or to remove the style from a window. The application must use the SetWindowPos function to set or remove the WS_EX_TOPMOST style.

Windows 95 automatically adds and removes the WS_EX_WINDOWEDGE style for windows in both version 3.x and 4.0 applications. In a version 3.x application, Windows 95 adds the WS_EX_WINDOWEDGE style to a window if, in version 3.1, the window would have a dialog border or a sizable border. Windows 95 removes the WS_EX_WINDOWEDGE style if the window's style changes so that it would no longer have a dialog border or sizable border in version 3.1. Windows 95 uses similar criteria for adding and removing the WS_EX_WINDOWEDGE style for a Windows version 4.0 application, except that any window that has a title bar receives the WS_EX_WINDOWEDGE style, regardless of the window's other border styles.

When the user drags the icon of a minimized window created by a version 3.x application, Windows 95 sends the window a WM_QUERYDRAGICON message to retrieve the cursor to use while dragging. Windows 95 also sends WM_QUERYDRAGICON to retrieve the icon to display in the task-switch window that appears when the user presses the alt+tab key combination. Windows 95 does not send WM_QUERYDRAGICON to a window created by a version 4.0 application. Instead, the application is expected either to use the WM_SETICON and WM_GETICON messages or to set the big and small icons when registering the window class.

When a window in a version 4.0 application loses the mouse capture as a result of a call to the SetCapture function, the window receives a WM_CAPTURECHANGED message, but Windows 95 sends the message asynchronously. In other words, the window receives the message, but possibly not right away. Some of the ways in which a window can lose the mouse capture include:

  • The user activated a different application by clicking one of its windows.
  • The DefWindowProc function changed the capture in response to a WM_CANCELMODE message.
  • Another window using the same message queue called the SetCapture function. (All 16-bit applications share the same queue, but each 32-bit thread has its own queue.)

If a child window in a version 3.x application has the WS_EX_NOPARENTNOTIFY style, Windows 95 disregards the style when the user clicks the child window. That is, Windows 95 sends the WM_PARENTNOTIFY message to all windows in the parent chain regardless of whether the child window has the WS_EX_NOPARENTNOTIFY style. If a child window in a version 4.0 application has this style, Windows 95 does not send WM_PARENTNOTIFY messages when the user clicks the child window.

In a version 3.x application, it is possible for the horizontal coordinate on the left side of a window's client area to be greater than that on the right side. This happens because version 3.x sometimes incorrectly handles an empty client rectangle that contains a vertical scroll bar. (Fixing the problem would cause some applications to generate general protection faults.) In a version 4.0 application, it is not possible for the horizontal coordinate of the left side of a client area to be greater than that of the right side.


Dialog Box Differences

A dialog box created by a version 4.0 application automatically receives the DS_3DLOOK style. This style gives three-dimensional borders to child controls in the dialog box and draws the entire dialog box using the three-dimensional color scheme. The DS_3DLOOK style is available to a dialog box created by a version 3.x application, but you must explicitly add the style to the dialog box template. The application that creates the dialog box determines the version number of the dialog box.

Windows 95 performs a strict validation check on the DS_ styles specified in a dialog box template. If the template contains any styles that Windows 95 does not recognize and a version 4.0 application is creating the dialog box, the creation fails. If a version 3.x application is creating the dialog box, the system debugger generates a warning, but Windows 95 creates the dialog box anyway.


Button Differences

The parent window of a button (except push buttons) in a version 3.x application receives a WM_CTLCOLORBTN message when the button is about to be drawn. In a version 4.0 application, however, the parent window of a button receives the WM_CTLCOLORSTATIC message, which retrieves a color appropriate for drawing text on the background of the dialog box. Windows 95 sends WM_CTLCOLORSTATIC to retrieve the background and text colors for the text area of check boxes, radio buttons, and group buttons. An application should process WM_CTLCOLORSTATIC in order to correctly set the colors of any dialog box item that contains text and appears directly on the dialog area.

Windows 95 performs default handling of the WM_CTLCOLORBTN message differently depending on an application's version. For a version 3.x application, the default handling for button colors is to use the COLOR_WINDOW value for the background color and the COLOR_WINDOWTEXT value for the foreground color. For a version 4.0 application, Windows 95 uses the COLOR_3DFACE value for the background and the COLOR_BTNTEXT value for the foreground.

In a version 3.x application, a push button's outer top left corner is nonwhite because the button is typically drawn on a white background. If the border was white, the background would appear to bleed into the button. In a version 4.0 application, a push button's outer top left corner is white (COLOR_3DHILIGHT) because the button is typically drawn on a nonwhite background (COLOR_3DFACE).


Edit Control Differences

In a version 3.x application, an edit control that is the descendant of an inactive window takes the input focus when the user clicks the control; an edit control in a version 4.0 application does not. Not taking the input focus prevents the situation where the user can enter text into what appears to be an inactive window.

An edit control in a version 3.x application retrieves its text and background colors by sending the WM_CTLCOLOREDIT message to its parent window. In a version 4.0 application, an edit control sends the WM_CTLCOLOREDIT or WM_CTLCOLORSTATIC message. The edit control sends WM_CTLCOLORSTATIC if it is disabled or read-only; otherwise, it sends WM_CTLCOLOREDIT. In addition, a disabled multiline edit control in a version 4.0 application uses the COLOR_GRAYTEXT value as its text color.

A multiline edit control in a version 4.0 application has a proportional scroll box (thumb), but a multiline edit control in a version 3.x application does not.

In a version 3.x application, the wParam parameter of the EM_REPLACESEL message is not used. In a version 4.0 application, the wParam parameter is a flag that specifies whether the replacement operation can be undone.


List Box Differences

In a version 4.0 application, a list box that is part of a combo box uses the WM_CAPTURECHANGED notification message to hide its drop-down list if it is open. For more information, see "Combo Boxes" later in this topic.

The DDL_EXCLUSIVE flag of the DlgDirList function does not have the expected result in a version 3.x application. Specifically, the flag does not exclude read-write files from the list. In a version 4.0 application, the DDL_EXCLUSIVE flag excludes read-write files.

If a list box in a version 3.x application has either the WS_HSCROLL or WS_VSCROLL style, the list box receives both horizontal and vertical scroll bars. Although one of the scroll bars is typically hidden, Windows 95 displays the hidden scroll bar if its scrolling range becomes greater than zero. In a version 4.0 application, a list box does not receive a horizontal scroll bar, unless it has the WS_HSCROLL style. Likewise, it does not receive a vertical scroll bar unless it has the WS_VSCROLL style.

When creating a list box in a version 3.x application, Windows 95 always increases the size of the list box by adding the border width to each side. This is done because Windows 95 assumes that the dimensions specified by the application or the dialog template are for the client area of the list box. Unfortunately, increasing the size in this way makes aligning a list box rather difficult. Windows 95 does not increase the size when creating a list box in a version 4.0 application; Windows 95 assumes that the specified size includes the borders.


Combo Box Differences

A combo box in a version 4.0 application passes the control color messages (WM_CTLCOLOR*) from its child components (edit control and list box) to the parent window of the combo box. In a version 3.x application, a combo box passes those messages to the DefWindowProc function.

A combo box in a version 4.0 application uses the WM_CAPTURECHANGED message to hide its drop-down list box if it is open. Windows 95 sends the message when another window takes the mouse capture, which typically happens when the user clicks another window. In a version 3.x application, a combo box does not use WM_CAPTURECHANGED to hide the drop-down list.

A combo box in a version 3.x application uses the WM_CTLCOLORLISTBOX message to retrieve the text and background colors. In a version 4.0 application, a combo box uses the WM_CTLCOLOREDIT or WM_CTLCOLORSTATIC message instead. The combo box uses WM_CTLCOLORSTATIC if it is disabled or contains a read-only selection field (in an edit control); otherwise, it uses WM_CTLCOLOREDIT.

In a version 3.x application, the background of the static text area in read-only combo boxes is filled with the system highlight color (COLOR_HILIGHT). In a version 4.0 application, Windows 95 fills the background of the static text area only for a combo box that is not owner drawn.

In a version 4.0 application, Windows 95 adds the ODS_COMBOBOXEDIT value to the itemState member of the DRAWITEMSTRUCT structure when Windows 95 sends the WM_DRAWITEM message to the parent window of an owner-drawn combo box to draw an item in the selection field. The ODS_COMBOBOXEDIT value tells the parent window that the drawing takes place in the selection field of the combo box rather than in the list box.


Menu Differences

A 16-bit version 3.x application that creates or loads a menu is considered to be the owner of the menu. However, when the application exits, the menu is "orphaned" until no 16-bit version components for Windows version 3.x remain. For 16-bit version 4.0 applications and all 32-bit applications, the application that creates the menu is the owner, and the menu is destroyed as soon as the application exits. Unlike graphics device interface (GDI) objects, there is no way to change the ownership of a menu.

In a version 3.x application, the Close command cannot be deleted from the System menu of an multiple document interface (MDI) child window. In a version 4.0 application, the Close command can be deleted.

Windows 95 increases the width of hierarchical, owner-drawn menu items in a version 3.x application. Some applications rely on this increased width and use it to include icons that simulate toolbars. In a version 4.0 application, Windows 95 does not automatically increase the width of hierarchical, owner-drawn menu items.

The wParam parameter of the WM_MENUSELECT message is interpreted differently depending on the subsystem version number of the application and whether the application is written for 16 or 32 bits:

  • In a 16-bit version 3.x application, the wParam parameter is the handle of the pop-up menu if the selected item activates a pop-up menu.
  • In a 16-bit version 4.0 application, wParam is the identifier of the menu item, regardless of whether the item activates a pop-up menu.
  • In a 32-bit application (both subsystem versions), the low-order word of wParam is the identifier of the menu item or, if the item activates a pop-up menu, the index of the pop-up menu. This high-order word contains the menu flags.


System Bitmap and Color Differences

In 16-bit version 3.x applications, purpose windows, such as dialog boxes, message boxes, and system-defined control windows, receive WM_CTLCOLOR messages when they are about to be drawn. The high-order word of the lParam parameter indicates the type of special purpose window about to be drawn (CTLCOLOR_BTN, CTLCOLOR_EDIT, and so on). By default, a special purpose window passes the WM_CTLCOLOR message to the parent or owner window (for both subsystem versions), allowing the parent or owner to set the foreground and background colors of the special purpose window. The same is true for 32-bit applications, except that the special purpose window receives one or more of the following messages instead of WM_CTLCOLOR.

WM_CTLCOLORBTN
WM_CTLCOLORDLG
WM_CTLCOLOREDIT
WM_CTLCOLORLISTBOX 		WM_CTLCOLORMSGBOX
WM_CTLCOLORSCROLLBAR
WM_CTLCOLORSTATIC

In 32-bit applications, the message itself indicates the type of special purpose window about to be drawn. The lParam parameter contains the window's 32-bit handle.

Display drivers for Windows version 3.x provide the bitmaps, icons, and cursors used by previous versions of Windows. Because Windows 95 renders and scales the system bitmaps, icons, and cursors itself, its display drivers do not (and should not) contain any OBM_, OIC_, or OCR_ resources.

For a version 3.x application, the default handling of the WM_CTLCOLORSTATIC and WM_CTLCOLORDLG messages is to use the COLOR_WINDOW value for the background and the COLOR_WINDOWTEXT value for the foreground. For a version 4.0 application, Windows 95 uses the COLOR_3DFACE value for the background and the COLOR_WINDOWTEXT value for the foreground.

When an application calls the GetClientRect function to retrieve the client rectangle of a minimized window created by a version 3.x application, Windows 95 retrieves the old dimensions for a minimized window (0, 0, 36, 36). For a minimized window in a version 3.1 or 4.0 application, Windows 95 retrieves 0, 0, GetSystemMetrics(SM_CXMINIMIZED), GetSystemMetrics(SM_CYMINIMIZED). These metrics change if the user changes the title bar height or minimized window width by using Control Panel. In other words, the GetClientRect function returns the dimensions of the entire minimized window, preventing an application from causing a general protection (GP) fault because of an unexpectedly empty client rectangle.


System Metrics Differences

When a version 3.x application calls the GetSystemMetrics function to retrieve the SM_CYVSCROLL or SM_CYHSCROLL metric value, the function returns a value that is one pixel more than the actual height of the corresponding type of standard scroll bar. Windows 95 adds a pixel because applications written for previous versions of windows routinely subtract one pixel from the return value. Subtracting one pixel accounts for the way a standard scroll bar in a version 3.x application overlaps the border of the window in which it resides. A version 4.0 application receives the actual height of the scroll bar.

When a version 3.x application retrieves the SM_CXDLGFRAME and SM_CYDLGFRAME system metric values, GetSystemMetrics returns a value that is one pixel less that the actual frame width or height. A version 4.0 application receives the actual width or height.

GetSystemMetrics returns one pixel more than the actual height of a title bar when a version 3.x application requests the SM_CYCAPTION system metric value. A version 4.0 application receives the actual height of the title bar.

GetSystemMetrics returns one pixel less than the actual height of a menu bar when a version 3.x application requests the SM_CYMENU system metric value. A version 4.0 application receives the actual height of the menu bar.

When a version 3.x application calls GetSystemMetrics to retrieve the SM_CYFULLSCREEN value (height of a maximized window's client area), the function returns a value that is one pixel less than the actual height. This is because GetSystemMetrics returns one pixel more than the actual title bar height when an application retrieves the SM_CYCAPTION value. (The sum of the height of a maximized window's client area and the height of a title bar must equal the height of the working area of the screen.) A version 4.0 application receives the actual height of the maximized window's client area when it requests the SM_CYFULLSCREEN value.


Parameter Validation Differences

If a 32-bit version 3.x application specifies invalid class styles when calling the RegisterClass function, Windows 95 strips out the invalid bits and generates warnings in the system debugger, but allows RegisterClass to succeed anyway. If a 32-bit version 4.0 application passes invalid class styles to RegisterClass, the function fails.

In a version 3.x application, Windows 95 does not validate the length member of the WINDOWPLACEMENT structure that is passed to the GetWindowPlacement and SetWindowPlacement functions. The length member, however, is validated for a version 4.0 application; Windows 95 fails these functions if the value of length is incorrect.

Windows 95 does not validate the cbSize member of the STARTUPINFO structure specified in the CreateProcess and GetStartupInfo functions for applications written for Windows version 3.x. The cbSize member is validated, however, for version 4.0 applications.

In the debugging version of Windows 95, the system fills the specified buffer with zeros up to the length specified by the cbSize parameter when a version 4.0 application calls the LoadString function. The buffer is not filled with zeros for a version 3.x application.


Windows 95, OEM Service Release 2

Windows 95, OEM Service Release 2 is the most recent OEM (Original Equipment Manufacturer) release of the Windows 95 operating system. Beginning in the second half of 1996, this is the version of Windows 95 that most computer manufacturers will pre-install on new machines.


Elements of Interest to Win32 Programmers

Several elements of Windows 95, OEM Service Release 2 may be of interest to Win32 programmers:

  • The FAT32 File System
  • The GetDiskFreeSpaceEx Function
  • The Cryptographic API
  • DirectX 2
  • ActiveMovie
  • Internet Explorer 3.0 and the Windows Internet Extensions API
  • OpenGL 1.1


The FAT32 File System

Windows 95, OEM Service Release 2 includes FAT32 File System.

FAT32 is an enhancement of the File Allocation Table (FAT) file system. FAT32 supports large drives with improved disk space efficiency.

Most Win32-based applications do not need to be revised for FAT32. The only applications that will need revising are those that use low-level disk structures, or those that use API functions that are dependent upon the on-disk FAT format of data.


The GetDiskFreeSpaceEx Function

Windows 95, OEM Service Release 2 supports the GetDiskFreeSpaceEx function.

Under Windows 95, including OEM Service Release 2, the existing Win32 function GetDiskFreeSpace caps the amount of free or total disk space reported on large drives to 2 gigabytes. Under OEM Service Release 2, in order to maintain compatibility with existing applications, even on volumes that are smaller than 2 gigabytes, GetDiskFreeSpace may return incorrect values.

The GetDiskFreeSpaceEx function obtains correct values for all volumes, including those that are larger than 2 gigabytes. New Win32-based applications should use the GetDiskFreeSpaceEx function. It is supported on Windows 95 OEM Service Release 2 and on Windows NT 4.0. As with all Windows 95, OEM Service Release 2 features, however, applications that call GetDiskFreeSpaceEx should be prepared to fall back to the GetDiskFreeSpace function to maintain compatibility with older Win32 implementations.


The Cryptographic API

Windows 95, OEM Service Release 2 supports the Cryptographic Application Programming Interface (CryptoAPI).

CryptoAPI is a set of functions that let applications encrypt or digitally sign data in a flexible manner, while providing protection for the user's sensitive private key data.


DirectX 2

Windows 95, OEM Service Release 2 includes DirectX 2.

DirectX 2 is a set of technologies that assist in multimedia and games programming. DirectX 2 includes DirectDraw, DirectSound, and DirectPlay.


ActiveMovie

Windows 95, OEM Service Release 2 includes ActiveMovie™.

ActiveMovie is a cross-platform digital video technology for the desktop and the Internet. ActiveMovie lets developers and creative professionals create and deliver stunning titles on multiple platforms with crisp synchronized audio, video, and special effects.


Internet Explorer 3.0 and the Windows Internet Extensions API

Windows 95, OEM Service Release 2 includes Internet Explorer 3.0, which in turn includes the Windows Internet Extensions API (WinInet).

WinInet provides a set of abstractions, layered over Windows Sockets, which support programming common operations for Internet protocols such as FTP and Gopher.

You can find documentation for WinInet in the ActiveX SDK. You can find the most current information about the ActiveX SDK at http://www.microsoft.com/intdev/.


OpenGL 1.1

Windows 95, OEM Service Release 2 includes OpenGL 1.1.

OpenGL is a three-dimensional (3-D) graphics software interface with which programmers create high-quality still and animated 3-D color images. The OpenGL overview describes the Windows NT and Windows 95 implementation of OpenGL.


Detecting Windows 95, OEM Service Release 2

Use the GetVersionEx function to determine that a system is running Windows 95, OEM Service Release 2 or a later release of the Windows 95 operating system.

The GetVersionEx function fills the members of an OSVERSIONINFO data structure. If the dwPlatformId member of that structure is VER_PLATFORM_WIN32_WINDOWS, and the low word of the dwBuildNumber member is greater than 1080, the system is running Windows 95,OEM Service Release 2 or a later release of Windows 95.

MS-DOS applications can check for an MS-DOS version number of 7.1 or higher to determine that a system is running Windows 95,OEM Service Release 2 or a later release of Windows 95.


Using Windows 95, OEM System Release 2 Functionality

After you have determined that a system is running Windows 95, OEM Service Release 2 or later, you can attempt to use its functionality. Some functions can be called directly. For other functions, you need to call the LoadLibrary or LoadLibraryEx function to load the appropriate DLL file, then call the GetProcAddress function to obtain an address for the function.

Applications that attempt to use Windows 95, OEM System Release 2 functionality should be prepared to fall back to earlier Windows 95 functionality in order to maintain compatibility with earlier versions of Windows 95.


Device I/O Control

Microsoft® Windows® 95 includes a device input and output control (IOCTL) interface that allows applications developed for the Microsoft® Win32® application programming interface (API) to communicate directly with virtual device drivers.


About Device I/O Control

Applications typically use the IOCTL interface to carry out selected Microsoft® MS-DOS® system functions, to obtain information about a device, or to carry out input and output (I/O) operations that are not available through standard Win32 functions.

This article describes the device IOCTL interface, explains how to use the interface in applications, and describes how to implement the interface in virtual devices (VxDs). For information about the device IOCTL interface for other operating systems that support the Win32 API, see the documentation included in the Microsoft Platform Software Development Kit (SDK).


Input and Output Control in Applications

You use the device IOCTL interface in an application to carry out "low-level" operations that are not supported by the Win32 API and that require direct communication with a VxD. Windows 95 implements the interface through the DeviceIoControl function, which sends commands and accompanying data directly to the given VxD. To use the interface, you open the VxD by using the CreateFile function, send commands to the VxD by using DeviceIoControl, and finally close the VxD by using the CloseHandle function.


Opening the VxD

You can open a static or dynamically loadable VxD by specifying the module name, filename, or registry entry identifying the VxD in a call to the CreateFile function. If the VxD exists and it supports the device IOCTL interface, the function returns a device handle that you can use in subsequent calls to the DeviceIoControl function. Otherwise, the function fails and sets the last error value to ERROR_NOT_SUPPORTED or ERROR_FILE_NOT_FOUND. You can use the GetLastError function to retrieve the error value.

When you open a VxD, you must specify a name having the following form.

\\.\VxdName

VxDName can be the module name of the VxD, the name of the VxD file, or the name of a registry entry that specifies the filename.

CreateFile checks for a filename extension to determine whether VxDName specifies a file. If a filename extension (such as .VXD) is present, the function looks for the file in the standard search path. In the following example, CreateFile looks for the SAMPLE.VXD file in the standard search path.

HANDLE hDevice;

hDevice = CreateFile("\\\\.\\SAMPLE.VXD", 0, 0, NULL, 0,
    FILE_FLAG_DELETE_ON_CLOSE, NULL);

If VxDName has no filename extension, CreateFile checks the registry to see if the name is also a value name under the KnownVxDs key in HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SessionManager. If it is a value name, CreateFile uses the current value associated with the name as the full path of the VxD file. This method is useful for specifying VxDs that are not in the standard search path. In the following example, CreateFile searches the registry for the MYVXDPATH value.

hDevice = CreateFile("\\\\.\\MYVXDPATH", 0, 0, NULL, 0,
    FILE_FLAG_DELETE_ON_CLOSE, NULL);

If VxDName has no filename extension and is not in the registry, CreateFile assumes that the name is a VxD module name and searches the internally maintained device descriptor blocks for an already loaded VxD having the given name. In the following example, CreateFile opens the standard VxD named VWIN32.VXD.

hDevice = CreateFile("\\\\.\\VWIN32", 0, 0, NULL, 0,
    0, NULL);

In all cases, if CreateFile cannot find or load the VxD, it sets the last error value to ERROR_FILE_NOT_FOUND. If the function loads the VxD but the VxD does not support the device IOCTL interface, CreateFile sets the last error value to ERROR_NOT_SUPPORTED.

You can open the same VxD any number of times. CreateFile provides a unique handle each time you open a VxD, but it makes sure that no more than one copy of the VxD is loaded into memory. To ensure that the system removes the VxD from memory when you close the last instance of the VxD, use the FILE_FLAG_DELETE_ON_CLOSE value when opening dynamically loadable VxDs. Static VxDs cannot be removed from memory.

Although CreateFile has several parameters, only the lpName and fdwAttrsAndFlags parameters are useful when opening an VxD. fdwAttrsAndFlags can be zero, the FILE_FLAG_DELETE_ON_CLOSE value, or the FILE_FLAG_OVERLAPPED value. FILE_FLAG_OVERLAPPED is used for asynchronous operation and is described later in this article.


Sending Commands

You use DeviceIoControl to send commands to a VxD. You must specify the previously opened device handle, control code, and input and output parameters for the call. The device handle identifies the VxD, and the control code specifies an action for the VxD to perform. In the following example, the DIOC_GETVERSION control code directs the given VxD to return version information.

HANDLE hDevice
BYTE bOutput[4];
DWORD cb;

fResult = DeviceIoControl(
    hDevice,          // device handle
    DIOC_GETVERSION,  // control code
    NULL, 0,          // input parameters
    bOutput, 4, &cb,  // output parameters
    0);

The input and output parameters of DeviceIoControl include the addresses and sizes of any buffers needed to pass data into or out of the VxD. Whether you use these parameters depends on how the VxD processes the control code. You supply an input buffer if the VxD requires that you pass it data for processing, and you supply an output buffer if the VxD returns the results of processing. In the previous example, only the output parameters are supplied. These include the address of the output buffer; the size, in bytes, of the buffer; and the address of the variable to receive the count of bytes actually copied to the buffer by the VxD.

Although the Win32 header files define a set of standard control codes, Windows 95 does not support these standard codes. Instead, the meaning and value of control codes in Windows 95 are specific to each VxD. Different VxDs may support different control codes.

Some VxDs support the DIOC_GETVERSION control code, which directs the VxD to return version information in the output buffer. Although the version information can have any format that helps the application determine the version of the VxD, keeping the information to 4 bytes or less is recommended. The VxD returns the version information only if you supply a buffer and specify a nonzero size for the buffer.

If you opened the VxD using the FILE_FLAG_OVERLAPPED value, you must also provide an OVERLAPPED structure when calling DeviceIoControl. This structure contains information that the VxD uses to process the control code asynchronously.


Closing a VxD

When you have finished using a VxD, you can close the associated device handle by using the CloseHandle function, or you can let the operating system close the handle when the application terminates. The following example closes a VxD.

CloseHandle(hDevice);

Closing a VxD does not necessarily remove the VxD from memory. If you open a dynamically loadable VxD using the FILE_FLAG_DELETE_ON_CLOSE value, CloseHandle also removes the VxD if no other valid handles are present in the system. The system maintains a reference count for dynamically loadable VxDs, incrementing the count each time the VxD is opened and decrementing when the VxD is closed. CloseHandle checks this count and removes the VxD from memory when the count reaches zero. The system does not keep a reference count for static VxDs; it does not remove these VxDs when their corresponding handles are closed.

In rare cases, you may need to use the DeleteFile function to remove a dynamically loadable VxD from memory. For example, you use DeleteFile if another application has loaded the VxD and you just want to unload it. You also use DeleteFile if you have successfully loaded a VxD by using CreateFile, but the VxD does not support the device IOCTL interface. In such cases, CreateFile loads the VxD but provides no handle to close and remove the VxD. The following example removes the VxD named SAMPLE from memory.

DeleteFile("\\\\.\\SAMPLE");

In this example, SAMPLE is the module name of the VxD. (Do not specify the filename.) Be aware that the module name of a VxD is not necessarily the same as the VxD's filename without a filename extension. In general, avoid using DeleteFile to remove a VxD from memory.


Asynchronous Operations and VxDs

You can direct a VxD to process a control code asynchronously. In an asynchronous operation, the DeviceIoControl function returns immediately, regardless of whether the VxD has finished processing the control code. Asynchronous operation allows an application to continue while the VxD processes the control code in the background. You request an asynchronous operation by specifying the address of an OVERLAPPED structure in the DeviceIoControl function. The hDevice member of OVERLAPPED specifies the handle of an event that the system sets to the signaled state when the VxD has completed the operation.

Asynchronous (overlapped) operations are useful for lengthy operations, such as formatting a disk. To perform an asynchronous operation, you must specify the FILE_FLAG_OVERLAPPED value when calling CreateFile to obtain a device handle. When calling DeviceIoControl, you must specify the address of an OVERLAPPED structure in the lpOverlapped parameter and the handle of a manual reset event in the hEvent member of the structure. The system ignores all other members.

If DeviceIoControl completes the operation before returning, it returns TRUE; otherwise, it returns FALSE. When the operation is finished, the system signals the manual reset event. You should call GetOverlappedResult when the thread that called DeviceIoControl needs to wait (that is, stop executing) until the operation has finished.


Using VWIN32 to Carry Out MS-DOS Functions

Windows 95 provides a VxD named VWIN32.VXD that supports a set of control codes that Win32-based applications can use to carry out selected MS-DOS system functions. These system-defined control codes consist of the following values.

Control code (value) | Meaning
VWIN32_DIOC_DOS_DRIVEINFO (6) | Performs Interrupt 21h Function 730X commands. This value is supported in Windows 95 OEM Service Release 2 and later.
VWIN32_DIOC_DOS_INT13 (4) | Performs Interrupt 13h commands
VWIN32_DIOC_DOS_INT25 (2) | Performs the Absolute Disk Read command (Interrupt 25h)
VWIN32_DIOC_DOS_INT26 (3) | Performs the Absolute Disk Write command (Interrupt 25h)
VWIN32_DIOC_DOS_IOCTL (1) | Performs the specified MS-DOS device I/O control function (Interrupt 21h Function 4400h through 4411h)

When an application calls the DeviceIoControl function with the dwIoControlCode parameter set to one of the predefined control codes, the lpvInBuffer and lpvOutBuffer parameters must specify the addresses of DIOC_REGISTERS structures. The DIOC_REGISTERS structure specified by lpvInBuffer contains a set of register values that specify a command for the VxD to execute and any data that the VxD needs to execute the command. After completing the command, the VxD fills the DIOC_REGISTERS structure specified by lpvOutBuffer with the register values that resulted from executing the command. The meaning of the register values depends on the specified command. Many of the MS-DOS and BIOS functions require segment:offset register pairs for pointers. However, because 32-bit code does not have segments, the DIOC_REGISTERS structure does not contain members for segment registers. Place the full pointer that would go into a real-mode segment:offset register pair into the structure member that corresponds to the offset of the register pair. For example, use the reg_EDI member for the pointer that would go into the ES:DI registers. When an application uses the DeviceIoControl function to send commands to a VxD other than VWIN32.VXD, the meaning of the function's parameters are defined by the VxD. The system does not validate the parameters. The system VxD, VWIN32.VXD, supports the IOCTL functions originally provided by MS-DOS Interrupt 21h. The following example shows how to call Get Media ID (Interrupt 21h Function 440Dh Minor Code 66h) from a Win32-based application.

#define VWIN32_DIOC_DOS_IOCTL 1

typedef struct _DIOC_REGISTERS {
    DWORD reg_EBX;
    DWORD reg_EDX;
    DWORD reg_ECX;
    DWORD reg_EAX;
    DWORD reg_EDI;
    DWORD reg_ESI;
    DWORD reg_Flags;
} DIOC_REGISTERS, *PDIOC_REGISTERS;

// Important: All MS_DOS data structures must be packed on a
// one-byte boundary.

#pragma pack(1)
typedef struct _MID {
    WORD  midInfoLevel;
    DWORD midSerialNum;
    BYTE  midVolLabel[11];
    BYTE  midFileSysType[8];
} MID, *PMID;
#pragma pack()

HANDLE hDevice;
DIOC_REGISTERS reg;
MID mid;
BOOL fResult;
DWORD cb;
int nDrive = 3;  // Drive C:

hDevice = CreateFile("\\\\.\\vwin32",
    0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL);

reg.reg_EAX = 0x440D;       // IOCTL for block devices
reg.reg_EBX = nDrive;       // zero-based drive identifier
reg.reg_ECX = 0x4866;       // Get Media ID command
reg.reg_EDX = (DWORD) &mid; // receives media identifier information
reg.reg_Flags = 0x0001;     // assume error (carry flag is set)

fResult = DeviceIoControl(hDevice,
    VWIN32_DIOC_DOS_IOCTL,
    &reg, sizeof(reg),
    &reg, sizeof(reg),
    &cb, 0);

if (!fResult || (reg.reg_Flags & 0x0001))
    ; // error if carry flag is set

CloseHandle(hDevice);


Supporting Input-Output Control in VxDs

A VxD can support the device IOCTL interface by processing the W32_DEVICEIOCONTROL message in the VxD's control procedure. You can take advantage of the device IOCTL interface by providing a VxD that performs privileged (ring 0) operations for your application.


Loading and Opening the VxD

When your application calls CreateFile, the system sends the W32_DEVICEIOCONTROL message to the control procedure of the specified VxD to determine if it supports the device IOCTL interface. The ESI register contains the address of a DIOCParams structure whose dwIoControlCode member specifies the DIOC_GETVERSION control code. A VxD that supports the device IOCTL interface must respond to the DIOC_GETVERSION control code by clearing the EAX register. (A VxD can also return version information in the buffer pointed to by the lpvOutBuffer member so long as the cbOutBuffer member is nonzero. If cbOutBuffer is zero, the calling application is not interested in version information, but the VxD must still return zero to indicate success.) If the VxD does not support the device IOCTL interface, it must place a nonzero value in EAX.

For dynamically loadable VxDs, the system sends a SYS_DYNAMIC_INIT control message to the VxD the first time that it is opened. If the VxD returns success, the system sends the W32_DEVICEIOCONTROL message with the DIOC_OPEN (identical in value to the DIOC_GETVERSION control code) control code. The VxD must return zero to inform the calling application that it supports W32_DEVICEIOCONTROL. The system sets the reference count for the VxD to 1. On every subsequent call to CreateFile for the VxD, the VxD receives the W32_DEVICEIOCONTROL message with the DIOC_OPEN control code and the reference count for the VxD is incremented.

The VxD receives a W32_DEVICEIOCONTROL message with the DIOC_CLOSEHANDLE control code if the application closes the device handle by calling the CloseHandle function, or if the operating system closes the handle when the application terminates (or DeleteFile if the VxD was not opened with the FILE_FLAG_DELETE_ON_CLOSE value). The VxD can use this notification to perform cleanup operations and release structures associated with the application. The reference count for the VxD is decremented before the message is sent. If the reference count is decremented to zero, the VxD receives the SYS_DYNAMIC_EXIT message and is subsequently unloaded.


Processing Control Codes

When an application calls DeviceIoControl, the system calls the control procedure of the VxD identified by the given device handle. The EAX register contains the W32_DEVICEIOCONTROL message, and the ESI register contains the address of a DIOCParams structure. The structure contains all of the parameters that the application specified in the DeviceIoControl function as well as additional information. The VxD should examine the dwIoControlCode member of the DIOCParams structure to determine the action to perform. The lpvInBuffer member contains supporting data that the VxD needs to complete the action. After processing the control code, the VxD should copy any information that it needs to return to the application to the buffer specified by the lpvOutBuffer member.

If the VxD successfully processes the control code, it should clear the EAX register before returning. Otherwise, the VxD should set EAX to a nonzero value.


Checking for Asynchronous Operations

A VxD can determine whether an application has requested an asynchronous operation by checking the lpoOverlapped member of the DIOCParams structure. If lpoOverlapped specifies the address of an OVERLAPPED structure, the application has requested an asynchronous operation. In that case, the VxD should return – 1 in the EAX register and then process the specified control code.

The operating system does not take any steps to make the application's memory available to the VxD at all times (in all contexts) for asynchronous operations. When implementing asynchronous operations, the VxD must use the appropriate virtual machine manager (VMM) services, such as LinPageLock with the PAGEMAPGLOBAL value, to make the application's memory pages available across contexts, including access to the OVERLAPPED structure.

When the VxD finishes processing the control code, it must notify the application by calling the VWIN32_DIOCCompletionRoutine service provided by VWIN32.VXD. The EBX register must contain the value of the Internal member of the OVERLAPPED structure. This member is reserved for operating system use only. Also, if the VxD copies any data to the buffer specified by the lpvOutBuffer member of the DIOCParams structure, the VxD must specify the count of bytes copied to the buffer in the InternalHigh member of OVERLAPPED. The remaining members of overlapped, Offset and OffsetHigh, can be used for developer-defined data.

Essentially, the VWIN32_DIOCCompletionRoutine service helps signal the event identified by the hEvent member of the OVERLAPPED structure. The application monitors the event to determine when the asynchronous operation is completed.


Device I/O Control Reference

The following structures, system messages, and service are associated with the device IOCTL interface.


Device I/O Control Structures

These structures are used to carry out device IOCTL functions:

DIOC_REGISTERS
DIOCParams


Device I/O Control System Messages

The following system message is used to implement the device IOCTL interface of a VxD:

W32_DEVICEIOCONTROL


Device I/O Services

The following service is used with device IOCTL:

VWIN32_DIOCCompletionRoutine


Exclusive Volume Locking

This article describes exclusive volume locking and provides guidelines for applications that carry out direct access on volumes while running with Microsoft® Windows® 95. This article also describes the input and output control (IOCTL) functions that applications need for managing exclusive volume locking.


About Exclusive Volume Locking

Disk utilities and other applications that directly modify file system structures, such as directory entries, must request exclusive volume locking (that is, exclusive use of the volume) before making modifications to the structures. Exclusive use prevents applications from inadvertently changing the file system while a disk utility is trying modify it and ensures that the information on a volume represents the current state of the volume.


Direct Access

Applications typically use direct access to make changes to the directory entries, paths, and allocation chains in the file allocation table (FAT) of a given volume. The applications access this information by using the Interrupt 13h functions, Absolute Disk Read and Write (Interrupts 25h and 26h), or the Interrupt 21h read, write, and format track IOCTL functions. Some applications may also access the volume using the disk controller input and output (I/O) ports.

As a multitasking operating system, Windows 95 permits any number of applications to access a volume at a given time. Applications that change the file system structures of a volume without regard to other applications risk corruption of that information and subsequent data loss. To prevent data loss, the system manages all requests for direct access. With the exception of floppy disk drives, Windows 95 does not permit direct write operations, unless the volume has been locked by the application. The system returns the ERROR_WRITE_PROTECT error value to functions or interrupts that attempt direct write operations when the volume has not been locked. An application can read directly from a volume, but the system may satisfy the request by reading from internal caches rather than from the medium itself. An application cannot access disk controller I/O ports; the system traps all access.

An application can override the default behavior of the system by requesting exclusive use of the volume using the lock and unlock volume IOCTL functions. An application that has exclusive use of a volume can read and write directly to the medium, and because the system flushes internal caches to the medium, the information there reflects the actual state of the volume. Locking a volume (including the floppy disk drives) ensures consistency of data, because other processes cannot update information about the volume while it is locked.


Exclusive Use Lock

To request exclusive use of a volume, an application use either Lock Logical Volume (Interrupt 21h Function 440Dh Minor Code 4Ah) or Lock Physical Volume (Interrupt 21h Function 440Dh Minor Code 4Bh). Before issuing an Interrupt 13h function, an application must acquire a physical volume lock. An application that only modifies logical volumes should acquire a logical volume lock. The calling interface for both locks is the same except for how the volume to lock is specified; the physical lock requires an Interrupt 13h device unit number, but the logical lock requires a logical drive number. When an application obtains a lock on a physical drive, the system acquires a logical volume lock for each logical volume on the physical drive. Obtaining a lock on a logical volume that is the parent (or host) drive also locks the child drives. For example, a compressed volume is locked when its host drive is locked.

The application that owns the lock can carry out direct disk write operations. Only one application at a time can lock the volume. If an application already owns the volume lock, the system fails subsequent calls to lock the volume.

The volume-locking functions allow the lock owner to control the kind of access that other processes have to the volume. There are three categories of access: read operations, which include opening a file as well as reading from a file; write operations, which include deleting and renaming a file as well as writing to a file; and new file mappings.

When an application calls either of the lock volume functions, it specifies a lock level and, depending on the level, passes in additional information known as permissions. The lock level and permissions specify what kind of operations the system allows processes other than the lock owner to do on the volume while it is locked.

When another process attempts to access the volume, the file system will fail the operation and return the ERROR_WRITE_PROTECT error value or it will block the operation, depending on the lock level and permissions. The system queues a blocked operation and puts the process requesting the operation to sleep until the lock is released and the operation can be performed.

When an application has completed its work, it must unlock the volume. Depending on whether it acquired a logical or physical lock, the application unlocks the volume by calling either Unlock Logical Volume (Interrupt 21h Function 440Dh Minor Code 6Ah) or Unlock Physical Volume (Interrupt 21h Function 440Dh Minor Code 6Bh). Unlocking the volume lets the system perform any blocked operations (in the order that they occurred) and resume normal activity. If an application exits without releasing the lock, the system automatically releases it.

If an application has a lock and the user attempts to close the virtual machine in which the application is running, the system displays a message warning the user that closing the virtual machine could result in damage to the volume. If the user confirms the closing, the system releases the lock and closes the virtual machine.

An application can lock volumes on local drives, but not on network drives or on drives that are not managed by the I/O supervisor, a virtual device driver. Also, the lock and unlock volume IOCTL functions are not available in previous versions of Microsoft® MS-DOS®. If the functions are used with a previous version, they return an error value.

Windows 95 provides 4 levels of exclusive volume locks. The level 0 lock is used alone, and lock levels 1, 2, and 3 form a hierarchy that increasingly restricts access to the file system based on the permissions set when the application obtains the level 1 lock. Although the level 0 lock is not part of the locking hierarchy formed by lock levels 1, 2, and 3, it has a more restrictive sublevel for applications that format volumes. Applications should perform direct disk write operations only in either a level 0 or 3 lock.


Level 0 Lock

The level 0 lock cannot be obtained on volumes that have any open files or handles. This restriction includes handles returned by the Windows FindFirstFile and FindFirstChangeNotification functions. Because the system always has open files, an application cannot take a level 0 lock on the drive that contains the Windows 95 system files. The locking hierarchy can be used on volumes with open files and handles. If the system fails a level 0 lock request because of open files, an application can obtain a list of all the open files on the volume by calling Enumerate Open Files (Interrupt 21h Function 440Dh Minor Code 6Dh).

Before returning from the call to lock the volume, Windows 95 flushes to disk all data from the file system cache. To ensure that the disk and file system remain in a consistent state, the system puts the cache into write-through mode so that it can immediately commit to disk all data from file write operations. If an application has obtained a lock on a child volume, the system does not automatically flush the file system cache after a write operation to the parent volume. To ensure that the cache is flushed when opening files with Open or Create File (Interrupt 21h Function 716Ch), an application should specify the OPEN_FLAGS_NO_BUFFERING (0100h) value. If a file has not been opened with OPEN_FLAGS_NO_BUFFERING or Absolute Disk Write (Interrupt 26h) has been used to write to the parent volume, an application should call Reset Drive (Interrupt 21h Function 710Dh) to flush the cache.

After a process obtains a level 0 lock, the system only allows the lock owner to have access to the volume. The system fails all read operations, write operations, and new file mappings by other processes until the lock owner releases the lock. An application should use a level 0 lock whenever possible, because it guarantees that no other process can access the locked volume.

An application that formats volumes must obtain a more restrictive mode of the level 0 lock. To format a volume, the application should follow these steps:

  1. Call the lock volume function to obtain a level 0 lock.
  2. Do any needed file system I/O that uses the Interrupt 21h file handle I/O functions while in the level 0 lock.
  3. Call the lock volume function a second time to obtain the more restrictive level 0 lock for formatting. When calling the lock volume function the second time, an application should specify 0 as the lock level and specify 4 in the permissions. The application, however, must already own the level 0 lock to obtain this lock.
  4. Format the disk using the Interrupt 21h IOCTL functions (such as Read/Write/Format/Verify Track on Logical Drive or Get/Set Device Parameters). Interrupt 13h will work too, but it is not the preferred method for performance reasons. The system allows direct disk I/O, but it fails all other file system I/O that uses the Interrupt 21h file handle I/O functions while the restrictive level 0 lock is in effect.
  5. Release the level 0 lock for formatting. An application is still in a level 0 lock at this point. Before the application releases this lock, the disk must be in a state that would be recognizable as normal FAT media. Otherwise, the functions mentioned in step 6 will not work.
  6. Resume normal file system I/O using the Interrupt 21h file handle I/O functions.
  7. Release the level 0 lock.


Locking Hierarchy

The locking hierarchy allows an application to obtain a lock in preparation for modifying the file system and yet allows other processes access to the drive. In this way, other processes are only denied access to the volume when absolutely necessary.

An application should perform direct disk write operations only within a level 3 lock. To obtain a level 3 lock, an application must make three calls to the lock volume function — first to obtain a level 1 lock, then a level 2 lock, and finally a level 3 lock. After obtaining the level 3 lock, the application can safely access the volume directly.

To release the lock on a volume, an application must call the appropriate unlock volume function the same number of times that the corresponding lock volume function was called. Each call to the unlock volume function decrements the lock level. For example, a level 3 lock returns to a level 2 lock, and the system processes any blocked read operations. A level 2 lock returns to a level 1 lock, and the system processes any blocked write operations or new file mappings. A call to the unlock volume function on a level 1 lock, however, releases the lock on the volume and allows other processes to obtain the lock.

Exclusive volume locks are owned by a process, not a thread. If necessary, a multithreaded application can obtain a level 1 lock in one thread, a level 2 lock in another, and a level 3 lock in yet another.

Even though the system may block or fail new file mappings, other processes are allowed to write to files through existing file mappings, because file mappings cannot be resized. Writing to an existing file mapping only changes the contents of the memory-mapped file, it does not cause changes to the file system.


Level 1

The level 1 lock acts as a sentinel to guarantee that only one application may obtain the level 2 and 3 locks. An application specifies permissions only when requesting the level 1 lock. The lock level and permissions determine the kind of access that processes other than the lock owner have to the volume while it is locked. Bit 0 of the Permissions parameter for the lock volume function determines if the system allows or fails write operations by other processes. Bit 1 of Permissions determines if the system allows or fails new file mappings by other processes. Bit 2 of Permissions is only used when obtaining the restrictive level 0 lock for formatting and is ignored for a level 1 lock. The following table shows which operations are allowed at each lock level based on the permissions set on the level 1 lock.

Permissions | Level 1 | Level 2 | Level 3
Bit 0 = 0 Bit 1 = 0 | Write operations are failed. New file mappings are allowed. Read operations are allowed. | Write operations are failed. New file mappings are allowed. Read operations are allowed. | Write operations are failed. New file mappings are blocked. Read operations are blocked.
Bit 0 = 0 Bit 1 = 1 | Write operations are failed. New file mappings are failed. Read operations are allowed. | Write operations are failed. New file mappings are failed. Read operations are allowed. | Write operations are failed. New file mappings are failed. Read operations are blocked.
Bit 0 = 1 Bit 1 = 0 | Write operations are allowed. New file mappings are allowed. Read operations are allowed. | Write operations are blocked. New file mappings are allowed. Read operations are allowed. | Write operations are blocked. New file mappings are blocked. Read operations are blocked.
Bit 0 = 1 Bit 1 = 1 | Write operations are allowed. New file mappings are failed. Read operations are allowed. | Write operations are blocked. New file mappings are failed. Read operations are allowed. | Write operations are blocked. New file mappings are failed. Read operations are blocked.

Calling an unlock physical or logical volume function on a level 1 lock completely releases the lock on the volume.


Level 2

The level 2 lock prevents all processes except the lock owner from writing to the disk, but the lock allows any application to read from it. Depending on the permissions set when the application obtained the level 1 lock, the system will either block or fail write operations and either allow or fail new file mappings. Before obtaining a level 3 lock, an application should call Get Lock Flag State (Interrupt 21h Function 440Dh Minor Code 6Ch) to determine if anything on the disk has changed, such as the swap file growing or shrinking. Calling Get Lock Flag State at this point is an optimization that is done to avoid obtaining the level 3 lock unnecessarily.

Calling an unlock physical or logical volume function on a level 2 lock decrements the lock level to 1 and causes the system to perform previously blocked operations that are allowed at the lower lock level.


Level 3

The level 3 lock prevents all processes except the lock owner from reading or writing to the disk. Read operations are blocked, and write operations and new file mappings are either blocked or failed depending on the permissions set in the level 1 lock. This is the most restrictive lock, not only because it prevents all other processes from accessing the disk but also because the lock owner is limited in what it can do.

Because read operations are blocked in the level 3 lock, an application must not execute any user interface or screen update functions, spawn applications, load dynamic-link libraries (DLLs), or yield to avoid deadlock. For example, if an application yields to a process with a discardable segment that the system has discarded, the system cannot reload the discarded segment because the process cannot read from the disk. This situation results in deadlock. Whenever a process obtains a level 3 lock, it should keep the lock for as short a period as possible to avoid severely degrading system performance. The purpose of the level 3 lock is to write changes to disk, so processes should only call disk I/O functions inside the lock.

After a level 3 lock is obtained, the file system takes several steps to allow a process to write directly to the disk. First, the system flushes all file system buffers and caches. Next, it puts the cache into write-through mode so that changes will be written to disk immediately. Finally, all open files are closed at the file system driver (FSD) level, which is invisible to all processes. While an application is in a level 3 lock, the system does not permit the swap file to grow or shrink, but it can still be read from or written to.

If an application has obtained a lock on a child volume, the system does not automatically flush the file system cache after a write operation to the parent volume. To ensure that the cache is flushed when Open or Create File (Interrupt 21h Function 716Ch) is used, the application should specify the OPEN_FLAGS_NO_BUFFERING (0100h) value. If the file has not been opened with OPEN_FLAGS_NO_BUFFERING or Absolute Disk Write (Interrupt 26h) has been used to write to the parent volume, the application should call Reset Drive (Interrupt 21h Function 710Dh) to flush the cache.

Before releasing the level 3 lock, the process is responsible for putting the file system into a state consistent with what existed before the lock was obtained. The process must be careful to correctly update all file system data, such as the FAT or directory entries. If a file was opened, it must not be deleted, renamed, or moved to a different volume. Otherwise, the system can become very unstable. An application should use Enumerate Open Files (Interrupt 21h Function 440Dh Minor Code 6Dh) to obtain a list of all open files on the volume.

When the level 3 lock is released, the system unblocks all pending read operations, reopens closed files on demand, and puts the cache back into write-behind mode. The lock owner returns to a level 2 lock.


Using the Locking Hierarchy

An application should obtain a level 1 lock before beginning an operation, such as a complete defragmentation or compression. The application should release the level 1 lock only after the entire operation is finished. This approach prevents other processes from obtaining a lock on the same disk, which would keep the lock owner from finishing its work.

To minimize the time spent in the level 3 lock, a process should remain in the level 2 lock to perform certain tasks, such as computing disk statistics and preparing data packets to be written before actually writing them in the level 3 lock. As soon as a process enters the level 3 lock, the application must call Get Lock Flag State (Interrupt 21h Function 440Dh Minor Code 6Ch) to determine if anything on the disk has changed, such as the swap file growing or shrinking. If a change has occurred, the process should release the level 3 lock, return to the level 2 lock to recompute any needed information, and then obtain the level 3 lock again. If Get Lock Flag State shows that the disk has not changed, the process should do its writing and then release the level 3 lock.


Swap File

The system pager requires access to the swap file at all times, even when an application has locked the volume containing the file. To ensure access, the system always gives the system pager the opportunity to accept or reject a lock request.

If the system grants a lock to a process, the requesting process must ensure that data for the swap file remains unchanged and that the pager can safely read from or write to the swap file at any time. In particular, the process must not change the allocation chain of the swap file, and if it moves the swap file's directory entry, it must ensure that the path to it is always consistent. Failure to observe these guidelines can result in a system crash.

An application can determine the directory entry and allocation chain of the swap file by retrieving the path of the file using Find Swap File (Interrupt 21h Function 440Dh Minor Code 6Eh).

The system permits the swap file to grow or shrink in the level 1 and 2 locks. Because of this, an application should call Get Lock Flag State (Interrupt 21h Function 440Dh Minor Code 6Ch) after obtaining a level 3 lock to determine if anything on the disk has changed as the result of the swap file growing or shrinking.


Lock Requests and Virtual Devices

The system broadcasts a message to all virtual devices (VxDs) when an application makes a request for a lock. Any VxD that uses virtual block device and I/O supervisor services to carry out direct I/O on the given volume must check for this message and either accept or reject the request when the message is received.

If the VxD rejects the request, it must return the appropriate error value. In such cases, the system does not grant the lock to the requesting application. If a VxD accepts the request, it must avoid all operations that may affect the consistency of the volume for the duration of the lock.

When the application releases the lock, the system again issues a broadcast message. The VxD can resume normal operation at this point.


Volume-Locking Guidelines

Applications that lock and modify volumes should follow these guidelines to avoid degrading system performance and to prevent data loss:

  • If there are no open files on the volume, applications should perform direct disk writes in a level 0 lock. Otherwise, they should use the locking hierarchy and perform disk write operations in a level 3 lock.
  • Applications should utilize the locking hierarchy to minimize the time spent in a level 3 lock. They should only call disk I/O functions inside a level 3 lock and drop down to a level 1 or 2 lock whenever possible.
  • Applications should neither terminate or relinquish control nor leave a level 0 or 3 lock if the volume information is incomplete or invalid. When applications leave one of these locks, the file system must be consistent with what it was when they entered the lock because other applications will regain access to the drive.
  • Because the Interrupt 21h file handle I/O functions rely on accurate information about the volume, applications should not use these functions when the volume information is incomplete or invalid.
  • Applications should not move the swap file.
  • Applications should not move memory-mapped files opened for write access. Read-only memory-mapped files may be moved cluster by cluster.
  • Applications may only move 32-bit Windows-based DLLs and executables cluster by cluster.
  • Applications may move directory entries for the swap file and open memory-mapped files, but the path to them must always be consistent, even in a level 3 lock.

Because read operations are blocked in the level 3 lock, all applications written for 16-bit Windows, 32-bit Windows, or MS-DOS should follow these guidelines to avoid deadlock while in a level 3 lock:

  • Applications should only access the disk by using the low-level disk functions (Interrupt 13h, Interrupt 25h, and Interrupt 26h) or the Interrupt 21h file handle read, write, seek, and IOCTL functions. Other MS-DOS functions are not guaranteed to work. Windows or C run-time library file I/O functions should not be used, because these functions may contain code or call code that is not safe to execute inside the level 3 lock.
  • Applications should not yield control, update the screen, execute any user-interface code, or do anything else that could cause Windows 95 to load a new or previously discarded segment, such as by spawning an application or loading a DLL.
  • Windows-based applications must have all the code for a level 3 lock contained within the processing for a single message. The application should not process other messages or call any Windows functions.


Special Considerations for 32-bit Windows-Based Applications

32-bit Windows-based applications must call the exclusive volume-locking IOCTL functions indirectly by opening VWIN32.VXD and using its DeviceIoControl interface.

In response, VWIN32.VXD issues the low-level disk I/O functions (Interrupt 13h, Interrupt 25h, and Interrupt 26h) as well as the MS-DOS Interrupt 21h file handle read, write, seek, and IOCTL functions in the context of the calling process.

32-bit Windows-based applications may safely call the Windows ReadFile, WriteFile, SetFilePointer, and DeviceIoControl functions within a level 3 lock. Other Windows or C run-time library functions should not be used while in the level 3 lock, because these functions may call other functions that are not safe inside a level 3 lock.


Special Considerations for 16-bit Windows-Based Applications

16-bit Windows-based applications may call the exclusive volume-locking IOCTL functions directly using the Interrupt 21h interface, which is described in the reference material. These applications must mark all of the code, data, and resource segments that will be accessed while inside the level 2 and 3 locks as PRELOAD NONDISCARDABLE in the module-definition (.DEF) file. This marking prevents deadlock in case the system needs to load one of the application's segments from the executable file inside a level 3 lock.


Special Considerations for MS- DOS - Based Applications

Special Considerations for MS- DOS – Based Applications

MS-DOS – based applications may directly call the volume-locking IOCTL functions by using Interrupt 21h, as described in the reference material.

When a windowed MS-DOS – based application obtains a level 3 lock, the system forces it to full screen mode to avoid deadlock with the display driver. When the application releases the level 3 lock, it remains in full screen mode.

Applications must not call the Advanced SCSI Programming Interface (ASPI) functions inside a level 3 lock. These functions bypass the file system, leaving it in an inconsistent state.

When MS-DOS – based applications run in single MS-DOS application mode (real mode), they may issue the volume-locking IOCTL functions and the functions will succeed. However, because there is no multitasking, there is only one lock rather than a hierarchy as when Windows 95 is running. The volume-locking IOCTL functions will fail on down-level versions of MS-DOS.


Exclusive Volume Locking Reference

The following functions can be used to manage exclusive volume locking.


Exclusive Volume Locking Functions

Function | Description
Interrupt 21h Function 440Dh Minor Code 4Ah | Lock Logical Volume
Interrupt 21h Function 440Dh Minor Code 4Bh | Lock Physical Volume
Interrupt 21h Function 440Dh Minor Code 6Ah | Unlock Logical Volume
Interrupt 21h Function 440Dh Minor Code 6Bh | Unlock Physical Volume
Interrupt 21h Function 440Dh Minor Code 6Ch | Get Lock Flag State
Interrupt 21h Function 440Dh Minor Code 6Dh | Enumerate Open Files
Interrupt 21h Function 440Dh Minor Code 6Eh | Find Swap File
Interrupt 21h Function 440Dh Minor Code 70h | Get Current Lock State
Interrupt 21h Function 710Dh | Reset Drive

The exclusive-volume locking IOCTL functions are similar to other MS-DOS functions. An application must copy function parameters to registers and issue an Interrupt 21h instruction to carry out the call.


FAT32 File System

FAT32 is a derivative of the File Allocation Table (FAT) file system that supports drives with over 2GB of storage. Because FAT32 drives can contain more than 65,526 clusters, smaller clusters are used than on large FAT16 drives. This method results in more efficient space allocation on the FAT32 drive.


File System Specifications

The largest possible file for a FAT32 drive is 4GB minus 2 bytes. Win32-based applications can open files this large without special handling. However, non-Win32 applications must use Int 21h Function 6Ch (FAT32) with the EXTENDED_SIZE flag.

The FAT32 file system includes four bytes per cluster within the file allocation table. This differs from the FAT16 file system, which contains 2 bytes per cluster, and the FAT12 file system, which contains 1.5 bytes per cluster within the file allocation table.

Note that the high 4 bits of the 32-bit values in the FAT32 file allocation table are reserved and are not part of the cluster number. Applications that directly read a FAT32 file allocation table must mask off these bits and preserve them when writing new values.

File System Cluster Limits:

System | Cluster Limit
FAT12 | The count of data clusters is less than 4087 clusters.
FAT16 | The count of data clusters is between 4087 and 65526 clusters, inclusive.
FAT32 | The count of data clusters is between 65526 and 268,435456 clusters, inclusive.


Boot Sector and Bootstrap Modifications

Reserved Sectors
 | FAT32 drives contain more reserved sectors than FAT16 or FAT12 drives. The number of reserved sectors is usually 32, but can vary.
Boot Sector Modifications
 | Because a FAT32 BIOS Parameter Block (BPB), represented by the BPB (FAT32) structure, is larger than a standard BPB, the boot record on FAT32 drives is greater than 1 sector. In addition, there is a sector in the reserved area on FAT32 drives that contains values for the count of free clusters and the cluster number of the most recently allocated cluster. These values are members of the BIGFATBOOTFSINFO (FAT32) structure which is contained within this sector. These additional fields allow the system to initialize the values without having to read the entire file allocation table.
Root Directory
 | The root directory on a FAT32 drive is not stored in a fixed location as it is on FAT16 and FAT12 drives. On FAT32 drives, the root directory is an ordinary cluster chain. The A_BF_BPB_RootDirStrtClus member in the BPB (FAT32) structure contains the number of the first cluster in the root directory. This allows the root directory to grow as needed. In addition, the BPB_RootEntries member of BPB (FAT32) is ignored on a FAT32 drive.
Sectors Per FAT
 | The A_BF_BPB_SectorsPerFAT member of BPB (FAT32) is always zero on a FAT32 drive. Additionally, the A_BF_BPB_BigSectorsPerFat and A_BF_BPB_BigSectorsPerFatHi members of the updated BPB (FAT32) provide equivalent information for FAT32 media.


FAT Mirroring

On all FAT drives, there may be multiple copies of the FAT. If an error occurs reading the primary copy, the file system will attempt to read from the backup copies. On FAT16 and FAT12 drives, the first FAT is always the primary copy and any modifications will automatically be written to all copies. However, on FAT32 drives, FAT mirroring can be disabled and a FAT other than the first one can be the primary (or "active") copy of the FAT.

Mirroring is enabled by clearing bit 0x0080 in the extdpb_flags member of a FAT32 Drive Parameter Block (DPB) structure, DPB (FAT32).

When Enabled (bit 0x0080 clear)
 | With mirroring enabled, whenever a FAT sector is written, it will also be written to every other FAT. Also, a mirrored FAT sector can be read from any FAT. A FAT32 drive with multiple FATs will behave the same as FAT16 and FAT12 drives with multiple FATs. That is, the multiple FATs are backups of each other.
When Disabled (bit 0x0080 set)
 | With mirroring disabled, only one of the FATs is active. The active FAT is the one specified by bits 0 through 3 of the extdpb_flags member of DPB (FAT32). The other FATs are ignored. Disabling mirroring allows better handling of a drive with a bad sector in one of the FATs. If a bad sector exists, access to the damaged FAT can be completely disabled. Then, a new FAT can be built in one of the inactive FATs and then made accessible by changing the active FAT value in extdpb_flags.


Partition Types

The following are all the valid partition types and their corresponding values for use in the Part_FileSystem member of the s_partition (FAT32) structure.

Partition Types

Value | Description
PART_UNKNOWN(00h) | Unknown
PART_DOS2_FAT(01h) | 12-bit FAT
PART_DOS3_FAT(04h) | 16-bit FAT. Partitions smaller than 32MB.
PART_EXTENDED(05h) | Extended MS-DOS Partition
PART_DOS4_FAT(06h) | 16-bit FAT. Partitions larger than or equal to 32MB.
PART_DOS32(0Bh) | 32-bit FAT. Partitions up to 2047GB.
PART_DOS32X(0Ch) | Same as PART_DOS32(0Bh), but uses Logical Block Address Int 13h extensions.
PART_DOSX13(0Eh) | Same as PART_DOS4_FAT(06h), but uses Logical Block Address Int 13h extensions.
PART_DOSX13X(0Fh) | Same as PART_EXTENDED(05h), but uses Logical Block Address Int 13h extensions.


Limitations of Some Existing Functions

The following functions have limitations on FAT32 media:

File Control Block Functions
 | The open and create functions will only work for creating a volume label on a FAT32 drive. However, FCB Find_First/Next, Delete, and Rename will work and will return the entire 32-byte directory entry on FAT32 media.
Handle-Based File Write Functions
 | Win32-based applications can extend a file to a size greater than 2GB minus 1byte without special handling. However, non-Win32 applications must open such files with Int 21h Function 6Ch (FAT32) specifying the EXTENDED_SIZE flag. If not, write functions will fail and ERROR_ACCESS_DENIED (0005h) will be returned.
Handle-Based File Open and Create Functions
 | Win32-based applications can open files larger than 2GB minus 1byte in size without special handling. Non-Win32-based applications must open such files with Int 21h Function 6Ch (FAT32) specifying the EXTENDED_SIZE flag. However, using an old style create to truncate a file will not fail.


FAT32 File System Reference

The following functions and structures are supported on the FAT32 file system.


FAT32 File System Functions

The FAT32 file system supports the following new Int 21h functions and updated IOCTL functions.

New Int 21h Functions

Several new interrupt 21h functions were implemented to support FAT32 media. These additions are effective for Windows 95 OEM Service Release 2 and later.

The new Interrupt 21h Function 730X functions can be called using the DeviceIoControl function. DeviceIoControl has been updated to support VWIN32_DIOC_DOS_DRIVEINFO, a new control code for Interrupt 21h Function 730X functions.

For more information, see Using VWIN32 to Carry Out MS-DOS Functions.

The following new interrupt 21h functions have been implemented:

Int21h Function 7302h Get_ExtDPB (FAT32)
Int21h Function 7303h Get_ExtFreeSpace (FAT32)
Int21h Function 7304h Set_DPBForFormat (FAT32)
SetDPB_SetAllocInfo (FAT32)
SetDPB_SetDPBFrmBPB (FAT32)
SetDPB_ForceMediaChng (FAT32)
SetDPB_GetSetActFATandMirr (FAT32)
SetDPB_GetSetRootDirClus (FAT32)
Int21h Function 7305h Ext_ABSDiskReadWrite (FAT32)

Updated IOCTL Functions

All IOCTL functions have been modified to accept a new device category value (CH = 48h) for FAT32 drives. These changes are effective for Windows 95 OEM Service Release 2 and later.

Most of the 08h and 48h forms of each function accept identical parameters. In some cases, the two forms of the call (48h and 08h) are interchangeable. However, this is not always true. As a result, applications that call the 48h form of the function must be prepared to fall back on the 08h form, in case of failure. Please refer to each specific function for information regarding these values.

Set Device Parameters | Int 21h Function 440Dh Minor Code 40h (FAT32)
Write Track on Logical Drive | Int 21h Function 440Dh Minor Code 41h (FAT32)
Format Track on Logical Drive | Int 21h Function 440Dh Minor Code 42h (FAT32)
Set Media ID | Int 21h Function 440Dh Minor Code 46h (FAT32)
Set Access Flag | Int 21h Function 440Dh Minor Code 47h (FAT32)
Lock/Unlock Removable Media | Int 21h Function 440Dh Minor Code 48h (FAT32)
Eject Removable Media | Int 21h Function 440Dh Minor Code 49h (FAT32)
Lock Logical Volume | Int 21h Function 440Dh Minor Code 4Ah (FAT32)
Lock Physical Volume | Int 21h Function 440Dh Minor Code 4Bh (FAT32)
Get Device Parameters | Int 21h Function 440Dh Minor Code 60h (FAT32)
Read Track on Logical Drive | Int 21h Function 440Dh Minor Code 61h (FAT32)
Verify Track on Logical Drive | Int 21h Function 440Dh Minor Code 62h (FAT32)
Get Media ID | Int 21h Function 440Dh Minor Code 66h (FAT32)
Get Access Flag | Int 21h Function 440Dh Minor Code 67h (FAT32)
Sense Media Type | Int 21h Function 440Dh Minor Code 68h (FAT32)
Unlock Logical Volume | Int 21h Function 440Dh Minor Code 6Ah (FAT32)
Unlock Physical Volume | Int 21h Function 440Dh Minor Code 6Bh (FAT32)
Get Lock Flag State | Int 21h Function 440Dh Minor Code 6Ch (FAT32)
Enumerate Open Files | Int 21h Function 440Dh Minor Code 6Dh (FAT32)
Find Swap File | Int 21h Function 440Dh Minor Code 6Eh (FAT32)
Get Drive Map Info | Int 21h Function 440Dh Minor Code 6Fh (FAT32)
Get Lock Level | Int 21h Function 440Dh Minor Code 70h (FAT32)
Get First Cluster | Int 21h Function 440Dh Minor Code 71h (FAT32)


FAT32 File System Structures

With the addition of the FAT32 file system, the BPB, DPB, and DEVICEPARAMS structures were updated to accommodate FAT32 information. Additionally, subordinate structures have been implemented to support the FAT32 file system main structures. These changes are effective for Windows OEM Service Release 2 and later.

BPB (FAT32)
BIGFATBOOTFSINFO (FAT32)
DPB (FAT32)
EA_DEVICEPARAMETERS (FAT32)
ExtGetDskFreSpcStruc (FAT32)
s_partition (FAT32)
SDPDFormatStruc (FAT32)

Note: Many data structures in this document are listed as reserved. This indicates that the user is not to assume or modify the values within these fields. They are used by the file system itself and are not available for any enhancements.


Long Filenames

Microsoft® Windows® 95 allows users and applications to create and use long names for their files and directories. A long filename is a name for a file or directory that exceeds the standard 8.3 filename format.


About Long Filenames

In the past, long filenames typically appeared on network servers that used file systems other than the Microsoft® MS-DOS® file allocation table (FAT) file system. In Windows 95, however, long filenames are available for use with network servers and with local disk drives supporting the protected-mode FAT file system.

This article describes the long filename functions and explains how to create and use long filenames in applications written for MS-DOS and 16-bit Windows version 3. x. Microsoft® Win32®-based applications automatically have access to long filenames through the use of the corresponding Win32 file management functions.


Long Filenames and the Protected-Mode FAT File System

The protected-mode FAT file system is the default file system used by Windows 95 for mass storage devices, such as hard disk and floppy disk drives. Protected-mode FAT is compatible with the MS-DOS FAT file system, using file allocation tables and directory entries to store information about the contents of a disk drive. Protected-mode FAT also supports long filenames, storing these names as well as the date and time that the file was created and the date that the file was last accessed in the FAT file system structures.

The protected-mode FAT file system allows filenames of up to 256 characters, including the terminating null character. In this regard, it is similar to the Microsoft® Windows NT® file system (NTFS), which allows filenames of up to 256 characters. Protected-mode FAT allows directory paths (excluding the filename) of up to 246 characters, including the drive letter, colon, and leading backslash. This limit of 246 allows for the addition of a filename in the standard 8.3 format with the terminating null character. The maximum number of characters in a full path, including the drive letter, colon, leading backslash, filename, and terminating null character, is 260.

When an application creates a file or directory that has a long filename, the system automatically generates a corresponding alias for that file or directory using the standard 8.3 format. The characters used in the alias are the same characters that are available for use in MS-DOS file and directory names. Valid characters for the alias are any combination of letters, digits, or characters with ASCII codes greater than 127, the space character (ASCII 20h), as well as any of the following special characters.

$ % ' - _ @ ~ ` ! ( ) { } ^ # &

The space character has been available to applications for filenames and directory names through the functions in current and earlier versions of MS-DOS. However, many applications do not recognize the space character as a valid character, and the system does not use the space character when it generates an alias for a long filename. MS-DOS does not distinguish between uppercase and lowercase letters in filenames and directory names, and this is also true for aliases.

The set of valid characters for long filenames includes all the characters that are valid for an alias as well as the following additional characters.

+ , ; = [ ]

Windows 95 preserves the case of the letters used in long filenames. However, the protected-mode FAT file system, which is not case sensitive, will not allow more than one file to have the same name except for case in the same directory. For example, files named Long File Name and long file name are not allowed to exist in the same directory. Although extended ASCII characters (characters with ASCII codes greater than 127) are also permitted in filenames, programs should avoid them, because the meanings of the extended characters may vary according to code page. On disk, the characters in the alias are stored using the OEM character set of the current code page, and the long filename is stored using Unicode format.

Although the protected-mode FAT file system is the default file system in Windows 95, it is not the only file system accessible to applications running with Windows 95. For example, applications that connect to network drives may encounter other file systems, such as NTFS. Before using long filenames for files and directories on a volume in a given drive, you must determine the maximum lengths of filenames and paths by using Get Volume Information (Interrupt 21h Function 71A0h function returns values that you can use to make sure your filenames and paths are within the limits of the file system.

In general, you should avoid using static buffers for filenames and paths. Instead, you should use the values returned by Get Volume Information to allocate buffers as you need them. If you must use static buffers, you should reserve 256 characters for filenames and 260 characters for paths. These are the maximum sizes currently recommended for Win32-based applications.


Filename Aliases

When an application creates a file or directory that has a long filename, the system automatically generates a corresponding short filename (alias) for that file or directory, using the standard 8.3 format. Aliases ensure that existing applications that do not handle long filenames can, nevertheless, access those files and directories.

If the long filename follows the standard 8.3 format, the alias has the same name except that all lowercase letters are converted to uppercase. For example, if the long filename is Examples.Txt, the corresponding alias will be EXAMPLES.TXT.

If the long filename does not follow the standard 8.3 format, the system automatically generates an alias, using the following scheme to ensure that the alias has a unique name. The system tries to create a name by using the first 6 characters of the long filename followed by a numeric tail. A numeric tail consists of the tilde (~) character followed by a number. The system starts with the number 1 in the numeric tail. If that filename already exists, it uses the number 2. It continues in this fashion until a unique name is found. If the long filename has a filename extension, the system will use the first three characters of the long filename's extension as the extension for the alias.

As the number of digits in the numeric tail grows, fewer characters in the long filename are used for the 8 characters in the alias. For example, the alias for Long File Name.File would be LONGFI~10.FIL if the names LONGFI~1.FIL through LONGFI~9.FIL already existed in the directory. Applications can override the default alias numbering scheme when creating a file by specifying the OPEN_FLAGS_ALIAS_HINT value and supplying a number to use in the call to Create or Open File (Interrupt 21h Function 716Ch).

A period is just another character in a long filename. Leading periods are allowed in a long filename, but trailing periods are stripped. A file can have multiple periods as part of its name. For example, MyFile.081293.Document is a valid filename, and its alias will be MYFILE~1.DOC. The first three characters after the last period in the filename are used as the filename extension for the alias, as long as the last period is not a leading period. A filename of .login is also valid, and its alias is LOGIN~1.

In a given directory, the long filename and its alias must uniquely identify a file. For example, if there is a file with the long filename Long File Name and the alias LONGFI~1, the system will not allow either Long File Name or LONGFI~1 to be used as another file's long filename.

If a file with a long filename is copied or edited, the alias for the resulting file may be different from the original alias. For example, if the destination directory contains an alias that conflicts with the original alias, the system generates another unique alias. If a long filename LongFileName is associated with the alias LONGFI~2 and is later copied to a different directory using the long filename, the alias in the destination directory might be LONGFI~1 (unless a file with that name already existed in the destination directory). The system always generates new aliases during these operations and always chooses aliases that do not conflict with existing filenames. An application must never rely on an alias being the same for all copies and versions of a given file.

Applications can open, read, and write from a file using the alias without affecting the long filename. However, some operations on the alias, such as copy, move, backup, and restore, may result in the original long filename being destroyed. For example, older versions of utilities that do not support long filenames can destroy the long filename while performing those operations.

The system attempts to preserve a long filename, even when the file associated with it is edited by an application that is not aware of long filenames. Typically, these applications operate on a temporary copy of the file, and when the user elects to save the file, the application deletes the destination file or renames it to another name. The application then renames the temporary file to the destination name or creates a new file with new contents.

When an application makes a system call to delete or rename an alias, the system first gathers and saves a packet of information about the file and then performs the delete or rename operation. The information saved includes the long filename as well as the creation date and time, the last modification date and time, and the last access date of the original file. After the system performs the delete or rename operation, the system watches for a short period of time (the default is 15 seconds) to see if a call is made to create or rename a file with the same name. If the system detects a create or rename operation of a recently deleted alias, it applies the packet of information that it had saved to the new file, thus preserving the long filename.

Currently, Load and Execute Program (Interrupt 21h Function 4B00h) does not accept long filenames. If an application starts other applications, it must retrieve the filename alias for the given executable file and pass that alias to Load and Execute Program.


File and Directory Management

The standard MS-DOS file and directory management functions do not accept long filenames. You must, therefore, use the long filename functions to create and manage files and directories having long names. The long filename functions are similar to existing MS-DOS system functions. You copy function parameters to registers and issue an Interrupt 21h instruction to carry out the call. The function sets or clears the carry flag to indicate whether the operation was successful and may also return information in registers.

If a long filename function has a corresponding MS-DOS function, the number that identifies the long filename function is four digits long, beginning with the number 71 and ending in the same number as the corresponding MS-DOS function. For example, the long filename function Make Directory (Interrupt 21h Function 7139h) corresponds to MS-DOS Create Directory (Interrupt 21h Function 39h).

You can create or open a file having a long filename by using Create or Open File (Interrupt 21h Function 716Ch). This function takes the name and attributes of the file to create or open and returns a handle that you use to identify the file in subsequent calls to standard MS-DOS functions, such as Read File or Device (Interrupt 21h Function 3Fh) and Write File or Device (Interrupt 21h Function 40h).

You can set or retrieve the time and attributes for a file having a long filename by using Get or Set File Time (Interrupt 21h Function 57h) and Get or Set File Attributes (Interrupt 21h Function 7143h). You can move a file having a long filename by using Rename File (Interrupt 21h Function 7156h) or delete the file by using Delete File (Interrupt 21h Function 7141h).

You can create a directory having a long filename by using Make Directory (Interrupt 21h Function 7139h) or remove the directory by using Remove Directory (Interrupt 21h Function 713Ah).

You can set and retrieve the current directory by using Change Directory (Interrupt 21h Function 713Bh) and Get Current Directory (Interrupt 21h Function 7147h).


File Searches

You can search directories for selected files by using Find First File and Find Next File (Interrupt 21h Functions 714Eh and 714Fh). These functions search for and return information about files having long filenames and aliases (filenames in the standard 8.3 format). The functions return information in a WIN32_FIND_DATA structure, which contains both the filename and the corresponding alias, if any.

Unlike MS-DOS Find First File (Interrupt 21h Function 4Eh), the long filename version of Find First File allocates internal storage for the search operations and returns a handle that identifies the storage. This handle is used with Find Next File. To make sure the internal storage is freed, you must use Find Close (Interrupt 21h Function 71A1h) to end the search.

You pass the Delete File (Interrupt 21h Function 7141h) and Find First File functions a filename, which may contain wildcard characters, such as an asterisk (*) or question mark (?). Because Find First File, Find Next File, and Delete File examine long filenames and aliases during the search, some wildcard searches may yield unexpected results. For example, if the system has generated the alias LONGFI~1 for the long filename LongFileName, a search for names that match the *1 pattern would always return the LongFileName file, even though that name does not end with a 1. Searches are not case-sensitive. For example, a search for names that match the *mid* pattern will yield the same results as that for the *MID* pattern. In general, you should check both names returned in the WIN32_FIND_DATA structure to determine which of them matched the pattern.

Wildcard searches are more flexible in Windows 95 than in MS-DOS. In the preceding examples, *1 finds the filenames that end in a 1 and *mid* finds filenames that contain the characters mid. In MS-DOS and in Windows 95 searching on real-mode FAT directories, all characters after the first * are ignored.


Down-Level Systems

Long filenames, file last access date, and file creation date and time are not supported while the file system is in single MS-DOS application mode. They are not supported either in versions of MS-DOS that only use the real-mode FAT file system. These file systems and others that do not support long filenames are referred to as down-level systems. If you intend for an application to run with both Windows 95 and down-level systems, you should always check the system to determine whether it supports the long filename functions. The easiest way to check is to call Get Volume Information (Interrupt 21h Function 71A0h). This function returns an error if the system does not support the long filename functions.

Another way of handling down-level systems is to use a combination of calls to long filename and standard MS-DOS functions to carry out file management. In this case, you call the standard function only if the long filename function is not supported. To indicate an unsupported function, the system sets the AL register to zero but leaves the AH register and the carry flag unchanged. The following example shows how to combine long filename and standard functions to carry out a file or directory management operation.

stc            ; set carry for error flag
               ; set registers here for LFN function call
int 21h        ; call long filename function
jnc success    ; call succeeded, continue processing
cmp ax, 7100h  ; is call really not supported?
jne failure    ; supported, but error occurred
               ; set registers here for MS-DOS function call
int 21h        ; call standard MS-DOS function

Application developers have to decide what to do when users save a file with a long filename to a down-level system. One approach is to imitate the behavior of the command interpreter (COMMAND.COM) and save the file using the alias without informing the user. A different approach is to have the application inform the user that the file system does not support long filenames and allow the user to save the file with a filename in the standard 8.3 format.


Last Access Date

The Windows 95 last access date is intended to reflect the last time a file was accessed for the purpose for which it was created. This date is intended to provide a means for applications, users, or both to determine which files have not been used recently. When an application saves a file, the system automatically resets the last access date. An application that cannot understand the contents of the files it is accessing should save the last access date and restore it after closing the file. For example, applications that back up a file, search files for strings, and scan for viruses should save and restore the last access date.

Applications should allow the system to set the last access date in the following cases:

  • Running a program should set the last access date for the .EXE file.
  • Loading a dynamic-link library (DLL) should set the last access date for the .DLL file.
  • Editing or printing a document should set the last access date for the document file.
  • In general, any use of a document by an application that creates or modifies that type of document should set the last access date (unless the document is being opened only to decide whether it is to be used in a find operation).
  • Application use of peripheral files (.INI files and so on) should set the last access date.

Win32-based applications can preserve the last access date by using the GetFileTime and SetFileTime functions. Applications written for MS-DOS or Windows version 3. x can use Get Last Access Date and Time (Interrupt 21h Function 5704h) and Set Last Access Date and Time (Interrupt 21h Function 5705h), or they can open the file with Create or Open File (Interrupt 21h Function 716Ch) using the OPEN_ACCESS_RO_NOMODLASTACCESS (0004h) access mode.


Long Filenames Reference

The long filename functions match the following Win32 file management functions.


Long Filenames Functions

The long filename functions match the following Win32 file management functions.

Long filename function | Win32 function
Interrupt 21h Function 5704h Get Last Access Date and Time | GetFileTime
Interrupt 21h Function 5705h Set Last Access Date and Time | SetFileTime
Interrupt 21h Function 5706h Get Creation Date and Time | GetFileTime
Interrupt 21h Function 5707h Set Creation Date and Time | SetFileTime
Interrupt 21h Function 7139h Make Directory | CreateDirectory
Interrupt 21h Function 713Ah Remove Directory | RemoveDirectory
Interrupt 21h Function 713Bh Change Directory | SetCurrentDirectory
Interrupt 21h Function 7141h Delete File | DeleteFile
Interrupt 21h Function 7143h Get or Set File Attributes | GetFileAttributes, SetFileAttributes
Interrupt 21h Function 7147h Get Current Directory | GetCurrentDirectory
Interrupt 21h Function 714Eh Find First File | FindFirstFile
Interrupt 21h Function 714Fh Find Next File | FindNextFile
Interrupt 21h Function 7156h Rename File | MoveFile
Interrupt 21h Function 7160h Minor Code 0h Get Full Path Name | GetFullPathName
Interrupt 21h Function 7160h Minor Code 1h Get Short Path Name | GetShortPathName
Interrupt 21h Function 7160h Minor Code 2h Get Long Path Name | No Win32 function equivalent
Interrupt 21h Function 716Ch Create or Open File | CreateFile, OpenFile
Interrupt 21h Function 71A0h Get Volume Information | GetVolumeInformation
Interrupt 21h Function 71A1h Find Close | FindClose
Interrupt 21h Function 71A6h Get File Info By Handle | GetFileInformationByHandle
Interrupt 21h Function 71A7h Minor Code 0h File Time To DOS Time | FileTimeToDOSDateTime
Interrupt 21h Function 71A7h Minor Code 1h DOS Time To File Time | DOSDateTimeToFileTime
Interrupt 21h Function 71A8h Generate Short Name | No Win32 function equivalent
Interrupt 21h Function 71A9h Server Create or Open File | No Win32 function equivalent
Interrupt 21h Function 71AAh Minor Code 0h Create Subst | No Win32 function equivalent
Interrupt 21h Function 71AAh Minor Code 1h Terminate Subst | No Win32 function equivalent
Interrupt 21h Function 71AAh Minor Code 2h Query Subst | No Win32 function equivalent

Note that Interrupt 21h Functions 71A2h through 71A5h exist, but they are for internal use by Windows 95 only.


MS-DOS Extensions

This article describes various MS-DOS extensions for Windows 95 and provides general information about the file system.


About MS-DOS Extensions

Microsoft® Windows 95® not only supports the complete set of Microsoft® MS-DOS® system functions and interrupts but also provides extensions that permit MS-DOS – based applications to take advantage of Windows 95 features, such as long filenames, exclusive volume locking, virtual machine services, message services, and program information file management. For more information about these topics, see the articles with those names in this guide. For more information about MS-DOS functions and interrupts, see the Microsoft MS-DOS Programmer's Reference.


Windows 95 Version of MS-DOS

When running with Windows 95, MS-DOS – based applications can check the operating system version by using Get MS-DOS Version Number (Interrupt 21h, Function 30h). For Windows 95, this function returns 7 as the major version number and 0 as the minor version number.

If you need to know that the system is running MS-DOS version 7.0, you must use Interrupt 2Fh Function 4A33h. This function returns zero in the AX register for MS-DOS version 7.0 or higher and returns a nonzero value in AX for any other versions of the disk operating system. In addition to the AX register, this function uses the DS, SI, DX, and BX registers.


File System Support

Windows 95 supports the long filename file allocation table (FAT) when running Windows. Any physical file on this extended FAT file system will logically be associated with two names — namely, the primary filename (also referred to as the long filename) and its alternate name or alias. Windows 95 automatically generates the alias, and it is always in the standard 8.3 filename format. When a file is saved to disk, the system creates a directory entry for both the long filename and alias. Because the number of entries in the root directory is limited, it is best to store files in a directory below it to avoid filling up the root. For more information about the filename conventions and how the system generates the alias, see Long Filenames.


Filename Limitations Under Real Mode

If Windows 95 is started in single MS-DOS application mode (real mode), only the standard FAT file system (and not the long filename FAT file system) is supported. This means that long filenames that are created in a Windows environment will not be visible when the user exits to single MS-DOS application mode, although the names themselves are physically present on the media. Only the alias (the 8.3 filename) will be visible.

When down-level file systems (such as MS-DOS version 6.0, Windows version 3.1, Microsoft® Windows NT® version 3.1, and OS/2® version 2.11) read a floppy disk that contains long filenames created using Windows 95, the long filename will not be visible; only the alias (the 8.3 filename) will be visible. However, Windows NT version 3.5 supports long filenames. Windows 95 will see the long filenames of files on a floppy disk that were created using Microsoft Windows NT version 3.5, and Windows NT version 3.5 will see the long filenames of files on a floppy disk that were created using Windows 95. Windows 95 will be able to see the long filenames on NTFS or Novell NetWare's file system if there are long filenames on the server.

Because down-level systems are not aware of long filenames, they will not preserve them. If you copy a file from a floppy disk to the hard disk on a down-level system, the long filename associated with the file is not copied over. If you edit a file on the floppy disk using the alias and then save a new copy back on the floppy disk using the down-level system, the long filename associated with the file will most likely be lost. If you take the floppy disk back to the Windows 95 system, only the alias will be associated with the file.


Preserving Filenames

Certain operations, such as copy, backup, and restore, using older versions of utilities that have not been updated to support long filenames will destroy the long filename. Running a utility called LFNBK that comes with Windows 95 before using older backup utilities will preserve the long filenames. Following are the steps for using LFNBK to backup and restore a disk:

  1. Preserve the long filename and alias (the 8.3 filename) association by running LFNBK /b drive-letter, where drive-letter is the drive that you plan to back up.
  2. Back up the drive (specified as drive-letter in the previous step) using an old backup program that is not be aware of long filenames.
  3. Restore the backup files to a drive, when necessary at some later point, using an old restore program that is not be aware of long filenames.
  4. Restore the long filenames on the drive, by running LFNBK /r drive-letter, where drive-letter is the drive where the files were restored to.


Searching Filenames

Searches of filenames apply to both the filename and its alias. The system presents a single unified namespace so that a single physical view of the file is preserved. However, if the result of a search shows only the long filename, it could be confusing to the user. For example, a set of files in a directory might include the following filenames and aliases.

Filename | Alias
LongFileName | LONGFI~1
File-1 | FILE-1

A search of files in the directory using DIR *1 would display the following information.

LONGFI~1    123    05-11-95    15:26    LongFileName
FILE-1      352    05-11-95    16:01    File-1

Note that the DIR command displays the alias first for compatibility with the older DIR format. However, a search utility that is aware of long filenames but displays only the filename, would also show both the LongFileName and File-1 files. This could be confusing at first glance to the user because the LongFileName file does not have the number 1 as specified in the search criteria. The file was matched to the search pattern because its alias contains the number 1.

The wildcard searches have been expanded in Windows 95. Using the old search criteria, the first * encountered caused all following characters to be ignored. However, in the preceding example, *1 is a valid specification. More than one wildcard can be used in Windows 95 when specifying search criteria. For example, to search for all files that contain the word mid somewhere in the filename, *mid* can be specified as the search criteria.


Performing Direct Disk Writes

Previously reserved fields in the file system directory entry are used for storing the last access date and the creation date and time. A file with a long filename, which is longer than 5 characters, will also cause the system to use previously reserved fields in the directory entry. In previous versions of MS-DOS and Windows, these reserved entries were zero. Older disk repair and checking utilities that have not been updated for Windows 95 might display errors about the disk because of the usage of these reserved entries. It is possible that an older disk repair utility could either destroy the long filename or the actual data in a file because it would mistakenly interpret the file as corrupted. For this reason, Windows 95 won't support old utilities that perform direct disk writes. A newer version of the utility that understands the newer on-disk file system structures will obtain an exclusive volume lock and proceed correctly. This feature is called exclusive volume locking.

Exclusive volume locking is also needed because the system is a multitasking system and disk utilities need exclusive access so that they can modify the file system without causing the file system to be inconsistent for the other executing applications.


Storing Filenames

When an application stores filenames, it should follow these guidelines:

  • Using an alias instead of a long filename can break the association with the file because certain operations, such as editing the file, can potentially change the alias. For example, if the server side of a network uses the alias instead of the long filename of a client file to store information related to the file (such as access permissions), it will be more susceptible to lose the association of permissions with the file. If the user edits the file on the client side, the alias may potentially change, and if it changes, the server side will lose the associated information.
  • When an application caches the absolute path to a filename, the path itself can be a mixture of filenames and aliases. Because of this, applications that need to store a path should store a canonical form of the absolute path. Applications may use either Get Short Path Name (Interrupt 21h Function 7160h Minor Code 1h) or te GetShortPathName function to retrieve the canonical form of a path. Applications that need to determine if two files are the same can use the nFileIndexHigh and nFileIndexLow members of the BY_HANDLE_FILE_INFORMATION structure. Note, however, that nFileIndexHigh and nFileIndexLow might not be supported on real-mode file systems, such as Microsoft CD-ROM Extensions (MSCDEX), or real-mode networks.
  • An installation program that needs to enter information into configuration files, such as CONFIG.SYS, should make sure it uses paths that only consist of 8.3 filename components, because the long filenames will not be visible at boot up time when startup files, such as CONFIG.SYS and AUTOEXEC.BAT, are processed. Again, the GetShortPathName function should be used for this purpose.


Filename Functions

With the exception of the OpenFile function, all of the functions in Windows version 3. x that require the application to pass in a filename (such as LoadLibrary, WinExec, _lopen, and _lcreate) have been updated to support long filenames. For compatibility reasons, functions that return filenames should return only aliases (8.3 filenames) to 16-bit Windows – based applications marked less than 4.0.

MS-DOS – based applications generally use the Interrupt 21h functions. Except for Extended Open/Create (Interrupt 21h Function 6Ch), the older Interrupt 21h functions have not changed in Windows 95. Extended Open/Create has been enhanced in Windows 95 to make use of the last access date for a file. To support long filenames, Windows 95 provides many new Interrupt 21h functions. Any MS-DOS – based application that will use long filenames must be updated to support the new functions. For information about the long filename Interrupt 21h functions, see Long Filenames

Windows 95 supports the new Interrupt 21h long filename functions on as many file systems as possible. On file systems, such as MSCDEX, Flash, and real-mode network redirectors, that do not support long filenames, the system automatically translates the newer Interrupt 21h calls to the appropriate older Interrupt 21h calls, as long as the filename passed as a parameter is a valid alias (8.3 filename). Applications may use Get Volume Information (Interrupt 21h Function 71A0h) to retrieve information on the capabilities of the underlying file system.


Command Interpreter for Command

The for command in the command interpreter (COMMAND.COM) is modal. The default is LFNFOR=OFF, which causes the for command to use the old Interrupt 21h function calls. In that case, only aliases (8.3 filenames) can be used in the for command. If LFNFOR=ON is set, the for command uses the new Interrupt 21h functions, and long filenames can be used as part of the for command.


Long Command Lines

Although in previous versions of MS-DOS the limit for environment variables and batch file lines is 128 characters, it is 1024 characters in Windows 95. The limit for the keyboard buffer, however, is still 128 characters. Although 1024 and 128 are the standard limits, users may configure their systems to lower these limits.

In previous versions of MS-DOS, command-line arguments are located in the command tail of the program segment prefix (PSP). The command tail in the PSP is limited to 128 characters, including the leading byte that specifies the length of the command line and the trailing carriage return character. In Windows 95, if the command line is less than or equal to 126 characters, it is set in the command tail of the PSP. For command lines that are greater than 126 characters, an application should follow these steps:

  1. Set the count byte in the command tail to 7Fh.
  2. Fill in 7Eh bytes of the command tail followed by the carriage return character (0Dh).
  3. Place the rest of the command line in the CMDLINE environment variable.


MS-DOS Extensions Reference

This section provides information about the following functions and structures.


MS-DOS Extensions Functions

This section provides information about the following functions.

Function | Description
Interrupt 21h Function 4302h | Get compressed file size.
Interrupt 21h Function 440Dh Minor Code 48h | Lock/unlock removable media.
Interrupt 21h Function 440Dh Minor Code 49h | Eject removable media.
Interrupt 21h Function 440Dh Minor Code 6Fh | Get drive map information.
Interrupt 21h Function 440Dh Minor Code 71h | Get first cluster.
Interrupt 21h Function 6Ch | Extended open/create.


MS-DOS Extensions Structures

This section provides information about the following structures.

DRIVE_MAP_INFO | Get Drive Map Info returns information about the specified drive in this structure.
MID | This structure, which is used by Get Media ID (Interrupt 21h Function 440Dh Minor Code 66h) and Set Media ID (Interrupt 21h Function 440Dh Minor Code 46h), has been updated to support compact disc (CD) file systems. For information about using these functions, see the Microsoft MS-DOS Programmer's Reference.
PARAMBLOCK | This structure is needed by Lock/Unlock Removable Media.


Thunk Compiler

This overview describes how to use the thunk compiler so that your Win32-based application running on Microsoft® Windows® 95 can take advantage of 16-bit components. In addition, this overview discusses related issues you should consider before choosing to use the thunk compiler.

Windows 95 implements a thunking model called flat thunks. Flat thunks allow 32-bit code to call functions implemented in 16-bit code. They also allow 16-bit code to call functions implemented in 32-bit code. Windows NT does not support flat thunks. Therefore, if you use flat thunks, your application cannot run on Windows NT unless you isolate your thunking code into platform-specific DLLs.

Windows NT uses a different thunking model. Windows NT supports generic thunks, which allow 16-bit code to call functions implemented in 32-bit code. Although Windows 95 supports generic thunks, it does not support the underlying process model used by Windows NT. This means that generic thunking code might not work identically under Windows 95 and Windows NT. For more information, see Generic Thunks.

The Platform Software Development Kit (SDK) includes a sample application that illustrates the use of the thunk compiler. This application, APP32.EXE, simply passes basic types from the 32-bit side to the 16-bit side of the thunk. This sample is an important supplement to the information in this overview.


About the Thunk Compiler

Writing Win32-based applications provides the following advantages over writing 16-bit Windows-based applications:

  • The flat address space. Your application can access up to 2 gigabytes of memory. You no longer need to consider the boundaries and limitations imposed by a segmented architecture. In addition, many system resource limits have been increased.
  • Better performance. Win32 platforms have faster memory management, networking, file operations, and floating-point operations. Your application can use threads to provide a responsive user interface. The system uses preemptive multitasking to schedule threads.
  • Greater robustness. The system does not crash often, but if it does crash, it does not destroy data or cause other executing applications to crash.

Despite these advantages, however, you may have problems porting your application to the Win32 API. For example, when porting your application to take advantage of new system features, you might find you must use features from an existing 16-bit DLL that has not been ported to Win32. Rather than delay the release of your application while waiting for a ported version the 16-bit DLL, you can use the thunk compiler to call the 16-bit DLL from your Win32-based application.


Role of the Thunk Compiler

The thunk compiler takes a thunk script as input, then produces an assembly-language file that implements one or more thunks. These thunks are code that allows 32-bit code to call 16-bit code and vice-versa. The following steps briefly describe how to use the thunk compiler to create a flat thunk.

To create a flat thunk
  1. Create a thunk script.
  2. Compile the thunk script with the thunk compiler.
  3. Assemble the .ASM file produced by the thunk compiler twice — once for a 16-bit .OBJ file and the second time for a 32-bit .OBJ file.
  4. Create a Win32-based thunk DLL and link it with the 32-bit .OBJ file created in step 3.
  5. Create a 16-bit thunk DLL and link it with the 16-bit .OBJ file created in step 3.

The DLLs you create using these steps implement flat thunks. They can provide multiple thunks. If the DLLs implement thunks from 16-bit code to 32-bit code and thunks from 32-bit code to 16-bit code, you will need to create two thunk scripts, one for each direction.

To use the thunk DLLs, simply call the function you want to use. For example, suppose your Win32-based application is calling MyFunction, which is implemented in a 16-bit DLL. The application calls a function implemented in the Win32-based thunk DLL that in turn calls the thunk function, MyFunction. When MyFunction is called in the 32-bit thunk DLL, the code generated by the thunk compiler calls the MyFunction implemented in the 16-bit thunk DLL.


Thunking Mechanics

There are differences in pointers, structure packing, and parameter size between the 16-bit and 32-bit portions of the thunk. The thunk compiler must process these differences correctly. In particular, the compiler must check for the following elements in a mixed 16-bit and 32-bit environment:

  • Pointers consist of a selector and a 16-bit offset in a 16-bit Windows environment. However, in a 32-bit Windows environment, pointers essentially consist of a 32-bit offset; that is, the DS, ES, SS, and CS registers all contain selectors that have the same base address. All pointers in this environment are considered to be near 0:32 pointers. Translating a 16:16 pointer to a 0:32 pointer involves determining the segment base for the selector portion of the pointer and adding the offset to it. Translating a 0:32 pointer to a 16:16 pointer involves allocating a selector and calculating the offset from the base of the corresponding segment.
  • Both 16-bit and 32-bit applications pass function parameters on the stack. However, 16-bit applications address the stack using the SS:SP registers, while 32-bit applications use the SS:ESP registers. When thunking from 16-bit code to 32-bit code (or thunking in the other direction), the processor's method of addressing the stack must be switched.
  • The size of an int is 32 bits in a 32-bit environment and 16 bits in a 16-bit environment. When an application uses both 16-bit and 32-bit environments, some piece of software must be able to translate 16-bit integers to 32-bit integers. The following 16-bit function illustrates the translation:
    DWORD Sample(int i);

    If a 32-bit component calls this 16-bit function, it pushes a 32-bit argument on the stack, but the 16-bit function only pops 16 bits off the stack. Later, when the function returns, it places the returned DWORD value in the DX:AX register pair, but the 32-bit calling application expects the return value to be in the EAX register. It is the thunking layer's responsibility to negotiate these translations.

  • To correctly handle packing and conversion, the thunk compiler translates structure members one at a time. The thunk compiler supports structure packing on 1-, 2-, or 4-byte boundaries (corresponding to the /Zp1, /Zp2, and /Zp4 compiler options for Microsoft C/C++ compilers). However, the compiler does not support 8-byte structure alignment. Structure-packing boundaries must be the same on both sides of a thunk.
  • Unlike 32-bit code, 16-bit code is usually not reentrant; 16-bit code is typically written with the assumption of a cooperative multitasking model. The thunk layer must serialize access to 16-bit code. In contrast, 32-bit code must execute without serialization to prevent deadlocks. The thunk layer manages serialization on transitions in both directions.


Thunk Script Keywords

You can use keywords in the thunk script to provide information to the thunk compiler beyond that which the C-style type definitions and function prototypes provide. These keywords enable you to optimize DLL loading and parameter translation. The thunk compiler supports the following keywords in the thunk script.

Keyword | Meaning
enablemapdirect1632=true; | Specifies a 16-bit to 32-bit thunk.
enablemapdirect3216=true; | Specifies a 32-bit to 16-bit thunk.
input | The parameter is used for input only; it is translated when the function is called.
output | The parameter is used for output only; it is translated when the function returns.
inout | The parameter is used for input and output; it is translated when the function is called and when it returns.
faulterrorcode | Specifies the error code when a 16-bit to 32-bit thunk fails because the 32-bit DLL cannot load or initialize. This value is returned when the application calls the first thunk. For more information, see Late Loading.
preload32 | Forces the 32-bit thunk DLL to load when the 16-bit thunk DLL is loaded in a 16-bit to 32-bit thunk.
preload16 | Not used. Late loading of a 16-bit DLL in a 32-bit to 16-bit thunk is not supported.
win31compat | Defers unloading a 32-bit thunk DLL until the process terminates. For more information, see Compatibility with Existing 16-bit DLLs.


Thunk Compiler and Data Types

The thunk compiler supports most of the built-in and user-defined types that the C and C++ languages support. The supported types behave as their C and C++ counterparts do, except as noted. You must define other types in the thunk script.

This section discusses the following topics:

  • Data Types Supported By the Thunk Compiler
  • Handling Data Types Not Supported by the Thunk Compiler
  • Supported and Unsupported Return Values
  • Supported and Unsupported Calling Conventions


Data Types Supported By the Thunk Compiler

The thunk compiler supports some C data types as parameters, return values, or both. The following data types are supported as function parameters:

  • Scalar data types such as int, char, unsigned int, and unsigned long.
  • A special type, bool, that is not supported by the C/C++ compiler. You should use bool in your thunk script for functions that use a nonzero value other than 1 to represent TRUE.
  • Pointers to scalar data types.
  • Structures passed by value or reference.
  • Structures within structures.
  • Pointers within structures, provided that the data type pointed to does not require repacking. The object can be another structure.
  • Arrays of scalar values embedded in structures.

The following data types are supported as function return values:

  • Scalar data types such as int, char, unsigned int, and unsigned long.
  • A special type, bool, that is not supported by the C/C++ compiler. You should use bool in your thunk script for functions that use a nonzero value other than 1 to represent TRUE.
  • Pointers to scalar data types for 32-bit to 16-bit thunks, provided that the data type does not change size. For example, pointers to int are not supported, because an int is 16 bits long in 16-bit code and 32 bits long in 32-bit code.
  • Structure pointers for 32-bit to 16-bit thunks, provided that the structure requires no repacking and contains no pointers. The segment address on the 16-bit side is not globally fixed by the thunk compiler. As a general rule, the thunk compiler deallocates the selectors it allocates.
  • Arrays of scalar values embedded in structures.

Note The int data type is 16 bits wide in 16-bit code and 32 bits wide in 32-bit code. In 32-bit to 16-bit thunks, variables of type int are first truncated from 32 bits to 16 bits (less than 65536), then sign-extended to 32 bits upon return. Likewise, in 16-bit to 32-bit thunks, variables of type int are first sign-extended to 32 bits, then truncated to 16 bits on return.


Handling Data Types Not Supported by the Thunk Compiler

There are several strategies for handling data types and calling conventions that the thunk compiler does not support. These strategies rely on substituting a supported type for the unsupported type and processing the data manually to obtain the original data. The thunk compiler does not support the following data types:

  • Arrays of pointers or structures
  • Unions
  • Floating-point types (such as float or double)
  • Pointers from 16-bit to 32-bit thunks
  • C++ classes and objects
  • Linked lists, binary trees, and other dynamic data structures (the count of items is undetermined at compile time)

Before considering substitution strategies, it is important to understand how the thunk compiler translates data. The thunk compiler uses the following rules to translate data:

  • Automatically translate 32-bit pointers into 16-bit far pointers.
  • Automatically translate 16-bit far pointers into 32-bit pointers.
  • Pass signed and unsigned scalar values unmodified, except for integer values. Because integers are 32 bits wide in 32-bit code and 16 bits wide in 16-bit code, values are truncated on the 16-bit side of the thunk and sign-extended on the 32-bit side.

You should use the following general principles for substituting data types and calling conventions:

  • Write wrapper functions around the thunk to handle unsupported calling conventions.
  • Substitute supported types for unsupported types in the thunk scripts. The supported type must be the same length as the unsupported type. In general, it should not be a pointer type.
  • If the unsupported type is larger than 8 bytes, pass its address to the other side of the thunk and handle its interpretation there.
  • To handle unsupported types in the return value, write wrapper functions for both sides of the thunk. Where necessary, give the actual function an extra parameter that points to a dynamically allocated buffer.

Handling Floating-Point Data Types

The thunk compiler does not support any floating-point types. There are three floating-point types: float, double, and long double.

A float is 4 bytes long on both the 16-bit and 32-bit sides of a thunk. To pass a float to a thunk function, declare it as a DWORD value in the thunk script. This causes the thunk compiler to pass a 4-byte value without translating its value.

A double is 8 bytes long on both the 16-bit and 32-bit sides of the thunk. To pass a double to a thunk function, declare a structure containing two DWORD values in the thunk script, and pass the structure to the function in the thunk script.

In 16-bit code, a long double is a native 80-bit type of the floating-point processors in the Intel x86 microprocessor family. Because RISC processors do not have a native 80-bit floating point type, 32-bit C and C++ compilers such as Microsoft Visual C++ implement this type as a 64-bit double. If you need additional precision, pass the 80-bit value as a structure consisting of two DWORD members and a WORD member, and handle the value manually on the 32-bit side of the thunk.

Handling Pointer Types

The thunk compiler automatically translates pointers to most types. It properly translates pointers to the following data types:

  • All scalar data types.

· Structures.

  • Pointers within structures, provided the data type pointed to does not require repacking. The object can be another structure.

The thunk compiler automatically translates pointers. To pass an address without having it translated, use the DWORD type instead of a pointer type. You can use the untranslated address on the target side of the thunk; however, keep in mind that dereferencing this address on the target side of the thunk will cause an access violation.

When a pointer is passed from 32-bit to 16-bit code, a single selector with a limit of 64K is allocated in the thunk. If the 16-bit code needs to access more than the first 64K of the block, it must change the base address of the selector or allocate additional selectors to access the block.

Pointers to pointers are translated partially. The "outside" pointer is translated, but the pointer it points to — the "inside" pointer — is not translated. The thunk compiler does not handle all cases of pointers used in aggregate types, such as arrays of pointers.

Handling Unions

The thunk compiler does not support unions because it cannot determine which type the union will represent at run time. For example, the following union must be treated differently by the thunk compiler depending on which member the application uses when it makes the thunk call:

union
{
    DWORD dwIntegerValue;
    LPSTR szFileName;
}

The problem is that the thunk compiler would have to pass the value unchanged, assuming that the dwIntegerValue member will be used, or translate the value as a pointer, assuming that the szFileName member will be used. Because the thunk compiler cannot make this decision, it cannot generate the correct code to process this union. To handle union types in thunks, declare a structure in the thunk script that is large enough to hold the union, then process the data manually on both sides of the thunk.


Supported and Unsupported Return Values

The thunk compiler does not support all return value types that the C and C++ languages support. This limitation is caused by the problems of translating addresses from 32-bit address spaces to 16-bit address spaces and vice-versa.

The thunk compiler supports returning all integral types. The signed and unsigned varieties of char, short int, and long int are the same size on both sides of a thunk, so they are returned unmodified. Because integers are 32 bits wide in 32-bit code and 16 bits wide in 16-bit code, values are truncated on return from a 16-bit to 32-bit thunk and sign-extended on return from a 32-bit to 16-bit thunk.

You cannot return a structure from either a 32-bit to 16-bit thunk or a 16-bit to 32-bit thunk. However, pointers to structures can be returned from a 32-bit to 16-bit thunk if the structure does not need to be repacked and does not contain pointers. A structure does not require repacking if the types of all members of the structure are the same size in 16-bit and 32-bit code and the structure is packed with the same alignment on both sides of the thunk. Refer to your compiler documentation for information on specifying structure packing.

You cannot return pointers from 16-bit to 32-bit thunks because the context of the 32-bit address space is not global. The 32-bit address space for the 32-bit DLL is mapped between 4 megabytes and 2 gigabytes, and it is context-switched. This means that a 16-bit Windows-based application or DLL could not use a pointer returned by a 16-bit to 32-bit thunk without causing a general protection (GP) fault. To work around this limitation, write a wrapper function for the 16-bit side of the thunk that allocates memory and passes it to the thunk function as an extra parameter. You should also write a wrapper function for the 32-bit side of the thunk to handle the extra parameter, and copy data to the memory allocated by the 16-bit wrapper.

You can return pointers in 32-bit to 16-bit thunks as long as the base type requires the same number of bytes on both sides of the thunk and does not require repacking. If the size of the base type of a pointer differs between the 16-bit and 32-bit sides, the thunk compiler generates an error. For example, a char is 1 byte on both sides of the thunk, so a pointer to a char is a supported return type. However, an int is 16 bits on the 16-bit side of the thunk and 32 bits on the 32-bit side, so a pointer to an int is not a supported return type.

To return a pointer to a data type whose size is different on the 16-bit and 32-bit sides of a 32-bit to16-bit thunk, write a wrapper function that returns the original type, and have the wrapper pass a buffer to the thunk function as an extra parameter. The target side of the thunk should put the return value into this buffer. After the target side of the thunk returns, the wrapper on the calling side should return the data from the buffer.


Supported and Unsupported Calling Conventions

The thunk compiler supports thunk functions that follow these guidelines for calling convention and parameters:

  • Use the __stdcall calling convention on the 32-bit side of the thunk
  • Use the __pascal calling convention on the 16-bit side of the thunk
  • Contain 14 or fewer parameters

If you try to build a thunk that uses an unsupported calling convention, the linker will return the error "unresolved external" because the function names produced by the C/C++ compiler will not match the names produced by the thunk compiler. Although the thunk must use the __pascal and __stdcall calling conventions, the thunk may call or be called by functions that use other calling conventions.

To thunk to a function that uses the __cdecl or __fastcall calling convention, you must create the thunk function with a supported calling convention. Then make the thunk function call the target function.


Behavior of Win32 Functions Inside 16-Bit Processes

When writing applications for Windows 95, you typically use 16-bit to 32-bit thunks for implementing callback thunks on 32-bit processes. You can also use them to execute 32-bit code in 16-bit processes. This method can improve performance and multitasking, but significant restrictions apply to 32-bit code executed in the context of a 16-bit process.

  • Win32-based applications use a 1-MB stack. However, 32-bit code executed in the context of a 16-bit process uses the approximately 64K stack reserved by the 16-bit application. The 16-bit application's stack is usually smaller than 64K, because it resides in the default data segment, along with global data, static data, and the local heap.
  • The 16-bit process cannot create new threads. Certain Win32 functions, such as those supporting common dialog boxes or those supporting console applications, create threads on behalf of the calling application. You cannot call these functions in the context of a 16-bit process.
  • No 16-bit application gets processing time while a 16-bit application blocks without yielding. Thunking into 32-bit code releases the 16-bit subsystem to other 32-bit processes, but other 16-bit processes are still blocked unless your process explicitly yields (typically as a result of calling the GetMessage function). In other words, 16-bit applications still multitask cooperatively, even when executing 32-bit code. A common problem occurs if you use the CreateProcess function to launch a 16-bit application, then wait for it to set a synchronization object. If the application does not yield, the child application never runs, so the object is never set to the signaled state, and deadlock occurs.

In general, 32-bit code running in the context of a 16-bit process should be limited to code that uses the 32-bit heap functions, memory-mapped file functions, file functions, and functions involving the current process and thread. You can also use GDI, dialog box, message box, and message functions from 32-bit code running in the context of a 16-bit process. You should avoid using third-party libraries unless you are sure they work safely in a 16-bit environment.


Compatibility with Existing 16-Bit DLLs

There are certain steps you must take to ensure compatibility with existing 16-bit DLLs. Using the win31compat statement in the thunk script causes the unloading of a 32-bit DLL to be deferred until the containing process terminates. Use this statement to ensure that interprocess loading and freeing procedures, which may have worked with the 16-bit DLL when it was called from 16-bit code, will not cause the 32-bit thunk DLL to be freed prematurely. It also allows the 16-bit library to be freed without execution of the 32-bit DLL's notification routine — an occurrence that could cause reentry into 16-bit code.

You must use the win31compat statement if a 16-bit DLL replaces a DLL that is currently used in a Windows version 3.1 environment or if the DLL runs as part of a graphics device interface (GDI) device driver. You might need use this statement even if your 16-bit DLL does not fit into one of these categories, because it provides extra protection from other DLLs that might be used by your thunk DLL.


16- to 32-Bit Thunks and Preemption

Because 16-bit processes multitask cooperatively with respect to each other, 16-bit code is often written with the assumption that it will not be interrupted by another process until it explicitly yields inside the 16-bit scheduler (typically as a result of calling the GetMessage function). In contrast, 32-bit code is written with the expectation that it can be preempted and blocked at any time. A 32-bit application can wait for a synchronization object to be set to the signaled state without impeding the progress of another process. If you mix code written under these different assumptions, you should take care to avoid deadlocks or errors due to unexpected reentrancy.

While a process is executing 32-bit code, it is possible for other processes to enter 16-bit code, possibly reentering the 16-bit code that performed the thunk. That is, entering a 16-bit to 32-bit thunk releases the 16-bit subsystem for use by other processes (under certain conditions noted in the following paragraph). Therefore, you should not use 16-bit to 32-bit thunks if your code cannot be reentered while the thunk code is executing. In addition, you should not use 16-bit to 32-bit thunks inside callback functions passed to a third-party DLL, unless the documentation indicates that the code calling the callback function is reentrant.

If the process executing the thunk is a 32-bit process, any other process can reenter 16-bit code inside a 16-bit to 32-bit thunk. On the other hand, if the process executing the thunk is a 16-bit process, only 32-bit processes can reenter 16-bit code, because 16-bit processes are cooperatively multitasked. Therefore, if your 16-bit code is used only by 16-bit processes, the reentrancy requirement can be relaxed, because other 16-bit processes can be scheduled only if your 16-bit process yields.


16- to 32-Bit Thunks in GDI Device Drivers

In a GDI device driver, you can use only the following control display driver interface (DDI) functions:

  • Control(ABORTDOC)
  • Control(ENDDOC)
  • Control(NEWFRAME)
  • Control(NEXTBAND)
  • Control(STARTDOC)

If you use thunking, your driver must be reentrant. You must also use the following compatibility statement in the thunk script:

win31compat = true;

You can call the OpenJob, StartSpoolPage, EndSpoolPage, CloseJob, and DeleteJob functions during the five listed control DDI calls. These calls are by drivers written for Windows version 3.x to support backward compatibility, but they will not be handled by Windows 95–based drivers.


Globally Fixing Handles

Translating a 16:16 pointer to a 0:32 pointer involves determining the segment linear base address for the selector portion of the pointer and adding the offset to it. The 16-bit global memory compactor in Windows 95 can move a block of memory allocated by 16-bit code at any time, making the linear base address invalid. When the thunk compiler converts pointers from 16:16 to 0:32, it fixes the segment portion of the 16:16 pointer before computing the linear base address. If you translate pointers without using the thunk compiler, however, you must fix the segment portion. For more information about the functions you can use to translate pointers, see Translating 16:16 Pointers.


Late Loading

Windows 95 improves system performance by supporting late loading for thunk DLLs. In a 16-bit to 32-bit thunk, the system loads the 32-bit DLL when the application calls the first 16-bit to 32-bit thunk. It does not load the 32-bit DLL when the 16-bit DLL is loaded.

Late loading has the following implications:

  • The performance and working set size are improved for 16-bit applications that use only the 16-bit portions of thunk DLLs. These processes do not load the 32-bit DLL.
  • The 16-bit DLL must not depend on any action taken by the 32-bit DLL's initialization code until the application has called at least one 16-bit to 32-bit thunk.
  • The system cannot detect missing 32-bit DLLs or failure to load a 32-bit DLL until the application makes the first call to a 16-bit to 32-bit thunk. If the 32-bit DLL does not load or fails to initialize, the 16-bit to 32-bit thunk call returns a value of zero. You can change this error code on a thunk-by-thunk basis by including the faulterrorcode keyword in the function prototype in the thunk script. For example, the following function instructs the thunk subsystem to return a – 1 from the thunk call if it is the first thunk call and the 32-bit DLL cannot finish loading.
    int Sample(void)
{
    faulterrorcode = -1;
}

Although late loading is a valuable optimization for a 16-bit DLL that can execute autonomously from its 32-bit counterpart, it does complicate error recovery. You can disable late loading by including the following line in the thunk script:

preload32 = true;

If you use this option, the 16-bit subsystem will be released during the loading of your 16-bit DLL, possibly causing other 16-bit code to be reentered. For this reason, the preload32 keyword is not available if your thunk script requires the win31compat keyword. For more information about the win31compat keyword, see Compatibility with Existing 16-Bit DLLs.

Although the thunk compiler supports a preload16 keyword, late loading of 16-bit DLLs is neither currently supported nor planned for a future version of Windows.


Using the Thunk Compiler

The following topics explain the steps required to implement a flat thunk using the thunk compiler:

  • Creating a Thunk Script
  • Compiling Flat Thunks
  • Creating a 16-Bit Thunk DLL
  • Creating a Win32-Based Thunk DLL


Creating a Thunk Script

The thunk compiler takes an input file called a thunk script. Thunk scripts contain C-style type definitions and prototypes of the functions that are to be called through the thunk. Thunk scripts usually have a .THK filename extension.

To create 32-bit to 16-bit thunks, place the following line at the beginning of the thunk script:

enablemapdirect3216 = true;     // Creates 32->16 thunks.

Alternatively, to create 16-bit to 32-bit thunks, place the following line at the beginning of the thunk script:

enablemapdirect1632 = true;     // Creates 16->32 thunks.

If you need to create both types of thunks, you must create two thunk scripts, one for 32-bit to16-bit thunks and the other for 16-bit to 32-bit thunks.

The remainder of the thunk script contains type definitions, followed by prototypes of the thunk functions. For an example of a simple thunk script, suppose we are calling the following 32-bit function from a 16-bit application:

BOOL WINAPI Sample(int n)
{
    // ...
}

The corresponding thunk script would look like this:

enablemapdirect1632=true;

typedef bool BOOL;

BOOL Sample(int n)
{
}


Sample Thunk Scripts

Many functions have pointers in their parameter lists. Some pointers are used for input only, some are used for output only, and some are used for both input and output. For example, the following function takes a pointer to an input string, updates a second string, and produces a third string as output:

BOOL WINAPI ThunkIt(LPSTR lpstrInput, LPSTR lpstrInOut,
    LPSTR lpstrOutput);

The corresponding thunk script for this function follows.

enablemapdirect1632=true;

typedef char *LPSTR;

BOOL ThunkIt(LPSTR lpstrInput, LPSTR lpstrInOut, LPSTR lpstrOutput)
{
    lpstrInput = input;   // Optional, as input is the default.
    lpstrInOut = inout;   // Pointer for input and output.
    lpstrOutput = output; // Pointer for output.
}

The following thunk script uses a nested structure as an input-output parameter:

enablemapdirect1632=true;

typedef unsigned int UINT;
typedef char *LPSTR;

typedef struct _POINT
{
    UINT x;
    UINT y;
} POINT;
typedef POINT *LPPOINT;

typedef struct _CIRCLE
{
    POINT center;
    UINT radius;
} CIRCLE, *LPCIRCLE;

void MyThunk32( LPCIRCLE lpCircleInOut )
{
    lpCircleInOut = inout;
}


Compiling Flat Thunks

Compile your thunk script using the thunk compiler to create an .ASM file containing the flat thunk. The thunk compiler has the following syntax:

thunk [{-|/}options] infile[.ext]

? | Displays the help screen.
h | Displays the help screen.
o name | Overrides the default output filename.
p n | Changes the 16-bit structure alignment (default = 2).
P n | Changes the 32-bit structure alignment (default = 4).
t name | Overrides the default base name.
N x name | Specifies the name segment or class, where x is either C32 (for 32-bit code segment name) or C16 (for 16-bit code segment name).

The .ASM file produced by the thunk compiler contains code for both sides of the thunk. The 16-bit code in the .ASM file includes a jump table containing the 16:16 address of each function named in the thunk scripts. The 16-bit linker must be able to resolve these references; the functions must either be implemented in the 16-bit DLL or be imported by the DLL. The 32-bit code in the .ASM file contains a WINAPI function for each thunk, which converts its parameters to 16-bit values, then calls the 16-bit target referenced in the jump table. When a Win32-based application uses a 16-bit function through the thunk, it calls these compiler-generated functions directly.

Assemble the resulting .ASM file to create the 16-bit side of the thunk by defining IS_16. For example, using Microsoft MASM version 6.11, you can use the following command line:

ml /DIS_16 /c /W3 /nologo /Fo thk16.obj 16to32.asm

Assemble the resulting .ASM file to create the 32-bit side of the thunk by defining IS_32. For example, using Microsoft MASM version 6.11, you can use the following command line:

ml /DIS_32 /c /W3 /nologo /Fo thk32.obj 16to32.asm

Create the following declaration for the LineTo function in the thunk script:

typedef bool         BOOL;
typedef unsigned int UINT;
typedef UINT         HANDLE;
typedef HANDLE       HDC;

BOOL LineTo(HDC, int, int)
{
}

When the thunk compiler processes the thunk script, it generates the following 16-bit code:

externDef LineTo:far16

FT_gdiTargetTable label word
    dw    offset LineTo
    dw       seg LineTo

In addition, the thunk compiler generates the following 32-bit code:

public LineTo@12
LineTo@12:
    mov    cl,0
; LineTo(16) = LineTo(32) {}
;
; dword ptr [ebp+8]:  param1
; dword ptr [ebp+12]:  param2
; dword ptr [ebp+16]:  param3
;
public IILineTo@12
IILineTo@12:
    call    QT_Entry
    push    word ptr [ebp+8]     ;param1: dword->word
    push    word ptr [ebp+12]    ;param2: dword->word
    push    word ptr [ebp+16]    ;param3: dword->word
    call    QT_Target_gdi
    movsx   ebx,ax
    jmp     QT_Exit12

When a Win32-based application calls the LineTo function, it is this routine that is executed. The routine builds a 16-bit call frame, calls a local routine requesting the appropriate address in the jump table, and sign-extends the return value. Each component receives its own set of routines (with the QT_ prefix), which automatically use the correct jump table.


Creating a 16-bit Thunk DLL

After you compile the thunk script to create the 16-bit code for the thunk, you must create the 16-bit thunk DLL. To implement the 16-bit thunk DLL, use the following steps.

To implement the 16-bit thunk DLL
  1. Add a function named DllMain to your 16-bit DLL. This function should have the following structure:
    BOOL FAR PASCAL __export DllMain(DWORD dwReason, WORD hInst,
        WORD wDS, WORD wHeapSize, DWORD dwReserved1,
        WORD wReserved2)
{
    if( !(XXX_ThunkConnect16( "DLL16.DLL",  // name of 16-bit DLL
        "DLL32.DLL",                        // name of 32-bit DLL
        hInst, dwReason)) )
    {
        return FALSE;
    }
    return TRUE;
}

    Note that DllMain calls the following function, which was generated by the thunk compiler:

    BOOL FAR PASCAL __export XXX_ThunkConnect16(LPSTR pszDll16,
    LPSTR pszDll32, WORD hInst, DWORD dwReason);

    In this example, XXX is the base name — that is, the name of the thunk script file, not including the path and filename extension. If you used the /t option with the thunk compiler to specify a different base name when you compiled the thunk script, use that base name here.

  2. Add the following statements to your 16-bit DLL's module definition (.DEF) file, choosing ordinals appropriate for your DLL.
    EXPORTS
DllMain             @1 RESIDENTNAME
XXX_ThunkData16     @2 RESIDENTNAME

IMPORTS
C16ThkSL01     = KERNEL.631
ThunkConnect16 = KERNEL.651
  3. Build the DLL. Be sure to link with the 16-bit .OBJ file created from the thunk script. This file contains the code for XXX_ThunkData16, which is a table of function calls the thunk compiler uses to implement the thunks.
  4. Mark the DLL with version 4.0, using the 16-bit resource compiler included with the Platform SDK.
    rc -40 DLL_Name

To ensure that your application works correctly, it is important that you use the following rules when implementing your thunks:

  • The 16-bit DllMain function is called each time the module's usage count is incremented or decremented. The dwReason parameter is 1 when the usage count is incremented and zero when it is decremented.
  • Because the system calls the DllMain function while loading is under way, the value returned by the GetModuleUsage function is not reliable if you call it inside your DllMain function.
  • Do not call thunks inside the DllMain routines. Do not perform operations that reenter the 16-bit loader, yield the 16-bit scheduler, or release the 16-bit subsystem. These actions could cause unpredictable results and are not guaranteed to work in future versions of the thunk compiler.
  • You can have multiple ThunkConnect calls, as long as they connect to the same DLL. In fact, this is the only way to get both 32- to 16-bit and 16-bit to 32-bit thunks from one set of thunk DLLs. The way to do this is to have a thunk script for each direction and link both into each DLL. Then each entry-point function will have two ThunkConnect calls.


Creating a Win32-Based Thunk DLL

After you compile the thunk script to create the 32-bit side of the thunk, you must create the Win32-based thunk DLL. To implement the Win32-based thunk DLL, use the following steps:

To implement the Win32-based thunk DLL
  1. Add the entry-point function to your 32-bit DLL's entry-point function (named DllMain by default). This function must call the following function created by the thunk compiler:
    BOOL WINAPI XXX_ThunkConnect32(LPSTR pszDll16, LPSTR pszDll32,
    DWORD hInst, DWORD dwReason);

    Here is an example of a DLL entry-point function calling XXX_ThunkConnect32:

    BOOL WINAPI DllMain(DWORD hInst, DWORD dwReason,
    DWORD dwReserved)
{
    if( !(XXX_ThunkConnect32( "DLL16.DLL",  // name of 16-bit DLL
        "DLL32.DLL",                        // name of 32-bit DLL
        hInst, dwReason)) )
    {
        return FALSE;
    }
    // Process dwReason.

    Return TRUE;
}
  2. Add the following export statement to your 32-bit DLL's .DEF file.
    EXPORTS
XXX_ThunkData32
  3. Export the function to which you are thunking.
  4. Build the DLL. Be sure to link with the 32-bit .OBJ file created from the thunk script and THUNK32.LIB. The 32-bit .OBJ file contains the code for XXX_ThunkData32, which is a table of function calls that the thunk compiler uses to implement the thunks.


Troubleshooting Flat Thunks

Debugging flat thunks generated by the thunk compiler can be difficult because the thunk mechanism is complex, and debugging tools capable of tracing through thunks are difficult to use. The following topics present an overall strategy for debugging flat thunks, several specific debugging techniques, and suggestions for how to solve many common thunking problems.

  • Limitations on What a Target DLL Can Do
  • Difficulties in Debugging Flat Thunks
  • Strategy For Debugging Thunks
  • Preliminary Thunk Debugging Checklist
  • Testing the Thunk
  • Common Thunking Problems


Limitations on What a Target DLL Can Do

Before debugging your thunks, keep in mind that there are some limitations on what a target DLL can do from code executed through a thunk. Common specific limitations include:

  • You cannot create threads inside a thunk from a 16-bit Windows-based application to a Win32-based DLL.
  • The code inside Win32-based DLLs called by thunks should require little stack space because the calling 16-bit processes have much smaller stacks than do 32-bit processes.
  • 16-bit DLLs that contain interrupt service routines (ISRs) must not thunk to Win32-based DLLs while handling interrupts.
  • Win32-based applications must not pass pointers to data located on the stack as parameters of thunks; nor can they call 16-bit DLLs that switch stacks.


Difficulties in Debugging Flat Thunks

Debugging flat thunks is difficult not only because the mechanism itself is complex, but also because the necessary debugging tools are difficult to master. The flat-thunk mechanism is complex because it must transform function calls in 32-bit compiled code into calls compatible with 16-bit code and vice versa. Because 32-bit code uses data types and CPU register sets that are different than those used with 16-bit code, the flat-thunk mechanism must translate function parameters, switch stacks, and translate return values. The flat-thunk mechanism is optimized for speed, yet must allow preemptive 32-bit code to call nonpreemptive 16-bit code. The thunk compiler makes creating flat thunks much easier than manually creating them, but it is not foolproof.

To debug flat thunks, you must use a system-level debugger, rather than the application-level debugger you would generally use. Application-level debuggers such as the Microsoft Visual C++ debugger and WinDBG cannot trace through thunks because they consist of both 32-bit and 16-bit code and cause the system to claim or release the Win16Mutex. To trace through a thunk, you need to use a system-level debugger such as WDEB386.EXE. Using WDEB386.EXE is more complicated than using an application-level debugger, because you must know Intel x86 assembly language, know how Intel x86 microprocessors work, and remember many debugger commands.


Debugging Strategy

Strategy For Debugging Thunks

The best strategy for debugging thunks is to divide the task into small, manageable tests. This approach is relatively easy and can eliminate most problems, without requiring advanced debugging techniques, such as tracing through assembly language code in a system-level debugger. Flat thunks consist of a Win32-based DLL and a 16-bit DLL, so it is possible to test each of these in isolation before testing them together. Create a 16-bit Windows-based application to test the 16-bit DLL, and create a Win32-based application to test the Win32-based DLL. Doing so allows you to use a wide variety of debugging tools to verify that each side works properly.


Preliminary Checklist

Preliminary Thunk Debugging Checklist

After you have verified that each side works correctly, the next step is to put the two sides together to test the thunk itself. However, before you compile the thunk using the thunk compiler, use the following checklist to verify that you created the thunks correctly:

  1. In your thunk script, make sure each function has the correct number and types of parameters. Also make sure that the thunk compiler supports the parameter types. If it does not, you will have to pass the data using a supported type.
  2. If you pass any structures as parameters, make sure you use the same structure packing in your Win32-based DLL, 16-bit DLL, and thunk script. You set structure packing in your C/C++ compiler's command line, and in the thunk compiler command line. Note that the thunk compiler's packing switch is lowercase for the 16-bit side, and uppercase for the 32-bit side.
  3. Make sure the functions you are thunking to are exported correctly, and use the PASCAL calling convention if they are 16-bit functions. Use WINAPI if they are 32-bit functions. The thunk compiler does not support the _cdecl and __fastcall calling conventions.
  4. Make sure your Win32-based DLL calls XXX_ThunkConnect32 each time its DllMain function is called. Likewise, make sure the 16-bit DLL has an exported DllMain function, separate from its LibMain function, that calls XXX_ThunkConnect16 and returns TRUE if ThunkConnect16 succeeds.
  5. Make sure that the value specified in the thunk compiler's -t option is the same for both thunk DLLs. The value must also correspond to the prefix of the ThunkConnect calls in your 16-bit and Win32-based DLLs.
  6. Verify that the 16-bit DLL has DLLEntryPoint and XXX_ThunkData16 exported with the RESIDENTNAME keyword in its module definition (.DEF) file. Without the RESIDENTNAME keyword, the XXX_ThunkConnect32 or XXX_ThunkConnect16 call fails and the DLLs are not loaded.
  7. Verify in your 16-bit DLL's makefile that the resource compiler is marking the DLL as version 4.0. If the DLL is marked with a version number earlier than 4.0, it will not load and the thunk will fail.
  8. If your 32-bit to 16-bit thunk function returns a pointer, make sure the base type is the same size on both the 16-bit and 32-bit sides of the thunk. If the size of the base type is different, the thunk compiler issues an error message stating, "Cannot return pointers to non-identical types." One way to work around this problem is to return a pointer to a different, but compatible, data type. For example, a thunk cannot return a pointer to an integer because an integer is 2 bytes on the 16-bit side, but 4 bytes on the 32-bit side. In the thunk script and the source code, change the return type from a pointer to an integer to a pointer to a long.

    If you write a 16-bit to 32-bit thunk that returns a pointer, the thunk compiler issues an error message stating, "Pointer types may not be returned." The thunk compiler does not allow 16-bit to 32-bit thunks to return pointer types because after the thunk returns from the 32-bit function, the pointer does not point to data in the correct Win32-based process address space. This is because all Win32-based processes use the same range of addresses and are preemptively context-switched.

  9. If the linker reports an "unresolved external" error, first check to make sure the symbol is a function name that is spelled consistently throughout all source code, module definition files, and the thunk script. Next, make sure all occurrences of its prototype are consistent. On the 32-bit side, declare the thunk function with WINAPI; on the 16-bit side, declare the function with the PASCAL type. With C++ projects, be sure to declare and define both sides of the thunk function with the extern "C" linkage specifier, in addition to the WINAPI or PASCAL type.


Testing the Thunk

After you complete the preliminary checklist provided in the previous topic, build your thunk DLLs and try to run them. If they run, continue with further testing to make sure they work as expected. If the DLLs do not run, use the following troubleshooting guide to determine and fix the cause of the problem.

If XXX_ThunkConnect16 or XXX_ThunkConnect32 fails, perform the following tasks:

  1. Run the debugging versions of the system DLLs. The debugging versions of KERNEL32.DLL and KRNL386.EXE contain many diagnostic messages to indicate why the thunk did not initialize. To run the debugging versions of the system DLLs, use the Switch to Debug DLLs icon in the SDK program group. Use Switch to Non-debugging DLLs to switch back to the retail version.
  2. Verify that the 16-bit DLL has a call to XXX_ThunkConnect16 and that the Win32-based DLL has a corresponding call to XXX_ThunkConnect32. If one of these is missing, the other will fail, and the thunk DLLs will fail to load.
  3. Put breakpoints in your Win32 DLL's DllMain, and in your 16-bit DLL's DllMain and LibMain functions to see which DLLs are not loading.

If your XXX_ThunkConnect16 and XXX_ThunkConnect32 calls are working properly, but the thunk still does not work, it is time to simplify your thunk. You can do this by removing parameters from the thunk one by one, recompiling, and testing. If you determine that a parameter is causing the failure, make sure it is the right type and that the function is declared and defined with the same number and types of parameters in both DLLs and the in the thunk script. Alternatively, you can create a simple thunk that works, and build it up until it fails by following these steps:

  1. Create a simple thunk and execute it just to make sure the thunk mechanism is set up correctly. A good choice for a simple thunk is a function with no return value and no parameters. If even the simple thunk does not work, run through the preliminary checklist in the previous topic to make sure the thunk is set up correctly. Then proceed with step 2.
  2. Check to make sure the target DLL and any DLLs it relies on can be found and loaded. If one is missing, or the loader cannot find it, the thunk will not work.
  3. Make sure your target DLL is not trying to do something that it cannot do in the context of a thunk. For more information, see Behavior of Win32 Functions Inside 16-Bit Processes.

After you have a simplified thunk that works, but the original thunk still does not work, check for the following symptoms:

  1. If your target DLL is a 16-bit DLL and it cannot access its global or static data, make sure you have exported the function correctly. If you use the /GD option with Visual C++, you must declare and define the function with the __export keyword in the 16-bit DLL's source code. Just listing the function's name in the DLL's module definition (.DEF) file is not enough. The compiler does not process the .DEF file, so it will not generate the prolog and epilog code that exported functions require.
  2. If calls to LocalAlloc in your target 16-bit DLL cause general protection (GP) faults, make sure your function is exported as described in step 1.
  3. If you get a GP fault in KERNEL32 just after your target 16-bit function returns, make sure the target function is declared and defined as PASCAL. You can not use the C calling convention. Although uncommon in C or C++ code, make sure the target function did not modify the DS, ES, FS, SS, EBP, EBX, ESI, or EDI registers. C or C++ code should not cause the registers to be modified, but check assembly-language code carefully.
  4. If you get a GP fault in your 32-bit thunk DLL or KERNEL32 immediately after your Win32-based target function returns, make sure the target function is declared with WINAPI and that it didn't modify the DS, ES, FS, SS, EBP, EBX, ESI, or EDI registers. C or C++ code should not cause the registers to be modified, but check assembly-language code carefully.
  5. If your 16-bit target function returns to an invalid location, make sure it is declared and defined as FAR. This is especially important for small-model DLLs; functions in medium- and large-model DLLs are FAR by default.
  6. If you experience a GP fault in a 16-bit function when you access more than 64K of data from a pointer passed as a parameter (that is, a translated pointer), you need to allocate an array of tiled selectors. This is described in the following article in the Microsoft Knowledge Base:

    ARTICLE-ID: Q132005
    TITLE: AllocSelector & FreeSelector Documentation Incomplete

    On the 16-bit side, thunked pointers always consist of a single selector with a limit of 64K, which means you cannot use them as huge pointers. The entire original range of data that the pointer addresses is accessible to the 16-bit target DLL. However, this is true only if the DLL creates an array of tiled selectors to reference it, and if it uses huge pointer variables to access the data.

The following are additional debugging tips:

  1. Make sure you use only a translated pointer in the context of the thunk. Selectors allocated by the thunk compiler for use by 16-bit targets are freed as soon as the thunk returns.
  2. Put breakpoints at the beginning of your target functions to make sure they are being executed. If they are, and you have debugged the target side independently of the thunk, and the error is caused inside the target DLL, it is possible that the target is doing something that cannot be done in a thunk, or referencing memory that does not exist. See steps 7 and 8.


Common Problems

Common Thunking Problems

This topic describes two common problems that can occur when thunking is implemented, and describes their likely causes.

  • The 32-bit DLL will not load.

    The Windows 95 loader requires that the 16-bit DLL be marked with version 4.0 or later. In addition, you must mark DllMain with the RESIDENTNAME modifier.

    To check the version number, run the Microsoft EXE File Header Utility (EXEHDR), using the following command line:

    exehdr -v <your-16-bit-DLL>

    The output should contain the following line:

    Operating system: Microsoft Windows - version 4.0

    If the version number is earlier than 4.0, you should use RC.EXE from the Platform SDK to set the version of your 16-bit DLL correctly.

  • Loading the 16-bit DLL does not load the 32-bit DLL.

    This is by design. A 32-bit DLL does not load into a process context until that process calls its first 16-bit to 32-bit thunk. For more information, see Late Loading.

    If this feature is incompatible with your DLL design, you may disable it by including the following line in your thunk script.

    preload32 = true;


Virtual Machine Services

This article describes the virtual machine services and shows how to use them in MS-DOS – based applications.


About Virtual Machine Services

Virtual machine services allow Microsoft® MS-DOS® – based applications to take advantage of features provided by Microsoft® Windows® 95 when the applications run in a window. MS-DOS – based applications can retrieve and, optionally, set the title of the window in which they run.


Window Title

The window title for an MS-DOS – based application, which is displayed when the application runs in a window, identifies the application and its operating state. The operating system sets the title when an application first starts, but the application can change portions of the title to better communicate its state to the user.

The window title consists of three strings: a virtual machine state, a virtual machine title, and an application title. The system creates the window title by concatenating the three strings, separating the strings with a system-defined separator, typically a hyphen.

The virtual machine state, which can be set by the operating system only, identifies whether the virtual machine is inactive or whether the user is carrying out tasks, such as cut and paste operations. The state is frequently an empty string. The virtual machine title and the application title, which can be set by an application, identify the application and the current document or activity of the application, respectively.

By default, the operating system sets the virtual machine title to the title stored in the corresponding .PIF file or to a title specified by the shell. You can determine the current virtual machine title by using the Get Virtual Machine Title function. You can change the title by using the Set Virtual Machine Title function.

The system typically sets the application title to the name of the application, so the virtual machine title and application title are frequently the same when the application first starts. Many applications change this title to the name of the current document or to an empty string if there is no current document. You can determine the current application title by using the Get Application Title function. You can change the title by using the Set Application Title function.

If you set the virtual machine title or application title, the length of the individual titles must not exceed 30 and 80 characters, respectively.

You can call the window title functions at any time. Furthermore, you can call these functions regardless of whether your application is running with the Windows 95 or MS-DOS operating system. However, not all operating systems support these calls. The functions are not supported if a call to a function leaves the AX register unchanged.


Close-Aware Applications

A close-aware application is any MS-DOS – based application that periodically checks the state of an internal close flag and terminates if the flag is set. Windows 95 sets this flag when the user chooses the Close command from the system menu of the window in which the MS-DOS – based application runs. Close-aware applications enable the Close command, which gives the user an alternate way to exit the application and close the window.

An application enables or disables the Close command by using the Enable or Disable Close Command function. The function takes a flag indicating whether to enable or disable the command. Once the command is enabled, the application must periodically check the close flag by using the Query Close function. The function returns zero in the AX register if the user has chosen the command.

If the Query Close function returns zero in AX, the application should call the Acknowledge Close function to acknowledge the close state of the internal close flag. After the application acknowledges the close state, subsequent calls to the Query Close function will return 1 in AX, indicating that the user has chosen the Close command and the close state has been acknowledged. After acknowledging the close state, an application should take all necessary steps to shut down and eventually exit, or it should cancel the close operation by calling the Cancel Close function.

An application should acknowledge the close state if it needs to perform additional keyboard input before exiting. When the close state has been signaled but has not yet been acknowledged by the application, all keyboard reads will return NULL and buffered line input will return an empty string.

After an application acknowledges the close state, the state reverts to unacknowledged if the application either exits or cancels the close operation. If the application acknowledges the close state and then exits, the parent process will be in an unacknowledged close state. The application must then acknowledge the close state to perform additional keyboard input before exiting or canceling the close operation.

For example, if a text editor receives a positive response from the Query Close function and has some buffers that have not been saved, it should call Acknowledge Close and ask the user if the buffers should be saved with these possible responses: "Yes," "No," or "Cancel."

If the user responds "Yes" or "No," the text editor should save (or not save if the response was "No") the buffers and then exit. The close state remains active, and the parent process (probably the command interpreter) will also receive a positive response from Query Close and will also terminate.

If the response is "Cancel," the application should call the Cancel Close function and not exit. Canceling the close operation informs the system that any attempted shutdown should be abandoned.

This sequence of operations is analogous to the way that Windows-based applications handle the WM_QUERYENDSESSION message.

Depending on the tasking option chosen for the application, there may be some time between when the user chooses the Close command and the application checks the internal close flag. During this time, the system changes the window title of the application, appending the word "Closing" to it, and gives the user the opportunity to cancel the command by changing the command name to Cancel Close. If the user chooses the Cancel Close command, the close flag is reset, preventing the application from closing. If a close-aware application fails to check the close flag within a system-defined amount of time, the system automatically abandons the operation and resets the close flag.

The system tracks the close-awareness and close state for each process. For the virtual machine to close, all applications in the virtual machine must close. When the user chooses the Close command, the operating system detects applications that are not close-aware and displays a dialog box with a warning message, but gives the user the option of forcing the application to exit anyway. If you make an application close-aware, it can shut down cleanly.


Virtual Machine Services Reference

The following window title and close-aware functions are used with virtual machine services.


Window Title Functions

The following window title functions are used with virtual machine services:

Get Application Title
Get Virtual Machine Title
Set Application Title
Set Virtual Machine Title


Close-Aware Application Functions

The following close-aware application functions are used with virtual machine services:

Acknowledge Close
Cancel Close
Enable or Disable Close Command
Query Close


Windows 95 Service Control Manager

Microsoft® Windows NT® supports a Win32-based application type known as a service. A service may be started in two ways: automatically, when the system starts up; or upon demand, by Win32-based applications that use the functions provided by the Service Control Manager. For more information, see Services.

The Windows NT Service Control Manager and its associated functions are not supported by Microsoft® Windows® 95. Instead, Windows 95 provides a scaled-down Service Control Manager.


About the Windows 95 Service Control Manager

The Windows 95 Service Control Manager uses two registry keys to allow applications to start at system startup. It uses one function to allow an application to continue to run after the user logs off.

  • The RunServices and RunServicesOnce Keys
  • The RegisterServiceProcess Function


The RunServices and RunServicesOnce Keys

During system startup, the Service Control Manager starts the applications listed under the following registry keys: RunServices and RunServicesOnce. These keys are located under the key

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion

You can use any unique value name for each application. For the value data, use a string that represents the command line the Service Control Manager will use to start the application. Following is an example of a RunServices list that contains entries for three applications:

MyApp1="myapp1.exe"
MyApp2="myapp2.exe" param1 param2
MyApp3="c:\mydir\myapp3.exe"

The system deletes values under the key RunServicesOnce after the application starts.

These applications start before the user logs on. The user is not yet validated, and the applications cannot assume that networking permissions are enabled. Until the user logs on, the application does not have access to network resources that the user has access to.


The RegisterServiceProcess Function

Applications started by the system using the RunServices and RunServicesOnce keys will close when the user selects Close all programs and log on as a different user from the Shutdown dialog box. By calling the RegisterServiceProcess function, a Win32-based application can prevent itself or any other Win32-based application from being closed when the user logs off. Win32-based applications registered in this manner close only when the system is shut down.

The application should provide for different users logging on at different times during its execution. The application can distinguish between a user logging off and the system shutting down by examining the lParam parameter of the WM_QUERYENDSESSION and WM_ENDSESSION messages. If the user shuts down the system, lParam is NULL. If the user logs off, lParam is set to EWX_REALLYLOGOFF.


Windows 95 Service Control Manager Reference

The following functions are supported by the Windows 95 Service Control Manager.


Windows 95 Service Control Manager Functions

The following function is supported by the Windows 95 Service Control Manager.

RegisterServiceProcess


Acknowledge Close

Acknowledges the close state of the internal close flag.

mov ah, 16h    ; Windows multiplex function
mov al, 8Fh    ; VM Close
mov dh, 2      ; Acknowledge Close
mov dl, 0      ; always 0
int 2Fh
or ax, ax
jz success

Return Value

Returns zero in the AX register if successful.

Remarks

Acknowledging the close state is necessary if an application needs to perform additional keyboard input before exiting. If the close state has been signaled but not yet acknowledged by an application, all keyboard read operations will return NULL and buffered line input will return an empty string.


Cancel Close

Cancels the close operation.

mov ah, 16h    ; Windows multiplex function
mov al, 8Fh    ; VM Close
mov dh, 3      ; Cancel Close
mov dl, 0      ; always 0
int 2Fh
or ax, ax
jz success

Return Value

Returns zero in the AX register if successful.

Remarks

After acknowledging the close state of the internal close flag, an application should either exit or cancel the close operation by calling Cancel Close.


Enable or Disable Close Command

Enables or disables the Close command in the system menu.

mov ah, 16h    ; Windows multiplex function
mov al, 8Fh    ; VM Close
mov dh, 0      ; Enable or Disable Close Command
mov dl, Flags  ; see below
int 2Fh
or ax, ax
jz success

Parameters

Flags
Close flags. This parameter can be one of these values:
00h | Disables the Close command.
01h | Enables the Close command.

Return Value

Returns zero in the AX register if successful.


Get Application Title

Copies the application title to the specified buffer.

mov  ah, 16h           ; Windows multiplex function
mov  al, 8Eh           ; VM Title
mov  di, seg AppTitle  ; see below
mov  es, di
mov  di, offset AppTitle
mov  cx, Size          ; see below
mov  dx, 2             ; Get Application Title
int  2Fh
cmp  ax, 1
je   success

Parameters

AppTitle
Address of a buffer that receives the application title. This parameter must not be zero.
Size
Size, in bytes, of the buffer pointed to by AppTitle.

Return Value

Returns 1 in the AX register if successful or zero otherwise.

Remarks

Get Application Title copies as much of the title as possible, but never more than the specified number of bytes. The function always appends a terminating null character to the title in the buffer.


Get Virtual Machine Title

Copies the virtual machine title to the specified buffer.

mov  ah, 16h           ; Windows multiplex function
mov  al, 8Eh           ; VM Title
mov  di, seg VMTitle   ; see below
mov  es, di
mov  di, offset VMTitle
mov  cx, Size          ; see below
mov  dx, 3             ; Get Virtual Machine Title
int  2Fh
cmp  ax, 1
je   success

Parameters

VMTitle
Address of a buffer that receives the virtual machine title. This parameter must not be zero.
Size
Size, in bytes, of the buffer pointed to by VMTitle.

Return Value

Returns 1 in the AX register if successful or zero otherwise.

Remarks

Get Virtual Machine Title copies as much of the title as possible, but never more than the specified number of bytes. The function always appends a terminating null character to the title in the buffer.


Interrupt 21h Function 4302h

Obtains the compressed size, in bytes, of a given file or directory.

mov ax, 4302h            ; Get Compressed File Size
mov dx, seg PathName     ; see below
mov ds, dx
mov dx, offset PathName
int 21h

jc error

Parameters

PathName
Address of a null-terminated string that specifies the file or directory to retrieve the file size for.

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

The function obtains the actual number of bytes of disk storage used to store the file. If the file is located on a volume that supports compression and the file is compressed, the value obtained is the compressed size of the specified file. If the file is not located on a volume that supports compression or if the file is not compressed, the value obtained is the file size, in bytes, rounded up to the nearest cluster boundary.


Interrupt 21h Function 440Dh Minor Code 48h

Locks or unlocks the volume in the given drive (preventing or permitting its removal) or returns the locked status of the given drive.

mov ax, 440Dh           ; generic IOCTL
mov bx, DriveNum        ; see below
mov ch, 8               ; device category
mov cl, 48h             ; Lock or Unlock Removable Media
mov dx, seg ParamBlock  ; see below
mov ds, dx
mov dx, offset ParamBlock
int 21h

jc  error

Parameters

DriveNum
Drive to lock or unlock. This parameter can be 0 for default drive, 1 for A, 2 for B, and so on.
ParamBlock
Address of a PARAMBLOCK structure that specifies the operation to carry out and receives a count of the number of locks on the drive.

Return Value

Clears the carry flag and copies the number of pending locks on the given drive to the NumLocks member of the PARAMBLOCK structure if successful. Otherwise, the function sets the carry flag and sets the AX register to one of the following error values:

01h | The function is not supported.
B0h | The volume is not locked in the drive.
B2h | The volume is not removable.
B4h | The lock count has been exceeded.


Interrupt 21h Function 440Dh Minor Code 49h

Ejects the specified media.

mov ax, 440Dh     ; generic IOCTL
mov bx, DriveNum  ; see below
mov ch, 8         ; device category
mov cl, 49h       ; Eject Removable Media
int 21h

jc  error

Parameters

DriveNum
Drive to eject. This parameter can be 0 for default drive, 1 for A, 2 for B, and so on.

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to one of the following error values:

01h | The function is not supported.
B1h | The volume is locked in the drive.
B2h | The volume is not removable.
B5h | The valid eject request has failed.

Remarks

If a given physical drive has more than one logical volume, all volumes must be unlocked by using Lock/Unlock Removable Media (Interrupt 21h Function 440Dh Minor Code 48h) before the drive will eject.


Interrupt 21h Function 440Dh Minor Code 4Ah

Locks the logical volume.

mov ax, 440Dh        ; generic IOCTL
mov bh, LockLevel    ; see below
mov bl, DriveNum     ; see below
mov ch, 08h          ; device category (must be 08h)
mov cl, 4Ah          ; Lock Logical Volume
mov dx, Permissions  ; see below
int 21h

jc error

Parameters

LockLevel
Level of the lock. This parameter must be either 0, 1, 2, or 3.
DriveNum
Drive to lock. This parameter can be 0 for the default drive, 1 for A, 2 for B, and so on.
Permissions
Operations that the system permits while the volume is locked. This parameter is specified only when a level 1 lock is obtained or when a level 0 lock is obtained for the second time for formatting the volume. For other lock levels, this parameter is zero. When a level 1 lock is obtained, bits 0 and 1 of this parameter specify whether the system permits write operations, new file mappings, or both by other processes during a level 1 lock as well as during level 2 and 3 locks. If this parameter specifies that write operations, new file mappings, or both are failed, these operations are failed during level 1, 2, and 3 locks. This parameter has the following form:
Bit | Meaning
0 | 0 = Write operations are failed (specified when a level 1 lock is obtained).
0 | 1 = Write operations are allowed (specified when a level 1 lock is obtained).
1 | 0 = New file mapping are allowed (specified when a level 1 lock is obtained).
1 | 1 = New file mapping are failed (specified when a level 1 lock is obtained).
2 | 1 = The volume is locked for formatting (specified when a level 0 lock is obtained for the second time).

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

The volume must be locked before the application performs direct disk write operations by using Interrupt 26h or the IOCTL control functions. Lock Physical Volume (Interrupt 21h Function 440Dh Minor Code 4Bh) is used instead of this function before a call to an Interrupt 13h function. Unlock Logical Volume (Interrupt 21h Function 440Dh Minor Code 6Ah) should be used to release the lock.


Interrupt 21h Function 440Dh Minor Code 4Bh

Locks the physical volume.

mov ax, 440Dh        ; generic IOCTL
mov bh, LockLevel    ; see below
mov bl, DriveNum     ; see below
mov ch, 08h          ; device category (must be 08h)
mov cl, 4Bh          ; Lock Physical Volume
mov dx, Permissions  ; see below
int 21h

jc error

Parameters

LockLevel
Level of the lock. This parameter must be either 0, 1, 2, or 3.
DriveNum
Drive to lock. This parameter must be one of these values (same device unit numbers as for Interrupt 13h):
00 - 7Fh | Floppy disk drive (00 for the first floppy drive, 01 for the second, and so on).
80 - FFh | Hard disk drive (80 for the first hard disk drive, 81 for the second, and so on).

Permissions
Operations that the system permits while the volume is locked. This parameter is specified only when a level 1 lock is obtained or when a level 0 lock is obtained for the second time for formatting the volume. For other lock levels, this parameter is zero. When a level 1 lock is obtained, bits 0 and 1 of this parameter specify whether the system permits write operations, new file mappings, or both by other processes during a level 1 lock as well as during level 2 and 3 locks. If this parameter specifies that write operations, new file mappings, or both are failed, these operations are failed during level 1, 2, and 3 locks. This parameter has the following form:
Bit | Meaning
0 | 0 = Write operations are failed (specified when a level 1 lock is obtained).
0 | 1 = Write operations are allowed (specified when a level 1 lock is obtained).
1 | 0 = New file mapping are allowed (specified when a level 1 lock is obtained).
1 | 1 = New file mapping are failed (specified when a level 1 lock is obtained).
2 | 1 = The volume is locked for formatting (specified when a level 0 lock is obtained for the second time).

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

The volume must be locked before the application performs direct disk write operations by using Interrupt 13h, Interrupt 26h, or the Interrupt 21h IOCTL functions. A single physical volume may be divided into more than one logical volume, which is also called a partition. The system automatically takes a logical volume lock on all logical volumes on the specified physical drive. If the application performs disk writes only to a logical drive, Lock Logical Volume (Interrupt 21h Function 440Dh Minor Code 4Ah) is used instead of this function. Unlock Physical Volume (Interrupt 21h Function 440Dh Minor Code 6Bh) should be called to release the lock.


Interrupt 21h Function 440Dh Minor Code 6Ah

Unlocks the logical volume or decrements the lock level.

mov ax, 440Dh      ; generic IOCTL
mov bl, DriveNum   ; see below
mov ch, 08h        ; device category (must be 08h)
mov cl, 6Ah        ; Unlock Logical Volume
int 21h

jc error

Parameters

DriveNum
Drive to unlock. This parameter can be 0 for the default drive, 1 for A, 2 for B, and so on.

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

This function is used to release the lock obtained by using Lock Logical Volume (Interrupt 21h Function 440Dh Minor Code 4Ah). Only the lock owner can release the lock on a volume.

To release the lock on the volume, an application must call Unlock Logical Volume the same number of times that Lock Logical Volume was called.


Interrupt 21h Function 440Dh Minor Code 6Bh

Unlocks the physical volume or decrements the lock level.

mov ax, 440Dh      ; generic IOCTL
mov bl, DriveNum   ; see below
mov ch, 08h        ; device category (must be 08h)
mov cl, 6Bh        ; Unlock Physical Volume
int 21h

jc enter

Parameters

DriveNum
Drive to unlock. This parameter must be one of these values (same device unit numbers as for Interrupt 13h):
00 - 7Fh | Floppy disk drive (00 for the first floppy drive, 01 for the second, and so on).
80 - FFh | Hard disk drive (80 for the first hard disk drive, 81 for the second, and so on).

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

This function is used to release the lock obtained by using Lock Physical Volume (Interrupt 21h Function 440Dh Minor Code 4Bh). Only the lock owner can release the lock on a volume.

To release the lock on the volume, an application must call Unlock Physical Volume the same number of times that Lock Physical Volume was called.


Interrupt 21h Function 440Dh Minor Code 6Ch

Polls the state of the access flag on a volume to determine if a write operation (for example, deleting or renaming a file or writing to a file) or a new file mapping has occurred since the last poll.

mov ax, 440Dh        ; generic IOCTL
mov bl, DriveNum     ; see below
mov ch, 08h          ; device category (must be 08h)
mov cl, 6Ch          ; Get Lock Flag State
int 21h

jc error
mov [AccessFlag], ax  ; state of access flag

Parameters

DriveNum
Drive to poll. This parameter can be 0 for the default drive, 1 for A, 2 for B, and so on.

Return Value

Clears the carry flag and sets the AX register to one of the following values if successful:

0 | No write operations or file mappings have occurred since the last poll.
1 | A write operation has occurred since the last poll (clears the volume access flag).
2 | A file mapping has occurred since the last poll, or a 32-bit Windows-based DLL or executable has been opened (clears the volume access flag).

Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

Only the current lock owner may poll the access flag. The system fails other processes with ERROR_ACCESS_DENIED error value. Write operations performed by the lock owner do not cause a change in the state of the access flag.

When a lock is obtained that allows write operations or new file mappings, the system sets a flag whenever one of these operations happens on the volume. If a write operation or new file mapping has occurred since the last poll, Get Lock Flag State returns 1 or 2 respectively in the AX register and clears the volume access flag. If the swap file has grown or shrunk since the last poll, Get Lock Flag State returns 1. Note that write operations to the swap file that do not cause a change in size do not cause a change in the state of the access flag. If a 32-bit Windows-based DLL or executable has been opened since the last poll, Get Lock Flag State returns 2.


Interrupt 21h Function 440Dh Minor Code 6Dh

Enumerates open files on the specified drive.

mov ax, 440Dh           ; generic IOCTL
mov bx, DriveNum        ; see below
mov ch, 08h             ; device category (must be 08h)
mov cl, 6Dh             ; Enumerate Open Files
mov dx, seg PathBuf     ; see below
mov ds, dx
mov dx, offset PathBuf
mov si, FileIndex       ; see below
mov di, EnumType        ; see below
int 21h

jc  error
mov [OpenMode], ax      ; mode file was opened in
mov [FileType], cx      ; normal file or memory-mapped file

Parameters

DriveNum
Drive on which to enumerate the files. This parameter can be 0 for the default drive, 1 for A, 2 for B, and so on.
PathBuf
Address of a buffer that receives the path of the open file. The length of the buffer varies depending on the volume. Get Volume Information (Interrupt 21h Function 71A0h) is used to determine the maximum allowed length of a path for the volume.
FileIndex
Index of the file to retrieve the path for.
EnumType
Kind of file to enumerate. This parameter can be 0 to enumerate all open files or 1 to enumerate only open unmovable files, including open memory-mapped files and other open unmovable files (32-bit Windows-based DLLs and executables).

Return Value

Clears the carry flag, copies the path of an open file to the given buffer, and sets the AX and CX registers to the following values if successful:

AX | Mode that the file was opened in, which is a combination of access mode, sharing mode, and open flags. It can be one value each from the access and sharing modes and any combination of open flags.
 | Access modes
 | OPEN_ACCESS_READONLY (0000h)
 | OPEN_ACCESS_WRITEONLY (0001h)
 | OPEN_ACCESS_READWRITE (0002h)
 | OPEN_ACCESS_RO_NOMODLASTACCESS (0004h)
 | Share modes
 | OPEN_SHARE_COMPATIBLE (0000h)
 | OPEN_SHARE_DENYREADWRITE (0010h)
 | OPEN_SHARE_DENYWRITE (0020h)
 | OPEN_SHARE_DENYREAD (0030h)
 | OPEN_SHARE_DENYNONE (0040h)
 | Open flags
 | OPEN_FLAGS_NOINHERIT (0080h)
 | OPEN_FLAGS_NO_BUFFERING (0100h)
 | OPEN_FLAGS_NO_COMPRESS (0200h)
 | OPEN_FLAGS_ALIAS_HINT (0400h)
 | OPEN_FLAGS_NOCRITERR (2000h)
 | OPEN_FLAGS_COMMIT (4000h)
CX | File type. It can be one of the following values:
 | 0 | For normal files
 | 1 | For a memory-mapped files (memory-mapped files are unmovable)
 | 2 | For any other unmovable files (32-bit Windows-based DLLs and executables)
 | 4 | For the swap file

Note that if a memory-mapped file is returned (CX = 1), the value returned in the AX register is limited to the following values:

OPEN_ACCESS_READONLY (0000h)
OPEN_ACCESS_READWRITE (0002h)

Otherwise, the function sets the carry flag and sets the AX register to the following error value:

ERROR_ACCESS_DENIED The value of FileIndex exceeds the number of open files on the drive.

Remarks

This function returns information about one file at a time. To enumerate all open files, the function must be called repeatedly with FileIndex set to a new value for each call. FileIndex should be set to zero initially and then incremented by one for each subsequent call. The function returns the ERROR_NO_MORE_FILES error value when all open files on the volume have been enumerated.

This function may return inconsistent results when used to enumerate files on an active volume — that is, on a volume where other processes may be opening and closing files. Applications should use Lock Logical Volume (Interrupt 21h Function 440Dh Minor Code 4Ah) to take a level 3 lock before enumerating open files.


Interrupt 21h Function 440Dh Minor Code 6Eh

Retrieves information about the swap file.

mov ax, 440Dh           ; generic IOCTL
mov ch, 08h             ; device category (must be 08h)
mov cl, 6Eh             ; Find Swap File
mov dx, seg PathBuf     ; see below
mov ds, dx
mov dx, offset PathBuf
int 21h

jc  error
mov [PagerType], ax            ; pager type
mov WORD PTR [FileSize], bx    ; swap file size in 4K pages
mov WORD PTR [FileSize+2], cx

Parameters

PathBuf
Address of the buffer that receives the path of the swap file. To determine the maximum allowed length of a path for the volume, call Get Volume Information (Interrupt 21h Function 71A0h).

Return Value

Clears the carry flag, copies the swap file path to the given buffer, and sets the following registers if successful:

AX | Pager type. It can be 1 for no pager, 2 for paging through MS-DOS, and 3 for paging through the protected-mode input and output (I/O) supervisor.
CX:BX | Current size of the swap file in 4K pages.

Otherwise, this function sets the carry flag and sets the AX register to an error value.


Interrupt 21h Function 440Dh Minor Code 6Fh

Retrieves information about the specified drive.

mov ax, 440Dh            ; generic IOCTL
mov bx, DriveNum         ; see below
mov ch, 8                ; device category
mov cl, 6Fh              ; Get Drive Map Info
mov dx, seg DriveMapInfo ; see below
mov ds, dx
mov dx, offset DriveMapInfo
int 21h

jc  error

Parameters

DriveNum
Drive to obtain information about. This parameter can be 0 for the default drive, 1 for A, 2 for B, and so on.
DriveMapInfo
Address of the DRIVE_MAP_INFO structure that receives information about the specified drive.


Interrupt 21h Function 440Dh Minor Code 70h

Retrieves the current lock level and permissions on the specified drive.

mov ax, 440Dh        ; generic IOCTL
mov bl, DriveNum     ; see below
mov ch, 08h          ; device category (must be 08h)
mov cl, 70h          ; Get Current Lock State
int 21h

jc error

Parameters

DriveNum
Drive to retrieve lock information about. This parameter can be 0 for the default drive, 1 for A, 2 for B, and so on.

Return Value

Clears the carry flag and sets the AX and CX registers to these values if successful:

AX | Current lock level. It may be either 0, 1, 2 or 3. If the volume is not locked, AX contains – 1
CX | Lock permissions. The bits have the following form:

Bit | Meaning
0 | 0 = Write operations are failed.
0 | 1 = Write operations are allowed, unless they are blocked by the lock level.
1 | 0 = New file mapping are allowed, unless they are blocked by the lock level.
1 | 1 = New file mapping are failed.
2 | 1 = The volume is locked for formatting.

Remarks

The lock level and the permissions determine the kind of access processes other than the lock owner have to the volume while it is locked. The following operations are allowed by processes other than lock owner at each lock level:

Level | Operations
0 | Read operations, write operations, and new file mappings are failed.
1 | Read operations are allowed. Write operations and new file mappings are either allowed or failed based on permissions.
2 | Read operations are allowed. Write operations and new file mappings are either failed or blocked based on permissions.
3 | Read operations are blocked. Write operations and new file mappings are either failed or blocked based on permissions.


Interrupt 21h Function 440Dh Minor Code 71h

Retrieves the first cluster of the specified file or directory.

mov ax, 440Dh            ; generic IOCTL
mov bx, CharSet          ; see below
mov ch, 08h              ; device category
mov cl, 71h              ; Get First Cluster
mov dx, seg PathName     ; see below
mov ds, dx
mov dx, offset PathName
int 21h

jc error

Parameters

CharSet
Character set of PathName. This parameter must be one of these values:
BCS_WANSI (0) | Windows ANSI character set
BCS_OEM (1) | Current OEM character set
BCS_UNICODE (2) | Unicode character set

PathName
Address of a null-terminated string containing the path of the file or directory to retrieve the first cluster for.

Return Value

Clears the carry flag and sets DX:AX to the first cluster number if successful. Otherwise, the function sets the carry flag and returns either the ERROR_INVALID_FUNCTION or ERROR_ACCESS_DENIED value in AX.

Remarks

The first cluster of a file is the first cluster of the FAT cluster chain describing the data associated with the file. The first cluster of a directory is the first cluster of the FAT cluster chain associated with the directory. It is the cluster that contains the "." and ".." entries. The function finds any file or directory regardless of attribute (system, hidden, or read-only). It does not find volume labels.

If your application is unable to accommodate a 32-bit cluster number, you must check to see if the value returned in the DX register is greater than zero.

if(MAKELONG(regAX,regDX) > 0x0000FFF8)
    b32BitNum = TRUE;
else
    b32BitNum = FALSE;

It is the calling application's responsibility to check to see if the returned cluster number is valid.

if((MAKELONG(regAX,regDX) < 2L) || (MAKELONG(regAX,regDX) > maxClus))
    bInvalidNum = TRUE;
else
    bInvalidNum = FALSE;

In the preceding example, the maxClus variable is the maximum legal cluster number, as a DWORD type, computed from the drive parameters.


Interrupt 21h Function 5704h

Retrieves the last access date for the given file.

mov ax, 5704h   ; Get Last Access Date and Time
mov bx, Handle  ; see below
int 21h

jc  error
mov [Date], dx  ; last access date
mov [Time], cx  ; currently not supported, always 0

Parameters

Handle
File handle.

Return Value

Clears the carry flag and sets the CX register to zero and the DX register to these values if successful:

Bits | Contents
0–4 | Day of the month (1–31)
5–8 | Month (1 = January, 2 = February, and so on)
9–15 | Year offset from 1980 (that is, add 1980 to get the actual year)

Otherwise, the function sets the carry flag and sets the AX register to an error value.


Interrupt 21h Function 5705h

Sets the last access date for the given file.

mov ax, 5705h       ; Set Last Access Date and Time
mov bx, Handle      ; see below
mov cx, 0           ; time currently not supported, always 0
mov dx, AccessDate  ; see below
int 21h

jc  error

Parameters

Handle
File handle.
AccessDate
New access date. The date is a packed 16-bit value with this form:
Bits | Contents
0–4 | Day of the month (1–31)
5–8 | Month (1 = January, 2 = February, and so on)
9–15 | Year offset from 1980 (that is, add 1980 to get the actual year)

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.


Interrupt 21h Function 5706h

Retrieves the creation date and time for the given file.

mov ax, 5706h           ; Get Creation Date and Time
mov bx, Handle          ; see below
int 21h

jc  error
mov [Time], cx          ; creation time
mov [Date], dx          ; creation date
mov [MilliSeconds], si  ; number of 10 ms intervals in 2 seconds

Parameters

Handle
File handle.

Return Value

Clears the carry flag and sets the CX, DX, and SI registers to these values if successful:

CX Creation time. The time is a packed 16-bit value with the following form:

Bits | Contents
0–4 | Second divided by 2
5–10 | Minute (0–59)
11–15 | Hour (0–23 on a 24-hour clock)

DX Creation date. The date is a packed 16-bit value with the following form:

Bits | Contents
0–4 | Day of the month (1–31)
5–8 | Month (1 = January, 2 = February, and so on)
9–15 | Year offset from 1980 (that is, add 1980 to get the actual year)

SI Number of 10 millisecond intervals in 2 seconds to add to the MS-DOS time. The number can be a value in the range of 0 to 199.

Otherwise, the function sets the carry flag and sets the AX register to an error value.


Interrupt 21h Function 5707h

Sets the creation date and time for the given file.

mov ax, 5707h         ; Set Creation Date and Time
mov bx, Handle        ; see below
mov cx, Time          ; see below
mov dx, Date          ; see below
mov si, MilliSeconds  ; see below
int 21h

jc  error

Parameters

Handle
File handle.
Time
New creation time. The time is a packed 16-bit value with the following form:
Bits | Contents
0–4 | Second divided by 2
5–10 | Minute (0–59)
11–15 | Hour (0–23 on a 24-hour clock)

Date
New creation date. The date is a packed 16-bit value with the following form:
Bits | Contents
0–4 | Day of the month (1–31)
5–8 | Month (1 = January, 2 = February, and so on)
9–15 | Year offset from 1980 (that is, add 1980 to get the actual year)

MilliSeconds
Number of 10 millisecond intervals in 2 seconds to add to the MS-DOS time. The number can be a value in the range 0 to 199.

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.


Interrupt 21h Function 6Ch

Opens or creates a file having the given name and attributes.

mov ah, 6Ch             ; Extended Open/Create
mov bx, ModeAndFlags    ; see below
mov cx, Attributes      ; see below
mov dx, Action          ; action to take
mov si, seg Filename    ; see below
mov ds, si
mov si, offset Filename
int 21h

jc error
mov [Handle], ax        ; file handle
mov [ActionTaken], cx   ; action taken to open file

Parameters

ModeAndFlags
Combination of access mode, sharing mode, and open flags. This parameter can be one value each from the access and sharing modes and any combination of open flags:
Access mode Meaning
OPEN_ACCESS_READONLY (0000h)
Opens the file for reading only.
OPEN_ACCESS_WRITEONLY (0001h)
Opens the file for writing only.
OPEN_ACCESS_READWRITE (0002h)
Opens the file for reading and writing.
0003h
Reserved; do not use.
OPEN_ACCESS_RO_NOMODLASTACCESS (0004h)
Opens the file for reading only without modifying the file's last access date.

Sharing mode Meaning
OPEN_SHARE_COMPATIBLE (0000h)
Opens the file with compatibility mode, allowing any process on a given computer to open the file any number of times.
OPEN_SHARE_DENYREADWRITE (0010h)
Opens the file and denies both read and write access to other processes.
OPEN_SHARE_DENYWRITE (0020h)
Opens the file and denies write access to other processes.
OPEN_SHARE_DENYREAD (0030h)
Opens the file and denies read access to other processes.
OPEN_SHARE_DENYNONE (0040h)
Opens the file without denying read or write access to other processes, but no process may open the file with compatibility mode.

Open flags Meaning
OPEN_FLAGS_NOINHERIT (0080h)
If this flag is set, a child process created with Load and Execute Program (Interrupt 21h Function 4B00h) does not inherit the file handle. If the handle is needed by the child process, the parent process must pass the handle value to the child process. If this flag is not set, child processes inherit the file handle.
OPEN_FLAGS_NOCRITERR (2000h)
If a critical error occurs while MS-DOS is opening this file, Critical-Error Handler (Interrupt 24h) is not called. Instead, MS-DOS simply returns an error value to the program.
OPEN_FLAGS_COMMIT (4000h)
After each write operation, MS-DOS commits the file (flushes the contents of the cache buffer to disk).

Attributes
Attributes for files that are created or truncated. This parameter may be a combination of these values:
_A_NORMAL (0000h)
The file can be read from or written to. This value is valid only if used alone.
_A_RDONLY (0001h)
The file can be read from, but not written to.
_A_HIDDEN (0002h)
The file is hidden and does not appear in an ordinary directory listing.
_A_SYSTEM (0004h)
The file is part of the operating system or is used exclusively by it.
_A_VOLID (0008h)
The name specified by Filename is used as the volume label for the current medium.
_A_ARCH (0020h)
The file is an archive file. Applications use this value to mark files for backup or removal.

Action
Action to take it the file exists or does not exist. This parameter can be a combination of these values:
FILE_CREATE (0010h) | Creates a new file if it does not already exist or fails if the file already exists.
FILE_OPEN (0001h) | Opens the file. The function fails if the file does not exist.
FILE_TRUNCATE (0002h) | Opens the file and truncates it to zero length (replaces the existing file). The function fails if the file does not exist.

The only valid combinations are FILE_CREATE combined with FILE_OPEN or FILE_CREATE combined with FILE_TRUNCATE.

Filename
Address of a null-terminated string specifying the name of the file to be opened or created. The name must be in the standard MS-DOS 8.3 filename format. The string must be a valid path for the volume associated with the given drive.

Return Value

Clears the carry flag, copies the file handle to the AX register, and sets CX to one of the following values if successful:

ACTION_OPENED (0001h)
ACTION_CREATED_OPENED (0002h)
ACTION_REPLACED_OPENED (0003h)

Otherwise, this function sets the carry flag and sets the AX register to one of the following error values:

ERROR_INVALID_FUNCTION (0001h)
ERROR_FILE_NOT_FOUND (0002h)
ERROR_PATH_NOT_FOUND (0003h)
ERROR_TOO_MANY_OPEN_FILES (0004h)
ERROR_ACCESS_DENIED (0005h)

Remarks

This function does not support long filenames. If the specified name is too long, this function truncates the name to the standard 8.3 format following the same naming scheme that the system uses when creating an alias for a long filename.

A file on a remote directory — that is, a directory on the network — cannot be opened, unless appropriate permissions for the directory exist.


Interrupt 21h Function 710Dh

Flushes file system buffers and caches and optionally remounts the drivespace volume. Any write operations that the system has buffered are performed, and all waiting data is written to the appropriate drive.

mov ax, 710Dh      ; Reset Drive
mov cx, Flag       ; see below
mov dx, DriveNum   ; see below
int 21h

jc  error

Parameters

Flag
Flag specifying whether the system should flush and invalidate the data in the cache as well as the file system buffers. This parameter must be one of these values:
0000h | Resets the drive and flushes the file system buffers for the given drive.
0001h | Resets the drive, flushes the file system buffers, and flushes and invalidates the cache for the specified drive.
0002h | Remounts the drivespace volume.

The Flag value of 0002h is only supported on drivespace volumes. You should specify this value when the on-media format of the drivespace volume has changed and you want the file system to reinitialize and read the new format.

DriveNum
Drive to reset. This parameter can be 0 for the default drive, 1 for A, 2 for B, and so on.

Return Value

This function has no return value.


Interrupt 21h Function 7139h

Creates a new directory having the given name.

mov ax, 7139h     ; Make Directory
mov dx, seg Name  ; see below
mov ds, dx
mov dx, offset Name
int 21h

jc  error

Parameters

Name
Address of a null-terminated string specifying the name of the directory to create. Long filenames are allowed.

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.


Interrupt 21h Function 713Ah

Removes the given directory. The directory must be empty.

mov ax, 713Ah     ; Remove Directory
mov dx, seg Name  ; see below
mov ds, dx
mov dx, offset Name
int 21h

jc  error

Parameters

Name
Address of a null-terminated string specifying the name of the directory to remove. Long filenames are allowed.

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

The root directory cannot be deleted.


Interrupt 21h Function 713Bh

Changes the current directory to the directory specified by the given path.

mov ax, 713Bh     ; Change Directory
mov dx, seg Path  ; see below
mov ds, dx
mov dx, offset Path
int 21h

jc error

Parameters

Path
Address of a null-terminated string specifying the directory to change to. The path, which can include the drive letter, must be a valid path for the given volume. Long filenames are allowed.

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

The current or default directory is the directory that the system uses whenever an application supplies a filename that does not explicitly specify a directory. Similarly, the current or default drive is the drive the system uses whenever an application supplies a path that does not explicitly specify a drive. If a drive other than the default drive is specified as part of the new directory path, this function changes the current directory on that drive but does not change the default drive. Set Default Drive (Interrupt 21h Function 0Eh) can be used to change the default drive.


Interrupt 21h Function 7141h

Deletes the given file or files. If the specified filename contains a wildcard character, this function can delete multiple files that match the wildcard.

mov ax, 7141h             ; Delete File
mov ch, MustMatchAttrs    ; see below
mov cl, SearchAttrs       ; see below
mov dx, seg Filename      ; see below
mov ds, dx
mov dx, offset Filename
mov si, WildcardAndAttrs  ; see below
int 21h

jc error

Parameters

MustMatchAttrs
Additional filter on the attributes specified in SearchAttrs. This parameter can be a combination of these values:
_A_NORMAL (0000h)
The file can be read from or written to. This value is valid only if used alone.
_A_RDONLY (0001h)
The file can be read from, but not written to.
_A_HIDDEN (0002h)
The file is hidden and does not appear in an ordinary directory listing.
_A_SYSTEM (0004h)
The file is part of the operating system or is used exclusively by it.
_A_VOLID (0008h)
The name specified by Filename is used as the volume label for the current medium.
_A_SUBDIR (0010h)
The name specified by Filename is used as a directory, not a file.
_A_ARCH (0020h)
The file is an archive file. Applications use this value to mark files for backup or removal.

SearchAttrs
File attributes to search for. This parameter can be a combination of these values:
_A_NORMAL (0000h)
_A_RDONLY (0001h)
_A_HIDDEN (0002h)
_A_SYSTEM (0004h)
_A_VOLID (0008h)
_A_SUBDIR (0010h)
_A_ARCH (0020h)

Filename
Address of a null-terminated string specifying the name of the file to delete. If WildcardAndAttrs is 1, the "*" and "?" wildcard characters are permitted in the filename. Long filenames are allowed.
WildcardAndAttrs
Search criteria. This parameter must be one of these values:
0 | Wildcard characters are not allowed in Filename. Any specified attributes are ignored.
1 | Wildcard characters are allowed in Filename. Files with specified attributes are matched.

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

Wildcard searches are more flexible in Windows 95 than in MS-DOS. Both long filenames and aliases are considered in searches. For example, *1 finds Windows 95 filenames (both long filenames and aliases) that end in a 1 and *mid* finds filenames that contain the characters mid. In MS-DOS and in Windows 95 searching on real-mode FAT directories, all characters after the first * are ignored.

For more information about how MustMatchAttrs and SearchAttrs are used, see the comments for Find First File (Interrupt 21h Function 714Eh).


Interrupt 21h Function 7143h

Retrieves or sets the file attributes, gets the compressed file size, or retrieves or sets the date and time for the given file.

mov ax, 7143h         ; Get or Set File Attributes
mov bl, Action        ; see below
mov cx, Attributes    ; see below
mov di, Date          ; see below
mov cx, Time          ; see below
mov si, MilliSeconds  ; see below
mov dx, seg Filename  ; see below
mov ds, dx
mov dx, offset Filename
int 21h

jc  error
; see below for return values

Parameters

Action
Action to take. This parameter can be one of the following values:
0 | Retrieve attributes.
1 | Set specified attributes.
2 | Get physical size of a compressed file.
3 | Set last write date/time.
4 | Get last write date/time.
5 | Set last access date.
6 | Get last access date.
7 | Set creation date/time.
8 | Get creation date/time.

Attributes
File attributes to set, which are used only if Action is 1. This parameter can be a combination of these values:
_A_NORMAL (0000h)
The file can be read from or written to. This value is valid only if used alone.
_A_RDONLY (0001h)
The file can be read from, but not written to.
_A_HIDDEN (0002h)
The file is hidden and does not appear in an ordinary directory listing.
_A_SYSTEM (0004h)
The file is part of the operating system or is used exclusively by it.
_A_ARCH (0020h)
The file is an archive file. Applications use this value to mark files for backup or removal.

Time
New time to set, which is used only if Action is 3 (set last write date/time) or 7 (set creation date/time) The time is a packed 16-bit value with the following form:
Bits | Contents
0–4 | Second divided by 2
5–10 | Minute (0–59)
11–15 | Hour (0–23 on a 24-hour clock)

Date
New date to set, which is used only if Action is 3 (set last write date/time), 5 (set last access date), or 7 (set creation date/time). The date is a packed 16-bit value with the following form:
Bits | Contents
0–4 | Day of the month (1–31)
5–8 | Month (1 = January, 2 = February, and so on)
9–15 | Year offset from 1980 (that is, add 1980 to get the actual year)

MilliSeconds
Number of 10 millisecond intervals in 2 seconds to add to the MS-DOS time. The number can be a value in the range 0 to 199. This value is only used if Action is 7 (set creation date/time).
Filename
Address of a null-terminated string specifying the name of the file to retrieve or set attributes for. Long filenames are allowed.

Return Value

Clears the carry flag if successful.

If Action is zero (retrieve attributes), the file attributes returned in the CX register may be a combination of the following values :

_A_NORMAL (0000h)
_A_RDONLY (0001h)
_A_HIDDEN (0002h)
_A_SYSTEM (0004h)
_A_VOLID (0008h)
_A_SUBDIR (0010h)
_A_ARCH (0020h)

If Action is 2 (get physical size of a compressed file), the size, in bytes, of the compressed file is returned in DX:AX. This value is the physical size of the compressed file — that is, the actual number of bytes that the compressed file occupies on disk.

If Action is 4 (get last write date/time) or 8 (get creation date/time), the CX register contains the time as a packed 16-bit value with the following form:

Bits | Contents
0–4 | Second divided by 2
5–10 | Minute (0–59)
11–15 | Hour (0–23 on a 24-hour clock)

If Action is 4 (get last write date/time), 6 (get last access date), or 8 (get creation date/time), the DI register contains the date as a packed 16-bit value with the following form:

Bits | Contents
0–4 | Day of the month (1–31)
5–8 | Month (1 = January, 2 = February, and so on)
9–15 | Year offset from 1980 (that is, add 1980 to get the actual year)

If Action is 8 (get creation date/time), the SI register contains the number of 10 millisecond intervals in 2 seconds to add to the MS-DOS time. The number can be a value in the range of 0 to 199.

If the function is not successful, it sets the carry flag and sets the AX register to an error value.


Interrupt 21h Function 7147h

Copies the path of the current directory for the given drive to the buffer. The copied path does not include the drive letter or the leading backslash.

mov ax, 7147h       ; Get Current Directory
mov dl, Drive       ; see below
mov si, seg Buffer  ; see below
mov ds, si
mov si, offset Buffer
int 21h

jc  error

Parameters

Drive
Drive number. This parameter can be 0 for current drive, 1 for A, 2 for B, and so on.
Buffer
Address of the buffer that receives the path. The buffer must be at least as big as the maximum allowed path for this volume as returned by Get Volume Information (Interrupt 21h Function 71A0h).

Return Value

Clears the carry flag and copies the path if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.


Interrupt 21h Function 714Eh

Searches a directory for the first file or directory whose name and attributes match the specified name and attributes.

mov ax, 714Eh             ; Find First File
mov ch, MustMatchAttrs    ; see below
mov cl, SearchAttrs       ; see below
mov dx, seg Filename      ; see below
mov ds, dx
mov dx, offset Filename
mov di, seg FindData      ; see below
mov es, di
mov di, offset FindData
mov si, DateTimeFormat    ; see below
int 21h

jc  error
mov [Handle], ax          ; search handle
mov [ConversionCode], cx  ; Unicode to OEM/ANSI conversion OK?

Parameters

MustMatchAttrs
Additional filter on the attributes specified in SearchAttrs. This parameter can be a combination of these values:
_A_NORMAL (0000h)
The file can be read from or written to. This value is valid only if used alone.
_A_RDONLY (0001h)
The file can be read from, but not written to.
_A_HIDDEN (0002h)
The file is hidden and does not appear in an ordinary directory listing.
_A_SYSTEM (0004h)
The file is part of the operating system or is used exclusively by it.
_A_VOLID (0008h)
The name specified by Filename is used as the volume label for the current medium.
_A_SUBDIR (0010h)
The name specified by Filename is used as a directory, not a file.
_A_ARCH (0020h)
The file is an archive file. Applications use this value to mark files for backup or removal.

SearchAttrs
File attributes to search for. This parameter can be a combination of these values:
_A_NORMAL (0000h)
_A_RDONLY (0001h)
_A_HIDDEN (0002h)
_A_SYSTEM (0004h)
_A_VOLID (0008h)
_A_SUBDIR (0010h)
_A_ARCH (0020h)

Filename
Address of a null-terminated string specifying the name of the file or directory to search for. The name, which must be a valid filename or directory name, can include the "*" and "?" wildcard characters. Long filenames are allowed.
FindData
Address of a WIN32_FIND_DATA structure that receives information about the file.
DateTimeFormat
Date and time format to be returned. This parameter must be one of these values:
0 | Returns the date and time in 64-bit file time format.
1 | Returns the MS-DOS date and time values. MS-DOS date and time values are returned in the low doubleword of the FILETIME structure. Within the doubleword, the date is returned in the high-order word; the time is in the low-order word.

Return Value

Clears the carry flag, copies information about the file to the specified buffer, returns the search handle in the AX register, and sets the CX register to a combination of the following values if successful:

0x0000 | All characters in the primary and alternate name members in the structure specified by FindData were successfully converted from Unicode.
0x0001 | The primary name returned in the structure specified by FindData contains underscore characters in place of characters that could not be converted from Unicode.
0x0002 | The alternate name returned in the structure specified by FindData contains underscore characters in place of characters that could not be converted from Unicode.

Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

Find First File and subsequent calls to Find Next File (Interrupt 21h Function 714Fh) use the following algorithm to match the attributes of a file or directory (referred to as Attributes in the algorithm) against MustMatchAttrs and SearchAttrs.

if  ((((<MustMatchAttrs> & ~<Attributes>) & 0x3F) == 0)
      && (((~<SearchAttrs> & <Attributes>) & 0x1E) == 0))
    {
         return the file or directory name
    }
    else
    {
         continue searching for the next name
    }

The following table lists the MustMatchAttrs and SearchAttrs values for some common searches where the specified filename is "*.*". In the table, the word normal means that the read only, hidden, or system attributes have not been set. Parentheses are used to indicate that a file or directory has more than one attribute. For example, (hidden and system) indicates that a file or directory has both the hidden attribute and the system attribute.

MustMatchAttrs | SearchAttrs | Find results
10h | 10h | All normal directories
10h | 12h | All normal and hidden directories
10h | 14h | All normal and system directories
10h | 16h | All normal, hidden, system and (hidden and system) directories
12h | 12h | All hidden directories
14h | 14h | All system directories
16h | 16h | All (hidden and system) directories
00h | 00h | All normal files
00h | 01h | All normal and read only files
00h | 02h | All normal and hidden files
00h | 04h | All normal and system files
00h | 06h | All normal, hidden, system, and (hidden and system) files
00h | 10h | All normal files and directories
01h | 01h | All read only files
02h | 02h | All hidden files
02h | 06h | All hidden and (hidden and system) files

This function can be used to return the volume label by specifying only _A_VOLID (0008h) in both MustMatchAttrs and SearchAttrs.

An application may use the handle returned in the AX register in subsequent calls to Find Next File (Interrupt 21h Function 714Fh). It is important to close the handle when it is no longer needed by calling Find Close (Interrupt 21h Function 71A1h).

Wildcard searches are more flexible in Windows 95 than in MS-DOS. For example, *1 finds the filenames (both long filenames and aliases) that end in a 1, and *mid* finds filenames that contain the characters mid. In MS-DOS and in Windows 95 searching on real-mode FAT directories, all characters after the first * are ignored.


Interrupt 21h Function 714Fh

Searches for the next file in a directory, returning information about the file in the given buffer.

mov ax, 714Fh            ; Find Next File
mov bx, Handle           ; see below
mov di, seg FindData     ; see below
mov es, di
mov di, offset FindData
mov si, DateTimeFormat   ; see below
int 21h

jc error
mov [ConversionCode], cx  ; Unicode to OEM/ANSI conversion OK?

Parameters

Handle
Search handle. It must have been previously returned from Find First File (Interrupt 21h Function 714Eh).
FindData
Address of a WIN32_FIND_DATA structure that receives information about the file.
DateTimeFormat
Date and time format to be returned. This parameter must be one of these values:
0 | Returns the date and time in 64-bit file time format.
1 | Returns the MS-DOS date and time values. MS-DOS date and time values are returned in the low doubleword of the FILETIME structure. Within the doubleword, the date is returned in the high-order word; the time is in the low-order word.

Return Value

Clears the carry flag, copies information to the specified buffer, and sets the CX register to a combination of these values if successful:

0x0000 | All characters in the primary and alternate name member in the structure specified by FindData were successfully converted from Unicode.
0x0001 | The primary name returned in the structure specified by FindData contains underscore characters in place of characters that could not be converted from Unicode.
0x0002 | The alternate name returned in the structure specified by FindData contains underscore characters in place of characters that could not be converted from Unicode.

Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

It is important to close the handle when it is no longer needed by calling Find Close (Interrupt 21h Function 71A1h).


Interrupt 21h Function 7156h

Changes the name of the given file or directory to the new name.

mov ax, 7156h           ; Rename File
mov dx, seg OldName     ; see below
mov ds, dx
mov dx, offset OldName
mov di, seg NewName     ; see below
mov es, di
mov di, offset NewName
int 21h

jc  error

Parameters

OldName
Address of a null-terminated string specifying the original name of the file or the directory to rename. Long filenames are allowed.
NewName
Address of a null-terminated string specifying the new name for the file or the directory. The function will fail if this parameter specifies an existing file or directory. The new name must not specify a drive different than the original drive. Long filenames are allowed.

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.


Interrupt 21h Function 7160h Minor Code 0h

Retrieves the full path for the specified file or path.

mov ax, 7160h
mov cl, 0                  ; Get Full Path Name
mov ch, SubstExpand        ; see below
mov si, seg SourcePath     ; see below
mov ds, si
mov si, offset SourcePath
mov di, seg DestPath       ; see below
mov es, di
mov di, offset DestPath
int 21h

jc  error

Parameters

SubstExpand
Flag that indicates whether the returned path should contain a SUBST drive letter or the path associated with the SUBST drive. Zero is specified to indicate that the returned path should contain the path associated with the SUBST drive, and 80h is specified to indicate that the returned path should contain the SUBST drive letter.
SourcePath
Address of a null-terminated string that names the file or path to retrieve the full path for. Either the long filename or the standard 8.3 filename format is acceptable.
DestPath
Address of the buffer that receives the full path. The buffer should be large enough to contain the largest possible Windows 95 path (260 characters, including the drive letter, colon, leading backslash, and terminating null character).

Return Value

Clears the carry flag, modifies the AX register, and returns the full path in the given buffer if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

When just a filename is specified, this function merges the name of the current drive and directory with the specified filename to determine the full path. Relative paths containing the characters "." and ".." in SourcePath are fully expanded. The function does no validation, so the specified filename or path does not need to exist.


Interrupt 21h Function 7160h Minor Code 1h

Retrieves the complete path in its short form (the standard 8.3 format) for the specified file or path. The function returns the 8.3 filename for all directories in the path.

mov ax, 7160h
mov cl, 1                  ; Get Short Path Name
mov ch, SubstExpand        ; see below
mov si, seg SourcePath     ; see below
mov ds, si
mov si, offset SourcePath
mov di, seg DestPath       ; see below
mov es, di
mov di, offset DestPath
int 21h
jc  error

Parameters

SubstExpand
Flag that indicates if the returned path should contain a SUBST drive letter or the path associated with the SUBST drive. Zero is specified to indicate that the returned path should contain the path associated with the SUBST drive, and 80h is specified to indicate that the returned path should contain the SUBST drive letter.
SourcePath
Address of a null-terminated string that names the file or path to retrieve the complete short path for. Either the long or short form is acceptable as the source string.
DestPath
Address of the buffer that receives the complete path. The buffer should be large enough to contain the largest possible Windows 95 path in the short form (260 characters, including the drive letter, colon, leading backslash, and terminating null character).

Return Value

Clears the carry flag, modifies the AX register, and returns the complete short path in the given buffer if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

Relative paths containing the characters "." and ".." in SourcePath are fully expanded. Since this function performs validation, SourcePath must contain either a valid filename or path.


Interrupt 21h Function 7160h Minor Code 2h

Retrieves the complete path in its long filename form for the specified file or path. The function returns the long name for all directories in the path.

mov ax, 7160h
mov cl, 2                  ; Get Long Path Name
mov ch, SubstExpand        ; see below
mov si, seg SourcePath     ; see below
mov ds, si
mov si, offset SourcePath
mov di, seg DestPath       ; see below
mov es, di
mov di, offset DestPath
int 21h
jc  error

Parameters

SubstExpand
Flag that indicates if the returned path should contain a SUBST drive letter or the path associated with the SUBST drive. Zero is specified to indicate that the returned path should contain the path associated with the SUBST drive, and 80h is specified to indicate that the returned path should contain the SUBST drive letter.
SourcePath
Address of a null-terminated string that names the file or path to retrieve the complete long path for. Either the long filename or the short form is acceptable as the source string.
DestPath
Address of the buffer that receives the complete path. The buffer should be large enough to contain the largest possible Windows 95 path (260 characters, including the drive letter, colon, leading backslash, and terminating null character).

Return Value

Clears the carry flag, modifies the AX register, and returns the complete long path in the given buffer if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

Relative paths containing the characters "." and ".." in SourcePath are fully expanded. Since this function performs validation, SourcePath must contain either a valid filename or path.


Interrupt 21h Function 716Ch

Creates or opens a file.

mov ax, 716Ch          ; Create or Open File
mov bx, ModeAndFlags   ; see below
mov cx, Attributes     ; see below
mov dx, Action         ; see below
mov si, seg Filename   ; see below
mov ds, si
mov si, offset Filename
mov di, AliasHint      ; see below
int 21h

jc error
mov [Handle], ax       ; file handle
mov [ActionTaken], cx  ; action taken to open file

Parameters

ModeAndFlags
Combination of access mode, sharing mode, and open flags. This parameter can be one value each from the access and sharing modes and any combination of open flags:
Access mode Meaning
OPEN_ACCESS_READONLY (0000h)
Opens the file for reading only.
OPEN_ACCESS_WRITEONLY (0001h)
Opens the file for writing only.
OPEN_ACCESS_READWRITE (0002h)
Opens the file for reading and writing.
0003h
Reserved; do not use.
OPEN_ACCESS_RO_NOMODLASTACCESS (0004h)
Opens the file for reading only without modifying the file's last access date.

Sharing mode Meaning
OPEN_SHARE_COMPATIBLE (0000h)
Opens the file with compatibility mode, allowing any process on a given computer to open the file any number of times.
OPEN_SHARE_DENYREADWRITE (0010h)
Opens the file and denies both read and write access to other processes.
OPEN_SHARE_DENYWRITE (0020h)
Opens the file and denies write access to other processes.
OPEN_SHARE_DENYREAD (0030h)
Opens the file and denies read access to other processes.
OPEN_SHARE_DENYNONE (0040h)
Opens the file without denying read or write access to other processes, but no process may open the file for compatibility access.

Open flags Meaning
OPEN_FLAGS_NOINHERIT (0080h)
If this flag is set, a child process created with Load and Execute Program (Interrupt 21h Function 4B00h) does not inherit the file handle. If the handle is needed by the child process, the parent process must pass the handle value to the child process. If this flag is not set, child processes inherit the file handle.
OPEN_FLAGS_NO_BUFFERING (0100h)
The file is to be opened with no intermediate buffering or caching done by the system. Read and write operations access the disk directly. All reads and writes to the file must be done at file positions that are multiples of the disk sector size, in bytes, and the number of bytes read or written should also be a multiple of the sector size. Applications can determine the sector size, in bytes, with the Get Disk Free Space function (Interrupt 21h, Function 36h).
OPEN_FLAGS_NO_COMPRESS (0200h)
The file should not be compressed on a volume that performs file compression. If the volume does not perform file compression, this flag is ignored. This flag is valid only on file creation and is ignored on file open.
OPEN_FLAGS_ALIAS_HINT (0400h)
The number in the DI register is to be used as the numeric tail for the alias (short filename). For more information, see AliasHint below.
OPEN_FLAGS_NOCRITERR (2000h)
If a critical error occurs while MS-DOS is opening this file, Critical-Error Handler (Interrupt 24h) is not called. Instead, MS-DOS simply returns an error value to the program.
OPEN_FLAGS_COMMIT (4000h)
After each write operation, MS-DOS commits the file (flushes the contents of the cache buffer to disk).

Attributes
Attributes for files that are created or truncated. This parameter may be a combination of these values:
_A_NORMAL (0000h)
The file can be read from or written to. This value is valid only if used alone.
_A_RDONLY (0001h)
The file can be read from, but not written to.
_A_HIDDEN (0002h)
The file is hidden and does not appear in an ordinary directory listing.
_A_SYSTEM (0004h)
The file is part of the operating system or is used exclusively by it.
_A_VOLID (0008h)
The name specified by Filename is used as the volume label for the current medium and is restricted to the standard 8.3 format. For information about an alternative way to set the volume label, see Set Media ID (Interrupt 21h Function 440Dh Minor Code 46h) in the Microsoft MS-DOS Programmer's Reference.
_A_ARCH (0020h)
The file is an archive file. Applications use this value to mark files for backup or removal.
Action
Action to take it the file exists or if it does not exist. This parameter can be a combination of these values:
FILE_CREATE (0010h) | Creates a new file if it does not already exist. The function fails if the file already exists.
FILE_OPEN (0001h) | Opens the file. The function fails if the file does not exist.
FILE_TRUNCATE (0002h) | Opens the file and truncates it to zero length (replaces the existing file). The function fails if the file does not exist.

The only valid combinations are FILE_CREATE combined with FILE_OPEN or FILE_CREATE combined with FILE_TRUNCATE.

Filename
Address of a null-terminated string specifying the name of the file to be opened or created. The string must be a valid path for the volume associated with the given drive. Long filenames are allowed.
AliasHint
Number that is used in the numeric tail for the alias (short filename). A numeric tail, which consists of the tilde character (~) followed a number, is appended to the end of a filename. The system constructs the alias from the first few characters of the long filename followed by the numeric tail. The system starts with the number 1 in the numeric tail. If that filename is in use, it uses the number 2. It continues in this fashion until a unique name is found. To override the default numbering scheme, you must specify the OPEN_FLAGS_ALIAS_HINT value when you create the file in addition to specifying this parameter. If a filename already exists with the specified numeric tail, the system uses the default numbering scheme. You should specify a number for this parameter, not the tilde character.

Return Value

Clears carry flag, copies the file handle to the AX register, and sets the CX register to one of the following values if successful:

ACTION_OPENED (0001h)
ACTION_CREATED_OPENED (0002h)
ACTION_REPLACED_OPENED (0003h)

Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

A file on a remote directory — that is, a directory on the network — cannot be opened, created, or modified, unless the appropriate permissions for the directory exist.


Interrupt 21h Function 71A0h

Returns information about the volume associated with the given root directory.

mov ax, 71A0h          ; Get Volume Information
mov di, seg Buffer     ; see below
mov es, di
mov di, offset Buffer
mov cx, BufSize        ; see below
mov dx, seg RootName   ; see below
mov ds, dx
mov dx, offset RootName
int 21h

jc  error
mov [Flags], bx        ; file system flags
mov [MaxFilename], cx  ; max. filename length, excluding null
mov [MaxPath], dx      ; max. path length, including null

Parameters

Buffer
Address of a buffer that receives a null-terminated string specifying the name of the file system.
BufSize
Size, in bytes, of the buffer that receives the name. The buffer should include space for the terminating null character.
RootName
Address of a null-terminated string specifying the name of the root directory of the volume to check. This parameter must not be NULL, or the function will fail. The format for this parameter is "C:\".

Return Value

Clears the carry flag, copies the file system name to the buffer given by the ES:DI register pair, and sets the BX, CX, and DX registers to the following values if successful:

BX File system flags, which can be a combination of these values:

FS_CASE_SENSITIVE (0001h)
Specifies that searches are case-sensitive.
FS_CASE_IS_PRESERVED (0002h)
Preserves case in directory entries.
FS_UNICODE_ON_DISK (0004h)
Uses Unicode characters in file and directory names.
FS_LFN_APIS (4000h)
Supports new long filename functions.
FS_VOLUME_COMPRESSED (8000h)
Specifies that the volume is compressed.

CX Maximum allowed length, excluding the terminating null character, of a filename for this volume. For example, on the protected-mode FAT file system, this value is 255.

DX Maximum allowed length of a path for this volume, including the drive letter, colon, leading slash, and terminating null character. For example, on the protected-mode FAT file system, this value is 260.

Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

This function accesses the disk the first time it is called, but subsequent calls do not access the disk.


Interrupt 21h Function 71A1h

Closes the file search identified by the search handle.

mov ax, 71A1h   ; Find Close
mov bx, Handle  ; see below
int 21h

jc  error

Parameters

Handle
Search handle. It must have been previously returned from Find First File (Interrupt 21h Function 714Eh).

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

Unlike MS-DOS Find First File (Interrupt 21h Function 4Eh), the long filename version of Find First File (Interrupt 21h Function 714Eh) allocates internal storage for the search operations and returns a handle that identifies the storage. This handle is used with Find Next File. To make sure this internal storage is freed, you must call Find Close to end the search.


Interrupt 21h Function 71A6h

Retrieves information about the specified file.

mov ax, 71a6h              ; Get File Info By Handle
mov bx, Handle             ; see below
mov dx, seg lpFileInfo     ; see below
mov ds, dx
mov dx, offset lpFileInfo
stc                        ; must set carry flag
int 21h

jnc success
cmp ax, 7100h
je not_supported

Parameters

Handle
File handle to retrieve information about.
lpFileInfo
Address of a BY_HANDLE_FILE_INFORMATION structure that receives the file information. The structure can be used in subsequent calls to Get File Info By Handle to refer to the information about the file.

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

Note that it is important to explicitly set the carry flag before calling this function.


Interrupt 21h Function 71A7h Minor Code 0h

Converts a 64-bit file time to MS-DOS date and time values.

mov ax, 71A7h           ; date and time format conversion
mov bl, 0               ; File Time To DOS Time
mov si, seg lpft        ; see below
mov ds, si
mov si, offset lpft
int 21h

jc  error
mov [DOSTime], cx
mov [DOSDate], dx
mov [MilliSeconds], bh  ; number of 10ms intervals in 2 seconds

Parameters

lpft
Address of a FILETIME structure containing the 64-bit file time to convert to the MS-DOS date and time format.

Return Value

Clears the carry flag, and sets the BH, CX, and DX registers to these values if successful:

BH | Number of 10 millisecond intervals in 2 seconds to add to the MS-DOS time. It can be a value in the range 0 to 199.
CX | MS-DOS time. The time is a packed 16-bit value with the following form:

Bits | Contents
0–4 | Second divided by 2
5–10 | Minute (0–59)
11–15 | Hour (0–23 on a 24-hour clock)

DX MS-DOS date. The date is a packed 16-bit value with the following form:

Bits | Contents
0–4 | Day of the month (1–31)
5–8 | Month (1 = January, 2 = February, and so on)
9–15 | Year offset from 1980 (that is, add 1980 to get the actual year)

Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

The MS-DOS date format can represent only dates between 1/1/1980 and 12/31/2107; this conversion fails if the input file time is outside this range.

The time in FILETIME must be Coordinated Universal Time (UTC). The MS-DOS time is local time.


Interrupt 21h Function 71A7h Minor Code 1h

Converts MS-DOS date and time values to 64-bit file time.

mov ax, 71A7h         ; date and time format conversion
mov bl, 1             ; Dos Time To File Time
mov bh, MilliSeconds  ; see below
mov cx, DOSTime       ; see below
mov dx, DOSDate       ; see below
mov di, seg lpft      ; see below
mov es, di
mov di, offset lpft
int 21h

jc  error

Parameters

MilliSeconds
Number of 10 millisecond intervals in 2 seconds to add to the MS-DOS time. The number can be a value in the range 0 to 199.
DOSTime
MS-DOS time to convert. The time is a packed 16-bit value with the following form:
Bits | Contents
0–4 | Second divided by 2
5–10 | Minute (0–59)
11–15 | Hour (0–23 on a 24-hour clock)

DOSDate
MS-DOS date to convert. The date is a packed 16-bit value with the following form:
Bits | Contents
0–4 | Day of the month (1–31)
5–8 | Month (1 = January, 2 = February, and so on)
9–15 | Year offset from 1980 (that is, add 1980 to get the actual year)

lpft
Address of a FILETIME structure to receive the converted 64-bit file time.

Return Value

Clears the carry flag and returns the 64-bit file time in the specified structure if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

The time in FILETIME must be Coordinated Universal Time (UTC). The MS-DOS time is local time.


Interrupt 21h Function 71A8h

Generates an alias (a filename in the 8.3 format) for the specified long filename.

mov ax, 71a8h               ; generate short name
mov si, seg LongFilename    ; see below
mov ds, si
mov si, offset LongFilename
mov di, seg ShortFilename   ; see below
mov es, di
mov di, offset ShortFilename
mov dh, ShortNameFormat     ; see below
mov dl, CharSet             ; see below
int 21h

Parameters

LongFilename
Address of null-terminated string that names the long filename to generate an alias for. This string must contain only a filename, not a path.
ShortFilename
Address of null-terminated string that receives the generated alias.
ShortNameFormat
Format for the returned alias (0 is specified for an 11 character directory entry format or 1 for an 8.3 format).
CharSet
Character set of both the long filename and alias. This parameter is a packed 8-bit value with the following form:
Bits | Contents
0–3 | Specifies the character set of the source long filename.
4–7 | Specifies the character set of the destination alias.

One of the following values is specified to indicate the character set for the long filename and alias:
BCS_WANSI (0) | Windows ANSI character set
BCS_OEM (1) | Current OEM character set
BCS_UNICODE (2) | Unicode character set

Return Value

Returns the generated alias in the specified buffer if successful.

Remarks

This function generates the alias using the same algorithm that the system uses with the exception that the returned alias will never have a numeric tail. A numeric tail is appended to the end of an alias and consists of the tilde character (~) followed a number. When the system generates an alias, it may attach a numeric tail if the default alias already exists in the current directory. Because this function does not check the current directory to see if the alias already exists, the returned alias will never have a numeric tail. This service is useful for disk utilities that are trying to establish whether the alias, which seems to be associated with a long filename, is correctly associated.


Interrupt 21h Function 71A9h

Creates or opens a file. This function is for use by real-mode servers only. It takes the same parameters as Create or Open File (Interrupt 21h Function 716Ch) and returns a global file handle.


Interrupt 21h Function 71AAh Minor Code 0h

Associates a path with a drive letter.

mov ax, 71aah            ; SUBST
mov bh, 0                ; Create Subst
mov bl, DriveNum         ; see below
mov dx, seg PathName     ; see below
mov ds, dx
mov dx, offset PathName
int 21h

jc error

Parameters

DriveNum
Drive to SUBST. This parameter can be 0 for the default drive, 1 for A, 2 for B, and so on.
PathName
Address of path to associate the drive with.

Return Value

Clears the carry flag if successful. Otherwise the function sets the carry flag and returns an error value in the AX register


Interrupt 21h Function 71AAh Minor Code 1h

Terminate the association between a path and a drive letter.

mov ax, 71aah            ; SUBST
mov bh, 1                ; Terminate Subst
mov bl, DriveNum         ; see below
int 21h

jc error

Parameters

DriveNum
Drive to terminate SUBST. This parameter can 1 for A, 2 for B, and so on. Note that DriveNum cannot be 0 to indicate the default drive.

Return Value

Clears the carry flag if successful. Otherwise, the function sets the carry flag and returns an error value in the AX register.


Interrupt 21h Function 71AAh Minor Code 2h

Determines if the specified drive is associated with a path and, if it is, retrieves the associated path.

mov ax, 71aah            ; SUBST
mov bh, 2                ; Query SUBST
mov bl, DriveNum         ; see below
mov dx, seg PathName     ; see below
mov ds, dx
mov dx, offset PathName
int 21h

jc error

Parameters

DriveNum
Drive to SUBST. This parameter can 1 for A, 2 for B, and so on. Note that DriveNum cannot be 0 to indicate the default drive.
PathName
Address of buffer that receives the null-terminated string of the path associated with the specified drive. The buffer must be of MAXPATHLEN size.

Return Value

Clears the carry flag and retrieves the associated path in the specified buffer if successful. Otherwise, the function sets the carry flag and returns an error value in the AX register.


Query Close

Indicates whether the user has attempted to close an MS-DOS – based application from Windows by choosing the Close command from the system menu.

mov ah, 16h   ; Windows multiplex function
mov al, 8Fh   ; VM Close
mov dh, 1     ; Query Close
mov dl, 0     ; always 0
int 2Fh

Return Value

Returns one of the following values in the AX register:

0 | The close command was chosen, and the application has not acknowledged the close state.
1 | The close command was chosen, and the application has acknowledged the close state.
168Fh | The close command has not been chosen, and the application should continue running.

Remarks

Query Close returns a nonzero value if the application has not enabled the Close command by using the Enable or Disable Close Command function.


RegisterServiceProcess

The RegisterServiceProcess function registers or unregisters a service process. A service process continues to run after the user logs off.

To call RegisterServiceProcess, retrieve a function pointer using GetProcAddress on KERNEL32.DLL. Use the function pointer to call RegisterServiceProcess.

DWORD RegisterServiceProcess(
  DWORD dwProcessId,
  DWORD dwType
);

Parameters

dwProcessId
Specifies the identifier of the process to register as a service process. Specifies NULL to register the current process.
dwType
Specifies whether the service is to be registered or unregistered. This parameter can be one of the following values.
Value | Meaning
0 | Unregisters the process as a service process.
1 | Registers the process as a service process.

Return Value

The return value is 1 if successful or 0 if an error occurs.


Set Application Title

Sets the application title to the given string.

mov  ah, 16h           ; Windows multiplex function
mov  al, 8Eh           ; VM Title
mov  di, seg AppTitle  ; see below
mov  es, di
mov  di, offset AppTitle
mov  dx, 0             ; Set Application Title
int  2Fh
cmp   ax, 1
je   success

Parameters

AppTitle
Address of a null-terminated string specifying the application title. The title must not exceed 80 characters, including the terminating null character. If this parameter is zero or points to an empty string, the function removes the current application title.

Return Value

Returns 1 in the AX register if successful or zero otherwise.

Remarks

Although not common, Set Application Title may return 1 in the AX register even though the title was not changed. In general, applications must not rely on the operating system to keep an accurate copy of the current title.


Set Virtual Machine Title

Sets the virtual machine title to the given string. Applications should not change the virtual machine title except under explicit instructions from the user.

mov  ah, 16h           ; Windows multiplex function
mov  al, 8Eh           ; VM Title
mov  di, seg VMTitle   ; see below
mov  es, di
mov  di, offset VMTitle
mov  dx, 1             ; Set Virtual Machine Title
int  2Fh
cmp   ax, 1
je   success

Parameters

VMTitle
Address of a null-terminated string specifying the virtual machine title. The title must not exceed 30 characters, including the terminating null character. If this parameter is zero or points to an empty string, the function removes the current virtual machine title.

Return Value

Returns 1 in the AX register if successful or zero otherwise.

Remarks

Although not common, Set Virtual Machine Title may return 1 in the AX register even though the title was not changed. In general, applications must not rely on the operating system to keep an accurate copy of the current title.


DIOC_REGISTERS

Contains the register values for calling Interrupt 21h commands through the DeviceIoControl function. The meaning of the registers depends on the given command.

typedef struct DIOCRegs {
    DWORD   reg_EBX;
    DWORD   reg_EDX;
    DWORD   reg_ECX;
    DWORD   reg_EAX;
    DWORD   reg_EDI;
    DWORD   reg_ESI;
    DWORD   reg_Flags;
} DIOC_REGISTERS;

Members

reg_EBX
EBX register.
reg_EDX
EDX register.
reg_ECX
ECX register.
reg_EAX
EAX register
reg_EDI
EDI register.
reg_ESI
ESI register.
reg_Flags
Flags register.

Remarks

Some interrupt functions require far pointers passed in segment:offset pairs where the segment is placed in a segment register. Since the 32-bit code does not have segments, the DIOC_REGISTERS structure contains no segment registers. You should place the full pointer into the structure member that corresponds to the register used to hold the offset portion of the real-mode pointer. For example, use reg_EDX for pointers that go into the DS:DX registers.


DIOCParams

Contains information that an application has passed to the virtual device driver (VxD) by calling the DeviceIoControl function.

include vwin32.inc

DIOCParams STRUC
    Internal1             DD  ?
    VMHandle              DD  ?
    Internal2             DD  ?
    dwIoControlCode       DD  ?
    lpvInBuffer           DD  ?
    cbInBuffer            DD  ?
    lpvOutBuffer          DD  ?
    cbOutBuffer           DD  ?
    lpcbBytesReturned     DD  ?
    lpoOverlapped         DD  ?
    hDevice               DD  ?
    tagProcess            DD  ?
DIOCParams ENDS

Members

Internal1
Reserved.
VMHandle
Handle of virtual machine.
Internal2
Reserved.
dwIoControlCode
Control code to process. This member can be a developer-defined value or one of these system-defined values:
DIOC_CLOSEHANDLE | Notifies a VxD that an application has closed its device handle for the VxD. The VxD should perform cleanup operations and release any structures associated with the application.
DIOC_GETVERSION | Queries the VxD to determine if it supports the device IOCTL interface. If the VxD supports the interface, it must clear the EAX register. Otherwise, it must place a nonzero value in EAX. If cbOutBuffer is nonzero and the VxD supports the interface, the VxD should copy version information to the lpvOutBuffer.

lpvInBuffer
Address of a buffer that contains data needed to process the control code.
cbInBuffer
Size, in bytes, of the buffer pointed to by lpvInBuffer.
lpvOutBuffer
Address of a buffer that receives the results of processing the control code.
cbOutBuffer
Size, in bytes, of the buffer pointed to by lpvOutBuffer.
lpcbBytesReturned
Number of bytes copied to the buffer pointed to by lpvOutBuffer.
lpoOverlapped
Address of an OVERLAPPED structure that contains information used to complete the command asynchronously. If the command is to be completed synchronously, this member is NULL.
hDevice
Handle of device.
tagProcess
Information that the VxD can use to tag the current request along with hDevice. When the VxD receives a DIOC_CLOSEHANDLE control code for hDevice and tagProcess, it should perform appropriate cleanup operations.


DRIVE_MAP_INFO

Contains information about the drive specified in the call to Get Drive Map Info (Interrupt 2lh Function 440Dh Minor Code 6Fh).

DRIVE_MAP_INFO    struc
    dmiAllocationLength   db ?
    dmiInfoLength         db ?
    dmiFlags              db ?
    dmiInt13Unit          db ?
    dmiAssociatedDriveMap dd ?
    dmiPartitionStartRBA  dq ?
DRIVE_MAP_INFO    ends

Members

dmiAllocationLength
Length of the buffer provided by the application calling Get Drive Map Info. This value should be the size of the DRIVE_MAP_INFO structure.
dmiInfoLength
Number of bytes that Get Drive Map Info used in the buffer provided by the calling application. Typically, this value is the size of the DRIVE_MAP_INFO structure.
dmiFlags
Flags describing the given drive. This member, which is filled by Get Drive Map Info, can be a combination of these values:
PROT_MODE_LOGICAL_DRIVE (01h) | A protected-mode driver is in use for this logical drive.
PROT_MODE_PHYSICAL_DRIVE (02h) | A protected-mode driver is in use for the physical drive corresponding to this logical drive.
PROT_MODE_ONLY_DRIVE (04h) | The drive is not available when running with MS-DOS.
PROT_MODE_EJECT (08h) | A protected-mode drive supports an electronic eject operation.
PROT_MODE_ASYNC_NOTIFY (10h) | The drive issues media arrival and removal notifications. This value is currently used for CD-ROM drives that are controlled by the protected-mode driver and that cause a broadcast message when media is removed or inserted without the application having to make a request to the drive. It can also be used by disk drivers.

dmiInt13Unit
Physical drive number of the given drive. This member, which is filled by Get Drive Map Info, can be one of these values:
00 - 7Fh | Floppy disk drive (00 for the first floppy drive, 01 for the second, and so on).
80 - FEh | Hard disk drive (80 for the first hard disk drive, 81 for the second, and so on).
FFh | The given drive does not map to a physical drive.

dmiAssociatedDriveMap
Logical drive numbers that are associated with the given physical drive. For example, a host drive C with child drive letters A and B would return with bits 0 and 1 set.
dmiPartitionStartRBA
Relative block address offset from the start of the physical volume to the start of the given partition.

Remarks

Before an application makes a call to Get Drive Map Info, the dmiAllocationLength member must be set to the size of the DRIVE_MAP_INFO structure. All other members of the structure are filled in by Get Drive Map Info.


MID

Contains information that uniquely identifies a disk or other storage medium.

MID struc
    midInfoLevel   dw 0
    midSerialNum   dd ?
    midVolLabel    db 11 dup (?)
    midFileSysType db 8 dup (?)
MID ends

Members

midInfoLevel
Information level. This member must be zero.
midSerialNum
Serial number for the medium.
midVolLabel
Volume label for the medium. If the label has fewer than 11 characters, space characters (ASCII 20h) fill the remaining bytes in this member.
midFileSysType
Type of file system as an 8-byte ASCII string. This member can be one of these values:
FAT12 | 12-bit file allocation table (FAT)
FAT16 | 16-bit FAT
CDROM | High Sierra file system
CD001 | ISO9660 file system
CDAUDIO | Audio disk

If the name has fewer than eight characters, space characters (ASCII 20h) fill the remaining bytes in this member.


PARAMBLOCK

Contains information about locked drives.

PARAMBLOCK struc
    Operation db ?
    NumLocks  db ?
PARAMBLOCK ends

Members

Operation
Operation to carry out provided by the calling application of Lock/Unlock Removable Media (Interrupt 21h Function 440Dh Minor Code 48h). This member can be one of these values:
0 | Locks the volume in the drive.
1 | Unlocks the volume in the drive.
2 | Returns the lock or unlock status.

All other values are reserved.

NumLocks
Number of locks pending on the given drive filled in by Lock/Unlock Removable Media.


VWIN32_DIOCCompletionRoutine

Notifies the system that an asynchronous operation in a virtual device driver is complete. The VxD calls this service after the asynchronous input and output (I/O) operation to signal the application.

mov ebx, Internal  ; see below
VxDCall VWIN32_DIOCCompletionRoutine

Parameters

Internal
Event identifier. This parameter must be the same value initially passed to the VxD in the Internal member of the OVERLAPPED structure.

Return Value

No return value.

Remarks

Before calling this service, the VxD must set the InternalHigh member of the OVERLAPPED structure to the number of bytes of return data.


W32_DEVICEIOCONTROL

Passes a control code and related information to a virtual device driver.

include VMM.INC

mov ebx, VMHandle
mov eax, W32_DEVICEIOCONTROL
mov esi, OFFSET32 dioparams
VMMCall System_Control

Parameters

VMHandle
Handle of the virtual machine.
dioparams
Address of a DIOCParams structure containing a control code and information that the VxD needs to process the control code.

Return Value

Returns one of the following values in the EAX register:

0 | The control code processed successfully.
– 1 | An asynchronous operation is in progress. A VxD must return this value only if the lpoOverlapped member of the DIOCParams structure is not NULL.
Error code | An error occurred.

Remarks

This message is sent to a VxD when an application specifies the name of a VxD in the CreateFile function and when an application specifies the device handle of the VxD in a call to the DeviceIoControl or CloseHandle function. This message uses the ESI register.


Int 21h Function 440Dh Minor Code 40h (FAT32)

[Windows 95 only.]

Sets the device parameters for the specified block device.

mov  bx, Drive           ;See below
mov  ch, DeviceCat       ;See below
mov  cl, 40h             ;Set device parameters
mov  dx, seg DriveDP     ;See below
mov  ds, dx
mov  dx, offset DriveDP  ;ds:dx points to a device parameters structure
mov  ax, 440Dh           ;IOCTL for block device
int  21h

jc  error_handler       ;carry set means error

Parameters

Drive
Specifies the drive that parameters are being set for (0 = default drive, 1 = A, 2 = B, and so on).
DeviceCat
Specifies the expected format of the device parameters information structure.
Value | Expected device parameters structure
08h | DEVICEPARAMS (FAT16 or FAT12 drive. Will fail on FAT32 drives.)
48h | EA_DEVICEPARAMETERS (FAT32) (FAT32, FAT16 or FAT12 drives). This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

DriveDP
Points to the applicable device parameters structure that contains the parameters for the specified block device. The format of the expected device parameters is indicated in the above DeviceCat field.

Return Values

If the function is successful, clears the carry flag. Otherwise, sets the carry flag and sets the AX register to one of the following error values.

Value | Name
0001h | ERROR_INVALID_FUNCTION
0002h | ERROR_FILE_NOT_FOUND
0005h | ERROR_ACCESS_DENIED

Remarks

Set Device Parameters returns 0002h (ERROR_FILE_NOT_FOUND) if the specified drive number is invalid.

If the number of sectors specified in the applicable device parameters structure is not zero, a TRACKLAYOUT structure specifying the size of each sector must follow the device parameters structure.

In the case of a FAT16 or FAT12 drive, the device parameters structure is a DEVICEPARAMS structure. For FAT32 drives, the device parameters structure is an EA_DEVICEPARAMETERS (FAT32) structure.


Int 21h Function 440Dh Minor Code 41h (FAT32)

[Windows 95 only.]

Writes data from a buffer to a track on the specified device.

mov     bx, Drive               ;See below
mov     ch, DeviceCat           ;See below
mov     cl, 41h                 ;Write Track on Logical Drive
mov     dx, seg WriteBlock      ;See below
mov     ds, dx
mov     dx, offset WriteBlock   ;ds:dx points to RWBLOCK structure
mov     ax, 440Dh               ;IOCTL for block device
int     21h

jc      error_handler           ;carry set means error

Parameters

Drive
Specifies the drive information is to be written to (0 = default drive, 1 = A, 2 = B, and so on).
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
Value | Description
08h | FAT16 or FAT12 drive. (Will fail on FAT32 drives.)
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

WriteBlock
Points to an RWBLOCK structure that contains information specifying the sectors to be written to. The rwBuffer field must contain the address of the buffer that contains the data to write to the disk. The RWBLOCK structure has the following form:
RWBLOCK STRUC
    rwSpecFunc      db  0  ;special functions (must be zero)
    rwHead          dw  ?  ;head to read/write
    rwCylinder      dw  ?  ;cylinder to read/write
    rwFirstSector   dw  ?  ;first sector to read/write
    rwSectors       dw  ?  ;number of sectors to read/write
    rwBuffer        dd  ?  ;address of buffer for read/write data
RWBLOCK ENDS

Return Values

If the function is successful, clears the carry flag. Otherwise, sets the carry flag and sets the AX register to one of the following error values.

Value | Name
0001h | ERROR_INVALID_FUNCTION
0002h | ERROR_FILE_NOT_FOUND
0005h | ERROR_ACCESS_DENIED

Remarks

Write Track on Logical Drive returns 0002h (ERROR_FILE_NOT_FOUND) if the specified drive number is invalid.


Int 21h Function 440Dh Minor Code 42h (FAT32)

[Windows 95 only.]

Formats and verifies a track on the specified device.

mov     bx, Drive                 ;See below
mov     ch, DeviceCat             ;See below
mov     cl, 42h                   ;Format track on logical drive
mov     dx, seg FormatBlock       ;See below
mov     ds, dx
mov     dx, offset FormatBlock    ;ds:dx points to FVBLOCK structure
mov     ax, 440Dh                 ;IOCTL for block device
int     21h

jc      error_handler             ;carry set means error

Parameters

Drive
Specifies the drive on which the track is to be formatted and verified (0 = default drive, 1 = A, 2 = B, and so on).
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
Value | Description
08h | FAT16 or FAT12 drive. (Will fail on FAT32 drives.)
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

FormatBlock
Points to an FVBLOCK structure that specifies the head and cylinder to format. The FVBLOCK structure has the following form:
FVBLOCK STRUC
    fvSpecFunc    db  0   ;special functions
    fvHead        dw  ?   ;head to format/verify
    fvCylinder    dw  ?   ;cylinder to format/verify
    fvTracks      dw  ?   ;tracks to format/verify
FVBLOCK ENDS

The fvSpecFunc field can be 0, 1, or 2. The fvTracks field is ignored.

Return Values

If the fvSpecFunc field in the FVBLOCK structure is 1, clears the carry flag and sets the fvSpecFunc field to one of the following values.

Value | Meaning
0 | ROM support for given format combination
1 | No ROM support
2 | Illegal format combination
3 | No media present

If the fvSpecFunc field is 0 and the function is successful, clears the carry flag. Otherwise, sets the carry flag and sets the AX register to one of the following error values.

Value | Name
0001h | ERROR_INVALID_FUNCTION
0002h | ERROR_FILE_NOT_FOUND
0005h | ERROR_ACCESS_DENIED

Format Track on Logical Drive returns 0002h (ERROR_FILE_NOT_FOUND) if the specified drive number is invalid.


Int 21h Function 440Dh Minor Code 46h (FAT32)

[Windows 95 only.]

Sets sets the volume label, serial number, and file system for the specified drive.

mov     bx, Drive               ;See below
mov     ch, DeviceCat           ;See below
mov     cl, 46h                 ;Set Media ID
mov     dx, seg MediaID         ;See below
mov     ds, dx
mov     dx, offset MediaID      ;ds:dx points to MID structure
mov     ax, 440Dh               ;IOCTL for block device
int     21h

jc      error_handler           ;carry set means error

Parameters

Drive
Specifies the drive for which identification is to be set (0 = default drive, 1 = A, 2 = B, and so on).
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
Value | Description
08h | FAT16 or FAT12 drive. (Will fail on FAT32 drives.)
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

MediaID
Points to a MID structure that contains information that uniquely identifies a disk or other storage medium. The MID structure has the following form:
MID STRUC
    midInfoLevel   dw  0           ;information level
    midSerialNum   dd  ?           ;serial number
    midVolLabel    db  11 dup (?)  ;ASCII volume label
    midFileSysType db  8 dup (?)   ;file system type
MID ENDS

Return Values

If the function is successful, clears the carry flag. Otherwise, sets the carry flag and sets the AX register to one of the following error values.

Value | Name
0001h | ERROR_INVALID_FUNCTION
0002h | ERROR_FILE_NOT_FOUND
0005h | ERROR_ACCESS_DENIED

Remarks

Set Media ID returns 0002h (ERROR_FILE_NOT_FOUND) if the specified drive number is invalid.


Int 21h Function 440Dh Minor Code 47h (FAT32)

[Windows 95 only.]

Sets the access flag for the specified drive.

mov     bx, Drive               ;See below
mov     ch, DeviceCat           ;See below
mov     cl, 47h                 ;Set access flag
mov     dx, seg SpecialFunc     ;See below
mov     ds, dx
mov     dx, offset SpecialFunc  ;ds:dx points to SPECIALFUNC structure
mov     ax, 440Dh               ;IOCTL for block device
int     21h

jc      error_handler           ;carry set means error

Parameters

Drive
Specifies the drive for which the access flag is to be set (0 = default drive, 1 = A, 2 = B, and so on).
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
Value | Description
08h | FAT16 or FAT12 drive. (Will fail on FAT32 drives.)
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

SpecialFunc
Points to a SPECIALFUNC structure that contains information specifying the state of the access flag. The SPECIALFUNC structure has the following form:
SPECIALFUNC STRUC
    sfFunction  db  0   ;special function (must be 0)
    sfAccessFlg db  ?   ;access flag, 0 if access blocked
                        ;"unformatted"
SPECIALFUNC ENDS

Return Values

If the function is successful, clears the carry flag. Otherwise sets the carry flag, and sets the AX register to one of the following error values.

Value | Name
0001h | ERROR_INVALID_FUNCTION
0002h | ERROR_FILE_NOT_FOUND
0005h | ERROR_ACCESS_DENIED

Remarks

Set Access Flag returns 0002h (ERROR_FILE_NOT_FOUND) if the specified drive number is invalid.


Int 21h Function 440Dh Minor Code 48h (FAT32)

[Windows 95 only.]

Locks or unlocks the volume in the given drive (preventing or permitting its removal) or returns the locked status of the given drive.

mov ax, 440Dh           ; Generic IOCTL
mov bx, DriveNum        ; See below
mov ch, DeviceCat       ; See below
mov cl, 48h             ; Lock or unlock removable media
mov dx, seg ParamBlock  ; See below
mov ds, dx
mov dx, offset ParamBlock
int 21h

jc  error_handler       ; Carry set means error

Parameters

DriveNum
Drive to lock or unlock (0 = default drive, 1 = A, 2 = B, and so on).
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
Value | Description
08h | FAT32, FAT16, or FAT12 drive.
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

ParamBlock
Address of a PARAMBLOCK structure that specifies the operation to carry out and receives a count of the number of locks on the drive.

Return Values

If the function is successful, clears the carry flag and copies the number of pending locks on the given drive to the NumLocks member of the PARAMBLOCK structure. Otherwise, sets the carry flag and sets the AX register to one of the following error values.

Value | Description
01h | The function is not supported.
B0h | The volume is not locked in the drive.
B2h | The volume is not removable.
B4h | The lock count has been exceeded.


Int 21h Function 440Dh Minor Code 49h (FAT32)

[Windows 95 only.]

Ejects the specified media.

mov ax, 440Dh      ; Generic IOCTL
mov bx, DriveNum   ; See below
mov ch, DeviceCat  ; See below
mov cl,            ; Eject Removable Media
int 21h

jc  error_handler  ; Carry set means error

Parameters

DriveNum
Drive to eject (0 = default drive, 1 = A, 2 = B, and so on).
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
Value | Description
08h | FAT16 or FAT12 drive
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

Return Values

If the function is successful, clears the carry flag. Otherwise, sets the carry flag and sets the AX register to one of the following error values.

01h | The function is not supported.
B1h | The volume is locked in the drive.
B2h | The volume is not removable.
B5h | The valid eject request has failed.

Remarks

If a given physical drive has more than one logical volume, all volumes must be unlocked by using Int 21h Function 440Dh Minor Code 48h (FAT32) before the drive will eject.


Int 21h Function 440Dh Minor Code 4Ah (FAT32)

[Windows 95 only.]

Locks the logical volume.

mov ax, 440Dh        ; generic IOCTL
mov bh, LockLevel    ; see below
mov bl, DriveNum     ; see below
mov ch, DeviceCat    ; see below
mov cl, 4Ah          ; Lock Logical Volume
mov dx, Permissions  ; see below
int 21h

jc error_handler

Parameters

LockLevel
Level of the lock. This parameter must be either 0, 1, 2, or 3.
DriveNum
Drive to lock. This parameter can be 0 for the default drive, 1 for A, 2 for B, and so on.
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
Value | Description
08h | FAT32, FAT16, or FAT12 drive.
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

Permissions
Operations that the system permits while the volume is locked. This parameter is specified only when a level 1 lock is obtained or when a level 0 lock is obtained for the second time for formatting the volume. For other lock levels, this parameter is zero. When a level 1 lock is obtained, bits 0 and 1 of this parameter specify whether the system permits write operations, new file mappings, or both by other processes during a level 1 lock as well as during level 2 and 3 locks. If this parameter specifies that write operations, new file mappings, or both are failed, these operations are failed during level 1, 2, and 3 locks. This parameter has the following form:
Bit | Meaning
0 | 0 = Write operations are failed (specified when a level 1 lock is obtained).
0 | 1 = Write operations are allowed (specified when a level 1 lock is obtained).
1 | 0 = New file mapping are allowed (specified when a level 1 lock is obtained).
1 | 1 = New file mapping are failed (specified when a level 1 lock is obtained).
2 | 1 = The volume is locked for formatting (specified when a level 0 lock is obtained for the second time).

Return Values

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

The volume must be locked before the application performs direct disk write operations by using Interrupt 26h or the IOCTL control functions. Lock Physical Volume (Interrupt 21h Function 440Dh Minor Code 4Bh (FAT32)) is used instead of this function before a call to an Interrupt 13h function. You must use Unlock Logical Volume (Interrupt 21h Function 440Dh Minor Code 6Ah (FAT32)) to release the lock.


Int 21h Function 440Dh Minor Code 4Bh (FAT32)

[Windows 95 only.]

Locks the physical volume.

mov ax, 440Dh        ; generic IOCTL
mov bh, LockLevel    ; see below
mov bl, DriveNum     ; see below
mov ch, DeviceCat    ; see below
mov cl, 4Bh          ; Lock Physical Volume
mov dx, Permissions  ; see below
int 21h

jc error_handler

Parameters

LockLevel
Level of the lock. This parameter must be either 0, 1, 2, or 3.
DriveNum
Drive to lock. This parameter must be one of the following values (same device unit numbers as for Interrupt 13h):
00 - 7Fh | Floppy disk drive (00 for the first floppy drive, 01 for the second, and so on).
80 - FFh | Hard disk drive (80 for the first hard disk drive, 81 for the second, and so on).

DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
Value | Description
08h | FAT32, FAT16, or FAT12 drive.
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

Permissions
Operations that the system permits while the volume is locked. This parameter is specified only when a level 1 lock is obtained or when a level 0 lock is obtained for the second time for formatting the volume. For other lock levels, this parameter is zero. When a level 1 lock is obtained, bits 0 and 1 of this parameter specify whether the system permits write operations, new file mappings, or both by other processes during a level 1 lock as well as during level 2 and 3 locks. If this parameter specifies that write operations, new file mappings, or both are failed, these operations are failed during level 1, 2, and 3 locks. This parameter has the following form:
Bit | Meaning
0 | 0 = Write operations are failed (specified when a level 1 lock is obtained).
0 | 1 = Write operations are allowed (specified when a level 1 lock is obtained).
1 | 0 = New file mapping are allowed (specified when a level 1 lock is obtained).
1 | 1 = New file mapping are failed (specified when a level 1 lock is obtained).
2 | 1 = The volume is locked for formatting (specified when a level 0 lock is obtained for the second time).

Return Values

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

The volume must be locked before the application performs direct disk write operations by using Interrupt 13h, Interrupt 26h, or the Interrupt 21h IOCTL functions. A single physical volume may be divided into more than one logical volume, which is also called a partition. The system automatically takes a logical volume lock on all logical volumes on the specified physical drive. If the application performs disk writes only to a logical drive, Lock Logical Volume (Interrupt 21h Function 440Dh Minor Code 4Ah (FAT32)) is used instead of this function. Unlock Physical Volume (Interrupt 21h Function 440Dh Minor Code 6Bh (FAT32)) should be called to release the lock.


Int 21h Function 440Dh Minor Code 60h (FAT32)

[Windows 95 only.]

Returns the device parameters for the specified block device.

mov  bx, Drive           ;See below
mov  ch, DeviceCat       ;See below
mov  cl, 60h             ;Get device parameters
mov  dx, seg DriveDP     ;See below
mov  ds, dx
mov  dx, offset DriveDP  ;ds:dx points to a device parameters structure
mov  ax, 440Dh           ;IOCTL for block device
int  21h

jc   error_handler       ;carry set means error

Parameters

Drive
Specifies the drive for which parameters are requested (0 = default drive, 1 = A, 2 = B, and so on).
DeviceCat
Specifies the expected format of device parameters information structure.
Value | Expected Device Parameters Structure
08h | DEVICEPARAMS (FAT16 or FAT12 drive. This call will work on FAT32 drives, but results are not reliable. Use the 48h form for FAT32 media).
48h | EA_DEVICEPARAMETERS (FAT32) (FAT32, FAT16 or FAT12) This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

DriveDP
Points to the applicable device parameters structure containing the parameters for the specified block device. The format of the expected device parameters is indicated in the DeviceCat field above.

The special functions field in the device parameters structure determines whether the function retrieves current or default information. If the field is set to 1, the function retrieves information about the current medium in the drive. If the field is set to 0, the function retrieves information about the default medium for the drive.

Return Values

If the function is successful, clears the carry flag. Otherwise, sets the carry flag and sets the AX register to one of the following error values.

Value | Name
0001h | ERROR_INVALID_FUNCTION
0002h | ERROR_FILE_NOT_FOUND
0005h | ERROR_ACCESS_DENIED

Remarks

Get Device Parameters returns 0002h (ERROR_FILE_NOT_FOUND) if the specified drive number is invalid.


Int 21h Function 440Dh Minor Code 61h (FAT32)

[Windows 95 only.]

Reads data from a track on the specified device and places the data in memory.

mov     bx, Drive               ;See below
mov     ch, DeviceCat           ;See below
mov     cl, 61h                 ;Read track on logical drive
mov     dx, seg ReadBlock       ;See below
mov     ds, dx
mov     dx, offset ReadBlock    ;ds:dx points to RWBLOCK structure
mov     ax, 440Dh               ;IOCTL for block device
int     21h

jc      error_handler           ;carry set means error

Parameters

Drive
Specifies the drive to be read from (0 = default drive, 1 = A, 2 = B, and so on).
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
Value | Description
08h | FAT16 or FAT12 drive. (Will fail on a FAT32 drive).
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

ReadBlock
Points to an RWBLOCK structure that contains information specifying the sectors to be read from. The RWBLOCK structure has the following form:
RWBLOCK STRUC
    rwSpecFunc      db  0  ;special functions (must be zero)
    rwHead          dw  ?  ;head to read/write
    rwCylinder      dw  ?  ;cylinder to read/write
    rwFirstSector   dw  ?  ;first sector to read/write
    rwSectors       dw  ?  ;number of sectors to read/write
    rwBuffer        dd  ?  ;address of buffer for read/write data
RWBLOCK ENDS

Return Values

If the function is successful, clears the carry flag. Otherwise, sets the carry flag and sets the AX register to one of the following error values.

Value | Name
0001h | ERROR_INVALID_FUNCTION
0002h | ERROR_FILE_NOT_FOUND
0005h | ERROR_ACCESS_DENIED

Remarks

Read Track on Logical Drive returns 0002h (ERROR_FILE_NOT_FOUND) if the specified drive number is invalid.


Int 21h Function 440Dh Minor Code 62h (FAT32)

[Windows 95 only.]

Verifies a track on the specified device.

mov     bx, Drive                 ;See below
mov     ch, DeviceCat             ;See below
mov     cl, 62h                   ;Verify track on logical drive
mov     dx, seg VerifyBlock       ;See below
mov     ds, dx
mov     dx, offset VerifyBlock    ;ds:dx points to FVBLOCK structure
mov     ax, 440Dh                 ;IOCTL for block device
int     21h

jc      error_handler             ;carry set means error

Parameters

Drive
Specifies the drive on which the track is to be verified (0 = default drive, 1 = A, 2 = B, and so on).
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
Value | Description
08h | FAT16 or FAT12 drive (Will fail on a FAT32 drive.)
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

VerifyBlock
Points to an FVBLOCK structure that specifies the head and cylinder to verify. The FVBLOCK structure has the following form:
FVBLOCK STRUC
    fvSpecFunc    db  0   ;special functions
    fvHead        dw  ?   ;head to format/verify
    fvCylinder    dw  ?   ;cylinder to format/verify
    fvTracks      dw  ?   ;tracks to format/verify
FVBLOCK ENDS

The fvSpecFunc field can be 0 or 2.

Return Values

If the function is successful, clears the carry flag. Otherwise, sets the carry flag and sets the AX register to one of the following error values.

Value | Name
0001h | ERROR_INVALID_FUNCTION
0002h | ERROR_FILE_NOT_FOUND
0005h | ERROR_ACCESS_DENIED

Remarks

Verify Track on Logical Drive returns 0002h (ERROR_FILE_NOT_FOUND) if the specified drive number is invalid.


Int 21h Function 440Dh Minor Code 66h (FAT32)

[Windows 95 only.]

Returns the volume label, serial number and file system for the specified drive.

mov     bx, Drive            ;See below
mov     ch, DeviceCat        ;See below
mov     cl, 66h              ;Get Media ID
mov     dx, seg MediaID      ;See below
mov     ds, dx
mov     dx, offset MediaID   ;ds:dx points to MID structure
mov     ax, 440Dh            ;IOCTL for block device
int     21h

jc      error_handler        ;carry set means error

Parameters

Drive
Specifies the drive for which information is to be returned (0 = default drive, 1 = A, 2 = B, and so on).
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
Value | Description
08h | FAT32, FAT16, or FAT12 drive.
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

MediaID
Points to an MID structure that receives information that uniquely identifies a disk or other storage medium. The MID structure has the following form:
MID STRUC
    midInfoLevel   dw  0           ;information level
    midSerialNum   dd  ?           ;serial number
    midVolLabel    db  11 dup (?)  ;ASCII volume label
    midFileSysType db  8 dup (?)   ;file system type
MID ENDS

Return Values

If the function is successful, clears the carry flag, and fills in the parameter block (an MID structure) with information about the disk. Otherwise, sets the carry flag and sets the AX register to one of the following error values.

Value | Name
0001h | ERROR_INVALID_FUNCTION
0002h | ERROR_FILE_NOT_FOUND
0005h | ERROR_ACCESS_DENIED

Remarks

Get Media ID returns 0002h (ERROR_FILE_NOT_FOUND) if the specified drive number is invalid.


Int 21h Function 440Dh Minor Code 67h (FAT32)

[Windows 95 only.]

Retrieves the access flag for the specified drive.

mov     bx, Drive               ;See below
mov     ch, DeviceCat           ;See below
mov     cl, 67h                 ;Get access flag
mov     dx, seg SpecialFunc     ;See below
mov     ds, dx
mov     dx, offset SpecialFunc  ;ds:dx points to SPECIALFUNC structure
mov     ax, 440Dh               ;IOCTL for block device
int     21h

jc      error_handler           ;carry set means error

Parameters

Drive
Specifies the drive for which the access flag is to be retrieved (0 = default drive, 1 = A, 2 = B, and so on).
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
08h | FAT32, FAT16, or FAT12 drive.
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

SpecialFunc
Points to a SPECIALFUNC structure that receives the state of the access flag. The SPECIALFUNC structure has the following form:
SPECIALFUNC STRUC
    sfFunction  db  0   ;special function (must be 0)
    sfAccessFlg db  ?   ;access flag, 0 if access blocked
                        ;"unformatted"
SPECIALFUNC ENDS

Return Values

If the function is successful, clears the carry flag. Otherwise, sets the carry flag and sets the AX register to one of the following error values.

Value | Name
0001h | ERROR_INVALID_FUNCTION
0002h | ERROR_FILE_NOT_FOUND
0005h | ERROR_ACCESS_DENIED

Remarks

Get Access Flag returns 0002h (ERROR_FILE_NOT_FOUND) if the specified drive number is invalid.


Int 21h Function 440Dh Minor Code 68h (FAT32)

[Windows 95 only.]

Returns the media type for the specified block device.

mov     bx, Drive               ;See below
mov     ch, DeviceCat           ;See below
mov     cl, 68h                 ;Sense media type
mov     dx, seg Media           ;See below
mov     ds, dx
mov     dx, offset Media        ;ds:dx points to buffer for media type
mov     ax, 440Dh               ;IOCTL for block device
int     21h

jc      error_handler           ;carry set means error

Parameters

Drive
Specifies the drive for which parameters are requested (0 = default drive, 1 = A, 2 = B, and so on).
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
08h | FAT32, FAT16, or FAT12 drive.
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

Media
Points to a 2-byte buffer that receives information about the media type for the given drive. The buffer has the following form:
Offset | Description
00h | Receives a value specifying whether the media type is the default value. This byte is set to 01h for the default media type and to 00h for any other media type.
01h | Receives a value specifying the media type. This byte is set to 02h for 720K disks, 07h for 1.44-MB disks, and 09h for 2.88-MB disks.

Return Values

If the function is successful, clears the carry flag. Otherwise, sets the carry flag and sets the AX register to one of the following error values.

Value | Name
0001h | ERROR_INVALID_FUNCTION
0005h | ERROR_ACCESS_DENIED

Remarks

Sense Media Type may also return a device-dependent error value as specified by the device driver.

Sense Media Type returns 0005h (ERROR_ACCESS_DENIED) if the media type for the specified drive cannot be determined or if the given drive is not ready. Programs can use Get Extended Error (Function 59h) to retrieve additional information about the error.


Int 21h Function 440Dh Minor Code 6Ah (FAT32)

[Windows 95 only.]

Unlocks the logical volume or decrements the lock level.

mov ax, 440Dh      ; generic IOCTL
mov bl, DriveNum   ; see below
mov ch, DeviceCat  ; see below
mov cl, 6Ah        ; Unlock Logical Volume
int 21h

jc error_handler

Parameters

DriveNum
Drive to unlock. This parameter can be 0 for the default drive, 1 for A, 2 for B, and so on.
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
08h | FAT32, FAT16, or FAT12 drive.
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

Return Values

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

Use this function to release the lock obtained by using Lock Logical Volume (Interrupt 21h Function 440Dh Minor Code 4Ah (FAT32)). Only the lock owner can release the lock on a volume.

To release the lock on the volume, an application must call Unlock Logical Volume the same number of times that Lock Logical Volume was called.


Int 21h Function 440Dh Minor Code 6Bh (FAT32)

[Windows 95 only.]

Unlocks the physical volume or decrements the lock level.

mov ax, 440Dh      ; generic IOCTL
mov bl, DriveNum   ; see below
mov ch, DeviceCat  ; see below
mov cl, 6Bh        ; Unlock Physical Volume
int 21h

jc error_handler

Parameters

DriveNum
Drive to unlock. This parameter must be one of these values (same device unit numbers as for Interrupt 13h):
00 - 7Fh | Floppy disk drive (00 for the first floppy drive, 01 for the second, and so on).
80 - FFh | Hard disk drive (80 for the first hard disk drive, 81 for the second, and so on).

DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
08h | FAT32, FAT16, or FAT12 drive.
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

Return Values

Clears the carry flag if successful. Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

This function is used to release the lock obtained by using Lock Physical Volume (Interrupt 21h Function 440Dh Minor Code 4Bh (FAT32)). Only the lock owner can release the lock on a volume.

To release the lock on the volume, an application must call Unlock Physical Volume the same number of times that Lock Physical Volume was called.


Int 21h Function 440Dh Minor Code 6Ch (FAT32)

[Windows 95 only.]

Polls the state of the access flag on a volume to determine if a write operation (for example, deleting or renaming a file or writing to a file) or a new file mapping has occurred since the last poll.

mov ax, 440Dh        ; generic IOCTL
mov bl, DriveNum     ; see below
mov ch, DeviceCat    ; see below
mov cl, 6Ch          ; Get Lock Flag State
int 21h

jc error_handler
mov [AccessFlag], ax  ; state of access flag

Parameters

DriveNum
Drive to poll. This parameter can be 0 for the default drive, 1 for A, 2 for B, and so on.
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
08h | FAT32, FAT16, or FAT12 drive.
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

Return Values

Clears the carry flag and sets the AX register to one of the following values if successful:

0 | No write operations or file mappings have occurred since the last poll.
1 | A write operation has occurred since the last poll (clears the volume access flag).
2 | A file mapping has occurred since the last poll, or a 32-bit Windows-based DLL or executable has been opened (clears the volume access flag).

Otherwise, the function sets the carry flag and sets the AX register to an error value.

Remarks

Only the current lock owner may poll the access flag. The system fails other processes with ERROR_ACCESS_DENIED error value. Write operations performed by the lock owner do not cause a change in the state of the access flag.

When a lock is obtained that allows write operations or new file mappings, the system sets a flag whenever one of these operations happens on the volume. If a write operation or new file mapping has occurred since the last poll, Get Lock Flag State returns 1 or 2 respectively in the AX register and clears the volume access flag. If the swap file has grown or shrunk since the last poll, Get Lock Flag State returns 1. Note that write operations to the swap file that do not cause a change in size do not cause a change in the state of the access flag. If a 32-bit Windows-based DLL or executable has been opened since the last poll, Get Lock Flag State returns 2.


Int 21h Function 440Dh Minor Code 6Dh (FAT32)

[Windows 95 only.]

Enumerates open files on the specified drive.

mov ax, 440Dh           ; generic IOCTL
mov bx, DriveNum        ; see below
mov ch, DeviceCat       ; see below
mov cl, 6Dh             ; Enumerate Open Files
mov dx, seg PathBuf     ; see below
mov ds, dx
mov dx, offset PathBuf
mov si, FileIndex       ; see below
mov di, EnumType        ; see below
int 21h

jc  error
mov [OpenMode], ax      ; mode file was opened in
mov [FileType], cx      ; normal file or memory-mapped file

Parameters

DriveNum
Drive on which to enumerate the files. This parameter can be 0 for the default drive, 1 for A, 2 for B, and so on.
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
08h | FAT32, FAT16, or FAT12 drive.
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

PathBuf
Address of a buffer that receives the path of the open file. The length of the buffer varies depending on the volume. Get Volume Information (Interrupt 21h Function 71A0h) is used to determine the maximum allowed length of a path for the volume.
FileIndex
Index of the file to retrieve the path for.
EnumType
Kind of file to enumerate. This parameter can be 0 to enumerate all open files or 1 to enumerate only open unmovable files, including open memory-mapped files and other open unmovable files (32-bit Windows-based DLLs and executables).

Return Values

Clears the carry flag, copies the path of an open file to the given buffer, and sets the AX and CX registers to the following values if successful:

AX | Mode that the file was opened in, which is a combination of access mode, sharing mode, and open flags. It can be one value each from the access and sharing modes and any combination of open flags.
 | Access modes
 | OPEN_ACCESS_READONLY (0000h)
 | OPEN_ACCESS_WRITEONLY (0001h)
 | OPEN_ACCESS_READWRITE (0002h)
 | OPEN_ACCESS_RO_NOMODLASTACCESS (0004h)
 | Share modes
 | OPEN_SHARE_COMPATIBLE (0000h)
 | OPEN_SHARE_DENYREADWRITE (0010h)
 | OPEN_SHARE_DENYWRITE (0020h)
 | OPEN_SHARE_DENYREAD (0030h)
 | OPEN_SHARE_DENYNONE (0040h)
 | Open flags
 | OPEN_FLAGS_NOINHERIT (0080h)
 | OPEN_FLAGS_NO_BUFFERING (0100h)
 | OPEN_FLAGS_NO_COMPRESS (0200h)
 | OPEN_FLAGS_ALIAS_HINT (0400h)
 | OPEN_FLAGS_NOCRITERR (2000h)
 | OPEN_FLAGS_COMMIT (4000h)
CX | File type. It can be one of the following values:

0 | For normal files
1 | For a memory-mapped files (memory-mapped files are unmovable)
2 | For any other unmovable files (32-bit Windows-based DLLs and executables)
4 | For the swap file

Note that if a memory-mapped file is returned (CX = 1), the value returned in the AX register is limited to the following values:

OPEN_ACCESS_READONLY (0000h)
OPEN_ACCESS_READWRITE (0002h)

Otherwise, the function sets the carry flag and sets the AX register to the following error value:

ERROR_ACCESS_DENIED The value of FileIndex exceeds the number of open files on the drive.

Remarks

This function returns information about one file at a time. To enumerate all open files, the function must be called repeatedly with FileIndex set to a new value for each call. FileIndex should be set to zero initially and then incremented by one for each subsequent call. The function returns the ERROR_NO_MORE_FILES error value when all open files on the volume have been enumerated.

This function may return inconsistent results when used to enumerate files on an active volume 3/4 that is, on a volume where other processes may be opening and closing files. Applications should use Lock Logical Volume (Interrupt 21h Function 440Dh Minor Code 4Ah) to take a level 3 lock before enumerating open files.


Int 21h Function 440Dh Minor Code 6Eh (FAT32)

[Windows 95 only.]

Retrieves information about the swap file.

mov ax, 440Dh       ; generic IOCTL
mov ch, DeviceCat       ; see below
mov cl, 6Eh             ; Find Swap File
mov dx, seg PathBuf     ; see below
mov ds, dx
mov dx, offset PathBuf
int 21h

jc  error_handler
mov [PagerType], ax            ; pager type
mov WORD PTR [FileSize], bx    ; swap file size in 4K pages
mov WORD PTR [FileSize+2], cx

Parameters

DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
08h | FAT32, FAT16, or FAT12 drive.
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

PathBuf
Address of the buffer that receives the path of the swap file. To determine the maximum allowed length of a path for the volume, call Get Volume Information (Interrupt 21h Function 71A0h).

Return Values

Clears the carry flag, copies the swap file path to the given buffer, and sets the following registers if successful:

AX | Pager type. It can be 1 for no pager, 2 for paging through MS-DOS, and 3 for paging through the protected-mode input and output (I/O) supervisor.
CX:BX | Current size of the swap file in 4K pages.

Otherwise, this function sets the carry flag and sets the AX register to an error value.


Int 21h Function 440Dh Minor Code 6Fh (FAT32)

[Windows 95 only.]

Retrieves information about the specified drive. This call only works under Windows 95. It will fail if called from exclusive MS-DOS mode.

mov ax, 440Dh             ; Generic IOCTL
mov bx, DriveNum          ; See below
mov ch, DeviceCat         ; See below
mov cl, 6Fh               ; Get drive map info
mov dx, seg DriveMapInfo  ; See below
mov ds, dx
mov dx, offset DriveMapInfo
int 21h

jc  error_handler         ; Carry set means error

Parameters

DriveNum
Drive to obtain information about (0 = default drive, 1 = A, 2 = B, and so on).
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
08h | FAT32, FAT16, or FAT12 drive.
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

DriveMapInfo
Address of the DRIVE_MAP_INFO structure that receives information about the specified drive. The DRIVE_MAP_INFO structure has the following form:
DRIVE_MAP_INFO    struc
    dmiAllocationLength   db ?
    dmiInfoLength         db ?
    dmiFlags              db ?
    dmiInt13Unit          db ?
    dmiAssociatedDriveMap dd ?
    dmiPartitionStartRBA  dq ?
DRIVE_MAP_INFO    ends


Int 21h Function 440Dh Minor Code 70h (FAT32)

[Windows 95 only.]

Retrieves the current lock level and permissions on the specified drive.

mov ax, 440Dh        ; generic IOCTL
mov bl, DriveNum     ; see below
mov ch, DeviceCat    ; see below
mov cl, 70h          ; Get Current Lock State
int 21h

jc error_handler

Parameters

DriveNum
Drive to retrieve lock information about. This parameter can be 0 for the default drive, 1 for A, 2 for B, and so on.
DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
08h | FAT32, FAT16, or FAT12 drive.
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

Return Values

Clears the carry flag and sets the AX and CX registers to these values if successful:

AX | Current lock level. It may be either 0, 1, 2 or 3. If the volume is not locked, AX contains - 1
CX | Lock permissions. The bits have the following form:

Bit | Meaning
0 | 0 = Write operations are failed.
0 | 1 = Write operations are allowed, unless they are blocked by the lock level.
1 | 0 = New file mapping are allowed, unless they are blocked by the lock level.
1 | 1 = New file mapping are failed.
2 | 1 = The volume is locked for formatting.

Remarks

The lock level and the permissions determine the kind of access processes other than the lock owner have to the volume while it is locked. The following operations are allowed by processes other than lock owner at each lock level:

Level | Operations
0 | Read operations, write operations, and new file mappings are failed.
1 | Read operations are allowed. Write operations and new file mappings are either allowed or failed based on permissions.
2 | Read operations are allowed. Write operations and new file mappings are either failed or blocked based on permissions.
3 | Read operations are blocked. Write operations and new file mappings are either failed or blocked based on permissions.


Int 21h Function 440Dh Minor Code 71h (FAT32)

[Windows 95 only.]

Retrieves the first cluster of the specified file or directory. This function is only supported by Windows 95. It will fail if called under MS-DOS. To call this function, the caller must hold a level 3 lock on the drive.

mov ax, 440Dh            ; Generic IOCTL
mov bx, CharSet          ; See below
mov ch, DeviceCat        ; See below
mov cl, 71h              ; Get first cluster
mov dx, seg PathName     ; See below
mov ds, dx
mov dx, offset PathName
int 21h

jc error_handler         ; Carry set means error

Parameters

CharSet
The character set of PathName. This parameter must be one of these values:
BCS_WANSI (0) | Windows ANSI character set
BCS_OEM (1) | Current OEM character set
BCS_UNICODE (2) | Unicode character set

DeviceCat
Specifies a FAT16, FAT12 or FAT32 drive.
08h | FAT32, FAT16, or FAT12 drive.
48h | FAT32, FAT16, or FAT12 drive. This value is supported on Windows 95 OEM Service Release 2 and later.

Note: Because this call may be implemented in the device driver, the 48h form of this call may fail on FAT16 or FAT12 media. Therefore, applications making the 48h form of this call must fall back on the 08h form if the 48h call fails.

PathName
Address of a null-terminated string containing the path of the file or directory to retrieve the first cluster for.

Return Values

If the function is successful, clears the carry flag and sets DX:AX to the first cluster number. Otherwise, sets the carry flag and returns either the ERROR_INVALID_FUNCTION or ERROR_ACCESS_DENIED value in AX.

Remarks

The first cluster of a file is the first cluster of the FAT cluster chain describing the data associated with the file. The first cluster of a directory is the first cluster of the FAT cluster chain associated with the directory. The first cluster is the cluster that contains the "." and ".." entries. The Get First Cluster function finds any file or directory regardless of attribute (system, hidden, or read-only). It does not find volume labels.

It is the calling application's responsibility to check to see if the returned cluster number is valid. The following code fragment checks for a valid cluster number and sets a flag accordingly. Note that the maxClus variable is a DWORD that represents the maximum legal cluster number computed from the drive parameters.

if((MAKELONG(regAX,regDX) < 2L) || (MAKELONG(regAX,regDX) > maxClus))
    bInvalidNum = TRUE;
else
    bInvalidNum = FALSE;


Int 21h Function 6Ch (FAT32)

[Windows 95 only.]

Opens or creates a file that has the given name and attributes.

mov ah, 6Ch             ; Extended Open/Create
mov bx, ModeAndFlags    ; See below
mov cx, Attributes      ; See below
mov dx, Action          ; See below
mov si, seg Filename    ; See below
mov ds, si
mov si, offset Filename
int 21h

jc error_handler        ; Carry set means error

mov [Handle], ax        ; file handle
mov [ActionTaken], cx   ; action taken to open file

Parameters

ModeAndFlags
A combination of access mode, sharing mode, and open flags. This parameter can be a combination of one value from the access and sharing modes and any combination of open flags:
Access mode Meaning
OPEN_ACCESS_READONLY (0000h)
Opens the file for reading only.
OPEN_ACCESS_WRITEONLY (0001h)
Opens the file for writing only.
OPEN_ACCESS_READWRITE (0002h)
Opens the file for reading and writing.
0003h
Reserved; do not use.
OPEN_ACCESS_RO_NOMODLASTACCESS (0004h)
Opens the file for reading only without modifying the file's last access date.

Sharing mode Meaning
OPEN_SHARE_COMPATIBLE (0000h)
Opens the file in compatibility mode, allowing any process on a given computer to open the file any number of times.
OPEN_SHARE_DENYREADWRITE (0010h)
Opens the file and denies both read and write access to other processes.
OPEN_SHARE_DENYWRITE (0020h)
Opens the file and denies write access to other processes.
OPEN_SHARE_DENYREAD (0030h)
Opens the file and denies read access to other processes.
OPEN_SHARE_DENYNONE (0040h)
Opens the file without denying read or write access to other processes, but no process may open the file in compatibility mode.

Open flags Meaning
OPEN_FLAGS_NOINHERIT (0080h)
Child processes created with Load and Execute Program (Interrupt 21h Function 4B00h) do not inherit the file handle. If the handle is needed by a child process, the parent process must pass the handle value to the child process. If this flag is not set, child processes inherit the file handle.
EXTENDED_SIZE (1000h)
The file is opened in extended mode. This allows access to files up to 4GB minus 2 bytes. Access includes open and create functions.
OPEN_FLAGS_NOCRITERR (2000h)
If a critical error occurs while MS-DOS is opening this file, Critical-Error Handler (Interrupt 24h) is not called. Instead, MS-DOS simply returns an error value to the program.
OPEN_FLAGS_COMMIT (4000h)
After each write operation, MS-DOS commits the file (flushes the contents of the cache buffer to disk).

Attributes
Attributes for files that are created or truncated. This parameter may be a combination of these values:
FILE_ATTRIBUTE_NORMAL (0000h)
The file can be read from or written to. This value is valid only if used alone.
FILE_ATTRIBUTE_READONLY (0001h)
The file can be read from, but not written to.
FILE_ATTRIBUTE_HIDDEN (0002h)
The file is hidden and does not appear in an ordinary directory listing.
FILE_ATTRIBUTE_SYSTEM (0004h)
The file is part of the operating system or is used exclusively by it.
FILE_ATTRIBUTE_VOLUME (0008h)
The name specified by Filename is used as the volume label for the current medium.
FILE_ATTRIBUTE_ARCHIVE (0020h)
The file is an archive file. Applications use this value to mark files for backup or removal.

Action
Action to take it the file exists or does not exist. This parameter can be a limited combination of the following values:
FILE_CREATE (0010h)
Creates a new file if it does not already exist or fails if the file already exists.
FILE_OPEN (0001h)
Opens the file. The function fails if the file does not exist.
FILE_TRUNCATE (0002h)
Opens the file and truncates it to zero length (replaces the existing file). The function fails if the file does not exist.

Note that valid combinations of the above values are limited to FILE_CREATE combined with FILE_OPEN or FILE_CREATE combined with FILE_TRUNCATE.

Filename
Address of a null-terminated string specifying the name of the file to be opened or created. The name must be in the standard MS-DOS 8.3 filename format. The string must be a valid path for the volume associated with the given drive.

Return Values

If the function is successful, clears the carry flag, copies the file handle to the AX register, and sets CX to one of the following values.

ACTION_OPENED (0001h)
ACTION_CREATED_OPENED (0002h)
ACTION_REPLACED_OPENED (0003h)

Otherwise, sets the carry flag and sets the AX register to one of the following error values.

ERROR_INVALID_FUNCTION (0001h)
ERROR_FILE_NOT_FOUND (0002h)
ERROR_PATH_NOT_FOUND (0003h)
ERROR_TOO_MANY_OPEN_FILES (0004h)
ERROR_ACCESS_DENIED (0005h)

Remarks

This function does not support long filenames. If the specified name is too long, this function truncates the name to the standard 8.3 format following the same naming scheme that the system uses when creating an alias for a long filename.

A file on a remote directory-that is, a directory on the network-cannot be opened, unless appropriate permissions for the directory exist.


Int 21h Function 7302h Get_ExtDPB (FAT32)

[Windows 95 only.]

Returns a copy of the extended DPB (FAT32) for any valid drive.

Buffer   dw  ?
DriveDPB DPB <>
BufferSize equ sizeof DPB + sizeof WORD
...
mov  dx, seg Buffer
mov  es, dx
mov  di, offset Buffer  ;See below

mov  dl, DriveNum       ;See below
mov  cx, BufferSize     ;See below
mov  ax, 7302h          ;Get_ExtDPB
int  21h

jc  error_handler       ;carry set means error

Parameters

Buffer
The address of the buffer at ES:DI that will receive the WORD (the size value), followed by the copy of the extended DPB.
DriveNum
The 1-based drive number (0=default; 1=A, 2=B, and so on).
BufferSize
The size of the buffer, in bytes.

The size value returned by this function represents the size of the DPB only. It does not include the two bytes of the size field itself.

This call will not work when the VDEF file system is mounted on the drive (for example during formatting).

Return Values

Clears the carry flag, and returns a copy of the DPB to ES:DI. The copy is a WORD equal to the size (in bytes) of the extended DPB, followed by the extended DPB itself (see EA_DEVICEPARAMETERS (FAT32)).

Remarks

When calling this function with DeviceIoControl, it is recommended to set the dwloControlCode parameter to VWIN32_DIOC_DOS_IOCTL (defined as 6 in VWIN32.H). For more information on this, see Using VWIN32 to Carry Out MS-DOS Functions.


Int 21h Function 7303h Get_ExtFreeSpace (FAT32)

[Windows 95 only.]

Returns the total disk space and the free disk space.

mov  dx, seg Buffer
mov  es, dx
mov  di, offset Buffer    ;See below
mov  es:[di].ExtGetDskFreSpcStruc.ExtFree_Level, ExpectLevel
mov  cx, BufferSize       ;See below

mov  dx, seg DriveName    ;See below
mov  ds, dx
mov  dx, offset DriveName ;See below

mov  ax, 7303h            ;Get_ExtFreeSpace
int  21h

jc  error_handler         ;carry set means error

Parameters

Buffer
The address of the buffer at ES:DI that will receive the disk space information.
BufferSize
The size (in bytes) of the buffer.
DriveName
The address of a null terminated string at DS:DX. In real mode, this must be in standard form ("C:\"). In Windows, either the standard name or a universal naming convention form ("\\Server\Share") is acceptable.

Return Values

Clears the carry flag and returns the total disk space and the free disk space of the specified drive, in the form of an ExtGetDskFreSpcStruc (FAT32) structure, to a buffer at ES:DI. It is recommended to initialize the buffer to the level value the application expects to receive.

Remarks

When calling this function with DeviceIoControl, the dwloControlCode parameter must be set to VWIN32_DIOC_DOS_IOCTL (defined as 6 in VWIN32.H). For more information on this, see Using VWIN32 to Carry Out MS-DOS Functions.


Int 21h Function 7304h Set_DPBForFormat (FAT32)

[Windows 95 only.]

Implements a sub-function to perform DPB operations.

There are five sub-functions that can be implemented. The buffer at ES:DI must contain a SDPDFormatStruc (FAT32) structure. The value in the DWORD field, SetDPB_Function, determines which sub-function is called.

mov  dx, seg Buffer
mov  es, dx
mov  di, offset Buffer   ;See below

mov  es:[di].SDPDFormatStruc.SetDPB_Level, ExpectLevel   ;See below

mov  ax, word ptr Value1 ; initialize SDPDFormatStruc values.
                         ; See specific sub-function for details.

mov  word ptr es:[di].SDPDFormatStruc.SetDPB_Value1, ax
mov  ax, word ptr Value1 + 2
mov  word ptr es:[di].SDPDFormatStruc.SetDPB_Value1+2, ax

mov  ax, word ptr SubFunction
mov  word ptr es:[di].SDPDFormatStruc.SetDPB_Function, ax
mov  word ptr es:[di].SDPDFormatStruc.SetDPB_Function+2, 0

mov  dl, DriveNum       ;See below
mov  cx, BufferSize     ;See below
mov  ax, 7304h          ;Set_DPBForFormat
int 21h

Parameters

Buffer
The address of a buffer containing a SDPDFormatStruc structure at ES:DI.
ExpectLevel
The expected return level value. This should be 0.
DriveNum
The 1-based drive number (0=default; 1=A, 2=B, and so on).
BufferSize
The size of the buffer, in bytes.

Remarks

Selecting a Sub-Function:

The value in the SetDPB_Function field of the SDPDFormatStruc structure determines which sub-function is implemented.

0 | SetDPB_SetAllocInfo
1 | SetDPB_SetDPBFrmBPB
2 | SetDPB_ForceMediaChng
3 | SetDPB_GetSetActFATandMirr
4 | SetDPB_GetSetRootDirClus

It is important to be aware of the state of the file system when using this call. If sectors of the drive are cached, or if there are files open, the function may produce unexpected results. To avoid this, ensure that the application closes all files and calls DiskReset to flush and invalidate any caches.

The SDPDFormatStruc also contains four ULONG fields: SetDPB_Value1, SetDPB_Value2, SetDPB_Value3, and SetDPB_Value4. Set these appropriately according to the requirements for each of the sub-functions.

When calling this function with DeviceIoControl, set the dwloControlCode parameter to VWIN32_DIOC_DOS_IOCTL (defined as 6 in VWIN32.H). For more information on this, see Using VWIN32 to Carry Out MS-DOS Functions.


SetDPB_SetAllocInfo (FAT32)

[Windows 95 only.]

Sets the dpb_free_cnt and dpb_next_free fields in the DPB.

This sub-function is called when the SetDPB_Function field of the SDPDFormatStruc (FAT32) structure is set to 0.

Return Values

Clears the carry flag and sets the dpb_free_cnt and dpb_next_free fields in the DPB based upon the values in the SetDPB_Value1 and SetDPB_Value2 fields within the Set_DPB_ForFormat structure.

Remarks

SetDPB_Value1 Setting | Result within DPB
0 | Does not change the dpb_free_cnt field.
0xFFFFFFFF | Sets dpb_free_cnt to unknown.
(any other value) | Sets dpb_free_cnt to the specified value if it is a valid cluster count for the drive,.

The free cluster count cannot be explicitly set to zero by this call. This can only be done by setting SetDPB_Value1 to 0xFFFFFFFF, which forces the free space to be re-computed. Also, setting this value improperly causes the free count value to be reported improperly by GetDiskFreeSpace. The settings of 0 or 0xFFFFFFFF are recommended.

SetDPB_Value2 Setting | Result within DPB
0 | Does not change the dpb_next_free field.
0xFFFFFFFF | Sets dpb_next_free to force the cluster search to begin at the beginning of the FAT.
(any other value) | Sets dpb_next_free to the given value if it is a valid cluster number for the drive. This causes the search for free clusters to begin at the specified cluster.

The assembler calling sequence for all Int 21h 7304h sub-functions is almost identical. See the main listing for a sample. (Int 21h Function 7304h Set_DPBForFormat (FAT32))


SetDPB_SetDPBFrmBPB (FAT32)

[Windows 95 only.]

Rebuilds the file system drive DPB from a passed-in BPB (FAT32).

This sub-function is called when the SetDPB_Function field of the SDPDFormatStruc (FAT32) structure is set to 1.

Remarks

On input, the SetDPB_Value2 member in SDPDFormatStruc must be a DWORD pointer to the BPB.

The PB that the SetDPB_Value2 points to can be in FAT12, FAT16 or FAT32 format.

The drive parameters are often held in the device driver for the drive as well. As a result, it is recommended to accompany this call with a call to Int 21h Function 440Dh Minor Code 40h (FAT32).

The assembler calling sequence for all Int 21h 7304h sub-functions is almost identical. See the main listing for a sample. (Int 21h Function 7304h Set_DPBForFormat (FAT32))


SetDPB_ForceMediaChng (FAT32)

[Windows 95 only.]

Forces a media change.

This sub-function is called when the SetDPB_Function field of the SDPDFormatStruc (FAT32) structure is set to 2.

Return Values

Sets a flag which causes the next MS-DOS access to the drive to call the BUILD_DPD routine in the drive's device driver.

Remarks

This is similar to the SetDPB_SetDPBFrmBPB (FAT32) call, except that the BPB is obtained from the device driver instead of a passed-in parameter.

The function does not take effect on this call. Rather, it takes effect upon the next access to the drive. Therefore, it is recommended to immediately follow this with some other Int 21h call to the drive (for example Int 21h Function 7303h Get_ExtFreeSpace (FAT32)).

As a side effect of this call, the next access to the drive also causes dpb_next_free (or extdpb_next_free) to be reset to 2, and the dpb_free_cnt to be reset to 0xFFFFFFFF.

The assembler calling sequence for all Int 21h 7304h sub-functions is almost identical. See the main listing for a sample. (Int 21h Function 7304h Set_DPBForFormat (FAT32))


SetDPB_GetSetActFATandMirr (FAT32)

[Windows 95 only.]

Allows the active FAT and FAT mirror properties of a FAT32 drive to be read and changed. This call is invalid on FAT12 and FAT16 drives.

This sub-function is called when the SetDPB_Function field of the SDPDFormatStruc (FAT32) structure is set to 3.

Parameters

SetDPB_Value1
The SetDPB_Value1 field in the SPDPFormatStruc structure determines the SET behavior. If the SetDPB_Value1 field is set to 0xFFFFFFFF, then no changes are made and the ActiveFat and FAT mirror property are returned to SetDPB_Value2.

Failure Conditions:

The low four bits of this value are the zero-based ActiveFAT number. If the ActiveFAT number is greater than or equal to the number of FATs on the drive, the call will fail.

Bit 0x00000080 is the "Disable FAT Mirror" bit. If any bits other than 0x80 and the low four bits are set, the call will fail.

If the FAT Mirror is enabled (bit 0x80 clear) and the ActiveFAT value specified in SetDPB_Value1 is not zero, the call will fail.

SetDPB_Value2
Used as a return field for the previous ActiveFAT and FAT mirror properties. Bits 0 through 3 indicate the active FAT number, bit 7 indicates the mirror state, and all other bits are reserved. If SetDPB_Value1 is 0xFFFFFFFF, the previous state is also the current state.
Bit 7 | Description
Set | Enable FAT Mirroring
Clear | Disable FAT Mirroring

Return Values

If the function is unsuccessful, the function sets the carry flag and returns ERROR_GEN_FAILURE (error code 31) to AX. Receiving ERROR_GEN_FAILURE as the return value indicates that a disk error occurred during the attempt to write. In this case, the DPB mirror property is changed, but not properly written to disk. If the function fails, it is recommended that the caller re-write the value returned to SetDBP_Value2 to attempt to undo the change.

Remarks

Side Effects of Set Form:

The BPB(s) and boot sector(s) of the drive are also written. This is because the ActiveFAT and FAT mirror properties are also stored in the BPB.

If the FAT Mirror is being enabled (that is, bit 0x80 is set in the current state, and bit 0x80 is clear in SetDPB_Value1.) this call will copy the active FAT sectors to all of the other FATs. This process can be very slow.

Note that the device driver may also contain these values as part of its current device parameters. This call will have no effect on the FAT Mirror properties held by the device driver. As a result, it is recommended to immediately follow the set form of the call with a SetDeviceParameters Generic IOCTL call to set the current BPB that the BuildBPB routine of the device returns.

Next Free DPB variable is reset to 2, and the Free Count DPB is reset to 0xFFFFFFFF.

The assembler calling sequence for all Int 21h 7304h sub-functions is almost identical. See the main listing for a sample. (Int 21h Function 7304h Set_DPBForFormat (FAT32))


SetDPB_GetSetRootDirClus (FAT32)

[Windows 95 only.]

Allows the first cluster of the root directory of a FAT32 drive to be read and changed. This call is invalid on FAT12 and FAT16 drives.

This sub-function is called when the SetDPB_Function field of the SDPDFormatStruc (FAT32) structure is set to 4.

Parameters

SetDPB_Value1
This field in the SPDPFormatStruc specifies the SET behavior. If the value is 0xFFFFFFFF, then no changes are made and the current root directory first cluster number is returned in SetDPB_Value2.

The value is range checked. It must be >=2 and <= the maximum valid cluster number for the drive.

SetDPB_Value2
This field in the SPDPFormatStruc is used as a return field where the previous root directory first cluster is held. When SetDPB_Value1 is 0xFFFFFFFF, the previous cluster is also the current root directory cluster.

Return Values

If the function is unsuccessful, the function sets the carry flag and returns ERROR_GEN_FAILURE (error code 31) to AX. Receiving ERROR_GEN_FAILURE as the return value indicates that a disk error occurred during the attempt to write. In this case, the DPB mirror property is changed, but not properly written to disk. If the function fails, it is recommended that the caller re-write the value returned to SetDBP_Value2 to attempt to undo the change.

Remarks

Since the start cluster of the root directory is also stored in the BPB of the boot sector(s) of the drive, this call re-writes these boot sectors as a side effect.

Note that the device driver may also contain these values as part of its current device parameters. This call will have no effect on the FAT Mirror properties held by the device driver. Because of this, it is recommended to immediately follow the set form of the call with a SetDeviceParameters Generic IOCTL call. This sets the current BPB that the BuildBPB routine of the device returns.

The assembler calling sequence for all Int 21h 7304h sub-functions is almost identical. See the main listing for a sample. (Int 21h Function 7304h Set_DPBForFormat (FAT32))


Int 21h Function 7305h Ext_ABSDiskReadWrite (FAT32)

[Windows 95 only.]

Allows absolute disk read/write to FAT32, FAT16, and FAT12 drives. This call replaces Int 25h/26h.

mov  si, 6001h          ;write normal file data. SI=0 for read
                        ;see "In Write Mode" below for more write values

mov  cx, -1             ;cx must be -1
mov  dx, seg Buffer
mov  ds, dx
mov  bx, offset Buffer  ;See below
mov  dl, DriveNum       ;See below

mov  ax, 7305h          ;Ext_ABSDiskReadWrite
int 21h

jc  error_handler       ;carry set means error

Parameters

Buffer
Points to a DISKIO structure that contains the starting sector, the sector count and an address of the buffer to receive the data. The structure must be initialized according to Int 25h/26h documentation. The DISKIO structure has the following form:
DISKIO  STRUC
    diStartSector   dd  ?   ;sector number to start
    diSectors       dw  ?   ;number of sectors
    diBuffer        dd  ?   ;address of buffer
DISKIO  ENDS
DriveNum
The 1-based drive number (0=default; 1=A, 2=B, and so on).
This function operates the same as Int 25h/26h, with the following exceptions:
CX must equal -1 (only the 32-bit starting sector number form is allowed).

The drive number is 1-based (0 = default drive) and is specified in DL instead of AL.

This call does not leave a flag word on the stack like Interrupts 25h and 26h.

This call modifies only the AX register and the flags.

Bit 0 of SI specifies whether the call is to do a READ (INT 0x25) or a WRITE (INT 0x26):

Read and Write Modes:
SI bit 0 clear | READ
SI bit 0 set | WRITE

In Write Mode:
When bit 0 of SI is set (that is, WRITE mode), bits 13, 14 and 15 of SI categorize what type of data is being written:
15 | 14 | 13 | Description
0 | 0 | 0 | Other/Unknown.
0 | 0 | 1 | FAT data.
0 | 1 | 0 | Directory data.
0 | 1 | 1 | Normal File data.
1 | x | x | Reserved. Bit 15 must be 0.

All other bits of SI (1 through 12) are reserved and must be 0.

This provides information to apps (like compression drivers) so that they can write the data properly based upon the data type specified by the above bits.

Warnings:
Do not set these flags in an attempt to make a compression driver write uncompressed data onto a compressed drive. Compression drivers are not the only applications use these flags.

Do not set the flags improperly, this information is to be used only to indicate what "type" the data is.

Return Values

If the function is successful, clears the carry flag. Otherwise, sets the carry flag, and sets the AX register with the error code as it is documented for Int 25h/26h.

Remarks

When calling this function with DeviceIoControl, it is recommended to set the dwloControlCode parameter to VWIN32_DIOC_DOS_DRIVEINFO (defined as 6 in VWIN32.H). For more information on this, see Using VWIN32 to Carry Out MS-DOS Functions.


Superseded Functions

The following functions have been superseded for Windows OEM Service Release 2 and later:

Interrupt 21h Function 1Fh Get Default DPB:
 | Superseded by Int 21h Function 7302h Get_ExtDPB (FAT32). Will fail if used on FAT32 media.
Interrupt 21h Function 32h Get DPB:
 | Superseded by Int 21h Function 7302h Get_ExtDPB (FAT32). Will fail if used on FAT32 media.
Interrupt 21h Function36h Get Disk Free Space:
 | If total or free disk space is greater than 2GB minus 320k, then 2GB minus 320k is returned. This function is superseded by Int 21h Function 7303h Get_ExtFreeSpace (FAT32).
Interrupts 25h/26h Absolute Disk Read / Write:
 | Superseded by Int 21h Function 7305h Ext_ABSDiskReadWrite (FAT32). These functions fail on FAT32 drives. This is to prevent non-FAT32 compatible software from being able to access FAT32 media.


BPB (FAT32)

[Windows 95 only.]

The BPB for FAT32 drives is an extended version of the FAT16/FAT12 BPB. It contains identical information to a standard BPB, but also includes several extra fields for FAT32 specific information.

This structure is implemented in Windows OEM Service Release 2 and later.

A_BF_BPB    STRUC
    A_BF_BPB_BytesPerSector       DW    ?
    A_BF_BPB_SectorsPerCluster    DB    ?
    A_BF_BPB_ReservedSectors      DW    ?
    A_BF_BPB_NumberOfFATs         DB    ?
    A_BF_BPB_RootEntries          DW    ?
    A_BF_BPB_TotalSectors         DW    ?
    A_BF_BPB_MediaDescriptor      DB    ?
    A_BF_BPB_SectorsPerFAT        DW    ?
    A_BF_BPB_SectorsPerTrack      DW    ?
    A_BF_BPB_Heads                DW    ?
    A_BF_BPB_HiddenSectors        DW    ?
    A_BF_BPB_HiddenSectorsHigh    DW    ?
    A_BF_BPB_BigTotalSectors      DW    ?
    A_BF_BPB_BigTotalSectorsHigh  DW    ?
    A_BF_BPB_BigSectorsPerFat     DW    ?
    A_BF_BPB_BigSectorsPerFatHi   DW    ?
    A_BF_BPB_ExtFlags             DW    ?
    A_BF_BPB_FS_Version           DW    ?
    A_BF_BPB_RootDirStrtClus      DW    ?
    A_BF_BPB_RootDirStrtClusHi    DW    ?
    A_BF_BPB_FSInfoSec            DW    ?
    A_BF_BPB_BkUpBootSec          DW    ?
    A_BF_BPB_Reserved             DW    6 DUP (?)
A_BF_BPB    ENDS

Members

A_BF_BPB_BytesPerSector
The number of bytes per sector.
A_BF_BPB_SectorsPerCluster
The number of sectors per cluster.
A_BF_BPB_ReservedSectors
The number of reserved sectors, beginning with sector 0.
A_BF_BPB_NumberOfFATs
The number of File Allocation Tables.
A_BF_BPB_RootEntries
This field is ignored on FAT32 drives.
A_BF_BPB_TotalSectors
The size of the partition, in sectors.
A_BF_BPB_MediaDescriptor
The media descriptor. Values in this field are identical to standard BPB.
A_BF_BPB_SectorsPerFAT
The number of sectors per FAT.

Note: This field will always be zero in a FAT32 BPB. Use the values from A_BF_BPB_BigSectorsPerFat and A_BF_BPB_BigSectorsPerFatHi for FAT32 media.

A_BF_BPB_SectorsPerTrack
The number of sectors per track.
A_BF_BPB_Heads
The number of read/write heads on the drive.
A_BF_BPB_HiddenSectors
The number of hidden sectors on the drive.
A_BF_BPB_HiddenSectorsHigh
The high word of the hidden sectors value.
A_BF_BPB_BigTotalSectors
The total number of sectors on the FAT32 drive.
A_BF_BPB_BigTotalSectorsHigh
The high word of the FAT32 total sectors value.
A_BF_BPB_BigSectorsPerFat
The number of sectors per FAT on the FAT32 drive.
A_BF_BPB_BigSectorsPerFatHi
The high word of the FAT32 sectors per FAT value.
A_BF_BPBExtFlags
Flags describing the drive. Bit 8 of this field indicates whether or not information written to the active FAT will be written to all copies of the FAT. The low 4 bits of this field contain the 0-based FAT number of the Active FAT, but are only meaningful if bit 8 is set. This field can contain a combination of the following values.
Value | Description
BGBPB_F_ActiveFATMsk (000Fh) | Mask for low four bits.
BGBPB_F_NoFATMirror (0080h) | Mask indicating FAT mirroring state. If set, FAT mirroring is disabled. If clear, FAT mirroring is enabled.

Bits 4-6 and 8-15 are reserved.

A_BF_BPB_FS_Version
The file system version number of the FAT32 drive. The high byte represents the major version, and the low byte represents the minor version.
A_BF_BPB_RootDirStrtClus
The cluster number of the first cluster in the FAT32 drive's root directory.
A_BF_BPB_RootDirStrtClusHi
The high word of the FAT32 starting cluster number.
A_BF_BPB_FSInfoSec
The sector number of the file system information sector. The file system info sector contains a BIGFATBOOTFSINFO structure. This field is set to 0FFFFh if there is no FSINFO sector. Otherwise, this value must be non-zero and less than the reserved sector count.
A_BF_BPB_BkUpBootSec
The sector number of the backup boot sector. This field is set to 0FFFFh if there is no backup boot sector. Otherwise, this value must be non-zero and less than the reserved sector count.
A_BF_BPB_Reserved
Reserved field. Do not use.


BIGFATBOOTFSINFO (FAT32)

[Windows 95 only.]

Contains information about the file system on a FAT32 volume. This structure is implemented in Windows OEM Service Release 2 and later.

BIGFATBOOTFSINFO STRUC
    bfFSInf_Sig               DD    ?
    bfFSInf_free_clus_cnt     DD    ?
    bfFSInf_next_free_clus    DD    ?
    bfFSInf_resvd             DD    3 DUP (?)
BIGFATBOOTFSINFO ENDS

Members

bfFSInf_Sig
The signature of the file system information sector. The value in this field is FSINFOSIG (0x61417272L).
bfFSInf_free_clus_cnt
The count of free clusters on the drive. Set to -1 when the count is unknown.
bfFSInf_next_free_clus
The cluster number of the cluster that was most recently allocated.
bfFSInf_resvd
Reserved field. Do not use.


DPB (FAT32)

[Windows 95 only.]

The DPB was extended to include FAT32 information. Changes are effective for Windows 95 OEM Service Release 2 and later.

DPB STRUC
    dpb_drive            DB    ?
    dpb_unit             DB    ?
    dpb_sector_size      DW    ?
    dpb_cluster_mask     DB    ?
    dpb_cluster_shift    DB    ?
    dpb_first_fat        DW    ?
    dpb_fat_count        DB    ?
    dpb_root_entries     DW    ?
    dpb_first_sector     DW    ?
    dpb_max_cluster      DW    ?
    dpb_fat_size         DW    ?
    dpb_dir_sector       DW    ?
    dpb_reserved2        DD    ?
    dpb_media            DB    ?
ifdef NOTFAT32
    dpb_first_access     DB    ?
else
    dpb_reserved         DB    ?
endif
    dpb_reserved3        DD    ?
    dpb_next_free        DW    ?
    dpb_free_cnt         DW    ?
ifndef NOTFAT32
    extdpb_free_cnt_hi   DW    ?
    extdpb_flags         DW    ?
    extdpb_FSInfoSec     DW    ?
    extdpb_BkUpBootSec   DW    ?
    extdpb_first_sector  DD    ?
    extdpb_max_cluster   DD    ?
    extdpb_fat_size      DD    ?
    extdpb_root_clus     DD    ?
    extdpb_next_free     DD    ?
endif
DPB ENDS

Members

dpb_drive
The drive number (0 = A, 1 = B, and so on).
dpb_unit
Specifies the unit number. The device driver uses the unit number to distinguish the specified drive from the other drives it supports.
dpb_sector_size
The size of each sector, in bytes.
dpb_cluster_mask
The number of sectors per cluster minus 1.
dpb_cluster_shift
The number of sectors per cluster, expressed as a power of 2.
dpb_first_fat
The sector number of the first sector containing the file allocation table (FAT).
dpb_fat_count
The number of FATs on the drive.
dpb_root_entries
The number of entries in the root directory.
dpb_first_sector
The sector number of the first sector in the first cluster.
dpb_max_cluster
The number of clusters on the drive plus 1. This field is undefined for FAT32 drives.
dpb_fat_size
The number of sectors occupied by each FAT. The value of zero indicates a FAT32 drive. Use the value in extdpb_fat_size instead.
dpb_dir_sector
The sector number of the first sector containing the root directory. This field is undefined for FAT32 drives.
dpb_reserved2
Reserved field. Do not use.
dpb_media
Specifies the media descriptor for the medium in the specified drive.
reserved
Reserved field. Do not use.
dpb_first_access
Indicates whether the medium in the drive has been accessed. This field is initialized to -1 to force a media check the first time this DPB is used.
dpb_reserved3
Reserved field. Do not use.
dpb_next_free
The cluster number of the most recently allocated cluster.
dpb_free_cnt
The number of free clusters on the medium. This field is 0FFFFh if the number is unknown.
extdpb_free_cnt_hi
The high word of free count.
extdpb_flags
Flags describing the drive. The low 4 bits of this field contain the 0-based FAT number of the Active FAT. This field can contain a combination of the following values.
Value | Description
BGBPB_F_ActiveFATMsk (000Fh) | Mask for low four bits.
BGBPB_F_NoFATMirror (0080h) | Do not Mirror active FAT to inactive FATs.

Bits 4-6 and 8-15 are reserved.

extdpb_FSInfoSec
The sector number of the file system information sector. This field is set to 0FFFFh if there is no FSINFO sector. Otherwise, this value must be non-zero and less than the reserved sector count.
extdpb_BkUpBootSec
The sector number of the backup boot sector. This field is set to 0FFFFh if there is no backup boot sector. Otherwise, this value must be non-zero and less than the reserved sector count.
extdpb_first_sector
The first sector of the first cluster.
extdpb_max_cluster
The number of clusters on the drive plus 1.
extdpb_fat_size
The number of sectors occupied by the FAT.
extdpb_root_clus
The cluster number of the first cluster in the root directory.
extdpb_next_free
The number of the cluster that was most recently allocated.


EA_DEVICEPARAMETERS (FAT32)

[Windows 95 only.]

The equivalent of the DEVICEPARAMS structure, but includes FAT32 specific information. This structure is implemented in Windows OEM Service Release 2 and later.

EA_DEVICEPARAMETERS STRUC
    EDP_SPECIALFUNCTIONS     DB     ?
    EDP_DEVICETYPE           DB     ?
    EDP_DEVICEATTRIBUTES     DW     ?
    EDP_CYLINDERS            DW     ?
    EDP_MEDIATYPE            DB     ?
    EDP_BPB                  DB     SIZE A_BF_BPB DUP (?)
    EDP_RESERVED1            DB     32 DUP (?)
    EDP_TRACKTABLEENTRIES    DW     ?
    EDP_SECTORTABLE          DB MAX_SECTORS_IN_TRACK * SIZE A_SECTORTABLE DUP (?)
EA_DEVICEPARAMETERS ENDS

This structure is identical to DEVICEPARAMS, but includes a FAT32 BPB instead of a standard BPB, followed by a 32 byte reserved field.


ExtGetDskFreSpcStruc (FAT32)

[Windows 95 only.]

A structure used by Int 21h Function 7303h Get_ExtFreeSpace (FAT32). The structure contains information about the drive's total disk space and free disk space.

This structure is implemented in Windows OEM Service Release 2 and later.

ExtGetDskFreSpcStruc STRUC
    ExtFree_Size                      DW    ?
    ExtFree_Level                     DW    ?
    ExtFree_SectorsPerCluster         DD    ?
    ExtFree_BytesPerSector            DD    ?
    ExtFree_AvailableClusters         DD    ?
    ExtFree_TotalClusters             DD    ?
    ExtFree_AvailablePhysSectors      DD    ?
    ExtFree_TotalPhysSectors          DD    ?
    ExtFree_AvailableAllocationUnits  DD    ?
    ExtFree_TotalAllocationUnits      DD    ?
    ExtFree_Rsvd                      DD    2 DUP (?)
ExtGetDskFreSpcStruc ENDS

Members

ExtFree_Size
A return value that represents the size of the ExtGetDskFreSpcStruc structure, in bytes. The Get_ExtFreeSpace sub-function returns the size value to this field. This member is used only as a return value.
ExtFree_Level
An input and return level value. This must be initialized to zero.
ExtFree_SectorsPerCluster
The number of sectors per cluster.
ExtFree_BytesPerSector
The number of bytes per sector.
ExtFree_AvailClusters
The number of available clusters.
ExtFree_TotalClusters
The total number of clusters on the drive.
ExtFree_AvailablePhysSectors
The number of physical sectors available on the drive, without adjustment for compression.
ExtFree_TotalPhysSectors
The total number of physical sectors on the drive, without adjustment for compression.
ExtFree_AvailableAllocationUnits
The number of available allocation units on the drive, without adjustment for compression.
ExtFree_TotalAllocationUnits
The total number of allocation units on the drive, without adjustment for compression.
ExtFree_Rsvd
Reserved field.


s_partition (FAT32)

[Windows 95 only.]

Note: Values for head and track are 0-based. Sector values are 1-based. This structure is implemented in Windows OEM Service Release 2 and later.

s_partition    STRUC
    Part_BootInd        DB    ?
    Part_FirstHead      DB    ?
    Part_FirstSector    DB    ?
    Part_FirstTrack     DB    ?
    Part_FileSystem     DB    ?
    Part_LastHead       DB    ?
    Part_LastSector     DB    ?
    Part_LastTrack      DB    ?
    Part_StartSector    DD    ?
    Part_NumSectors     DD    ?
s_partition    ENDS

Members

Part_BootInd
Specifies whether the partition is bootable or not. This value could be set to PART_BOOTABLE (80h), or PART_NON_BOOTABLE(00h). The first partition designated as PART_BOOTABLE is the boot partition. All others are not. Setting multiple partitions to PART_BOOTABLE will result in boot errors.
Part_FirstHead
The first head of this partition. This is a 0-based number representing the offset from the beginning of the disk. The partition includes this head.
Part_FirstSector
The first sector of this partition. This is a 1-based, 6-bit number representing the offset from the beginning of the disk. The partition includes this sector. Bits 0 through 5 specify the 6-bit value; bits 6 and 7 are used with the Part_FirstTrack field.
Part_FirstTrack
The first track of this partition. This is an inclusive 0-based, 10-bit number that represents the offset from the beginning of the disk. The high 2 bits of this value are specified by bits 6 and 7 of the Part_FirstSector field.
PartFileSystem
Specifies the file system for the partition. The following are acceptable values:
Value | Description
PART_UNKNOWN(00h) | Unknown.
PART_DOS2_FAT(01h) | 12-bit FAT.
PART_DOS3_FAT(04h) | 16-bit FAT. Partition smaller than 32MB.
PART_EXTENDED(05h) | Extended MS-DOS Partition.
PART_DOS4_FAT(06h) | 16-bit FAT. Partition larger than or equal to 32MB.
PART_DOS32(0Bh) | 32-bit FAT. Partition up to 2047GB.
PART_DOS32X(0Ch) | Same as PART_DOS32(0Bh), but uses Logical Block Address Int 13h extensions.
PART_DOSX13(0Eh) | Same as PART_DOS4_FAT(06h), but uses Logical Block Address Int 13h extensions.
PART_DOSX13X(0Fh) | Same as PART_EXTENDED(05h), but uses Logical Block Address Int 13h extensions.

Part_LastHead
The last head of the partition. This is a 0-based number that represents the offset from the beginning of the disk. The partition includes the head specified by this field.
Part_LastSector
The last sector of this partition. This is a 1-based, 6-bit number representing offset from the beginning of the disk. The partition includes the sector specified by this field. Bits 0 through 5 specify the 6-bit value; bits 6 and 7 are used with the Part_LastTrack field.
Part_LastTrack
The last track of this partition. This is a 0-based, 10-bit number that represents offset from the beginning of the disk. The partition includes this track. The high 2 bits of this value are specified by bits 6 and 7 of the Part_LastSector field.
Part_StartSector
Specifies the 1-based number of the first sector on the disk. This value may not be accurate for extended partitions. Use the Part_FirstSector value for extended partitions.
Part_NumSectors
The 1-based number of sectors in the partition.


SDPDFormatStruc (FAT32)

[Windows 95 only.]

Structure used to hold information on executing the various sub-functions of Int 21h Function 7304h Set_DPBForFormat (FAT32). This structure is implemented in Windows OEM Service Release 2 and later.

SDPDFormatStruc STRUC
    SetDPB_Size        DW    ?
    SetDPB_Level       DW    ?
    SetDPB_Function    DD    ?
    SetDPB_Value1      DD    ?
    SetDPB_Value2      DD    ?
    SetDPB_Value3      DD    ?
    SetDPB_Value4      DD    ?
SDPDFormatStruc ENDS

Members

SetDPB_Size
A return value field for the sub-functions. This is not an input field.
SetDPB_Level
An input and return level value field. This must be set to 0.
SetDPB_Funtion
Specifies which sub-function will be implemented. The acceptable values are as follows:
0 | SetDPB_SetAllocInfo
1 | SetDPB_SetDPBFrmBPB
2 | SetDPB_ForceMediaChng
3 | SetDPB_GetSetActFATandMirr
4 | SetDPB_GetSetRootDirClus

SetDPB_Value1
Input field for sub-function. See specific sub-function for details.
SetDPB_Value2
Input field for sub-function. See specific sub-function for details.
SetDPB_Value3
Input field for sub-function. See specific sub-function for details.
SetDPB_Value4
Input field for sub-function. See specific sub-function for details.


Legal Information

Performance Data Helper DLL

Information in this document is subject to change without notice. Companies, names, and data used in examples herein are fictitious unless otherwise noted. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without the express written permission of Microsoft Corporation.

Microsoft may have patents or pending patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. The furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property rights except as expressly provided in any written license agreement from Microsoft.

© 1996 - 1998 Microsoft Corporation. All rights reserved.

Microsoft, MS, Win32, Win32s, Windows, Windows NT, and Visual Basic are registered trademarks of Microsoft Corporation in the United States and/or other countries.

All other product and company names mentioned herein are the trademarks of their respective owners.


Performance Data Helper

You can use the performance data provided by applications, services, and drivers to determine system bottlenecks and fine-tune system and application performance. The easiest way to display the performance data is to use the Performance Monitor application located in the Administrative Tools group.

If you need to collect performance data for your application, the easiest way to do this is to use the interface provided by the Performance Data Helper (PDH) interface. Applications that need more control over performance data collection can use the registry interface directly. This is the method that is used by the functions in PDH.DLL and by the Performance Monitor. It is more efficient for the Performance Monitor to use the registry interface, because it displays counters grouped by object. If you are retrieving individual counters, rather than a group of counters from a particular object, it is just as efficient to use the PDH interface.

This overview discusses both interfaces.

  • The PDH Interface
  • The Registry Interface

In addition, this overview discusses how to add your own performance counters, by creating an extensible performance DLL. For more information, see Adding Performance Counters.


The PDH Interface

  • Collecting Performance Data.
  • Checking PDH Return Values
  • Enumerating Process Objects Using PDH


Collecting Performance Data

PDH functions work with queries and counters. A query is a set of performance counters that are grouped together so that you can collect their data at the same time. A counter is a performance data item stored in the Windows NT registry.

The counter names used by PDH are expressed as counter paths. A counter path uses a collection of hierarchical elements to describe a counter. In the same way that a file path includes drives, directories, subdirectories, and file names, a counter path includes machines, objects, instances, and counter names. The syntax for a counter path is:

\\Machine\PerfObject(ParentInstance/ObjectInstance#InstanceIndex)\Counter

The \\Machine component is optional; it specifies the name of the machine. If you do not supply this component, PDH uses the local machine name. Therefore, a single path string works on any machine that supports the counter.

The \PerfObject component is required; it specifies the performance object that contains the performance counter. These objects are listed in the PDH browse dialog box (see PdhBrowseCounters) and in the Performance Monitor Add To Chart dialog box, in the Objects combo box. If this object has a variable list of instances, then you must also specify an instance string.

The (ParentInstance/ObjectInstance#InstanceIndex) component is only required if the object supports multiple instances. If the instance supports a variable list of instances, then you must specify an instance string. The format of the string depends on the object type. If the object has simple instances, then the format is just the instance name enclosed in parentheses. For example:

(Explorer)

If the instance of this object requires a parent instance name as well, then the parent instance name must come before the object instance, and be separated by a forward slash character. For example:

(Explorer/0)

If the object has multiple instances that have the same name string, they can be indexed sequentially by specifying the instance index prefixed by a pound sign. Instance indexes are 0-based, so all instances have an implicit "0" index. For example:

(Explorer/0#1)

The \Counter component is required; it specifies the performance counter. The counter names are displayed in the PDH browse dialog box and in the Performance Monitor Add To Chart dialog box, in the Counters list box. The counters associated with the selected object are displayed.

The following are two common counters in the PDH counter path format:

\Processor(0)\% Processor Time
\System\% Total Processor Time

For more information on counters, see Performance Objects and Counters.

A query can contain one or more counters, and a counter can be contained in more than one query. To use PDH, you must create queries and add counters to them, as shown in the following sections.

  • Creating a query
  • Collecting data
  • Displaying data
  • Displaying statistical data
  • Ending data collection


Creating a Query

To create a new query, call the PdhOpenQuery function. The function returns a handle to the query to be used in other PDH function calls. You can create multiple queries to be used in your program.

After you create a query, call the PdhAddCounter function to add a counter to the query. Call PdhAddCounter for each counter to be added to the query. You can use one of the following methods to determine which counters to use.

  • Hard-code the counter name in the call to PdhAddCounter. Use this method if you always monitor the same counter.
  • Read the name from the registry or an initialization file. Use this method if the set of counters you monitor can change.
  • Call the PdhBrowseCounters function to display the PDH browse dialog box. The dialog box allows the user to browse and select performance counters. For more information, see Browsing Performance Counters.

You should use the PdhRemoveCounter function to remove a counter from a query.


Browsing Performance Counters

You can call the PdhBrowseCounters function to display the following dialog box, which lets you browse and select performance counters.

You control the configuration of the browse dialog box by setting members of the PDH_BROWSE_DLG_CONFIG structure that you pass to PdhBrowseCounters. The szReturnPathBuffer member contains a pointer to a buffer you allocate. The cchReturnPathLength member contains the size of the buffer you allocated. This buffer provides a communication link between your application and the browse dialog box.


Collecting Data

After you have created a query and added counters to it, call the PdhCollectQueryData function to retrieve the current raw data for all counters in the query. Many counters, such as rate counters, require the following two data samples before a valid data value can be determined.

  • Call PdhCollectQueryData before entering the section of code that you are measuring, to provide a starting value.
  • Call PdhCollectQueryData again after exiting the section of code that you are measuring, to get the ending value.


Displaying Data

The raw value of many counters is not what the user would expect to see. To get the information in the form described by most counter names, you need to compute the displayable value based on this raw data. PDH does this for you. For example, the Page Faults/Sec counter simply counts page faults, so if you view the raw data, you see a running total of page faults. To get the rate implied by the counter name, page faults per second, you need to call the PdhGetFormattedCounterValue function. In this case, the function divides the difference between two samples by the time between the samples.

The PdhGetFormattedCounterValue function performs its computations on the most recent sample. If you need to recalculate and redisplay a sample, you must retrieve the raw data with the PdhGetRawCounterValue function, store the raw data, and call the PdhCalculateCounterFromRawValue function to perform the calculation on the stored data.


Displaying Statistical Data

Calculating statistical values can be difficult, because many counter values are the result of a change over time. The PDH provides functions that perform calculations (such as minimum, maximum, and average values) on the raw counter data for you.

To retrieve the raw data for a counter to use in calculating statistical data, you must use the PdhGetRawCounterValue function. The raw values must be stored in an array of PDH_RAW_COUNTER structures allocated and maintained by the application. The raw values used to calculate the minimum, maximum, and average values.

After you have retrieved the raw data for a counter, call the PdhComputeCounterStatistics function to perform the necessary calculations on the raw data.


Ending Data Collection

After you are finished collecting data for a query, call the PdhCloseQuery function to close the query and release all allocated system resources. The function closes all counter handles associated with the query.


Checking PDH Return Values

The return value of PDH functions indicates the success or error of the function call, which is distinct from the status of the counter data. Always check the CStatus member of a counter value returned in the PDH structures to ensure that the data returned is valid before you use it. If the value of the CStatus member does not indicate success, do not use the data. The following are the possible status values for counters:

PDH_CSTATUS_NO_MACHINE
PDH was unable to connect to the machine specified in the counter path. If this status is returned when the counter is being added, the counter is not completely initialized. Each time the query is updated, PDH retries the connection. When the connection is established, normal data collection resumes.
PDH_CSTATUS_NO_OBJECT
The specified machine was found, but no matching performance object was found on that machine. If this status is returned when the counter is being added, the specified counter is not included in the query. If this status is returned by an active counter, the data for that counter is invalid. Each time the data is requested, PDH tries to obtain this counter data.
PDH_CSTATUS_NO_INSTANCE
The specified instance was not found in the object. If this status is returned while the counter is being added to the query, the counter is successfully added to the query, but no data is available until the specific instance appears and a successful status is returned.
PDH_CSTATUS_NO_COUNTER
The specified counter was not found in the specified object. If this status is returned when the counter is being added, then the counter is not added to the query. If this status is returned after a data update, the data for that counter is invalid. Each time the data is requested, PDH tries to obtain this counter data.
PDH_CSTATUS_INVALID_DATA
The counter was successfully found, but the data returned is not valid. One possible cause for this value is when the data of a normally increasing counter is less than the previous value. Another possible cause is a system timer that is not correct.
PDH_CSTATUS_VALID_DATA
The data for the counter was returned successfully, but is unchanged from the last time the counter was read.
PDH_CSTATUS_NEW_DATA
The data for the counter was returned successfully and is different from the last time the counter was read. PDH_CSTATUS_NEW_DATA can be returned on a rate counter even if the resulting rate is the same as the last sample. This is because the raw data value that is used in the determination of this status value has changed, not the computed rate.
PDH_CSTATUS_NO_COUNTERNAME
No counter path was specified.
PDH_CSTATUS_BAD_COUNTERNAME
The counter path format is incorrect.


Enumerating Process Objects Using PDH

The example in this topic uses the PDH interface to enumerate the process objects on the system.

#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE  1
#endif
#define tmain     wmain
#else
#define tmain     main
#endif

// This program only needs the essential windows header files.
#define WIN32_LEAN_AND_MEAN 1

#include <windows.h>
#include <winperf.h>
#include <malloc.h>
#include <stdio.h>
#include <tchar.h>
#include <pdh.h>

int
tmain ()
{
    PDH_STATUS  pdhStatus               = ERROR_SUCCESS;
    LPTSTR      szCounterListBuffer     = NULL;
    DWORD       dwCounterListSize       = 0;
    LPTSTR      szInstanceListBuffer    = NULL;
    DWORD       dwInstanceListSize      = 0;
    LPTSTR      szThisInstance          = NULL;

// Determine the required buffer size for the data.

    pdhStatus = PdhEnumObjectItems (
        NULL,                   // reserved
        NULL,                   // local machine
        TEXT("Process"),        // object to enumerate
        szCounterListBuffer,    // pass in NULL buffers
        &dwCounterListSize,     // an 0 length to get
        szInstanceListBuffer,   // required size
        &dwInstanceListSize,    // of the buffers in chars
        PERF_DETAIL_WIZARD,     // counter detail level
        0);

    if (pdhStatus == ERROR_SUCCESS)
    {
    // Allocate the buffers and try the call again.
        szCounterListBuffer = (LPTSTR)malloc (
            (dwCounterListSize * sizeof (TCHAR)));
        szInstanceListBuffer = (LPTSTR)malloc (
            (dwInstanceListSize * sizeof (TCHAR)));
        if ((szCounterListBuffer != NULL) &&
            (szInstanceListBuffer != NULL))
        {
            pdhStatus = PdhEnumObjectItems (
                NULL,   // reserved
                NULL,   // local machine
                TEXT("Process"), // object to enumerate
                szCounterListBuffer,    // pass in NULL buffers
                &dwCounterListSize,     // an 0 length to get
                szInstanceListBuffer,   // required size
                &dwInstanceListSize,    // of the buffers in chars
                PERF_DETAIL_WIZARD,     // counter detail level
                0);
            if (pdhStatus == ERROR_SUCCESS)
            {
                _tprintf (TEXT("\nRunning Processes:"));
            // Walk the return instance list.
                for (szThisInstance = szInstanceListBuffer;
                     *szThisInstance != 0;
                     szThisInstance += lstrlen(szThisInstance) + 1)
                {
                     _tprintf (TEXT("\n  %s"), szThisInstance);
                }
            }
        }
        else
        {
            _tprintf (TEXT("\nPROCLIST: unable to allocate buffers"));
        }

        if (szCounterListBuffer != NULL)
            free (szCounterListBuffer);

        if (szInstanceListBuffer != NULL)
            free (szInstanceListBuffer);
    }
    else
    {
        _tprintf(TEXT("\nUnable to determine required buffer size."));
    }
    return 0;
}


The Registry Interface

  • Performance Objects and Counters
  • The HKEY_PERFORMANCE_DATA_KEY
  • Performance Data Format
  • Navigating the Performance Data
  • Retrieving Counter Names and Explanations
  • Retrieving Selected Data
  • Displaying Object, Instance, and Counter Names
  • Adding Performance Counters


Performance Objects and Counters

The performance data is grouped by performance object to which it is related. A performance object consists of performance counters, which are used to measure various aspects of system, application, or device performance. For example, the Processor object includes the Processor Time counter to measure the percentage of time the processor spends executing threads that are not idle and the Interrupts/sec counter to measure the number of device interrupts the processor receives.

An instance is a unique copy of a particular object type. Not all object types support multiple instances. For example, a Memory object has only one instance, because a system has one memory. However, the Processor object supports multiple instances, because a system can have one or more processors.

Most performance counters in Windows NT increment and are never cleared. Therefore, to obtain performance data, use the following steps.

  • Take a snapshot of the relevant performance counters at the beginning of a time interval.
  • Take a snapshot of the same performance counters at the end of the time interval.
  • Find the difference between the counter values in the snapshots and apply the appropriate calculation function.

For a list of the system performance objects and performance counters, see Windows NT Performance Counters.


The HKEY_PERFORMANCE_DATA Key

The performance data is accessed through the registry key HKEY_PEFORMANCE_DATA. Each software component creates keys for its objects and counters when it is installed and writes counter data while it is executing. You can access this data as you would access any other registry data, using the registry functions. However, although you use the registry to collect performance data, the data is not stored in the registry database. Instead, calling the registry functions with the HKEY_PEFORMANCE_DATA key causes the system to collect the data from the appropriate system object managers.

To obtain performance data from the local system, use the RegQueryValueEx function, with the HKEY_PERFORMANCE_DATA key. The first call opens the key; you do not need to explicitly open the key first. However, be sure to use the RegCloseKey function to close the handle to the key when you are finished obtaining performance data. The user cannot install or remove a software component while its performance data is in use.

To obtain performance data from a remote system, you must use the RegConnectRegistry function, with the computer name of the remote system and the HKEY_PERFORMANCE_DATA key. This call retrieves a key representing the performance data for the remote system. To retrieve the data, call RegQueryValueEx using this key, rather than the HKEY_PERFORMANCE_DATA key.


Performance Data Format

The format of the data retrieved by the RegQueryValueEx function begins with a single header structure, PERF_DATA_BLOCK. The PERF_DATA_BLOCK structure describes the system and the performance data. The PERF_DATA_BLOCK structure is followed by a list of object information blocks (one per object).

PERF_DATA_BLOCK
Object 1 information
Object 2 information
Object 3 information
…
Object X information

Basic Performance Data Structure

Each object information block contains a PERF_OBJECT_TYPE structure, which describes the performance data for the object. The PERF_OBJECT_TYPE structure is followed by a list of PERF_COUNTER_DEFINITION structures, one for each counter defined for the object. For an object with only one instance, the list of PERF_COUNTER_DEFINITION structures is followed by a single PERF_COUNTER_BLOCK structure, followed by the data for each counter.

PERF_OBJECT_TYPE
PERF_COUNTER_DEFINITION 1
PERF_COUNTER_DEFINITION 2
PERF_COUNTER_DEFINITION 3
…
PERF_COUNTER_DEFINITION Y
PERF_COUNTER_BLOCK
Counter 1 data
Counter 2 data
Counter 3 data
…
Counter Y data

Structure of Object Information Block (One Instance)

For an object type that supports multiple instances, the list of PERF_COUNTER_DEFINITION structures is followed by a list of instance information blocks (one for each instance).

PERF_OBJECT_TYPE
PERF_COUNTER_DEFINITION 1
PERF_COUNTER_DEFINITION 2
PERF_COUNTER_DEFINITION 3
…
PERF_COUNTER_DEFINITION Y
Instance 1 Information
Instance 2 Information
Instance 3 Information
…
Instance Z Information

Structure of Object Information Block (Multiple Instances)

Each instance information block contains a PERF_INSTANCE_DEFINITION structure and a PERF_COUNTER_BLOCK structure.

PERF_INSTANCE_DEFINITION
Instance name
PERF_COUNTER_BLOCK
Counter Data 1
Counter Data 2
Counter Data 3
…
Counter Data Y

Structure of Instance Information Block


Navigating the Performance Data

The performance data contains information for a variable number of object types, instances per object, and counters per object type. Therefore, the number and size of blocks in the performance data varies. To ensure that your application correctly receives the performance data, you must use the offsets included in the performance structures to navigate through the data. Every offset is a count of bytes relative to the structure containing it.

For an example that navigates the registry, see Displaying Object, Instance, and Counter Names.

Note The reason the system uses offsets instead of pointers is that pointers are not valid across process boundaries. The addresses that the process that installs the counters would store would not be valid for the process that reads the counters.


Retrieving Counter Names and Explanations

Object type names, counter names, object explanations, and counter explanations are not made directly available in the performance data structures. Instead, the performance data structures contain indices you can use to locate where the names and explanations for each object and counter can be found. The ObjectNameTitleIndex and ObjectHelpTitleIndex members of the PERF_OBJECT_TYPE structure contain the indices to the object name and explanation, respectively. The CounterNameTitleIndex and CounterHelpTitleIndex members of the PERF_COUNTER_DEFINITION structure contain the indices to the counter name and explanation, respectively.

To access the names and explanations, read the Counter and Help values in the following registry key.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT
\CurrentVersion\Perflib\langid

The langid is the ASCII representation of the 3-digit hexadecimal language identifier. For example, the U.S. English langid is 009. In a non-English version of Windows NT, counters are stored in both the native language of the system and in English.

The data is stored as MULTI_SZ strings. This data type consists of a list of Unicode strings, each terminated with UNICODE_NULL. The last string is followed by an additional UNICODE_NULL. The strings are listed in pairs. The first string of each pair is the Unicode string of the index, and the second string is the actual name of the index. The Counter data uses only even-numbered indexes, while the Help data has odd-numbered indexes. For example, the Counter data contains the following object and counter name strings.

2    System
4    Memory
6    % Processor Time

The Help data contains the following counter explanations.

3    The System object type includes those counters that...
5    The Memory object type includes those counters that...
7    Processor Time is expressed as a percentage of the...

To retrieve a name or explanation for an object type or counter, given its index, an application should perform the following steps.

  1. If the system is remote, call the RegConnectRegistry function.
  2. Use the RegOpenKeyEx function to open the registry key containing the name and explanation text.
  3. Use the RegQueryValueEx function, specifying either Counter or Help as the name of the value to query.
  4. Convert the index into Unicode or ASCII, depending on whether your application is Unicode or ASCII.
  5. Search the MULTI_SZ data for the appropriate index.
  6. Retrieve the string following the matching index. The string contains the name or explanation.

If you are going to be looking up a number of counters, you should build a table for faster and easier lookup. For an example, see Displaying Object, Instance, and Counter Names.


Retrieving Selected Data

Retrieving the performance data is not without cost to the system, especially in terms of processor and memory requirements. In cases where your application does not need all the performance data, you can use the lpszValueName parameter of the RegQueryValueEx function to indicate the amount of information to retrieve. The following table lists the values you can specify for lpszValueName. Note that the value strings are case-sensitive, and if a string includes more than one word, your words must be separated by a space.

Value | Description
Global | The function returns all data for counters on the local computer, except those included in the Costly category.
nnn xx yyy | Each of these is a Unicode string representing the decimal value for an object name index. The function only returns data about the specified object types on the local computer. For example, if your program were to use "2 4", the System and Memory objects would be retrieved. Note that more object types can be returned than are requested. This occurs when the requested object type depends on another object type. For example, processes are needed to identify threads, so information for the Process object is also returned when you request information for the Thread object.
Foreign ssss | The string ssss is the name of a foreign computer, such as a Novell NetWare server or a UNIX system. If your system is capable of collecting data from a foreign computer, the function returns all data for counters on the foreign computer. Try this approach if the RegConnectRegistry function fails to connect to a foreign computer.
Foreign ssss nnn xx yyy | This format combines Foreign ssss and nnn xx yyy.
Costly | The function returns data for object types whose data is expensive to collect in terms of processor time or memory usage. Start a worker thread if your application needs to respond to the user during this lengthy data collection.


Calculations for Raw Counter Data

This section lists the types of performance counters and the calculations that the Performance Monitor uses to convert the raw data to the information you would expect from the counter name. The counter types and calculations are defined in winperf.h. For the calculations, the following key applies:

Symbol | Definition
N | Numerator
D | Denominator
TB | Time base (indicates the units of raw data if not used in calculation)
B | Base count (number of entries)
N0 | Oldest or first sample taken (of the numerator in this case; D0 would be of the denominator)
N1 | More recent sample
Nx | Most recent sample in calculation array (for average calculation)

PERF_100NSEC_MULTI_TIMER Timer for when multiple instances are in use, so the result can exceed 100%. The number of instances is in the next counter.

Element | Value
Numerator | CounterData
Denominator | 100NsTime
Time base | 100Ns
Calculation | (N1-N0)/(D1-D0)
Average function | (Nx-N0)/(Dx-D0)

PERF_100NSEC_MULTI_TIMER_INV The inverse of the timer for multiple instances (when the object is not in use).

Element | Value
Numerator | CounterData
Denominator | 100NsTime
Time base | 100Ns
Calculation | (B-((N1-N0)/(D1-D0)))
Average function | (B-((Nx-N0)/(Dx-D0)))

PERF_100NSEC_TIMER Timer for when the object is in use.

Element | Value
Numerator | CounterData
Denominator | 100NsTime
Time base | 100Ns
Calculation | (N1-N0)/(D1-D0)
Average function | (Nx-N0)/(Dx-D0)

PERF_100NSEC_TIMER_INV The inverse of the timer (when the object is not in use).

Element | Value
Numerator | CounterData
Denominator | 100NsTime
Time base | 100Ns
Calculation | (1-((N1-N0)/(D1-D0)))
Average function | (1-((Nx-N0)/(Dx-D0)))

PERF_AVERAGE_BASE Used as the denominator in the computation of time or count averages.

Element | Value
Numerator | N/A
Denominator | N/A
Time base | N/A
Calculation | N/A
Average function | N/A

PERF_AVERAGE_BULK A count which usually gives the bytes per operation when divided by the number of operations.

Element | Value
Numerator | CounterData
Denominator | BaseData
Time base | N/A
Calculation | (N1-N0)/(D1-D0)
Average function | (Nx-N0)/(Dx-D0)

PERF_AVERAGE_TIMER A timer which usually gives time per operation when divided by the number of operations.

Element | Value
Numerator | CounterData
Denominator | BaseData
Time base | PerfFreq
Calculation | ((N1-N0)/TB)/(D1-D0)
Average function | ((Nx-N0)/TB)/(Dx-D0)

PERF_COUNTER_BULK_COUNT Used to count byte transmission rates.

Element | Value
Numerator | CounterData
Denominator | PerfTime
Time base | PerfFreq
Calculation | (N1-N0)/((D1-D0)/TB)
Average function | (Nx-N0)/((Dx-D0)/TB)

PERF_COUNTER_COUNTER Rate of counts. The most common counter.

Element | Value
Numerator | CounterData
Denominator | PerfTime
Time base | PerfFreq
Calculation | (N1-N0)/((D1-D0)/TB)
Average function | (Nx-N0)/((Dx-D0)/TB)

PERF_COUNTER_DELTA Difference between two counters.

Element | Value
Numerator | CounterData
Denominator | N/A
Time base | N/A
Calculation | (N1-N0)
Average function | (Nx-N0)/x

PERF_COUNTER_LARGE_DELTA Difference between two counters.

Element | Value
Numerator | CounterData
Denominator | N/A
Time base | N/A
Calculation | (N1-N0)
Average function | (Nx-N0)/x

PERF_COUNTER_LARGE_QUEUELEN_TYPE Average count per time interval.

Element | Value
Numerator | CounterData
Denominator | PerfTime
Time base | PerfFreq
Calculation | (N1-N0)/(D1-D0)
Average function | (Nx-N0)/(Dx-D0)

PERF_COUNTER_LARGE_RAWCOUNT Instantaneous counter value.

Element | Value
Numerator | CounterData
Denominator | N/A
Time base | N/A
Calculation | (N0)
Average function | SUM(N)/x

PERF_COUNTER_LARGE_RAWCOUNT_HEX Instantaneous counter value, as a hexadecimal number.

Element | Value
Numerator | CounterData
Denominator | N/A
Time base | N/A
Calculation | (N0)
Average function | SUM(N)/x

PERF_COUNTER_MULTI_BASE Base for MULTI counters.

Element | Value
Numerator | N/A
Denominator | N/A
Time base | N/A
Calculation | N/A
Average function | N/A

PERF_COUNTER_MULTI_TIMER Timer for when multiple instances are in use, so the result can exceed 100%. The number of instances is in the next counter.

Element | Value
Numerator | CounterData
Denominator | PerfTime
Time base | PerfFreq
Calculation | (N1-N0)/(D1-D0)
Average function | (Nx-N0)/(Dx-D0)

PERF_COUNTER_MULTI_TIMER_INV The inverse of the timer for multiple instances (when the object is not in use).

Element | Value
Numerator | CounterData
Denominator | PerfTime
Time base | PerfFreq
Calculation | (B-((N1-N0)/(D1-D0)))
Average function | (B-((Nx-N0)/(Dx-D0)))

PERF_COUNTER_NODATA There is no data for this counter.

Element | Value
Numerator | 0
Denominator | N/A
Time base | N/A
Calculation | 0
Average function | 0

PERF_COUNTER_QUEUELEN_TYPE Average count per time interval.

Element | Value
Numerator | CounterData
Denominator | PerfTime
Time base | PerfFreq
Calculation | (N1-N0)/(D1-D0)
Average function | (Nx-N0)/(Dx-D0)

PERF_COUNTER_RAWCOUNT Instantaneous counter value.

Element | Value
Numerator | CounterData
Denominator | N/A
Time base | N/A
Calculation | (N0)
Average function | SUM(N)/x

PERF_COUNTER_RAWCOUNT_HEX Instantaneous counter value, as a hexadecimal number.

Element | Value
Numerator | CounterData
Denominator | N/A
Time base | N/A
Calculation | (N0)
Average function | SUM(N)/x

PERF_COUNTER_TEXT Indicates the data is not a counter, but is Unicode text.

Element | Value
Numerator | N/A
Denominator | N/A
Time base | N/A
Calculation | N/A
Average function | N/A

PERF_COUNTER_TIMER The most common timer.

Element | Value
Numerator | CounterData
Denominator | PerfTime
Time base | PerfFreq
Calculation | (N1-N0)/(D1-D0)
Average function | (Nx-N0)/(Dx-D0)

PERF_COUNTER_TIMER_INV The inverse of the timer (when the object is not in use).

Element | Value
Numerator | CounterData
Denominator | PerfTime
Time base | PerfFreq
Calculation | (1-((N1-N0)/(D1-D0)))
Average function | (1-((Nx-N0)/(Dx-D0)))

PERF_ELAPSED_TIME The data is the start time of the item being measured. For display, subtract the start time from the snapshot time to yield the elapsed time. The PerfTime member of the PERF_OBJECT_TYPE structure contains the sample time. Use the PerfFreq member of the PERF_OBJECT_TYPE structure to convert the time into seconds.

Element | Value
Numerator | CounterData
Denominator | ObjectTime
Time base | ObjectFreq
Calculation | (D0-N0)/TB
Average function | (Dx-N0)/TB

PERF_RAW_BASE Used as a base. Check that this value is greater than zero before dividing.

Element | Value
Numerator | N/A
Denominator | N/A
Time base | N/A
Calculation | N/A
Average function | N/A

PERF_RAW_FRACTION Instantaneous value, to be divided by the base.

Element | Value
Numerator | CounterData
Denominator | BaseData
Time base | N/A
Calculation | (N0/D0)
Average function | SUM(N/D)/x

PERF_SAMPLE_BASE Used as a base. Check that this value is greater than zero before dividing.

Element | Value
Numerator | N/A
Denominator | N/A
Time base | N/A
Calculation | N/A
Average function | N/A

PERF_SAMPLE_COUNTER A count that is sampled on each sampling interrupt. Must be divided by the base.

Element | Value
Numerator | CounterData
Denominator | PerfTime
Time base | PerfFreq
Calculation | (N1-N0)/((D1-D0)/TB)
Average function | (Nx-N0)/((Dx-D0)/TB)

PERF_SAMPLE_FRACTION A count that is either 1 or 0 on each sampling interrupt.

Element | Value
Numerator | CounterData
Denominator | BaseData
Time base | N/A
Calculation | (N1-N0)/(D1-D0)
Average function | (Nx-N0)/(Dx-D0)


Displaying Object, Instance, and Counter Names

The following example displays the index and name of each object, along with the indices and names of its counters.

The object and counter names are stored in the registry, by index. This example creates a function, GetNameStrings, to load the indices and names of each object and counter from the registry into an array, so that they can be easily accessed. GetNameStrings uses the following standard registry functions to access the data: RegOpenKey, RegCloseKey, RegQueryInfoKey, and RegQueryValueEx.

This example creates the following functions for navigating the performance data: FirstObject, FirstInstance, FirstCounter, NextCounter, NextInstance, and NextCounter. These functions navigate the performance data by using the offsets stored in the performance structures.

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>

#define TOTALBYTES    8192
#define BYTEINCREMENT 1024

LPSTR lpNameStrings;
LPSTR *lpNamesArray;

/*****************************************************************
 *                                                               *
 * Functions used to navigate through the performance data.      *
 *                                                               *
 *****************************************************************/

PPERF_OBJECT_TYPE FirstObject( PPERF_DATA_BLOCK PerfData )
{
    return( (PPERF_OBJECT_TYPE)((PBYTE)PerfData +
        PerfData->HeaderLength) );
}

PPERF_OBJECT_TYPE NextObject( PPERF_OBJECT_TYPE PerfObj )
{
    return( (PPERF_OBJECT_TYPE)((PBYTE)PerfObj +
        PerfObj->TotalByteLength) );
}

PPERF_INSTANCE_DEFINITION FirstInstance( PPERF_OBJECT_TYPE PerfObj )
{
    return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfObj +
        PerfObj->DefinitionLength) );
}

PPERF_INSTANCE_DEFINITION NextInstance(
    PPERF_INSTANCE_DEFINITION PerfInst )
{
    PPERF_COUNTER_BLOCK PerfCntrBlk;

    PerfCntrBlk = (PPERF_COUNTER_BLOCK)((PBYTE)PerfInst +
        PerfInst->ByteLength);

    return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfCntrBlk +
        PerfCntrBlk->ByteLength) );
}

PPERF_COUNTER_DEFINITION FirstCounter( PPERF_OBJECT_TYPE PerfObj )
{
    return( (PPERF_COUNTER_DEFINITION) ((PBYTE)PerfObj +
        PerfObj->HeaderLength) );
}

PPERF_COUNTER_DEFINITION NextCounter(
    PPERF_COUNTER_DEFINITION PerfCntr )
{
    return( (PPERF_COUNTER_DEFINITION)((PBYTE)PerfCntr +
        PerfCntr->ByteLength) );
}

/*****************************************************************
 *                                                               *
 * Load the counter and object names from the registry to the    *
 * global variable lpNamesArray.                                 *
 *                                                               *
 *****************************************************************/

void GetNameStrings( )
{
    HKEY hKeyPerflib;      // handle to registry key
    HKEY hKeyPerflib009;   // handle to registry key
    DWORD dwMaxValueLen;   // maximum size of key values
    DWORD dwBuffer;        // bytes to allocate for buffers
    DWORD dwBufferSize;    // size of dwBuffer
    LPSTR lpCurrentString; // pointer for enumerating data strings
    DWORD dwCounter;       // current counter index

// Get the number of Counter items.

    RegOpenKeyEx( HKEY_LOCAL_MACHINE,
        "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib",
        0,
        KEY_READ,
        &hKeyPerflib);

    dwBufferSize = sizeof(dwBuffer);

    RegQueryValueEx( hKeyPerflib,
        "Last Counter",
        NULL,
        NULL,
        (LPBYTE) &dwBuffer,
        &dwBufferSize );

    RegCloseKey( hKeyPerflib );

// Allocate memory for the names array.

    lpNamesArray = malloc( (dwBuffer+1) * sizeof(LPSTR) );

// Open key containing counter and object names.

    RegOpenKeyEx( HKEY_LOCAL_MACHINE,
    "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009",
        0,
        KEY_READ,
        &hKeyPerflib009);

// Get the size of the largest value in the key (Counter or Help).

    RegQueryInfoKey( hKeyPerflib009,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        &dwMaxValueLen,
        NULL,
        NULL);

// Allocate memory for the counter and object names.

    dwBuffer = dwMaxValueLen + 1;

    lpNameStrings = malloc( dwBuffer * sizeof(CHAR) );

// Read Counter value.

    RegQueryValueEx( hKeyPerflib009,
        "Counter",
        NULL,
        NULL,
        lpNameStrings, &dwBuffer );

// Load names into an array, by index.

    for( lpCurrentString = lpNameStrings; *lpCurrentString;
         lpCurrentString += (lstrlen(lpCurrentString)+1) )
    {
        dwCounter = atol( lpCurrentString );

        lpCurrentString += (lstrlen(lpCurrentString)+1);

        lpNamesArray[dwCounter] = (LPSTR) lpCurrentString;
    }
}

/*****************************************************************
 *                                                               *
 * Display the indices and/or names for all performance objects, *
 * instances, and counters.                                      *
 *                                                               *
 *****************************************************************/

void main()
{
    PPERF_DATA_BLOCK PerfData = NULL;
    PPERF_OBJECT_TYPE PerfObj;
    PPERF_INSTANCE_DEFINITION PerfInst;
    PPERF_COUNTER_DEFINITION PerfCntr, CurCntr;
    PPERF_COUNTER_BLOCK PtrToCntr;
    DWORD BufferSize = TOTALBYTES;
    DWORD i, j, k;

// Get the name strings through the registry.

    GetNameStrings( );

// Allocate the buffer for the performance data.

    PerfData = (PPERF_DATA_BLOCK) malloc( BufferSize );

    while( RegQueryValueEx( HKEY_PERFORMANCE_DATA,
                               "Global",
                               NULL,
                               NULL,
                               (LPBYTE) PerfData,
                               &BufferSize ) == ERROR_MORE_DATA )
    {
    // Get a buffer that is big enough.

        BufferSize += BYTEINCREMENT;
        PerfData = (PPERF_DATA_BLOCK) realloc( PerfData, BufferSize );
    }

// Get the first object type.

    PerfObj = FirstObject( PerfData );

// Process all objects.

    for( i=0; i < PerfData->NumObjectTypes; i++ )
    {
    // Display the object by index and name.

        printf( "\nObject %ld: %s\n", PerfObj->ObjectNameTitleIndex,
            lpNamesArray[PerfObj->ObjectNameTitleIndex] );

    // Get the first counter.

        PerfCntr = FirstCounter( PerfObj );

        if( PerfObj->NumInstances > 0 )
        {
        // Get the first instance.

            PerfInst = FirstInstance( PerfObj );

        // Retrieve all instances.

            for( k=0; k < PerfObj->NumInstances; k++ )
            {
            // Display the instance by name.

                printf( "\n\tInstance %S: \n",
                    (char *)((PBYTE)PerfInst + PerfInst->NameOffset));
                CurCntr = PerfCntr;

            // Retrieve all counters.

                for( j=0; j < PerfObj->NumCounters; j++ )
                {
                // Display the counter by index and name.

                    printf("\t\tCounter %ld: %s\n",
                        CurCntr->CounterNameTitleIndex,
                        lpNamesArray[CurCntr->CounterNameTitleIndex]);

                // Get the next counter.

                    CurCntr = NextCounter( CurCntr );
                }

            // Get the next instance.

                PerfInst = NextInstance( PerfInst );
            }
        }
        else
        {
        // Get the counter block.

            PtrToCntr = (PPERF_COUNTER_BLOCK) ((PBYTE)PerfObj +
                            PerfObj->DefinitionLength );

        // Retrieve all counters.

            for( j=0; j < PerfObj->NumCounters; j++ )
            {
            // Display the counter by index and name.

                printf( "\tCounter %ld: %s\n", PerfCntr->CounterNameTitleIndex,
                    lpNamesArray[PerfCntr->CounterNameTitleIndex] );

            // Get the next counter.

                PerfCntr = NextCounter( PerfCntr );
            }
        }

    // Get the next object type.

        PerfObj = NextObject( PerfObj );
    }
}


Adding Performance Counters

Windows NT provides a mechanism for you to add performance objects and counters for your application and other software components. Performance counters specific to your application can help you tune performance while you develop and debug the application. After your application is complete and installed on target systems, the counters can help system administrators adjust configurable settings for your application.

To add an extended object and its counters, use the following steps.

  1. Design the object types and counters for the application. See Object and Counter Design.
  2. Create an initialization (.INI) file containing the names and descriptions of the counter objects and counters. See Adding Counter Names and Descriptions to the Registry.
  3. Create a header (.H) file containing the relative offsets at which the counter objects and counters will be installed in the registry. See Adding Counter Names and Descriptions to the Registry.
  4. Set up the necessary performance monitoring entries in the registry. This includes the following steps.
    1. Create a registry key in the Services key for the application. If you do not have such a node, create it under the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services. Creating the Application's Performance Key
    2. Use the lodctr utility with the .INI and .H files to install the information in the registry. This utility succeeds only if a performance key exists in the Services key for the application. See Adding Counter Names and Descriptions to the Registry.
  5. Create a performance DLL containing a set of exported functions that provide the link between the application and a performance monitoring application. See Creating the Performance DLL.
  6. Modify the application's setup file to automate adding information to the registry (as described in step 4) and move your performance DLL to the system directory at setup.

To view an extended object, its functions, and its counter, use the extensible counter list utility (EXCTRLST.EXE). For more information, see ExCtrLst.


Object and Counter Design

A performance object is an entity for which performance data is available. Performance counters define the type of data that is available for a counter object. An application can provide information for multiple performance objects, each with one or more counters.

An application can also define objects that have multiple instances. For example, a SCSI application could use a single set of counter definitions to define a drive object with two counters, such as Bytes Read and Bytes Written. The performance DLL for the application could report performance data for each drive controlled by the application.

The Windows NT Performance Monitor can show some counters as rates, such as Page Faults/sec, as well as a raw count. This gives context to the users, so they do not have to compare data from different time intervals. However, you do not have to take this into account when you design a counter. You increment the counter and let the monitor application do the work of converting raw counts to a rate.

The method you use to collect the data can be as simple as incrementing a counter each time a particular routine in the application is called, or it can involve time-consuming calculations. Counters and timers should increment and never be cleared. Counters can wrap, as long as they do not wrap twice between snapshots. Your application can collect and store data during its normal execution, as long as it does not affect the its performance.

For some types of data, it may be more efficient or appropriate to collect the data on demand. In this situation, the performance DLL must communicate to the application that the data has been requested. For data that is expensive to collect (in terms of processor time or memory usage), consider collecting data only when the performance monitoring program requests Costly data. This allows a custom performance monitoring program to routinely request data for all counters that are not costly. The data can be requested only when needed. The Windows NT Performance Monitor does not collect Costly data.


Updating the Registry

There are several updates that you must make to the registry when you install or uninstall your performance DLL.

  • Creating the application's performance key
  • Adding counter names and descriptions to the registry.
  • Removing counter names and descriptions from the registry.
  • Creating other registry entries


Creating the Application's Performance Key

An application that supports performance counters must have a Performance key under the Services key. The following example shows the values you should include for this key.

HKEY_LOCAL_MACHINE
    \SYSTEM
        \CurrentControlSet
            \Services
                \Application_Name
                    \Performance
                        Library = DLL_Name
                        Open = Open_Function_Name
                        Collect = Collect_Function_Name
                        Close = Close_Function_Name

The Library value provides the name of the performance DLL, and the Open, Collect, and Close values provide the names of the functions exported from the performance DLL. When a performance monitoring application requests performance data, the system uses these values to determine which performance DLLs to load and which DLL functions to call.


Adding Counter Names and Descriptions to the Registry

The names and descriptions of all performance objects and their counters are stored using the registry. You must add this information for the objects and counters you add to the system.

The following example shows the registry location where performance counter names and descriptions are stored.

HKEY_LOCAL_MACHINE
    \SOFTWARE
        \Microsoft
            \Windows NT
                \CurrentVersion
                    \Perflib
                        Last Counter = highest counter index
                        Last Help = highest help index
                        \009
                            Counter = 2 System 4 Memory ...
                            Help = 3 The System object type ...
                        \supported language, other than U.S. English
                            Counter = ...
                            Help = ...

To add names and descriptions of the objects and counters for your application, use the lodctr utility included with Windows NT. The lodctr utility takes strings from an .INI file and adds them to the Counter and Help values under the appropriate language subkeys. It also updates the Last Counter and Last Help values. In addition to adding values under the PerfLib key, the lodctr utility also adds the following value entries to the Services node for the application.

\HKEY_LOCAL_MACHINE
    \SYSTEM
        \CurrentControlSet
            \Services
                \Application_Name
                    \Performance
                        First Counter = lowest counter index
                        First Help = lowest help index
                        Last Counter = highest counter index
                        Last Help = highest help index

Using lodctr

The command-line syntax for lodctr is:

lodctr MyApplication.ini

Initialization (.INI) File

The .INI file used by lodctr has the following format:

[info]
drivername=Application_Name
symbolfile=SymbolFile

// One key (value optional) for each language supported.
[languages]
langid=
 .
 .
 .

// Name and description for each counter or counter object
[text]
offset_langid_NAME=Name         // Counter name string.
offset_langid_HELP=Description  // Help description string.
 .
 .
 .

The .INI file entries are variables with the following meanings:

Variable | Description
DriverName | The name of the performance key created under the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services key.
SymbolFile | An .H file containing symbolic offsets of counters. The performance DLL also uses the offsets in this file along with the First Counter and First Help registry values to determine the indexes of the various counters and counter objects.
Langid | An ID corresponding to the language subkey in the registry (for example, 009 for U.S. English).
Offset | A symbolic constant defined in SymbolFile. Offsets must be consecutive, even numbers beginning with zero. These offsets determine the order in which the counters are installed in the Counter and Help values in the registry.

The following is an example SymbolFile.

// SYMFILE.H

#define OBJECT_1    0
#define DEVICE_COUNTER_1    2
#define DEVICE_COUNTER_2    4

The following is an example .INI file.

// begin .INI file example
[info]
drivername=MyApplication
symbolfile=symfile.h

[languages]
009=English
011=OtherLanguage

[text]
OBJECT_1_009_NAME=Device Name
OBJECT_1_009_HELP=Displays performance statistics on Device Name
OBJECT_1_011_NAME=Device Name in other language
OBJECT_1_011_HELP=Displays performance of Device Name in other language

DEVICE_COUNTER_1_009_NAME=Counter A
DEVICE_COUNTER_1_009_HELP=Displays the current value of Counter A
DEVICE_COUNTER_1_011_NAME=Counter A in other language
DEVICE_COUNTER_1_011_HELP=Displays the value of Counter A in other language

DEVICE_COUNTER_2_009_NAME=Counter B
DEVICE_COUNTER_2_009_HELP=Displays the current rate of Device B
DEVICE_COUNTER_2_011_NAME=Counter B in other language
DEVICE_COUNTER_2_011_HELP=Displays the rate of Device B in other language

If you run lodctr to add counters for an application and the application does not have a Services key, lodctr returns without modifying the Perflib values.

Note The loading function of LODCTR, LoadPerfCounterTextStrings, is declared in LOADPERF.H and exported from LOADPERF.DLL. This allows you to call this function directly from your install program. The syntax for this function is as follows:

LONG LoadPerfCounterTextStrings(

LPSTR lpCommandLine,
BOOL bQuietModeArg
);

where lpCommandLine is the name of your initialization file and bQuietModeArg is a Boolean parameter that indicates whether to display output during the loading of the counter text strings. If the function succeeds, the return value is ERROR_SUCCESS. If the function fails, the return value is a nonzero error code defined in WINERROR.H.


Removing Counter Names and Descriptions from the Registry

If you need to remove counter names and descriptions from the registry, use the unlodctr utility. This removes the registry entries made by lodctr.

Using unlodctr

The command-line syntax for unlodctr is:

unlodctr Application_Name

The unlodctr utility looks up the First Counter and Last Counter values in the application's Performance key to determine the indexes of the counter objects to remove. Using these indexes, it makes the following changes to the Perflib key.

HKEY_LOCAL_MACHINE
    \SOFTWARE
        \Microsoft
            \Windows NT
                \CurrentVersion
                    \Perflib
                        Last Counter = updated if changed
                        Last Help = updated if changed
                        \009
                            Counter = application text removed
                            Help    = application text removed
                        \supported language, other than U.S. English
                            Counter = application text removed
                            Help    = application text removed

The unlodctr utility also removes the First Counter, First Help, Last Counter, and Last Help values from the application's Performance key.

Note The unloading function of UNLODCTR, UnloadPerfCounterTextStrings, is declared in LOADPERF.H and exported from LOADPERF.DLL. This allows you to call this function directly from your uninstall program. The syntax for this function is as follows:

LONG UnloadPerfCounterTextStrings(

LPSTR lpCommandLine,
BOOL bQuietModeArg
);

where lpCommandLine is the name of your application and bQuietModeArg is a Boolean parameter that indicates whether to display output during the unloading of the counter text strings. If the function succeeds, the return value is ERROR_SUCCESS. If the function fails, the return value is a nonzero error code defined in WINERROR.H.


Creating Other Registry Entries

To obtain the performance data for some applications (those that return counters using the DeviceIOControl function), it is necessary to use the CreateFile function to open the device associated with the application. In this case, the name specified in CreateFile must also be installed in the DOS Devices node of the registry, as shown here:

HKEY_LOCAL_MACHINE
    \SYSTEM
        \CurrentControlSet
            \Control
                \Session Manager
                    \DOS Devices

Applications that manage multiple device instances with performance data for each device, must put a Linkage key in the its Services key. The Linkage key contains an Export value whose data is a list of the device names. For example, a system with two Etherlink cards could have the following registry entries:

HKEY_LOCAL_MACHINE
    \SYSTEM
        \CurrentControlSet
            \Services
                \Elnkii
                    \Linkage
                        Export = "\Device\Elnk01" "\Device\Elnk02"
                    \Performance
                        Library = "ElnkStat.dll"
                        Open = "OpenElnkStats"
                        Collect = "GetElnkStats"
                        Close = "CloseElnkStats"
                \Elnk01
                    \Linkage
                    \Parameters
                \Elnk02
                    \Linkage
                    \Parameters

When the system calls the Open function in an application's performance DLL, its argument is a string containing the list of device names from the application's Export value, if it is present. The Open function can then use these names to determine the devices for which to collect performance data.


Creating the Performance DLL

Your application's performance DLL defines the counter and object data structures that it uses to pass performance data to the performance monitor application. Your DLL also provides the following exported functions that are called by the system in response to requests for performance data.

Function | Description
Open | Initializes performance monitoring for the application.
Collect | Reports performance data when requested.
Close | Closes performance monitoring.

The prototypes for these functions, and the structures and constants used to define counters and counter objects, are defined in the WINPERF.H file distributed with the Platform SDK.

Communication between an application and its performance DLL differs for user-mode and privileged-mode applications. The application's performance DLL executes in user mode. Because of this, user-mode applications, such as print and display applications, can use any technique for interprocess communication, such as named pipes, file mapping, or RPC. However, privileged-mode applications must provide an IOCTL interface that returns the performance data to the performance DLL.


How the DLL Interfaces with a Performance Monitor Application

An application retrieves performance data by specifying HKEY_PERFORMANCE_DATA in a call to the RegQueryValueEx function. If successful, RegQueryValueEx fills a buffer of the application with the requested performance data.

The first time an application calls RegQueryValueEx, or if the application uses the RegOpenKey function to open HKEY_PERFORMANCE_DATA, the system calls the Open function for each application with the correct registry entries. This gives each performance DLL an opportunity to initialize its performance data structures. Then, if the Open function returns successfully (or if there is no Open function), the system calls the Collect function. Subsequent calls to RegQueryValueEx cause the system to call the Collect function.

When the application has finished collecting performance data, it specifies HKEY_PERFORMANCE_DATA in a call to the RegCloseKey function. This causes the system to call the Close function for each application. The performance DLLs are then unloaded.

Note It is possible for multiple programs to collect performance data at the same time. The system calls Open and Close functions only once for each application requesting performance data. For remote measurement, the system limits access to these routines to one thread at a time, so synchronization is not a problem. However, for local measurement, because multiple processes may be making simultaneous calls, you must prevent any conflicts from multiple concurrent requests for data.


The Open Function

The system calls the Open function whenever an application first connects to the registry to collect performance data. This function performs the initialization required for the application to provide performance data.

Use the following function prototype for your Open function.

DWORD CALLBACK OpenPerformanceData(LPWSTR lpDeviceNames);

The name OpenPerformanceData is a place-holder for an application-defined name. The lpDeviceNames argument points to a buffer containing the Unicode strings stored in the Export value in the following registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
Application_Name\Linkage

The strings are REG_MULTI_SZ strings, separated by a UNICODE_NULL, and terminated by two UNICODE_NULL characters. If this entry does not exist, lpDeviceNames should be NULL. The strings are the names of the devices managed by this application. The Open function should call the CreateFile function to open a handle to each device named. If CreateFile fails, the Open function should return the error code returned by the GetLastError function; otherwise, it should return ERROR_SUCCESS.

The Open function initializes the data structures it returns to the performance monitor application. In particular, it examines the registry to get the Counter and Help indices of the objects and counters supported by the application. It then stores these indices in the appropriate members of the PERF_OBJECT_TYPE and PERF_COUNTER_DEFINITION structures.

Other initialization tasks that might be performed by the Open function include the following:

  • Open and map a file mapping object used by the program to store performance data. Create a mutex to prevent the application from changing a value while the performance DLL is reading it. This is one way to communicate performance data from the application to the performance DLL. If you are using another form of interprocess communication, substitute the appropriate steps to initialize that mechanism.
  • Initialize event logging, if the DLL uses event logging to report errors. This is the only way for the performance DLL to report error conditions to the user, other than through a debugger. For more information, see Event Logging.
  • Initialize the object and counter indexes. This must be done each time the performance DLL is loaded, because the indices vary from machine to machine.
  • Perform other initialization tasks necessary for the Collect function to collect performance data efficiently.

The Open function should write any error that prevents the function from completing successfully in the system event log.


The Collect Function

The system calls each application's Collect function whenever a performance monitor program calls the RegQueryValueEx function to collect performance data. This function returns the application's performance data.

Use the following function prototype for your Collect function.

DWORD WINAPI CollectPerformanceData(
    LPWSTR lpwszValue,
    LPVOID *lppData,
    LPDWORD lpcbBytes,
    LPDWORD lpcObjectTypes);

The name CollectPerformanceData is a place-holder for an application-defined name.

Argument | Description
lpwszValue | Pointer to a string specified by the performance monitor program in a call to the RegQueryValueEx function. The string uses one of the formats described in Retrieving Selected Data.
LppData | On input, points to a pointer to the location where the data is to be placed. On successful exit, set *lppData to the next byte in the buffer available for data, such as one byte past the last byte of your data. The data returned must be a multiple of a DWORD in length. It must conform to the PERF_OBJECT_TYPE structure, unless this is a collection from a foreign computer. If foreign, any PERF_OBJECT_TYPE structures returned must be preceded by a PERF_DATA_BLOCK structure for the foreign computer. If the Collect function fails for any reason, leave *lppData unchanged.
LpcbBytes | On input, points to a 32-bit value that specifies the size, in bytes, of the lppData buffer. On successful exit, set *lpcbBytes to the size, in bytes, of the data written to the lppData buffer. This must be a multiple of sizeof(DWORD) (a multiple of 4). If the Collect function fails for any reason, set *lpcbBytes to zero.
lpcObjectTypes | On successful exit, set *lpcObjectTypes to the number of object type definitions being returned. If the Collect function fails for any reason, it should set *lpcObjectTypes to zero.

If the requested data specified by lpwszValue does not correspond to any of the object indexes or foreign computers supported by your program, leave *lppData unchanged, and set *lpcbBytes and *lpcObjectTypes both to zero. This indicates that no data is returned. If your data collection is time-consuming, you should only respond to specific requests and Costly requests. You should also lower the priority of the thread collecting the data, so that it does not adversely affect system performance.

The Collect function must return one of the values shown in the following table.

Return value | Description
ERROR_MORE_DATA | Indicates that the size of the lppData buffer as specified by *lpcbBytes is not large enough to store the data to be returned. In this case, leave *lppData unchanged, and set *lpcbBytes and *lpcObjectTypes to zero. No attempt is made to indicate the required buffer size, because this may change before the next call.
ERROR_SUCCESS | Return this value in all other cases, even if no data is returned or an error occurs. To report errors other than insufficient buffer size, use the system event log, but do not flood the event log with errors on every data collection operation.

To provide more information to the user, the Collect function should write any error that prevents the function from completing successfully in the system event log. For more information, see Event Logging.

If the application collecting the data is running on another machine (remotely), then the extensible counter functions are called in the context of the Winlogon process, which handles the server side of the remote connection. This distinction is important when troubleshooting problems that only occur remotely. The Winlogon process may access the functions using multiple threads, usually one per remote connection. This means that the Open procedure can be called more than once. You should handle this in your code accordingly, so that initialization tasks are not performed more than necessary. The Collect function may also be called concurrently by multiple threads, so you should be careful how you initialize and use temporary data. Static variables should only be used if the data is intended to be shared across threads.

The connection to the machine providing the data should be tested each time data is requested. If the connection cannot be made, you need to return some sort of indication. One suggestion is to provide a Status counter for the object that indicates whether a valid connection exists. When the connection does not exist, set the Status counter and return the last set of valid data.

For foreign computer interfaces, the opening of a channel to the foreign computer must be done in the Collect function because the computer name is not provided to the Open function. The performance DLL should save a handle to the foreign computer to avoid reconnecting on each data collection call, which would significantly slow down system performance.

Once you get the data for a foreign computer, construct a PERF_DATA_BLOCK as the first thing in *lppData, so that your application can return the data. If the system you are measuring does not provide the requested information, provide a reasonable value. You should use values from the local system for time and counter frequency if they are not provided remotely. You may need to use the PerfTime and .PerfFreq members of the PERF_OBJECT_TYPE structure for some counters as well.

Other things that you might do in the Collect function include:

  • Validate the shared memory pointer and check that the Open function had successfully completed. If the Open function failed, it should have already logged an event, so the Collect function need not report this error.
  • Determine the data request type, as described in Retrieving Selected Data. If the request is for Foreign data, it is ignored and the Collect function should return no data. If the request is for a specific object or list of objects, search for its index in the list of object and counter indices. If you do not find a match, the data from this object is not desired, so the function should return no data.
  • Request ownership of the mutex for the shared memory object. Wait to get access to the data in the shared memory block.
  • Estimate the size of the data to make sure there is enough room for the data in the buffer. If the estimated size is larger than the available size, return a status of ERROR_MORE_DATA. The system passes this error to the thread that issued the call to RegQueryValueEx to request the data.
  • Copy the performance data from the shared memory to the performance data structure to be returned.
  • When all data has been transferred from the shared memory file to the performance data buffer, release the shared memory mutex and update the pointers and counter fields. The updating of the pointers and counter fields is very important, to prevent an access violation from the application, monitor, or system due to misleading buffer length information.

After the collect procedure returns successfully, the system performs the following tests to try and catch logic errors in the collect procedure. The first test to fail will generate an event log message and, in most cases, the data is discarded to prevent any further problems due to invalid pointers. These tests are normally enabled though they can be disabled by changing a registry variable value as described below:

HKEY_LOCAL_MACHINE

\Software

\Microsoft

\Windows NT

\CurrentVersion

\Perflib

ExtCounterTestLevel = Test_Level

The Test_Level is a REG_DWORD that specifies the test level. Test level 1 requests all tests. Test level 2 requests basic tests. Test level 3 requests no tests. The default is test level 1.

The basic tests performed on the data buffer are as follows:

  • Is the BytesLeft return value consistent with the returned pointer? The returned value of the BytesLeft argument to the Collect procedure is compared to the returned buffer pointer. If all is consistent, the BytesLeft value added to the original buffer pointer passed in to the Collect procedure should be the same as the buffer pointer returned by the procedure. If they are not the same a warning message is logged and the BytesLeft parameter is replaced by the value computed by finding the difference between the buffer pointer after the function call and the buffer pointer before the function call. This is somewhat risky, in that it assumes the BytesLeft value is assumed to be the incorrect one, when in fact it could be that the buffer pointer is the incorrect one.
  • Has the returned buffer pointer exceeded the allocated buffer extent? The actual buffer passed to the collect function is allocated specifically for that function call by the performance library and contains a 1K-Byte Guard Page above and below the size indicated by the remaining size of the user's buffer. A separate buffer is used to allow testing of the extensible counter DLL's returned data without corrupting the caller's buffer. If the returned buffer pointer (the pointer to the next byte after this object's data) exceeds the size of this buffer (not including guard pages) then the buffer is assumed to be invalid and discarded since it is too large to be copied into the caller's buffer. This test consists of two parts. If the buffer pointer exceeds the end of the buffer, but not the end of the guard page then a buffer overrun error is logged. If the buffer pointer is past the end of the guard page, then a heap error is logged since the heap that the buffer was allocated from could have been corrupted causing other memory errors.
  • Are the guard pages corrupted? The 1K byte Guard Pages above and below the block of memory passed to the collect procedure are initialized with a data pattern before the collect function is called. This data pattern is checked after the collect procedure returns. If any discrepancy is detected a buffer overrun or other memory error is assumed and the buffer is discarded.

The following tests are performed only if test level 1 is used.

  • Test object TotalByteLength field consistency. This test walks the object(s) returned by the extensible counter to see if the sum of the length of all the objects returned is the same as the value of the size of the returned buffer. Since the Collect function generally returns one or more object structures (including the instance definitions, and counter definitions and data) the sum of each object's length should be the same as the bytes returned. A failure here can indicate the object is not computing the value of the TotalByteLength field correctly. This can cause an application program using the data to fail by having it get lost in the data structures.
  • Test Instance ByteLength field consistency. This test is similar to the test above. The test walks the list of instances in each object that returns multiple instances, to see if the next object or end of buffer follows the last instance. As above, if an inconsistency is detected, the buffer is discarded to prevent the application program from crashing due to a lost pointer.


The Close Function

The system calls each application's Close function when an application calls the RegCloseKey function to close the HKEY_PERFORMANCE_DATA key. This function performs any cleanup required by the application's performance data collection mechanism. For example, the function could close device handles opened by the CreateFile function, or close a handle to a file mapping object.

Use the following function prototype for your Close function.

DWORD WINAPI ClosePerformanceData();

The name ClosePerformanceData is a place-holder for an application-defined name.

The function should return ERROR_SUCCESS.


Error Handling in the DLL

Use event logging to record errors that occur during any of the functions in the performance DLL. Logging error events aids in troubleshooting applications providing performance data during development and after installation. Be careful not to log error events on every Collect call, however, because data collection can be frequent.

The following errors are logged to the event log by the performance library if it has problems with the Open procedure. If one of the errors listed below occurs, then the performance library makes no further calls to this performance DLL. Instead, the DLL is unloaded and data for the object provided by the performance DLL is not returned with the performance data.

  • PERFLIB_OPEN_PROC_NOT_FOUND – Logged when the procedure name defined in the registry could not be found in the DLL as an exported function. This usually occurs when the performance counter DLL or the service is not installed correctly or the function name has been renamed without updating the installation procedure.
  • PERFLIB_OPEN_PROC_FAILURE – Logged when the open procedure returned an error status other than ERROR_SUCCESS. This usually occurs when an expected error condition has occurred in the open procedure. Should this happen, the Counter DLL should have also entered an event log entry describing the conditions that caused the failure.
  • PERFLIB_OPEN_PROC_EXCEPTION – Logged when the open procedure encounters an unhandled exception. This is usually due to an unexpected error condition encountered by the open procedure.


Performance DLL Sample

The Platform SDK contains a sample performance DLL. This sample is located in the directory MSTOOLS\SAMPLES\WIN32\WINNT\PerfTool.


Performance Data Reference

The following functions and structures are supported for working with performance data.


Performance Data Functions

The following functions are supported for working with performance data.

PDH Interface

CounterPathCallback
PdhAddCounter
PdhBrowseCounters
PdhCalculateCounterFromRawValue
PdhCloseQuery
PdhCollectQueryData
PdhComputeCounterStatistics
PdhConnectMachine
PdhEnumMachines
PdhEnumObjectItems
PdhEnumObjects
PdhExpandCounterPath
PdhGetCounterInfo
PdhGetDefaultPerfCounter
PdhGetDefaultPerfObject
PdhGetFormattedCounterValue
PdhGetRawCounterValue
PdhMakeCounterPath
PdhOpenQuery
PdhParseCounterPath
PdhParseInstanceName
PdhRemoveCounter
PdhSetCounterScaleFactor
PdhValidatePath

PDH Interface (Visual Basic)

PdhAddCounter (VB)
PdhCloseQuery (VB)
PdhCollectQueryData (VB)
PdhCreateCounterPathList (VB)
PdhGetCounterPathElements (VB)
PdhGetCounterPathFromList (VB)
PdhGetDoubleCounterValue (VB)
PdhGetOneCounterPath (VB)
PdhIsGoodStatus (VB)
PdhOpenQuery (VB)
PdhRemoveCounter (VB)


Performance Data Structures

The following structures are supported for working with performance data.

PDH Interface

PDH_BROWSE_DLG_CONFIG
PDH_COUNTER_INFO
PDH_COUNTER_PATH_ELEMENTS
PDH_FMT_COUNTERVALUE
PDH_STATISTICS

Registry Interface

PERF_COUNTER_BLOCK
PERF_COUNTER_DEFINITION
PERF_DATA_BLOCK
PERF_INSTANCE_DEFINITION
PERF_OBJECT_TYPE


PDH Reference

This section describes the PDH data types, functions, and structures.


PDH Data Types

All PDH string structures are shown as "TCHAR", meaning that both Unicode and ANSI string structures are supported. Internally, the native or preferred code path inside the PDH is the Unicode string format, since it is built only for Windows NT. An ANSI version of each function is provided for those functions that have string arguments. They are, however, slightly less efficient since they must convert the ANSI string arguments to Unicode arguments before calling the Unicode version of the function.

The string data types expected are determined by the Unicode symbol when the application is compiled. If Unicode is defined, then the Unicode or wide character strings are expected. If the symbol is undefined, then the 8-bit or ANSI character strings are expected.

Data Type | Description
HQUERY | Handle to a query (HANDLE).
HCOUNTER | Handle to a counter. PDH maintains the linkage between counters and queries.
PDH_STATUS | LONG PDH status value.

Unless otherwise specified, all functions return a Win32 status value of ERROR_SUCCESS if the function completes successfully or a PDH error status value defined in the PDHMSG.H include file.

For data collection and formatting functions it is important to remember that the return value of the function indicates the success or error of the function call and not necessarily that of the counter data. Always check the CStatus field of the counter value returned to ensure that the data returned is valid before you use it. If the value of the CStatus field does not indicate success, do not use the data.


PDH Functions

This section describes the Performance Data Helper functions.


CounterPathCallback

The CounterPathCallback function is an application-defined callback function that processes the counter path strings read from the szReturnPathBuffer member of the PDH_BROWSE_DLG_CONFIG structure.

PDH_STATUS __stdcall CounterPathCallback(
  IN DWORD dwArg  // Pointer to a PDH_BROWSE_DLG_CONFIG structure
);

Parameters

dwArg
The user-defined DWORD value passed to the callback function by the browser dialog box. This value is the dwCallBackArg member of the PDH_BROWSE_DLG_CONFIG structure.

Remarks

The following members in the PDH_BROWSE_DLG_CONFIG structure are used to communicate with the callback function:

szReturnPathBuffer
Contains the counter path strings currently selected by the user.
cchReturnPathLength
Contains the current maximum size of the szReturnPathBuffer member. If the callback function reallocates a new buffer, it must also update this value.
CallBackStatus
On entry to the callback function, this member contains the status of the path buffer. On exit, the callback function sets the status value resulting from processing.

If the buffer is too small to load the current selection, the browser will set this value to PDH_MORE_DATA. If the browser sets this member to ERROR_SUCCESS, then the szReturnPathBuffer member contains a valid counter path or counter path list.

If the callback function reallocates a new buffer, it should set this member to PDH_RETRY so that the browser will try to load the buffer with the selected paths and call the callback function again.

If some other error occurred, then the callback function should return the appropriate PDH error status value.

Return Values

If the function succeeds (processes the buffer and does not need to be called again), it returns ERROR_SUCCESS.

If the function fails (an error occurs and the function needs to be called again to retry the processing), it returns PDH_RETRY. This is usually the result of insufficient memory.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhBrowseCounters, PDH_BROWSE_DLG_CONFIG


PdhAddCounter

The PdhAddCounter function initializes a counter structure for the specified counter in the specified query.

PDH_STATUS PdhAddCounter(
  IN HQUERY hQuery,       // handle to the query
  IN LPCTSTR szFullCounterPath,
                          // path of the counter
  IN DWORD dwUserData,    // user-defined value
  IN HCOUNTER *phCounter  // pointer to the counter handle buffer
);

Parameters

hQuery
The handle of the query to which the new counter will be added.
szFullCounterPath
The fully qualified and resolved path of the counter to create. This path cannot contain wild card path strings or characters. See PDH_COUNTER_PATH_ELEMENTS.
dwUserData
A user-defined value, typically, a pointer or index to the user's counter structure.
phCounter
A pointer to the buffer that is to receive the handle to the counter that is created.

Return Values

If the function succeeds, it returns ERROR_SUCCESS, creates a new counter, and returns the handle to the counter in the buffer pointed to by phCounter.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_CSTATUS_BAD_COUNTERNAME
The counter name path string could not be parsed or interpreted.
PDH_CSTATUS_NO_COUNTER
The specified counter was not found.
PDH_CSTATUS_NO_COUNTERNAME
An empty counter name path string was passed in.
PDH_CSTATUS_NO_MACHINE
A machine entry could not be created.
PDH_CSTATUS_NO_OBJECT
The specified object could not be found.
PDH_FUNCTION_NOT_FOUND
The calculation function for this counter could not be determined.
PDH_INVALID_ARGUMENT
One or more arguments are invalid.
PDH_INVALID_HANDLE
The query handle is not valid.
PDH_MEMORY_ALLOCATION_FAILURE
A memory buffer could not be allocated.

See Also

Performance Data Helper Overview, Performance Data Functions, PdhRemoveCounter, PDH_COUNTER_PATH_ELEMENTS


PdhBrowseCounters

The PdhBrowseCounters function displays the counter browsing dialog box so that the user can select the counters to be returned to the caller.

PDH_STATUS PdhBrowseCounters(
  IN PPDH_BROWSE_DLG_CONFIG pBrowseDlgData  // pointer to dialog
                                            // structure
);

Parameters

pBrowseDlgData
Pointer to a PDH_BROWSE_DLG_CONFIG structure that specifies the behavior of the dialog box that receives the counter path strings.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h.

See Also

Performance Data Helper Overview, Performance Data Functions, , CounterPathCallback, PDH_BROWSE_DLG_CONFIG


PdhCalculateCounterFromRawValue

The PdhCalculateCounterFromRawValue function computes the current value of a counter as referenced by the hCounter parameter, using the raw counter data passed in the parameter list.

PDH_STATUS PdhCalculateCounterFromRawValue(
  IN HCOUNTER hCounter,           // handle of the counter
  IN DWORD dwFormat,              // format code
  IN PPDH_RAW_COUNTER rawValue1,  // first raw counter
  IN PPDH_RAW_COUNTER rawValue2,  // second raw counter
  IN PPDH_FMT_COUNTERVALUE fmtValue  // calculated value
);

Parameters

hCounter
The handle of the counter used for the computation. This determines how the data will be computed.
dwFormat
The format code composed of the following values:
Value | Meaning
PDH_FMT_DOUBLE | Return the calculated value as a double-precision floating point real.
PDH_FMT_LARGE | Return the calculated value as a 64-bit integer.
PDH_FMT_LONG | Return the calculated value as a long integer.

The value selected from the previous table can be combined using the OR operator with one of the following scaling flags:

Flag | Meaning
PDH_FMT_NOSCALE | Do not apply the counter's scaling factors in the calculation.
PDH_FMT_1000 | Multiply the final value by 1000.

rawValue1
A pointer to the raw counter value used to compute the counter value. Some counters (for example, rate counters) require two raw values for a calculation. The format of the buffer depends on the type of counter to be processed.
rawValue2
A pointer to the raw counter value used in computations for counters that require two raw values (for example, rate counters). This value must be the older of the two raw values.
fmtValue
A pointer to the data buffer that will receive the calculated counter value.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

Value | Meaning
PDH_INVALID_ARGUMENT | An argument is not correct or is incorrectly formatted.
PDH_INVALID_HANDLE | The counter handle is not valid.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhGetFormattedCounterValue, PdhGetRawCounterValue, PdhSetCounterScaleFactor


PdhCloseQuery

The PdhCloseQuery function closes all counters contained in the specified query, closes all handles related to the query, and frees all memory associated with the query.

PDH_STATUS PdhCloseQuery(
  IN HQUERY hQuery  // handle of the query to close and delete.
);

Parameters

hQuery
The handle of the query to close and delete.

Return Values

If the function succeeds, it returns ERROR_SUCCESS and closes and deletes the query.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following is a possible error value:

Value | Meaning
PDH_INVALID_HANDLE | The query handle is not valid.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhOpenQuery


PdhCollectQueryData

The PdhCollectQueryData function collects the current raw data value for all counters in the specified query and updates the status code of each counter.

PDH_STATUS PdhCollectQueryData(
  IN HQUERY hQuery  // handle of the query
);

Parameters

hQuery
The handle of the query from which to collect data.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

Value | Meaning
PDH_INVALID_HANDLE | The query handle is not valid.
PDH_NO_DATA | The query does not currently have any counters.

Remarks

The PdhCollectQueryData function can succeed, but may not have collected data for all counters. Always check the status code of each counter in the query before using the data.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhOpenQuery


PdhComputeCounterStatistics

The PdhComputeCounterStatistics function computes statistics for a counter from an array of raw values.

PDH_STATUS PdhComputeCounterStatistics(
  IN HCOUNTER hCounter,  // handle of the counter
  IN DWORD dwFormat,     // format code
  IN DWORD dwFirstEntry, // first entry in the array
  IN DWORD dwNumEntries, // number of entries in the array
  IN PPDH_RAW_COUNTER lpRawValueArray,
                         // array of raw counter values
  IN PPDH_STATISTICS data  // buffer for counter statistics
);

Parameters

hCounter
The handle of the counter used for the computation. This determines how the data will be computed.
dwFormat
The formatting information sent by the caller to indicate how the calculated value should be returned. This parameter can be one of the following values:
PDH_FMT_DOUBLE
Return the calculated value as a double-precision floating point real.
PDH_FMT_LARGE
Return the calculated value as a 64-bit integer.
PDH_FMT_LONG
Return the calculated value as a long integer.

The value selected from the previous table can be combined using the OR operator with one of the following scaling flags:

PDH_FMT_NOSCALE
Do not apply the counter's scaling factors in the calculation.
PDH_FMT_1000
Multiply the final value by 1000.
dwFirstEntry
The zero-based index of the first raw counter buffer to look at. This value must point to the oldest entry in the buffer. The PdhComputeCounterStatistics function starts at this entry and scans through the buffer, wrapping at the last entry back to the beginning of the buffer and up to the dwFirstEntry-1 entry, which is assumed to be the newest or most recent data.
dwNumEntries
The number of raw counter entries in the lpRawValueArray buffer.
lpRawValueArray
A pointer to the raw counter value or values used to compute the counter value. Some counters (for example, rate counters) require two values for a calculation. The format of the buffer is assumed to be an array of PDH_RAW_COUNTER structures that contain dwNumEntries entries.
data
A pointer to the PDH_STATISTICS buffer to receive the counter statistics.

Return Values

If the function succeeds, it returns ERROR_SUCCESS. The function can return successfully, but the returned data buffer can contain invalid data. Always check the CStatus member of the data buffer before using the returned statistics.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_INVALID_ARGUMENT
An argument is not correct or is incorrectly formatted.
PDH_INVALID_HANDLE
The counter handle is not valid.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhCalculateCounterFromRawValue, PdhGetRawCounterValue, PDH_RAW_COUNTER, PdhSetCounterScaleFactor, PDH_STATISTICS


PdhConnectMachine

The PdhConnectMachine function connects to the specified machine, and creates and initializes a machine entry in the PDH DLL.

PDH_STATUS PdhConnectMachine(
  IN LPCTSTR szMachineName  // machine to browse
);

Parameters

szMachineName
The name of the machine to browse.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_CSTATUS_NO_MACHINE
Unable to connect to the specified machine. Could be caused by the machine not being on, not running Windows NT, not being connected to the network, or having the permissions set on the registry to not allow remote connections or remote performance monitoring by the user.
PDH_MEMORY_ALLOCATION_FAILURE
Unable to allocate a dynamic memory block. Occurs when there is a serious memory shortage in the system due to too many applications running on the system or an insufficient memory paging file.

Remarks

An application can call PdhConnectMachine to establish a connection to a remote machine at a more convenient time than when the application opens a query and adds counters.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhEnumMachines


PdhEnumMachines

The PdhEnumMachines function returns a list of the names of the machines that have been opened previously by the PDH DLL. The machines listed include those that are currently connected and online, as well as those that are offline or not returning performance data. For information about how to connect to a machine, see PdhConnectMachine.

PDH_STATUS PdhEnumMachines(
  IN LPCTSR szReserved,        // reserved
  IN LPTSTR mszMachineNameList,  // list of connected machines
  IN LPDWORD pcchBufferLength  // pointer to buffer length
);

Parameters

szReserved
Reserved. Must be NULL.
mszMachineNameList
The buffer, allocated by the calling function, to receive the list of MULTI_SZ strings of machines to which the PDH DLL is currently connected. This parameter may be NULL if the value in the DWORD referenced by pcchBufferLength is 0.
pcchBufferLength
A pointer to the DWORD containing the size, in characters, of the available buffer on entry and the size of the returned buffer on exit. If the buffer size on entry is zero, then no data is returned in the mszMachineNameList buffer (and the pointer may be NULL), and the size of the buffer required, in characters, is returned in the DWORD pointed to by pcchBufferLength. The size returned includes both terminating NULL characters of the MULTI_SZ string.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_MORE_DATA
More data is available then the current buffer can hold. Some entries may be returned in the mszMachinenameList buffer.
PDH_INSUFFICIENT_BUFFER
The buffer provided is not large enough to contain any data.
PDH_INVALID_ARGUMENT
A required argument is invalid or a reserved argument is not NULL.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhConnectMachine


PdhEnumObjectItems

The PdhEnumObjectItems function returns the available counters and instances provided by the specified object on the specified machine.

PDH_STATUS PdhEnumObjectItems(
  IN LPCTSTR szReserved,  // reserved
  IN LPCTSTR szMachineName,  // machine name
  IN LPCTSTR szObjectName,  // object name
  IN LPTSTR mszCounterList,  // buffer for object's counters
  IN LPDWORD pcchCounterListLength,
                          // size of counter list buffer
  IN LPTSTR mszInstanceList,  // buffer for object's instances
  IN LPDWORD pcchInstanceListLength,
                          // size of instance list buffer
  IN DWORD dwDetailLevel,  // detail level
  IN DWORD dwFlags        // formatting flag
);

Parameters

szReserved
Reserved. Must be NULL.
szMachineName
The name of the machine on which to list the object items. If the machine specified is not in the list of currently connected machines, the PDH will try to connect to it.
szObjectName
The name of the object on the specified machine from which the items are to be listed.
mszCounterList
The buffer allocated by the calling function that is to receive the MULTI_SZ list of performance counters provided by the specified object on the specified machine. This parameter can be NULL if the value of the DWORD referenced by pcchCounterListLength is 0.
pcchCounterListLength
A pointer to a DWORD containing the size, in characters, of the available buffer, and which returns the size of the buffer used. If the buffer size on entry is zero, then no data is returned in the mszCounterList buffer, and the size of the buffer required is returned in the DWORD pointed to by pdwCounterListLength. The size returned includes both terminating NULL characters of the MULTI_SZ string.
mszInstanceList
The buffer allocated by the calling function that is to receive the MULTI_SZ list of the instances of the specified object on the specified machine. This argument can be NULL if the value of the DWORD pointed to by pcchCounterListLength is 0.
pcchInstanceListLength
A pointer to the DWORD containing the size, in characters, of the available buffer, and which returns the size of the buffer used. If the buffer size on entry is zero, then no data is returned in the mszInstanceList buffer, and the size of the buffer required is returned in the DWORD pointed to by pcchInstanceListLength. The size returned includes both terminating NULL characters of the MULTI_SZ string. If the specified object does not support variable instances, then the returned value will be 0. If the specified object does support variable instances, but does not currently have any instances, then the value returned in this DWORD will be 2, which is the size, in characters, of an empty MULTI_SZ list string.
dwDetailLevel
The detail level of the performance items to return. All items that are of the specified detail level or less will be returned.
dwFlags
Must be 0.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_MORE_DATA
There are more entries available to return than there is room in the buffer. Some entries might be returned in the buffer, however.
PDH_INSUFFICIENT_BUFFER
The buffer provided is not large enough to contain any data.
PDH_INVALID_ARGUMENT
A required argument is invalid or a reserved argument is not NULL.
PDH_MEMORY_ALLOCATION_FAILURE
A required temporary buffer could not be allocated.
PDH_CSTATUS_NO_MACHINE
The specified machine is offline or unavailable.
PDH_CSTATUS_NO_OBJECT
The specified object could not be found on the specified machine.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhConnectMachine, PdhEnumObjects


PdhEnumObjects

The PdhEnumObjects function returns a list of objects available on the specified machine.

PDH_STATUS PdhEnumObjects(
  IN LPCTSTR szReserved,    // reserved
  IN LPCTSTR szMachineName,  // machine name
  IN LPTSTR mszObjectList,  // buffer for objects
  IN LPDWORD pcchBufferLength,  // size of buffer
  IN DWORD dwDetailLevel,   // detail level
  IN BOOL bRefresh          // refresh flag for connected machines
);

Parameters

szReserved
Reserved. Must be NULL.
szMachineName
The name of the machine on which to list the objects. If the machine specified is not in the list of currently connected machines, the PDH will try to connect to the machine and add it to the list.
mszObjectList
The buffer allocated by the calling function that is to receive the MULTI_SZ list of objects available on the specified machine. This parameter may be NULL if the value of the DWORD pointed to by pcchBufferLength is 0.
pcchBufferLength
A pointer to the DWORD containing the size, in characters, of the available buffer on entry and the size of the returned buffer on exit. If the buffer size on entry is zero, then no data is returned in the mszObjectList buffer, and that parameter may be NULL. However, the size of the buffer required, in characters, is returned in the DWORD pointed to by pcchBufferLength. The size returned includes both terminating NULL characters of the MULTI_SZ string.
dwDetailLevel
The detail level of the performance items to return. All items that are of the specified detail level or less will be returned.
bRefresh
Indicates that a new list of objects should be obtained from the specified machine. If the machine is not currently connected by the PDH, then this flag is ignored and the list is refreshed automatically.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_MORE_DATA
There are more entries available to return than there is room in the buffer. Some entries might be returned in the buffer, however.
PDH_INSUFFICIENT_BUFFER
The buffer provided is not large enough to contain any data.
PDH_INVALID_ARGUMENT
A required argument is invalid or a reserved argument is not NULL.

Remarks

When you request a required buffer size, the bRefresh flag should be FALSE for all subsequent calls to this function. Otherwise, the size might not be valid.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhConnectMachine, PdhEnumMachines


PdhExpandCounterPath

The PdhExpandCounterPath function examines the specified machine (or local machine if none is specified) for counters and instances of counters that match the wild card strings in the counter path. The counter path format is assumed to be:

\\machine\object(parent/instance#index)\countername

and the parent, instance, index, and countername elements may contain either a valid name or a wild card character.

PDH_STATUS PdhExpandCounterPath(
  IN LPCTSTR szWildCardPath,  // counter path to expand
  IN PPTSTR mszExpandedPathList,  // names that match
  IN LPDWORD pcchPathListLength  // size of buffer
);

Parameters

szWildCardPath
The counter path to expand.
mszExpandedPathList
The buffer to receive the list of counter path names that match the wild card specification in the szWildCardPath buffer.
pcchPathListLength
The size of the mszExpandedPathList buffer, in characters, on entry and the size of the buffer used by the returned path strings on return.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhMakeCounterPath


PdhGetCounterInfo

The PdhGetCounterInfo function retrieves information about a counter, such as data size, counter type, path, and user-supplied data values.

PDH_STATUS PdhGetCounterInfo(
  IN HQUERY hCounter,        // handle of the counter
  IN BOOLEAN bRetrieveExplainText,
                             // TRUE to retrieve explain text
  IN LPDWORD pdwBufferSize,  // pointer to size of lpBuffer
  IN PPDH_COUNTER_INFO lpBuffer  // buffer for counter information
);

Parameters

hCounter
The handle of the counter from which to retrieve the information.
bRetrieveExplainText
Determines whether explain text is retrieved. If you set this parameter to TRUE, then the explain text for the counter is retrieved. If you set this parameter to FALSE, the field in the returned buffer is NULL.
pdwBufferSize
A pointer to the size, in bytes, of the buffer passed in lpBuffer. If the counter requires a buffer larger than is indicated by pdwBufferSize, then PdhGetCounterInfo will return the required buffer size in this field. If the function succeeds, then this field will contain the size of the data returned in lpBuffer. If the size is zero, then no data will be returned in the buffer (in fact, lpBuffer can be NULL); and the size, in bytes, will be returned in the DWORD.
lpBuffer
A pointer to the data buffer to receive the counter information. The buffer returned is variable-length, because the string data is appended to the end of the fixed-format portion of the structure. This is done so that all data is returned in a single buffer allocated by the caller.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_INVALID_ARGUMENT
An argument is not correct or is incorrectly formatted.
PDH_INVALID_HANDLE
The counter handle is not valid.
PDH_MORE_DATA
The buffer supplied is not large enough to receive the requested data.

See Also

Performance Data Helper Overview, Performance Data Functions, , PDH_COUNTER_INFO


PdhGetDefaultPerfCounter

The PdhGetDefaultPerfCounter function retrieves the name of the default counter for the specified object. This can be used to set the initial selection of the counter browser list/combo box.

PDH_STATUS PdhGetDefaultPerfCounter(
  IN LPCTSTR szReserved,          // reserved
  IN LPCTSTR szMachineName,       // machine to query
  IN LPCTSTR szObjectName,        // name of object
  IN LPTSTR szDefaultCounterName, // buffer to receive counter name
  IN LPDWORD pcchBufferSize       // size of counter name
);

Parameters

szReserved
Reserved. Must be NULL.
szMachineName
The name of the machine to query.
szObjectName
The name of the object in szMachineName to query.
szDefaultCounterName
A pointer to the buffer that will receive the default counter name for the specified object. This parameter can be NULL if the value of the DWORD referenced by pcchBufferSize is 0.
pcchBufferSize
The size of the szDefaultCounterName buffer, in characters, when called, and the size of the counter name returned on return. If the value in the DWORD pointed to by this parameter is 0, then the required buffer size, in characters, for this object name will be returned in the DWORD and no data will be copied to the buffer.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_INSUFFICIENT_BUFFER
The buffer provided is not large enough for the available data.
PDH_INVALID_ARGUMENT
A required argument is invalid or a reserved argument is not NULL.
PDH_MEMORY_ALLOCATION_FAILURE
A required temporary buffer could not be allocated.
PDH_CSTATUS_NO_MACHINE
The specified machine is offline or unavailable.
PDH_CSTATUS_NO_COUNTERNAME
The default object name cannot be read or found.
PDH_CSTATUS_NO_OBJECT
The specified object could not be found on the specified machine.
PDH_CSTATUS_NO_COUNTER
The default counter was not found in the specified object.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhGetDefaultPerfObject


PdhGetDefaultPerfObject

The PdhGetDefaultPerfObject function retrieves the name of the default performance object. The name can be used to select the default entry in the object browser list box.

PDH_STATUS PdhGetDefaultPerfObject(
  IN LPCTSTR szReserved,          // reserved
  IN LPCTSTR szMachineName,       // machine to query
  IN LPTSTR szDefaultObjectName,  // buffer to receive object
  IN LPDWORD pcchBufferSize       // size of object name
);

Parameters

szReserved
Reserved. Must be NULL.
szMachineName
The name of the machine to query.
szDefaultObjectName
A pointer to the buffer to receive the default object name. This parameter can be NULL if the value of the DWORD referenced by pcchBufferSize is 0.
pcchBufferSize
The size of the szDefaultObjectName buffer, in characters, on entry and the size of the returned object name on exit. If the value in the DWORD referenced by this parameter is 0, then the required buffer size, in characters, for this object name will be returned in the DWORD and no data will be copied to the buffer.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_INSUFFICIENT_BUFFER
The buffer provided is not large enough for the available data.
PDH_INVALID_ARGUMENT
A required argument is invalid or a reserved argument is not NULL.
PDH_MEMORY_ALLOCATION_FAILURE
A required temporary buffer could not be allocated.
PDH_CSTATUS_NO_MACHINE
The specified machine is offline or unavailable.
PDH_CSTATUS_NO_COUNTERNAME
The default object name cannot be read or found.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhGetDefaultPerfCounter


PdhGetFormattedCounterValue

The PdhGetFormattedCounterValue function returns the current value of a specified counter in the format requested by the caller.

PDH_STATUS PdhGetFormattedCounterValue(
  IN HCOUNTER hCounter,            // handle of the counter
  IN DWORD dwFormat,               // formatting flag
  IN LPDWORD lpdwType,             // counter type
  IN PPDH_FMT_COUNTERVALUE pValue  // counter value
);

Parameters

hCounter
The handle of the counter whose current value is to be formatted and returned.
dwFormat
The formatting information sent by the caller to indicate how the data should be returned. This parameter can be one of the following values:
PDH_FMT_DOUBLE
Return data as a double-precision floating point real.
PDH_FMT_LARGE
Return data as a 64-bit integer.
PDH_FMT_LONG
Return data as a long integer.

The value selected from the previous table can be combined using the OR operator with one of the following scaling flags:

PDH_FMT_NOSCALE
Do not apply the default scaling factor.
PDH_FMT_1000
Multiply the actual value by 1000.
lpdwType
A pointer to a DWORD buffer that will receive the counter type. The possible counter types are described in winperf.h. This parameter is optional.
pValue
A pointer to the data buffer that will receive the counter value.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_INVALID_ARGUMENT
An argument is not correct or is incorrectly formatted.
PDH_INVALID_DATA
The specified counter does not contain valid data or a successful status code.
PDH_INVALID_HANDLE
The counter handle is not valid.

Remarks

The data for the counter is locked (protected) for the duration of the call to PdhGetFormattedCounterValue to prevent any changes during the processing of the call. Reading the data (calling this function successfully) clears the data-changed flag for the counter.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhGetRawCounterValue, PdhSetCounterScaleFactor


PdhGetRawCounterValue

The PdhGetRawCounterValue function returns the current raw value of the counter.

PDH_STATUS PdhGetRawCounterValue(
  IN HCOUNTER hCounter,       // handle of the counter
  IN LPDWORD lpdwType,        // counter type
  IN PPDH_RAW_COUNTER pValue  // counter value
);

Parameters

hCounter
The handle of the counter from which to retrieve the current raw value.
lpdwType
A pointer to a DWORD buffer that will receive the counter type. The possible counter types are described in winperf.h. This parameter is optional. You can pass NULL if you don't want the type information.
pValue
A pointer to the data buffer that will receive the counter value.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_INVALID_ARGUMENT
An argument is not correct or is incorrectly formatted.
PDH_INVALID_HANDLE
The counter handle is not valid.

Remarks

The data for the counter is locked (protected) for the duration of the call to PdhGetRawCounterValue to prevent any changes during processing of the call.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhGetFormattedCounterValue, PdhCalculateCounterFromRawValue


PdhMakeCounterPath

The PdhMakeCounterPath function creates a full counter path using the members specified in the structure passed in the parameter list.

PDH_STATUS PdhMakeCounterPath(
  IN PDH_COUNTER_PATH_ELEMENTS *pCounterPathElements,
                              // counter path elements
  IN LPTSTR szFullPathBuffer,  // path string buffer
  IN LPDWORD pcchBufferSize,  // size of buffer
  IN DWORD dwFlags            // reserved
);

Parameters

*pCounterPathElements
Pointer to a PDH_COUNTER_PATH_ELEMENTS structure that contains the individual members that are to make up the path. The following table indicates which members are required and which are optional:
Member | Required or Optional
LPTSTR szMachineName | optional
LPTSTR szObjectName | required
LPTSTR szInstanceName | optional
LPTSTR szParentInstance | optional
DWORD dwInstanceIndex optional
((DWORD)–1 if no index)
LPTSTR szCounterName | required

If a required member is not present, then no path string will be constructed. If the szMachineName member is NULL, then no machine name will be included in the path (a generic path will be created). If the instance name argument is NULL, then no instance reference will be inserted into the path string and the szParentInstance and the dwInstanceIndex members will be ignored.

szFullPathBuffer
The buffer allocated by the caller that will receive the full path string created by this function.
pcchBufferSize
A pointer to the DWORD containing the size, in bytes, of the available buffer, and which returns with the size of the buffer used. If the buffer size on entry is zero, then no data is returned in the szFullPathBuffer buffer, however, the size of the buffer required is returned in the DWORD. The size returned includes the terminating NULL character of the string.
dwFlags
Reserved. Must be zero.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h.

See Also

Performance Data Helper Overview, Performance Data Functions, , PDH_COUNTER_PATH_ELEMENTS, PdhParseCounterPath


PdhOpenQuery

The PdhOpenQuery function creates and initializes a unique query structure that is used to manage collection of performance data.

PDH_STATUS PdhOpenQuery(
  IN LPVOID pReserved,  // reserved
  IN DWORD dwUserData,  // a value associated with this query
  IN HQUERY *phQuery    // pointer to a buffer that will receive the
                        // query handle
);

Parameters

pReserved
Reserved. Must be NULL.
dwUserData
A user-defined DWORD value that is to be associated with this query. You can call PdhGetCounterInfo to retrieve the user data value for the query in which a counter resides.
phQuery
A pointer to the buffer to receive the handle to the query that is created.

Return Values

If the function succeeds, it returns ERROR_SUCCESS, creates a new query, and returns the handle to the query in the buffer pointed to by phQuery.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_INVALID_ARGUMENT
One or more arguments are invalid.
PDH_MEMORY_ALLOCATION_FAILURE
A memory buffer could not be allocated.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhCloseQuery, PdhGetCounterInfo


PdhParseCounterPath

The PdhParseCounterPath function parses the elements of the counter path and stores the results in the structure passed by the caller.

PDH_STATUS PdhParseCounterPath(
  IN LPCTSTR szFullPathBuffer,  // path string buffer
  IN PDH_COUNTER_PATH_ELEMENTS *pCounterPathElements,
                             // counter path elements
  IN LPDWORD pdwBufferSize,  // size of buffer
  IN DWORD dwFlags           // reserved
);

Parameters

szFullPathBuffer
The buffer containing the counter path to parse into individual components.
pCounterPathElements
A pointer to a PDH_COUNTER_PATH_ELEMENTS structure that will receive the individual components of the path referenced by the szFullPathBuffer parameter. The buffer space allocated for this should be large enough for the structure and the strings that will be referenced by the members in this structure. As this function parses the elements in the path, they are stored in the buffer after the PDH_COUNTER_PATH_ELEMENTS structure. This allows the calling function to allocate, and eventually free, only a single block of memory for this structure and the strings referenced by the members of this structure, rather than having the calling function allocate the structure and the string buffers separately.
pdwBufferSize
A pointer to the DWORD containing the size, in bytes, of the buffer referenced by pCounterPathElements and returns with the size of the buffer used. If the buffer size on entry is zero, then no data is returned in the pCounterPathElements buffer, however, the size of the buffer required is returned in the DWORD referenced by this pointer.
dwFlags
Reserved. Must be zero.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_INVALID_ARGUMENT
An argument is incorrect, or this function does not have the necessary access to that argument.
PDH_INSUFFICIENT_BUFFER
The buffer supplied is not large enough to accept the resulting data.
PDH_INVALID_PATH
The path is not formatted correctly and cannot be parsed.
PDH_MEMORY_ALLOCATION_FAILURE
A temporary buffer cannot be allocated.

See Also

Performance Data Helper Overview, Performance Data Functions, , PDH_COUNTER_PATH_ELEMENTS, PdhMakeCounterPath


PdhParseInstanceName

The PdhParseInstanceName function parses the elements of an instance string and returns them in the buffers supplied by the caller.

PDH_STATUS PdhParseInstanceName(
  IN LPCTSTR szInstanceString,       // instance string
  IN LPTSTR szInstanceName,          // parsed instance name
  IN LPDWORD pcchInstanceNameLength, // length of name
  IN LPTSTR szParentName,            // name of parent index
  IN LPDWORD pcchParentNameLength,   // length of parent name
  IN LPDWORD lpIndex                 // instance index
);

Parameters

szInstanceString
A pointer to the string containing the instance substring to parse into individual components. This string can contain the following formats, and is less than MAX_PATH characters in length:

instance
instance#index
parent/instance
parent/instance#index

szInstanceName
A pointer to the buffer that will receive the instance name parsed from the instance string. This pointer can be NULL if the DWORD referenced by the pcchInstanceNameLength parameter is 0.
pcchInstanceNameLength
A pointer to the DWORD that contains the length of the szInstanceName buffer. If the value of this DWORD is 0, then the buffer size required to hold the instance name will be returned.
szParentName
A pointer to the buffer that will receive the name of the parent index if one is specified. This parameter can be NULL if the value of the DWORD referenced by the pcchParentNameLength parameter is 0.
pcchParentNameLength
A pointer to the DWORD that contains the length of the szParentName buffer. If the value of this DWORD is 0, then the buffer size required to hold the instance name will be returned.
lpIndex
A pointer to the DWORD that will receive the index value of the instance. If an index entry is not present in the string, then this value will be 0. This argument can be NULL if this information is not needed.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_INVALID_ARGUMENT
An argument is invalid or incorrect.
PDH_INSUFFICIENT_BUFFER
One or both of the string buffers supplied is not large enough for the strings to be returned.
PDH_INVALID_INSTANCE
The instance string is incorrectly formatted, exceeds MAX_PATH characters in length, or cannot be parsed.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhMakeCounterPath


PdhRemoveCounter

The PdhRemoveCounter function removes a counter from a query.

PDH_STATUS PdhRemoveCounter(
  IN HCOUNTER hCounter  // handle of the counter
);

Parameters

hCounter
The handle of the counter to remove from its query.

Return Values

If the function succeeds, it returns ERROR_SUCCESS and removes the specified counter from its query.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following is a possible error value:

PDH_INVALID_HANDLE
The counter handle is not valid.

Remarks

After you remove a counter, any references to it using the handle passed in hCounter will be invalid and will return an error.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhAddCounter, PdhOpenQuery


PdhSetCounterScaleFactor

The PdhSetCounterScaleFactor function sets the scale factor that is applied to the calculated value of the specified counter when you request the formatted counter value. If the PDH_FMT_NOSCALE flag is set, then this scale factor is ignored.

PDH_STATUS PdhSetCounterScaleFactor(
  IN HCOUNTER hCounter,  // handle of the counter
  IN LONG lFactor        // power of ten used to multiply value
);

Parameters

hCounter
The handle of the counter to receive the scale factor in lFactor.
lFactor
The power of ten by which to multiply the calculated value before returning it. The valid range of this parameter is PDH_MIN_SCALE (–7) (the returned value is the actual value times 10–7) to PDH_MAX_SCALE (+7) (the returned value is the actual value times 10+7). A value of zero will set the scale to one, so that the actual value is returned.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is an error status defined in pdhmsg.h. The following are possible error values:

PDH_INVALID_ARGUMENT
The scale value is out of range.
PDH_INVALID_HANDLE
The counter handle is not valid.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhCalculateCounterFromRawValue, PdhComputeCounterStatistics, PdhGetFormattedCounterValue


PdhValidatePath

The PdhValidatePath function validates that the specified counter is present on the machine specified in the counter path.

PDH_STATUS PdhValidatePath(
  IN LPCTSTR szFullCounterPath  // counter path to validate
);

Parameters

szFullCounterPath
The counter path to validate.

Return Values

If the function succeeds, it returns ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhmsg.h. The following are possible error values:

PDH_CSTATUS_NO_INSTANCE
The specified instance of the performance object was not found.
PDH_CSTATUS_NO_COUNTER
The specified counter was not found in the performance object.
PDH_CSTATUS_NO_OBJECT
The specified performance object was not found on the machine.
PDH_CSTATUS_NO_MACHINE
The specified machine could not be found or connected to.
PDH_CSTATUS_BAD_COUNTERNAME
The counter path string could not be parsed.
PDH_MEMORY_ALLOCATION_FAILURE
The function is unable to allocate a required temporary buffer.

See Also

Performance Data Helper Overview, Performance Data Functions, , PdhMakeCounterPath


PDH Functions for Visual Basic 4.0

The functions described in this section enable the Visual Basic programmer to use Windows NT Performance Data Helper within a Visual Basic application program.


PdhAddCounter (VB)

The Visual Basic PdhAddCounter function creates a counter entry in the specified query object, and returns the handle for that counter upon successful completion.

PdhAddCounter(
  ByVal QueryHandle as Long,
  ByVal CounterPath as String,
  ByRef CounterHandle as Long)
as Long

Parameters

QueryHandle
The ID of the query to assign this counter to. This must be a value returned by a successful call to PdhOpenQuery.
CounterPath
The text string containing the name of the counter path to add to the query. The contents of this string must be a valid counter path, as obtained from the counter browser or other source.
CounterHandle
The unique reference that identifies this counter in the query. This variable must be initialized to zero before the function is called. It contains a valid value on return only if the function completes successfully.

Return Values

If the function succeeds, it returns a Long integer equal to ERROR_SUCCESS and a new handle in the CounterHandle variable.

If the function fails, the return value is a PDH error status defined in pdhdefs.txt. The following are possible error values:

PDH_INVALID_ARGUMENT
One or more of the arguments is invalid or incorrect.
PDH_MEMORY_ALLOCATION_FAILURE
A memory buffer could not be allocated.
PDH_INVALID_HANDLE
The query handle is not valid.
PDH_CSTATUS_NO_COUNTER
The specified counter was not found.
PDH_CSTATUS_NO_OBJECT
The specified object could not be found.
PDH_CSTATUS_NO_MACHINE
A machine entry could not be created.
PDH_CSTATUS_BAD_COUNTERNAME
An empty counter name path string was passed in.
PDH_FUNCTION_NOT_FOUND
The calculation function for this counter could not be determined.

See Also

Performance Data Helper Overview, Performance Data Functions


PdhCloseQuery (VB)

The Visual Basic PdhCloseQuery function closes the specified query and all counters related to that query. All resources allocated for the query and its counters are freed. The handles of counters added to this query should be deleted or zeroed and not used after the query they belong to is deleted.

PdhCloseQuery(
  ByVal QueryHandle as Long)
as Long

Parameters

QueryHandle
The ID of the query to close and delete. Closing a query closes all the counters associated with the query.

Return Values

If the function succeeds, it returns a Long integer equal to ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhdefs.txt. The following is a possible error value:

PDH_INVALID_HANDLE
The handle is invalid.

See Also

Performance Data Helper Overview, Performance Data Functions


PdhCollectQueryData (VB)

The Visual Basic PdhCollectQueryData function collects the current raw value of each counter in the query referenced by the QueryHandle parameter and updates the internal buffers of each counter object.

PdhCollectQueryData(
  ByVal QueryHandle as Long)
as Long

Parameters

QueryHandle
The ID of the query to update. This must be a value returned by a call to PdhOpenQuery.

Return Values

If the function succeeds, it returns a Long integer equal to ERROR_SUCCESS. Note that the function can return successfully, but some or all counters in the query may not have been updated.

If the function fails, the return value is a PDH error status defined in pdhdefs.txt. The following are possible error values:

PDH_INVALID_HANDLE
The query handle is not valid.
PDH_NO_DATA
The query does not have any counters defined yet.

See Also

Performance Data Helper Overview, Performance Data Functions


PdhCreateCounterPathList (VB)

The Visual Basic PdhCreateCounterPathList function displays the performance counter browsing dialog box, which lets the user select several performance counters. Each selected counter path must then be read using the PdhGetCounterPathFromList function.

PdhCreateCounterPathList(
  ByVal DetailLevel as Long,
  ByVal CaptionString as String)
as Long

Parameters

DetailLevel
One of the following values defined in PDHDEFS.TXT. The selected value indicates the types of counters to be displayed in the dialog box:
Value | Counters Displayed
PERF_DETAIL_NOVICE | Only counters that the novice user is likely to understand.
PERF_DETAIL_ADVANCED | Counters that the advanced user is likely to understand, in addition to the novice-user counters.
PERF_DETAIL_EXPERT | Counters that the expert user and software developer is likely to understand, in addition to the counters for the novice and advanced users.
PERF_DETAIL_WIZARD | All counters in the system.

CaptionString
A string variable that contains the text that will be displayed in the caption bar of the dialog box.

Return Values

The function returns the number of counter paths that the user selected.

See Also

Performance Data Helper Overview, Performance Data Functions


PdhGetCounterPathElements (VB)

The Visual Basic PdhGetCounterPathElements function parses a fully qualified performance counter path string into its individual elements. Each of the string variables must be the same size (BufferSize) and dimensioned and initialized before it is used in this function.

PdhGetCounterPathElements(
  ByVal PathString as String,
  ByVal MachineName as String,
  ByVal ObjectName as String,
  ByVal InstanceName as String,
  ByVal ParentInstance as String,
  ByVal CounterName as String,
  ByVal BufferSize as Long)
as Long

Parameters

PathString
The counter path string that is to be broken up into its individual elements.
MachineName
The string to receive the Machine name element of the counter path specified in PathString.
ObjectName
The string to receive the Object element of the counter path specified in PathString.
InstanceName
The string to receive the Instance name element, if used, of the counter path specified in PathString.
ParentInstance
The string to receive the Parent Instance element, if used, of the counter path specified in PathString.
CounterName
The string to receive the Machine name element of the counter path specified in PathString.
BufferSize
The maximum size of each string variable used as a parameter to this function call.

Return Values

If the function succeeds, it returns a Long integer equal to ERROR_SUCCESS.

If the function fails, the return value is a PDH error status defined in pdhdefs.txt. The following are possible error values:

PDH_INVALID_ARGUMENT
One or more of the string buffers is not the correct size.
PDH_INSUFFICIENT_BUFFER
One or more of the counter path elements is too large for the return buffer length.
PDH_MEMORY_ALLOCATION_FAILURE
A temporary memory buffer could not be allocated.

See Also

Performance Data Helper Overview, Performance Data Functions


PdhGetCounterPathFromList (VB)

The Visual Basic PdhGetCounterPathFromList function copies the counter path referenced by the Index parameter from a counter path list created by the user from the most recent call to the PdhCreateCounterPathList function.

PdhGetCounterPathFromList(
  ByVal Index as Long,
  ByVal Buffer as String,
  ByVal BufferLength as Long)
as Long

Parameters

Index
The index of the counter path to retrieve. This must be a value that is greater than or equal to 1, and less than or equal to the value returned by the PdhCreateCounterPathList function.
Buffer
A dimensioned and initialized string that will receive the counter path that corresponds to the value of the Index parameter.
BufferLength
The maximum number of characters that will fit in the string referenced by Buffer.

Return Values

The function returns the number of characters copied to Buffer.

See Also

Performance Data Helper Overview, Performance Data Functions


PdhGetDoubleCounterValue (VB)

The Visual Basic PdhGetDoubleCounterValue function returns the current value of the specified counter as a double-precision floating point value. You should check CounterStatus before using the returned number, because the counter may not be valid when it is read. Call PdhIsGoodStatus to check the CounterStatus.

PdhGetDoubleCounterValue(
  ByVal CounterHandle as Long,
  ByRef CounterStatus as Long)
as Double

Parameters

CounterHandle
The ID of the counter whose current value is to be read.
CounterStatus
The variable in which the current status of the counter value is returned to the caller. The returned data value is valid if and only if the value returned in CounterStatus is PDH_CSTATUS_VALID_DATA or PDH_CSTATUS_NEW_DATA (defined in PDHDEFS.TXT). If the value returned in CounterStatus is any other value, do not use the data.

Return Values

PdhGetDoubleCounterValue returns the double-precision floating point value of the current counter, computed and formatted as defined by the counter type.

See Also

Performance Data Helper Overview, Performance Data Functions


PdhGetOneCounterPath (VB)

The Visual Basic PdhGetOneCounterPath function displays a dialog box that lets the user browse the available performance counters on a Windows NT system and select one counter. The counter selected is returned in the PathString variable. The PathString variable must be dimensioned and initialized before this function is called, and the dimensioned size must be indicated by the PathLength variable.

PdhGetOneCounterPath(
  ByVal PathString as String,
  ByVal PathLength as Long,
  ByVal DetailLevel as Long,
  ByVal CaptionString as String)
as Long

Parameters

PathString
The initialized string variable used to receive the counter path selected by the user.
PathLength
The length of the initialized PathString.
DetailLevel
One of the following values defined in PDHDEFS.TXT. The selected value indicates the types of counters to be displayed in the dialog box:
Value | Counters Displayed
PERF_DETAIL_NOVICE | Only counters that the novice user is likely to understand.
PERF_DETAIL_ADVANCED | Counters that the advanced user is likely to understand, in addition to the novice-user counters.
PERF_DETAIL_EXPERT | Counters that the expert user and software developer is likely to understand, in addition to the counters for the novice and advanced users.
PERF_DETAIL_WIZARD | All counters in the system.

CaptionString
A string variable that contains the text that will be displayed in the caption bar of the dialog box.

Return Values

The function returns the number of characters written to the PathString buffer.

See Also

Performance Data Helper Overview, Performance Data Functions


PdhIsGoodStatus (VB)

The Visual Basic PdhIsGoodStatus function tests a status value to determine if it is a success or failure code. If the status value is a successful one, then the return value will be nonzero. If it is a failure status code, the return value will be zero.

PdhIsGoodStatus(
  ByVal StatusValue as Long)
as Long

Parameters

StatusValue
The PDH status value returned by another PDH function that is to be tested.

Return Values

The function returns zero if the status code is a failure status code. It returns nonzero if the status code is a success status code.

See Also

Performance Data Helper Overview, Performance Data Functions


PdhOpenQuery (VB)

The Visual Basic PdhOpenQuery function creates and initializes a unique query structure that is used to manage the collection of performance data.

PdhOpenQuery(
  ByRef QueryHandle as Long)
as Long

Parameters

QueryHandle
A variable that is cleared (equals 0) before the function is called and, if the function is successful, contains the unique ID of the query that is created and opened. This handle is used in the subsequent calls to other PDH functions to identify the query.

Return Values

If the function succeeds, it returns a Long integer equal to ERROR_SUCCESS and a new handle in the QueryHandle variable.

If the function fails, the return value is a PDH error status defined in pdhdefs.txt. The following are possible error values:

PDH_INVALID_ARGUMENT
The argument is invalid or incorrect.
PDH_MEMORY_ALLOCATION_FAILURE
A temporary memory buffer could not be allocated.

See Also

Performance Data Helper Overview, Performance Data Functions


PdhRemoveCounter (VB)

The Visual Basic PdhRemoveCounter function removes the counter entry identified by the CounterHandle parameter.

PdhRemoveCounter(
  ByVal CounterHandle as Long)
as Long

Parameters

CounterHandle
The ID of the counter returned by the PdhAddCounter function.

Return Values

If the function succeeds, it returns a Long integer equal to ERROR_SUCCESS and the counter entry is deleted from the query.

If the function fails, the return value is a PDH error status defined in pdhdefs.txt. The following is a possible error value:

Value | Meaning
PDH_INVALID_HANDLE | The counter handle is not valid.


PDH Structures

The following are Performance Data Helper structures.

See Also

Performance Data Helper Overview, Performance Data Functions


PDH_BROWSE_DLG_CONFIG

The PDH_BROWSE_DLG_CONFIG structure is used by the PdhBrowseCounters function to configure the PDH Browse Counters dialog box.

typedef struct _BrowseDlgConfig {
    // Configuration flags
    DWORD   bIncludeInstanceIndex:1,
            bSingleCounterPerAdd:1,
            bSingleCounterPerDialog:1,
            bLocalCountersOnly:1,
            bWildCardInstances:1,
            bHideDetailBox:1,
            bInitializePath:1,
            bReserved:25;

    HWND                hWndOwner;
    LPTSTR              szReserved;
    LPTSTR              szReturnPathBuffer;
    DWORD               cchReturnPathLength;
    CounterPathCallBack pCallBack;
    DWORD               dwCallBackArg;
    PDH_STATUS          CallBackStatus;
    DWORD               dwDefaultDetailLevel;
    LPTSTR              szDialogBoxCaption;
} PDH_BROWSE_DLG_CONFIG, *PPDH_BROWSE_DLG_CONFIG;

Members

Configuration Flags
The initial DWORD of the PDH_BROWSE_DLG_CONFIG structure contains the following configuration flag fields. The default value for each field is FALSE.
bIncludeInstanceIndex
TRUE: The returned counter path will include the instance index for the instance.

FALSE: The returned counter path will not contain an instance number.

bSingleCounterPerAdd
TRUE: Multiple and wild card selections are permitted. Selected counters are returned as a MULTI_SZ string each time the Add button is clicked.

FALSE: Multiple selections are not permitted. Only one counter will be returned each time the Add button is clicked.

bSingleCounterPerDialog
TRUE: The dialog box is closed after the Add button is clicked the first time. Therefore, you can only add a single counter.

FALSE: The dialog box is not closed until the Close button is clicked. The Add button can be clicked multiple times.

bLocalCountersOnly
TRUE: The machine name will not prefix the counter path in the returned string.

FALSE: The machine name will prefix the counter path unless the user selects the Local Counters Only radio button.

bWildCardInstances
TRUE: If wild card instances (for example, ALL) are selected, then the returned counter path will include the wild-card syntax (for example, "*") for the instance field.

FALSE: If All Instances has been selected, all the instances currently found for that object will be returned in a MULTI_SZ string.

bHideDetailBox
TRUE: Removes the Detail Level combo box from the dialog box so the user cannot change the detail level of the counters displayed in the dialog box. The detail level will be fixed to the value of the dwDefaultDetailLevel member.

FALSE: Displays the Detail Level combo box in the dialog box, allowing the user to change the detail level of the counters displayed.

Note that the counters displayed will be those whose detail level is less than or equal to the current detail level selection. Selecting a detail level of Wizard will display all counters and objects.

bInitializePath
TRUE: Selects the counter and object based on the first counter path contained in the szReturnPathBuffer member when the dialog box is first displayed, instead of using the default counter and object specified by the machine.

FALSE: Selects the initial counter and object using the default counter and object information returned by the machine.

hWndOwner
The handle of the calling function's window.
szReserved
Reserved. Must be NULL.
szReturnPathBuffer
The buffer, allocated by the caller, that is used to initialize the first selection in the list boxes (bInitializePath == TRUE) and to return the selected counters to the calling function or the callback procedure.
cchReturnPathLength
The current maximum size, in characters, of the buffer referenced by the szReturnPathBuffer member. If the callback function reallocates a new buffer, it must also update this value.
pCallBack
The address of the callback function used to update application buffers and controls when a multiple-selection dialog box is configured. For more information, see CounterPathCallback.
dwCallBackArg
User-defined argument that is passed as the only argument to the callback function when it is called by the dialog box.
CallBackStatus
On entry to the callback function, this member contains the status of the path buffer. On exit, the callback function sets the status value resulting from processing.

If the buffer is too small to load the current selection, the browser will set this value to PDH_MORE_DATA. If the browser sets this member to ERROR_SUCCESS, then the szReturnPathBuffer member contains a valid counter path or counter path list.

If the callback function reallocates a new buffer, it should set this member to PDH_RETRY so that the browser will try to load the buffer with the selected paths and call the callback function again.

If some other error occurred, then the callback function should return the appropriate PDH error status value.

dwDefaultDetailLevel
The default detail level to show on startup in the Detail Level combo box. If the Detail Level combo box is not shown, this is the detail level to use in filtering the displayed performance counters and objects.
szDialogBoxCaption
The optional caption to be displayed in the caption bar of the PDH Browse Counters dialog box. If this member is NULL, the caption will be Browse Performance Counters.

Remarks

Each time the Add button is clicked, the szReturnPathBuffer buffer contains the selected counter and the pCallBack callback function is called. The callback function should call the PdhAddCounter function for each counter in the buffer.

See Also

Performance Data Helper Overview, Performance Data Structures, CounterPathCallback, PdhAddCounter, PdhBrowseCounters


PDH_COUNTER_INFO

The PDH_COUNTER_INFO structure contains information describing the properties of a counter. This information also includes the counter path. The format of this buffer is to have the structure described below followed by a variable-length buffer containing the string information referenced by the string pointers in the structure (szFullPath, szMachineName, szObjectName, szInstanceName, szParentInstance, szCounterName, and szExplainText).

typedef struct _PDH_COUNTER_INFO {
    DWORD   dwLength;
    DWORD   dwType;
    DWORD   CVersion;
    DWORD   CStatus;
    LONG    lScale;
    LONG    lDefaultScale;
    DWORD   dwUserData;
    DWORD   dwQueryUserData;
    LPTSTR  szFullPath;
    union   {
        PDH_COUNTER_PATH_ELEMENTS CounterPath;
        struct {
            LPTSTR   szMachineName;
            LPTSTR   szObjectName;
            LPTSTR   szInstanceName;
            LPTSTR   szParentInstance;
            DWORD    dwInstanceIndex;
            LPTSTR   szCounterName;
        };
    };
    LPTSTR  szExplainText;
    DWORD   DataBuffer[1];
} PDH_COUNTER_INFO, *PPDH_COUNTER_INFO;

Members

dwLength
The length of the structure, including strings.
dwType
The counter type.
CVersion
Counter version information.
CStatus
The current counter status. See Counter Status versus Function Status.
lScale
The current scale factor.
lDefaultScale
The recommended scale factor.
dwUserData
The value of the counter's User Data field.
dwQueryUserData
The value of the User Data field for the query to which the counter belongs.
szFullPath
The full counter path.
CounterPath
See PDH_COUNTER_PATH_ELEMENTS.
szExplainText
The explain text for this counter.
DataBuffer[1]
The first byte of string data appended to the structure.

See Also

Performance Data Helper Overview, Performance Data Structures, PDH_COUNTER_PATH_ELEMENTS, PdhGetCounterInfo


PDH_COUNTER_PATH_ELEMENTS

The PDH_COUNTER_PATH_ELEMENTS structure contains the parsed elements of a fully qualified counter path. The main purpose of this structure is to provide formatted text to the calling application for display.

typedef struct _PDH_COUNTER_PATH_ELEMENTS {
    LPTSTR  szMachineName;
    LPTSTR  szObjectName;
    LPTSTR  szInstanceName;
    LPTSTR  szParentInstance;
    DWORD   dwInstanceIndex;
    LPTSTR  szCounterName;
} PDH_COUNTER_PATH_ELEMENTS, *PPDH_COUNTER_PATH_ELEMENTS;

Members

szMachineName
The machine name, parsed from the counter path.
szObjectName
The object name, parsed from the counter path.
szInstanceName
The instance name, parsed from counter path.
szParentInstance
The parent instance name, parsed from counter path.
dwInstanceIndex
The index of duplicate instance names.
szCounterName
The counter name.

See Also

Performance Data Helper Overview, Performance Data Structures, PdhMakeCounterPath, PdhParseCounterPath


PDH_FMT_COUNTERVALUE

The PDH_FMT_COUNTERVALUE structure is the most commonly used method of reading the data from within an application. The data type of the data returned (member of the union that will have meaningful data) is specified by the caller when requesting the data. The CStatus member provides the status of the counter. Check this member before using the data in a calculation or display. The counter, and therefore the data, could be invalid.

typedef struct _PDH_FMT_COUNTERVALUE {
    DWORD    CStatus;
    union {
        LONG        longValue;
        double      doubleValue;
        LONGLONG    largeValue;
    };
} PDH_FMT_COUNTERVALUE, *PPDH_FMT_COUNTERVALUE;

Members

CStatus
The status of last collection operation for this counter. See Counter Status versus Function Status.

See Also

Performance Data Helper Overview, Performance Data Structures, PdhCalculateCounterFromRawValue, PdhGetFormattedCounterValue


PDH_RAW_COUNTER

The PDH_RAW_COUNTER structure returns the data as it was collected from the counter provider. No translation, formatting, or other interpretation is performed on the data.

typedef struct _PDH_RAW_COUNTER {
    DWORD       CStatus;
    FILETIME    TimeStamp;
    LONGLONG    FirstValue;
    LONGLONG    SecondValue;
    DWORD       MultiCount;
} PDH_RAW_COUNTER, *PPDH_RAW_COUNTER;

Members

CStatus
The status of the last collection operation for this counter. See Counter Status versus Function Status.
TimeStamp
The local time this data was collected.
FirstValue
The first raw counter value.
SecondValue
The second (if necessary) raw counter value.
MultiCount
The multi count (normally 1).

See Also

PdhCalculateCounterFromRawValue, PdhComputeCounterStatistics, PdhGetRawCounterValue


PDH_STATISTICS

The PDH_STATISTICS structure is used to return the statistics of the values in an array of raw counters managed by the application program. The format of the data in the PDH_FMT_COUNTERVALUE structure is described in the dwFormat member.

typedef struct _PDH_STATISTICS {
    DWORD                   dwFormat;
    DWORD                   count;
    PDH_FMT_COUNTERVALUE    min;
    PDH_FMT_COUNTERVALUE    max;
    PDH_FMT_COUNTERVALUE    mean;
} PDH_STATISTICS, *PPDH_STATISTICS;

Members

dwFormat
The format of the data.
count
The number of values in the array.
min
The minimum of the values.
max
The maximum of the values.
mean
The mean of the values.

See Also

Performance Data Helper Overview, Performance Data Structures, PdhComputeCounterStatistics, PDH_FMT_COUNTERVALUE


PERF_COUNTER_BLOCK

The PERF_COUNTER_BLOCK structure contains the length, in bytes, of the performance-counter data. This structure is followed by data for the number of counters specified in the PERF_OBJECT_TYPE structure.

typedef struct _PERF_COUNTER_BLOCK { // pcd
    DWORD ByteLength;
} PERF_COUNTER_BLOCK;

Members

ByteLength
Specifies the length, in bytes, of this structure, including the counters that follow.

Remarks

This structure is part of the performance data provided by the RegQueryValueEx function when the HKEY_PERFORMANCE_DATA key is used.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winperf.h.

See Also

Performance Data Helper Overview, Performance Data Structures, PERF_OBJECT_TYPE, RegQueryValueEx


PERF_COUNTER_DEFINITION

The PERF_COUNTER_DEFINITION structure describes a performance counter. The Unicode names in this structure must appear in a message file.

typedef struct _PERF_COUNTER_DEFINITION { // pcd
    DWORD  ByteLength;
    DWORD  CounterNameTitleIndex;
    LPWSTR CounterNameTitle;
    DWORD  CounterHelpTitleIndex;
    LPWSTR CounterHelpTitle;
    DWORD  DefaultScale;
    DWORD  DetailLevel;
    DWORD  CounterType;
    DWORD  CounterSize;
    DWORD  CounterOffset;
} PERF_COUNTER_DEFINITION;

Members

ByteLength
Contains the length, in bytes, of this structure.
CounterNameTitleIndex
Contains the index of the counter name in the title database of the registry.
CounterNameTitle
Points to the name of the counter. This member contains NULL, initially, but it can contain a pointer to the actual string once the string is located.
CounterHelpTitleIndex
Contains the index to the counter's Help title in the title database of the registry.
CounterHelpTitle
Points to the title of Help. This member contains NULL, initially, but it can contain a pointer to the actual string once the string is located.
DefaultScale
Specifies the power of 10 by which to scale a chart line, assuming the vertical axis is 100. If this value is zero, the scale value is 1; if this value is 1, the scale value is 10; if this value is –1, the scale value is .10; and so on.
DetailLevel
Specifies the level of detail for the counter. Applications use this value to control display complexity. This member can be one of the following values:
Value | Meaning
PERF_DETAIL_NOVICE | The data can be understood by the uninformed user.
PERF_DETAIL_ADVANCED | The data is designed for the advanced user.
PERF_DETAIL_EXPERT | The data is designed for the expert user.
PERF_DETAIL_WIZARD | The data is designed for the system designer.

CounterType
Specifies the type of counter. This member is some combination of the following values.

These values indicate the counter's data size:
Value | Meaning
PERF_SIZE_DWORD | The counter data is a doubleword.
PERF_SIZE_LARGE | The counter data is a large integer.
PERF_SIZE_ZERO | The counter data is a zero-length field.
PERF_SIZE_VARIABLE_LEN | The size of the counter data is in the CounterSize member.

These values indicate the additional contents of this member:
Value | Meaning
PERF_TYPE_NUMBER | The counter data is a number value but not a counter.
PERF_TYPE_COUNTER | The counter data is an increasing numeric value.
PERF_TYPE_TEXT | The counter data is a text field.
PERF_TYPE_ZERO | The counter data is always zero.

If PERF_TYPE_NUMBER is specified, one of these values is also specified to indicate the format of the number:
Value | Meaning
PERF_NUMBER_HEX | The counter data should be displayed as a hexadecimal value.
PERF_NUMBER_DECIMAL | The counter data should be displayed as a decimal value.
PERF_NUMBER_DEC_1000 | The counter data should be divided by 1000 and displayed as a decimal value.

If PERF_TYPE_COUNTER is specified, one of these values is also specified to indicate the type of counter:
Value | Meaning
PERF_COUNTER_VALUE | The counter value is valid without additional calculation; that is, it should be displayed as is.
PERF_COUNTER_RATE | The counter value should be divided by the elapsed time.
PERF_COUNTER_FRACTION | The counter value should be divided by the base value indicated by the next counter if it is of type PERF_COUNTER_BASE or by the value of the counter subtype.
PERF_COUNTER_BASE | The counter value is the base value to use in fractions.
PERF_COUNTER_ELAPSED | The counter value is a start time to be subtracted from the current time.
PERF_COUNTER_QUEUELEN | The performance application should use the Queuelen counter — that is, the Queue Length Space-Time Product formula. The next counter is the number currently in the queue. Multiply it by the current time (units specified by this counter's subtype). Add the product to the original value of the counter. To obtain the average queue length, divide the result of the addition by the delta time.
PERF_COUNTER_HISTOGRAM | The counter value begins or ends a histogram.

If PERF_TYPE_COUNTER is specified, one of these values is also specified to indicate the subtype of counter:
Value | Meaning
PERF_TIMER_TICK | The frequency of the high-resolution performance counter should be used as the base.
PERF_TIMER_100NS | The time base units of the 100-nanosecond timer should be used as the base.
PERF_OBJECT_TIMER | The object-timer frequency should be used as the base unit. This value is system-defined in this counter's PERF_OBJECT_TYPE definition.

If PERF_TYPE_TEXT is specified, one of these values is also specified to indicate the type of text:
Value | Meaning
PERF_TEXT_UNICODE | The counter data contains Unicode text.
PERF_TEXT_ASCII | The counter data contains ASCII text.

These values indicate how to use the counter data in a calculation:
Value | Meaning
PERF_DELTA_COUNTER | The difference between the previous counter value and the current counter value is computed before proceeding.
PERF_DELTA_BASE | The difference between the previous base value and the current base value is computed before proceeding.
PERF_INVERSE_COUNTER | After other calculations, the counter should be inverted before displaying or converting to a percentage.
PERF_MULTI_COUNTER | This value is a sum of counters from several sources, the number of which is indicated by the next counter.

These values indicate the display suffix of the counter data:
Value | Meaning
PERF_DISPLAY_NO_SUFFIX | There is no display suffix.
PERF_DISPLAY_PER_SEC | The display suffix is '/sec'.
PERF_DISPLAY_PERCENT | The display suffix is '%'.
PERF_DISPLAY_SECONDS | The display suffix is 'secs'.
PERF_DISPLAY_NOSHOW | The counter value should not be displayed.

CounterSize
Specifies the counter size, in bytes.
CounterOffset
Specifies the offset from the start of the PERF_COUNTER_BLOCK structure to the first byte of this counter.

Remarks

This structure is part of the performance data provided by the RegQueryValueEx function when the HKEY_PERFORMANCE_DATA key is used.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winperf.h.

See Also

Performance Data Helper Overview, Performance Data Structures, RegQueryValueEx


PERF_DATA_BLOCK

The PERF_DATA_BLOCK structure describes the performance data provided by RegQueryValueEx function. The data starts with a PERF_DATA_BLOCK structure and is followed by a PERF_OBJECT_TYPE structure and other object-specific data for each type of object monitored.

typedef struct _PERF_DATA_BLOCK { // pdb
    WCHAR         Signature[4];
    DWORD         LittleEndian;
    DWORD         Version;
    DWORD         Revision;
    DWORD         TotalByteLength;
    DWORD         HeaderLength;
    DWORD         NumObjectTypes;
    DWORD         DefaultObject;
    SYSTEMTIME    SystemTime;
    LARGE_INTEGER PerfTime;
    LARGE_INTEGER PerfFreq;
    LARGE_INTEGER PerfTime100nSec;
    DWORD         SystemNameLength;
    DWORD         SystemNameOffset;
} PERF_DATA_BLOCK;

Members

Signature
Contains the Unicode string PERF.
LittleEndian
Contains zero if the processor is big endian and one if it is little endian.
Version
Contains the version of the performance (PERF_) structures. This member is greater than or equal to one.
Revision
Contains the revision of the performance (PERF_) structures. This member is greater than or equal to zero.
TotalByteLength
Contains the total length, in bytes, of the performance data.
HeaderLength
Contains the length, in bytes, of this structure.
NumObjectTypes
Contains the number of object types being monitored.
DefaultObject
Contains the object title index of the default object whose performance data is to be displayed. This member can be –1 to indicate that no data is to be displayed.
SystemTime
Contains the time when the system is monitored. This member is in Coordinated Universal Time (UTC) format.
PerfTime
Contains the performance-counter value, in counts, for the system being monitored.
PerfFreq
Contains the performance-counter frequency, in counts per second, for the system being monitored.
PerfTime100nSec
Contains the performance-counter value, in 100 nanosecond units, for the system being monitored.
SystemNameLength
Contains the length, in bytes, of the system name.
SystemNameOffset
Contains the offset from the beginning of this structure to the name of the system being monitored.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winperf.h.

See Also

Performance Data Helper Overview, Performance Data Structures, PERF_OBJECT_TYPE, RegQueryValueEx


PERF_INSTANCE_DEFINITION

The PERF_INSTANCE_DEFINITION structure contains the instance-specific information for a block of performance data. There is one PERF_INSTANCE_DEFINITION structure for each instance specified in the PERF_OBJECT_TYPE structure.

typedef struct _PERF_INSTANCE_DEFINITION { // pid
    DWORD ByteLength;
    DWORD ParentObjectTitleIndex;
    DWORD ParentObjectInstance;
    DWORD UniqueID;
    DWORD NameOffset;
    DWORD NameLength;
} PERF_INSTANCE_DEFINITION;

Members

ByteLength
Specifies the length, in bytes, of this structure, including the subsequent name.
ParentObjectTitleIndex
Specifies the index of the name of the "parent" object in the title database. For example, if the object is a thread, the parent object type is a process, or if the object is a logical drive, the parent is a physical drive.
ParentObjectInstance
Specifies the index to an instance of the parent object type that is the parent of this instance. This member may be zero or greater.
UniqueID
Specifies the unique identifier used instead of the instance name. This member is PERF_NO_UNIQUE_ID if there is no such identifier.
NameOffset
Specifies the offset from the beginning of this structure to the Unicode name of this instance.
NameLength
Specifies the length, in bytes, of the instance name. This member is zero if the instance does not have a name.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winperf.h.

See Also

Performance Data Helper Overview, Performance Data Structures, PERF_OBJECT_TYPE


PERF_OBJECT_TYPE

The PERF_OBJECT_TYPE structure describes object-specific performance information. This structure is followed by a list of PERF_COUNTER_DEFINITION structures, one for each counter defined for the type of object.

typedef struct _PERF_OBJECT_TYPE {  // pot
    DWORD  TotalByteLength;
    DWORD  DefinitionLength;
    DWORD  HeaderLength;
    DWORD  ObjectNameTitleIndex;
    LPWSTR ObjectNameTitle;
    DWORD  ObjectHelpTitleIndex;
    LPWSTR ObjectHelpTitle;
    DWORD  DetailLevel;
    DWORD  NumCounters;
    DWORD  DefaultCounter;
    DWORD  NumInstances;
    DWORD  CodePage;
    LARGE_INTEGER PerfTime;
    LARGE_INTEGER PerfFreq;
} PERF_OBJECT_TYPE;

Members

TotalByteLength
Contains the length, in bytes, of the object-specific data. This value includes this structure, the PERF_COUNTER_DEFINITION structures, and the PERF_INSTANCE_DEFINITION and PERF_COUNTER_BLOCK structures for each instance. This member specifies the offset from the beginning of this structure to the next PERF_OBJECT_TYPE structure if one exists.
DefinitionLength
Contains the length, in bytes, of the object-specific data. This value includes this structure and the PERF_COUNTER_DEFINITION structures for this object. This member is the offset from the beginning of the PERF_OBJECT_TYPE structure to the first PERF_INSTANCE_DEFINITION structure or to the PERF_COUNTER_DEFINITION structures if there is no instance data.
HeaderLength
Contains the length, in bytes, of this structure. This member is the offset to the first PERF_COUNTER_DEFINITION structure for this object.
ObjectNameTitleIndex
Contains the index to the object's name in the title database.
ObjectNameTitle
Points to the name of the object. This member initially contains NULL, but it can contain a pointer to the actual string once the string is located.
ObjectHelpTitleIndex
Contains the index to the object's Help title in the title database.
ObjectHelpTitle
Points to the title of Help. This member initially contains NULL, but it can contain a pointer to the actual string once the string is located.
DetailLevel
Specifies the level of detail. Applications use this value to control display complexity. This value is the minimum detail level of all the counters for a given object. This member can be one of the following values:
Detail level | Meaning
PERF_DETAIL_NOVICE | No technical ability is required to understand the counter data.
PERF_DETAIL_ADVANCED | The counter data is provided for advanced users.
PERF_DETAIL_EXPERT | The counter data is provided for expert users.
PERF_DETAIL_WIZARD | The counter data is provided for system designers.

NumCounters
Specifies the number of counters in each counter block. There is one counter block per instance.
DefaultCounter
Specifies the default counter whose information is to be displayed when this object is selected. This member is typically greater than or equal to zero. However, this member may be –1 to indicate that there is no default.
NumInstances
Specifies the number of object instances for which counters are being provided.
CodePage
Specifies the code page. This member is zero if the instance strings are in Unicode. Otherwise, this member is the code-page identifier of the instance names.
PerfTime
Specifies the current value, in counts, of the high-resolution performance counter.
PerfFreq
Specifies the current frequency, in counts per second, of the high-resolution performance counter.

Remarks

If there is only one instance of the object type, the counter definitions are followed by a single PERF_COUNTER_BLOCK structure. This structure is followed by data for each counter. (The PERF_COUNTER_BLOCK structure contains the total length of the structure and the counter data that follows it.)

If there is more than one instance of the object type, the list of counter definitions is followed by a PERF_INSTANCE_DEFINITION structure and a PERF_COUNTER_BLOCK structure for each instance. The PERF_INSTANCE_DEFINITION structure includes the name, the identifier, and the name of the parent of the instance.

Following the counter data, there is a PERF_INSTANCE_DEFINITION structure and a PERF_COUNTER_BLOCK structure for each instance specified in the PERF_DATA_BLOCK structure that begins the performance-data area.

QuickInfo

Windows NT: Requires version 3.1 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winperf.h.

See Also

Performance Data Helper Overview, Performance Data Structures, PERF_COUNTER_BLOCK, PERF_COUNTER_DEFINITION, PERF_INSTANCE_DEFINITION


Process Status Helper

The process status helper functions make it easier for you to obtain information about processes and device drivers running on Microsoft® Windows NT®. These functions are available in PSAPI.DLL, which is distributed in the Microsoft® Platform Software Development Kit (SDK). The same information is generally available through the performance data in the registry, but it is more difficult to get to it. For more information on performance data, see The Registry Interface. For information on Performance Data Helper (PDH), see The PDH Interface.


About PSAPI

The process status API (PSAPI) provides sets of functions for retrieving the following information:

  • Process Information
  • Module Information
  • Device Driver Information
  • Process Memory Usage Information
  • Working Set Information
  • Memory-Mapped File Information


Process Information

The system maintains a list of running processes. You can retrieve the identifiers for these processes by calling the EnumProcesses function. This function fills an array of DWORD values with the identifiers of all processes in the system.

Many functions in PSAPI and the Win32 API require a process handle. To obtain a process handle for a running process, pass its process identifier (obtained from EnumProcesses) to the OpenProcess function. Remember to call the CloseHandle function when you are finished with the process handle.


Module Information

A module is an executable file or DLL. Each process consists of one or more modules. You can retrieve the list of module handles for a process by calling the EnumProcessModules function. This function fills an array of HMODULE values with the module handles for the specified process. The first module is the executable file. Remember that these module handles are most likely from some other process, so you cannot use them with Win32 functions such as GetModuleFileName. However, you can use PSAPI functions to obtain information about a module from another process.

To obtain module information
  1. Call the GetModuleBaseName function. This function takes a process handle and a module handle as input and fills in a buffer with the base name of a module (for example, KERNEL32.DLL). A related function, GetModuleFileNameEx, takes the same parameters as input but returns the full path to the module (for example, C:\WINNT\SYSTEM32\KERNEL32.DLL).
  2. Call the GetModuleInformation function. This function takes a process handle and a module handle and fills a MODULEINFO structure with the load address of the module, the size of the linear address space it occupies, and a pointer to its entry point.


Device Driver Information

Device drivers and modules are similar in that they are both based on PE files. However, while each process has its own private list of loaded modules, device drivers have modules that are global to the system. Therefore, PSAPI has specific functions for obtaining the list of device drivers and their names.

You can retrieve the load address for each device driver by calling the EnumDeviceDrivers function. This function fills an array of LPVOID values with the load addresses of all device drivers in the system.

The GetDeviceDriverBaseName function takes a driver load address as input and fills in a buffer with the base name of the driver (for example, WIN32K.SYS). A related function, GetDeviceDriverFileName, takes the same parameters and returns the full path to the device driver (for example, C:\WINNT\SYSTEM32\WIN32K.SYS).


Process Memory Usage Information

The GetProcessMemoryInfo function takes a process handle as input and fills a PROCESS_MEMORY_COUNTERS structure with information about the memory statistics for the process. The cb member receives the size of the structure. The PageFaultCount member receives the number of page faults. The remaining members receive the current and peak memory usage in the following categories:

  • working set
  • paged pool
  • nonpaged pool
  • pagefile

The working set is the amount of memory physically mapped to the process context at a given time. Memory in the paged pool is system memory that can be transferred to the paging file on disk (paged) when it is not being used. Memory in the nonpaged pool is system memory that cannot be paged to disk as long as the corresponding objects are allocated. The pagefile usage represents how much memory is set aside for the process in the system paging file. When memory usage is too high, the virtual memory manager pages selected memory to disk. When a thread needs a page that is not in memory, the memory manager reloads it from the paging file.


Working Set Information

The working set of a process is the amount of memory physically mapped to its process context. PSAPI enables you to take snapshots of the working set or to monitor the working set.

The QueryWorkingSet function fills a buffer with a snapshot of the information for every page in the current working set of the specified process. The function reports only those pages that are physically present at the exact moment it is called.

You can use working set monitoring to find out how much additional RAM a particular operation takes (for example, saving a file). To begin monitoring the working set, call the InitializeProcessForWsWatch function. Not all processes let you read their working set information, so be sure that the function returns a nonzero value before you continue. Next, call the GetWsChanges function. This function reports only the pages that have been loaded in memory since you began monitoring the working set. The function returns data in an array of PSAPI_WS_WATCH_INFORMATION structures, one structure for each new page added to the working set of the process. The structure tells you which pages are in memory, and what caused the system to page them in.

The EmptyWorkingSet function takes a process handle. It removes as many pages as possible from the process working set. This operation is useful primarily for testing and tuning. Note that the SetProcessWorkingSetSize function does the same thing if you pass it 0xFFFFFFFF for the minimum and maximum sizes.


Memory-Mapped File Information

A memory-mapped file (or file mapping) is the result of associating a file's contents with a portion of the virtual address space of a process. It can be used to share a file or memory between two or more processes.

The GetMappedFileName function receives a process handle and a pointer to an address as input. If the address is within a memory-mapped file in the virtual address space of the process, the function returns the name of the memory-mapped file. The filenames returned by GetMappedFileName use device form, rather than drive letters. For example, the filename c:\winnt\system32\ctype.nls would look like this in device form:

\Device\Harddisk0\Partition1\WINNT\System32\ctype.nls

For more information about memory-mapped files, see File Mapping.


Using PSAPI

The following examples show you how to use the PSAPI functions:

  • Enumerating all processes
  • Enumerating all modules for a process
  • Collecting memory usage information for a process


Enumerating All Processes

Task Manager is an example of a program that enumerates all running processes on Windows NT. It is implemented using data from the performance registry. The following sample code uses the EnumProcesses function to enumerate the current processes in the system. This method is easier than using the performance registry.

#include <windows.h>
#include <stdio.h>
#include "psapi.h"

void PrintProcessNameAndID( DWORD processID )
{
    char szProcessName[MAX_PATH] = "unknown";

    // Get a handle to the process.

    HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                   PROCESS_VM_READ,
                                   FALSE, processID );

    // Get the process name.

    if ( hProcess )
    {
        HMODULE hMod;
        DWORD cbNeeded;

        if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
             &cbNeeded) )
        {
            GetModuleBaseName( hProcess, hMod, szProcessName,
                               sizeof(szProcessName) );
        }
    }

    // Print the process name and identifier.

    printf( "%s (Process ID: %u)\n", szProcessName, processID );

    CloseHandle( hProcess );
}

void main( )
{
    // Get the list of process identifiers.

    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return;

    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the name and process identifier for each process.

    for ( i = 0; i < cProcesses; i++ )
        PrintProcessNameAndID( aProcesses[i] );
}

The main function obtains a list of processes by using the EnumProcesses function. For each process, main calls the PrintProcessNameAndID function, passing it the process identifier. PrintProcessNameAndID in turn calls the OpenProcess function to obtain the process handle. If OpenProcess fails, the output shows only the process identifier. For example, OpenProcess fails for the Idle and CSRSS processes because their access restrictions prevent user-level code from opening them. Next, PrintProcessNameAndID calls the EnumProcessModules function to obtain the module handles. Finally, PrintProcessNameAndID calls the GetModuleBaseName function to obtain the name of the executable file.


Enumerating All Modules For a Process

To determine which processes have loaded a particular DLL, you must enumerate the modules for each process. The following sample code uses the EnumProcessModules function to enumerate the modules of current processes in the system.

#include <windows.h>
#include <stdio.h>
#include "psapi.h"

void PrintModules( DWORD processID )
{
    HMODULE hMods[1024];
    HANDLE hProcess;
    DWORD cbNeeded;
    unsigned int i;

    // Print the process identifier.

    printf( "\nProcess ID: %u\n", processID );

    // Get a list of all the modules in this process.

    hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION |
                                    PROCESS_VM_READ,
                                    FALSE, processID );

    if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
    {
        for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
        {
            char szModName[MAX_PATH];

            // Get the full path to the module's file.

            if ( GetModuleFileNameEx( hProcess, hMods[i], szModName,
                                      sizeof(szModName)))
            {
                // Print the module name and handle value.

                printf("\t%s (0x%08X)\n", szModName, hMods[i] );
            }
        }
    }

    CloseHandle( hProcess );
}

void main( )
{
    // Get the list of process identifiers.

    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return;

    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the name of the modules for each process.

    for ( i = 0; i < cProcesses; i++ )
        PrintModules( aProcesses[i] );
}

The main function obtains a list of processes by using the EnumProcesses function. For each process, the main function calls the PrintModules function, passing it the process identifier. PrintModules in turn calls the OpenProcess function to obtain the process handle. If OpenProcess fails, the output shows only the process identifier. For example, OpenProcess fails for the Idle and CSRSS processes because their access restrictions prevent user-level code from opening them. Next, PrintModules calls the EnumProcessModules function to obtain the module handles function. Finally, PrintModules calls the GetModuleFileNameEx function, once for each module, to obtain the module names.


Collecting Memory Usage Information For a Process

To determine the efficiency of your application, you may want to examine its memory usage. The following sample code uses the GetProcessMemoryInfo function to obtain information about the memory usage of a process.

#include <windows.h>
#include <stdio.h>
#include "psapi.h"

void PrintMemoryInfo( DWORD processID )
{
    HANDLE hProcess;
    PROCESS_MEMORY_COUNTERS pmc;

    // Print the process identifier.

    printf( "\nProcess ID: %u\n", processID );

    // Print information about the memory usage of the process.

    hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION |
                                    PROCESS_VM_READ,
                                    FALSE, processID );

    if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
    {
        printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount );
        printf( "\tPeakWorkingSetSize: 0x%08X\n",
                  pmc.PeakWorkingSetSize );
        printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize );
        printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n",
                  pmc.QuotaPeakPagedPoolUsage );
        printf( "\tQuotaPagedPoolUsage: 0x%08X\n",
                  pmc.QuotaPagedPoolUsage );
        printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n",
                  pmc.QuotaPeakNonPagedPoolUsage );
        printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n",
                  pmc.QuotaNonPagedPoolUsage );
        printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage );
        printf( "\tPeakPagefileUsage: 0x%08X\n",
                  pmc.PeakPagefileUsage );
    }

    CloseHandle( hProcess );
}

void main( )
{
    // Get the list of process identifiers.

    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return;

    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the memory usage for each process

    for ( i = 0; i < cProcesses; i++ )
        PrintMemoryInfo( aProcesses[i] );
}

The main function obtains a list of processes by using the EnumProcesses function. For each process, main calls the PrintMemoryInfo function, passing the process identifier. PrintMemoryInfo in turn calls the OpenProcess function to obtain the process handle. If OpenProcess fails, the output shows only the process identifier. For example, OpenProcess fails for the Idle and CSRSS processes because their access restrictions prevent user-level code from opening them. Finally, PrintMemoryInfo calls the GetProcessMemoryInfo function to obtain the memory usage information.


PSAPI Reference

This section describes the PSAPI functions and structures.

· PSAPI Functions

· PSAPI Structures


PSAPI Functions

The following are the PSAPI functions.

EmptyWorkingSet
EnumDeviceDrivers
EnumProcesses
EnumProcessModules
GetDeviceDriverBaseName
GetDeviceDriverFileName
GetMappedFileName
GetModuleBaseName
GetModuleFileNameEx
GetModuleInformation
GetProcessMemoryInfo
GetWsChanges
InitializeProcessForWsWatch
QueryWorkingSet


EmptyWorkingSet

The EmptyWorkingSet function removes as many pages as possible from the working set of the specified process.

BOOL EmptyWorkingSet(
  HANDLE hProcess  // identifies the process
);

Parameters

hProcess
Handle to the process.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

You can also use the SetProcessWorkingSetSize function to do what EmptyWorkingSet does if you pass it 0xFFFFFFFF for the minimum and maximum sizes.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses, SetProcessWorkingSetSize


EnumDeviceDrivers

The EnumDeviceDrivers function retrieves the load address for each device driver in the system.

BOOL EnumDeviceDrivers(
  LPVOID *lpImageBase,  // array to receive the load addresses
  DWORD cb,             // size of the array
  LPDWORD lpcbNeeded    // receives the number of bytes returned
);

Parameters

lpImageBase
Pointer to an array that receives the list of load addresses for the device drivers.
cb
Specifies the size, in bytes, of the lpImageBase array. If the value is zero, lpcbNeeded receives the size, in bytes, of the array needed to store the load addresses.
lpcbNeeded
Receives the number of bytes returned in the lpImageBase array.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

It is a good idea to give EnumDeviceDrivers a large array of LPVOID values, because it is hard to predict how many device drivers there will be at the time you call EnumDeviceDrivers. To determine how many device drivers were enumerated by the call to EnumDeviceDrivers, divide the resulting value in the lpcbNeeded parameter by sizeof(LPVOID).

See Also

Process Status Helper Overview, PSAPI Functions


EnumProcesses

The EnumProcesses function retrieves the process identifier for each process object in the system.

BOOL EnumProcesses(
  DWORD * lpidProcess,  // array to receive the process identifiers
  DWORD cb,             // size of the array
  DWORD * cbNeeded      // receives the number of bytes returned
);

Parameters

lpidProcess
Pointer to an array that receives the list of process identifiers.
cb
Specifies the size, in bytes, of the lpidProcess array.
cbNeeded
Receives the number of bytes returned in the lpidProcess array.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

It is a good idea to give EnumProcesses a large array of DWORD values, because it is hard to predict how many processes there will be at the time you call EnumProcesses. To determine how many processes were enumerated by the call to EnumProcesses, divide the resulting value in the cbNeeded parameter by sizeof(DWORD).

To obtain process handles for the processes whose identifiers you have just obtained, call the OpenProcess function.

See Also

Process Status Helper Overview, PSAPI Functions, OpenProcess


EnumProcessModules

The EnumProcessModules function retrieves a handle for each module in the specified process.

BOOL EnumProcessModules(
  HANDLE hProcess,      // handle to the process
  HMODULE * lphModule,  // array to receive the module handles
  DWORD cb,             // size of the array
  LPDWORD lpcbNeeded    // receives the number of bytes returned
);

Parameters

hProcess
Handle to the process.
lphModule
Pointer to the array that receives the list of module handles.
cb
Specifies the size, in bytes, of the lphModule array.
lpcbNeeded
Receives the number of bytes returned in the lphModule array.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

It is a good idea to give EnumProcessModules a large array of HMODULE values, because it is hard to predict how many modules there will be in the process at the time you call EnumProcessModules. To determine how many modules were enumerated by the call to EnumProcessModules, divide the resulting value in the lpcbNeeded parameter by sizeof(HMODULE).

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses


GetDeviceDriverBaseName

The GetDeviceDriverBaseName function retrieves the base name of the specified device driver.

DWORD GetDeviceDriverBaseName(
  LPVOID ImageBase,  // the load address of the driver
  LPTSTR lpBaseName, // receives the base name of the driver
  DWORD nSize        // size of the buffer
);

Parameters

ImageBase
The load address of the device driver.
lpBaseName
Pointer to the buffer that receives the base name of the device driver.
nSize
Specifies the size, in bytes, of the lpBaseName buffer.

Return Value

If the function succeeds, the return value specifies the length of the string copied to the buffer.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

See Also

Process Status Helper Overview, PSAPI Functions, EnumDeviceDrivers


GetDeviceDriverFileName

The GetDeviceDriverFileName function retrieves the fully qualified path for the specified device driver.

DWORD GetDeviceDriverFileName(
  LPVOID ImageBase,  // the load address of the driver
  LPTSTR lpFilename, // buffer that receives the path
  DWORD nSize        // size of the buffer
);

Parameters

ImageBase
The load address of the device driver.
lpFilename
Pointer to the buffer that receives the fully qualified path to the device driver.
nSize
Specifies the size, in bytes, of the lpFilename buffer.

Return Value

If the function succeeds, the return value specifies the length of the string copied to the buffer.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

See Also

Process Status Helper Overview, PSAPI Functions, EnumDeviceDrivers


GetMappedFileName

The GetMappedFileName function checks if the specified address is within a memory-mapped file in the address space of the specified process. If so, the function returns the name of the memory-mapped file.

DWORD GetMappedFileName(
  HANDLE hProcess,    // handle to the process
  LPVOID lpv,         // the address to verify
  LPTSTR lpFilename,  // buffer that receives the filename
  DWORD nSize         // size of the buffer
);

Parameters

hProcess
Handle to the process.
lpv
The address to verify.
lpFilename
Pointer to the buffer that receives the name of the memory-mapped file to which the address specified by lpv belongs.
nSize
Specifies the size, in bytes, of the lpFilename buffer.

Return Value

If the function succeeds, the return value specifies the length of the string copied to the buffer.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses


GetModuleBaseName

The GetModuleBaseName function retrieves the base name of the specified module.

DWORD GetModuleBaseName(
  HANDLE hProcess,    // handle to the process
  HMODULE hModule,    // handle to the module
  LPTSTR lpBaseName,  // buffer that receives the base name
  DWORD nSize         // size of the buffer
);

Parameters

hProcess
Handle to the process that contains the module.
hModule
Handle to the module.
lpBaseName
Pointer to the buffer that receives the base name of the module.
nSize
Specifies the size, in bytes, of the lpBaseName buffer.

Return Value

If the function succeeds, the return value specifies the length of the string copied to the buffer.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses, GetModuleFileNameEx


GetModuleFileNameEx

The GetModuleFileNameEx function retrieves the fully qualified path for the specified module.

DWORD GetModuleFileNameEx(
  HANDLE hProcess,    // handle to the process
  HMODULE hModule,    // handle to the module
  LPTSTR lpFilename,  // buffer that receives the path
  DWORD nSize         // size of the buffer
);

Parameters

hProcess
Handle to the process that contains the module.
hModule
Handle to the module.
lpFilename
Pointer to the buffer that receives the fully qualified path to the module.
nSize
Specifies the size, in bytes, of the lpFilename buffer.

Return Value

If the function succeeds, the return value specifies the length of the string copied to the buffer.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses, GetModuleBaseName


GetModuleInformation

The GetModuleInformation function retrieves information about the specified module in the MODULEINFO structure.

BOOL GetModuleInformation(
  HANDLE hProcess,         // handle to the process
  HMODULE hModule,         // handle to the module
  LPMODULEINFO lpmodinfo,  // structure that receives information
  DWORD cb                 // size of the structure
);

Parameters

hProcess
Handle to the process that contains the module.
hModule
Handle to the module.
lpmodinfo
Pointer to the MODULEINFO structure that receives information about the module.
cb
Specifies the size, in bytes, of the MODULEINFO structure.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses, MODULEINFO


GetProcessMemoryInfo

The GetProcessMemoryInfo function retrieves information about the memory usage of the specified process in the PROCESS_MEMORY_COUNTERS structure.

BOOL GetProcessMemoryInfo(
  HANDLE Process,  // handle to the process
  PPROCESS_MEMORY_COUNTERS ppsmemCounters,
                   // structure that receives information
  DWORD cb         // size of the structure
);

Parameters

Process
Handle to the process.
ppsmemCounters
Pointer to the PROCESS_MEMORY_COUNTERS structure that receives information about the memory usage of the process.
cb
Specifies the size, in bytes, of the PROCESS_MEMORY_COUNTERS structure.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses, PROCESS_MEMORY_COUNTERS


GetWsChanges

The GetWsChanges function retrieves information about the pages that have been added to the working set of the specified process since the InitializeProcessForWsWatch function initiated monitoring.

BOOL GetWsChanges(
  HANDLE hProcess,  // handle to the process
  PPSAPI_WS_WATCH_INFORMATION lpWatchInfo,
                    // structure that receives information
  DWORD cb          // size of the structure
);

Parameters

hProcess
Handle to the process.
lpWatchInfo
Pointer to the PSAPI_WS_WATCH_INFORMATION structure that receives information about a page added to a process working set.
cb
Specifies the size, in bytes, of the PSAPI_WS_WATCH_INFORMATION structure.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses, InitializeProcessForWsWatch, PSAPI_WS_WATCH_INFORMATION


InitializeProcessForWsWatch

The InitializeProcessForWsWatch function initiates monitoring of the working set of the specified process. You must call this function before calling the GetWsChanges function.

BOOL InitializeProcessForWsWatch(
  HANDLE hProcess  // handle to the process
);

Parameters

hProcess
Handle to the process.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses, GetWsChanges


QueryWorkingSet

The QueryWorkingSet function retrieves information about the pages currently added to the working set of the specified process.

BOOL QueryWorkingSet(
  HANDLE hProcess,  // handle to the process
  PVOID pv,         // buffer that receives the information
  DWORD cb          // size of the buffer
);

Parameters

hProcess
Handle to the process.
pv
Pointer to the buffer that receives the information.
cb
Specifies the size, in bytes, of the buffer.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The return buffer consists of a variable number of DWORD values. The first DWORD contains the number of valid DWORD values that follow it in the buffer. Each remaining DWORD represents one page in the process working set, and is composed of an address combined with various flag values.

To decode these DWORD values, it is necessary to split the high 20 bits from the low 12 bits. The high 20 bits (obtained by using a bitwise AND operator with 0xFFFFF000) contain the address of a page of memory loaded into the specified process. The bottom 12 bits are flag values that can be interpreted as follows.

Value | Meaning
0x001 | The page is read-only (if bit 0x004 is not set).
0x002 | The page is executable (code).
0x004 | The page is read/write (if bit 0x001 is not set).
0x005 | The page is copy-on-write (bits 0x001 and 0x004 are both set).
0x100 | The page can be shared across processes.

For example, consider the following DWORD values:

0x00000003
0x00400103
0x00480101
0x00500004

Breaking apart the bits, these DWORD values can be interpreted as follows:

0x00000003 | There are three DWORD values to follow.
0x00400103 | The page at address 0x00400000 has read-only, executable, and shared access.
0x00480101 | The page at address 0x00480000 has read-only and shared access.
0x00500004 | The page at address 0x00500000 has read/write access.

Windows NT Alpha: Split the high 19 bits from the low 13 bits, because pages are 8 KB in size, whereas pages are 4 KB in size on an x86 computer.

See Also

Process Status Helper Overview, PSAPI Functions, EnumProcesses


PSAPI Structures

The following are the PSAPI structures.

MODULEINFO
PROCESS_MEMORY_COUNTERS
PSAPI_WS_WATCH_INFORMATION


MODULEINFO

The MODULEINFO structure contains the module load address, size, and entry point.

typedef struct _MODULEINFO {
    LPVOID lpBaseOfDll;
    DWORD SizeOfImage;
    LPVOID EntryPoint;
} MODULEINFO, *LPMODULEINFO;

Members

lpBaseOfDll
The load address of the module.
SizeOfImage
The size, in bytes, of the linear space that the module occupies.
EntryPoint
The entry point of the module.

Remarks

The load address of a module is the same as the HMODULE value. The information returned in the SizeOfImage and EntryPoint members comes from the module's Portable Executable (PE) header. The module entry point is the location called during process startup, thread startup, process shutdown, and thread shutdown. While this is not the address of the DllMain function, it should be close enough for most purposes.

See Also

Process Status Helper Overview, PSAPI Structures, DllMain, GetModuleInformation


PROCESS_MEMORY_COUNTERS

The PROCESS_MEMORY_COUNTERS structure contains the memory statistics for a process.

typedef struct _PROCESS_MEMORY_COUNTERS {
    DWORD cb;
    DWORD PageFaultCount;
    DWORD PeakWorkingSetSize;
    DWORD WorkingSetSize;
    DWORD QuotaPeakPagedPoolUsage;
    DWORD QuotaPagedPoolUsage;
    DWORD QuotaPeakNonPagedPoolUsage;
    DWORD QuotaNonPagedPoolUsage;
    DWORD PagefileUsage;
    DWORD PeakPagefileUsage;
} PROCESS_MEMORY_COUNTERS;
typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS;

Members

cb
The size of the structure, in bytes.
PageFaultCount
The number of page faults.
PeakWorkingSetSize
The peak working set size.
WorkingSetSize
The current working set size.
QuotaPeakPagedPoolUsage
The peak paged pool usage.
QuotaPagedPoolUsage
The current paged pool usage.
QuotaPeakNonPagedPoolUsage
The peak nonpaged pool usage.
QuotaNonPagedPoolUsage
The current nonpaged pool usage.
PagefileUsage
The current pagefile usage.
PeakPagefileUsage
The peak pagefile usage.

See Also

Process Status Helper Overview, PSAPI Structures, GetProcessMemoryInfo


PSAPI_WS_WATCH_INFORMATION

The PSAPI_WS_WATCH_INFORMATION structure contains information about a page added to a process working set.

typedef struct _PSAPI_WS_WATCH_INFORMATION {
    LPVOID FaultingPc;
    LPVOID FaultingVa;
} PSAPI_WS_WATCH_INFORMATION, *PPSAPI_WS_WATCH_INFORMATION;

Members

FaultingPc
Pointer to the instruction that caused the page fault.
FaultingVa
Pointer to the page that was added to the working set.

See Also

Process Status Helper Overview, PSAPI Structures, GetWsChanges


Windows NT Performance Counters

This appendix describes the Windows NT performance objects and their associated performance counters. The following objects are covered.

  • AppleTalk Object
  • Browser Object
  • Cache Object
  • Client Service for Netware Object
  • ICMP Object
  • Image Object
  • IP Object
  • Logical Disk Object
  • Memory Object
  • NBT Connection Object
  • NetBEUI Object
  • NetBEUI Resource Object
  • Network Interface Object
  • Network Segment Object
  • NWLink IPX Object
  • NWLink NetBIOS Object
  • NWLink SPX Object
  • Objects Object
  • Paging File Object
  • Physical Disk Object
  • Process Object
  • Process Address Space Object
  • Processor Object
  • RAS Port Object
  • RAS Total Object
  • Redirector Object
  • Server Object
  • Server Work Queues Object
  • System Object
  • TCP Object
  • Thread Object
  • Thread Details Object
  • UDP Object


AppleTalk Object

The AppleTalk performance object.

Packets In/sec

Number of packets received per second by Appletalk on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Packets Out/sec

Number of packets sent per second by Appletalk on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Bytes In/sec

Number of bytes received per second by Appletalk on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Out/sec

Number of bytes sent per second by Appletalk on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_BULK_COUNT

Average Time/DDP Packet

Average time in milliseconds to process a DDP packet on this port.

Detail Level: Novice
Counter Type: PERF_AVERAGE_BULK

DDP Packets/sec

Number of DDP packets per second received by Appletalk on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Average Time/AARP Packet

Average time in milliseconds to process an AARP packet on this port.

Detail Level: Novice
Counter Type: PERF_AVERAGE_BULK

AARP Packets/sec

Number of AARP packets per second received by Appletalk on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Average Time/ATP Packet

Average time in milliseconds to process an ATP packet on this port.

Detail Level: Novice
Counter Type: PERF_AVERAGE_BULK

ATP Packets/sec

Number of ATP packets per second received by Appletalk on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Average Time/NBP Packet

Average time in milliseconds to process an NBP packet on this port.

Detail Level: Novice
Counter Type: PERF_AVERAGE_BULK

NBP Packets/sec

Number of NBP packets per second received by Appletalk on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Average Time/ZIP Packet

Average time in milliseconds to process a ZIP packet on this port.

Detail Level: Novice
Counter Type: PERF_AVERAGE_BULK

ZIP Packets/sec

Number of ZIP packets per second received by Appletalk on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Average Time/RTMP Packet

Average time in milliseconds to process an RTMP packet on this port.

Detail Level: Novice
Counter Type: PERF_AVERAGE_BULK

RTMP Packets/sec

Number of RTMP packets per second received by Appletalk on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

ATP Retries Local

Number of ATP requests retransmitted on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

ATP Retries Remote

Number of ATP requests retransmitted to this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

ATP Response Timouts

Number of ATP release timers that have expired on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

ATP XO Response/Sec

Number of ATP Exactly-once transaction responses per second on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

ATP ALO Response/Sec

Number of ATP At-least-once transaction responses per second on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

ATP Recvd Release/Sec

Number of ATP transaction release packets per second received on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Current NonPaged Pool

The current amount of nonpaged memory resources used by AppleTalk.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Packets Routed In/Sec

Number of packets routed in on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Packets Routed Out/Sec

Number of packets routed out on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Packets dropped

Number of packets dropped due to resource limitations on this port.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT


Browser Object

The Browser performance object consists of counters that measure the rates of announcements, enumerations, and other Browser transmissions.

Announcements Server/sec

Announcements Server/sec is the rate at which the servers in this domain have announced themselves to this server.

Detail Level: Novice
Counter Type: PERF_COUNTER_BULK_COUNT

Announcements Domain/sec

Announcements Domain/sec is the rate at which a Domain has announced itself to the network.

Detail Level: Novice
Counter Type: PERF_COUNTER_BULK_COUNT

Announcements Total/sec

Announcements Total/sec is the sum of Announcements Server/sec and Announcements Domain/sec.

Detail Level: Novice
Counter Type: PERF_COUNTER_BULK_COUNT

Election Packets/sec

Election Packets/sec is the rate of Browser election packets that have been received by this workstation.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Mailslot Writes/sec

Mailslot Writes/sec is the rate of mailslot messages that have been successfully received.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Server List Requests/sec

Server List Requests/sec is the rate of requests to retrieve a list of browser servers that have been processed by this workstation.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Enumerations Server/sec

Enumerations Server/sec is the rate of Server browse requests that have been processed by this workstation.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Enumerations Domain/sec

Enumerations Domain/sec is the rate of Domain browse requests that have been processed by this workstation.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Enumerations Other/sec

Enumerations Other/sec is the rate of browse requests processed by this workstation that were not domain or server browse requests.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Enumerations Total/sec

Enumerations Total/sec is the rate of browse requests that have been processed by this workstation. This is the sum of Enumerations Server, Enumerations Domain, and Enumerations Other.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Missed Server Announcements

Missed Server Announcements is the number of server announcements that have been missed due to configuration or allocation limits.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Missed Mailslot Datagrams

Missed Mailslot Datagrams is the number of Mailslot Datagrams that have been discarded due to configuration or allocation limits.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Missed Server List Requests

Missed Server List Requests is the number of requests to retrieve a list of browser servers that were received by this workstation, but could not be processed.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Server Announce Allocations Failed/sec

Server Announce Allocations Failed/sec is the rate of server (or domain) announcements that have failed due to lack of memory.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Mailslot Allocations Failed

Mailslot Allocations Failed is the number of times the datagram receiver has failed to allocate a buffer to hold a user mailslot write.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Mailslot Receives Failed

Mailslot Receives Failed indicates the number of mailslot messages that couldn't be received due to transport failures.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Mailslot Writes Failed

Mailslot Writes Failed is the total number of mailslot messages that have been successfully received, but that were unable to be written to the mailslot.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Mailslot Opens Failed/sec

Mailslot Opens Failed/sec indicates the rate of mailslot messages received by this workstation that were to be delivered to mailslots that are not present on this workstation.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Duplicate Master Announcements

Duplicate Master Announcements indicates the number of times that the master browser has detected another master browser on the same domain.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Illegal Datagrams/sec

Illegal Datagrams/sec is the rate of incorrectly formatted datagrams that have been received by the workstation.

Detail Level: Novice
Counter Type: PERF_COUNTER_BULK_COUNT


Cache Object

The Cache performance object consists of counters that monitor the file system cache, an area of physical memory that stores recently used data as long as possible to permit access to the data without having to read from the disk. Because applications typically use the cache, the cache is monitored as an indicator of application I/O operations. When memory is plentiful, the cache can grow, but when memory is scarce, the cache can become too small to be effective.

Data Maps/sec

Data Maps/sec is the frequency that a file system such as NTFS, maps a page of a file into the file system cache to read the page.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Sync Data Maps/sec

Sync Data Maps/sec counts the frequency that a file system, such as NTFS, maps a page of a file into the file system cache to read the page, and wishes to wait for the page to be retrieved if it is not in main memory.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Async Data Maps/sec

Async Data Maps/sec is the frequency that an application using a file system, such as NTFS, to map a page of a file into the file system cache to read the page, and does not wait for the page to be retrieved if it is not in main memory.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Data Map Hits %

Data Map Hits is the percentage of data maps in the file system cache that could be resolved without having to retrieve a page from the disk, because the page was already in physical memory.

Detail Level: Wizard
Counter Type: PERF_SAMPLE_FRACTION

Data Map Hits %

Data Map Hits is the percentage of data maps in the file system cache that could be resolved without having to retrieve a page from the disk, because the page was already in physical memory.

Detail Level: Wizard
Counter Type: PERF_SAMPLE_BASE

Data Map Pins/sec

Data Map Pins/sec is the frequency of data maps in the file system cache that resulted in pinning a page in main memory, an action usually preparatory to writing to the file on disk. While pinned, a page's physical address in main memory and virtual address in the file system cache will not be altered.

Detail Level: Wizard
Counter Type: PERF_SAMPLE_FRACTION

Data Map Pins/sec

Data Map Pins/sec is the frequency of data maps in the file system cache that resulted in pinning a page in main memory, an action usually preparatory to writing to the file on disk. While pinned, a page's physical address in main memory and virtual address in the file system cache will not be altered.

Detail Level: Wizard
Counter Type: PERF_SAMPLE_BASE

Pin Reads/sec

Pin Reads/sec is the frequency of reading data into the file system cache preparatory to writing the data back to disk. Pages read in this fashion are pinned in memory at the completion of the read. While pinned, a page's physical address in the file system cache will not be altered.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Sync Pin Reads/sec

Sync Pin Reads/sec is the frequency of reading data into the file system cache preparatory to writing the data back to disk. Pages read in this fashion are pinned in memory at the completion of the read. The file system will not regain control until the page is pinned in the file system cache, in particular if the disk must be accessed to retrieve the page. While pinned, a page's physical address in the file system cache will not be altered.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Async Pin Reads/sec

Async Pin Reads/sec is the frequency of reading data into the file system cache preparatory to writing the data back to disk. Pages read in this fashion are pinned in memory at the completion of the read. The file system will regain control immediately even if the disk must be accessed to retrieve the page. While pinned, a page's physical address will not be altered.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Pin Read Hits %

Pin Read Hits is the percentage of pin read requests that hit the file system cache, i.e., did not require a disk read in order to provide access to the page in the file system cache. While pinned, a page's physical address in the file system cache will not be altered. The LAN Redirector uses this method for retrieving data from the cache, as does the LAN Server for small transfers. This is usually the method used by the disk file systems as well.

Detail Level: Expert
Counter Type: PERF_SAMPLE_FRACTION

Pin Read Hits %

Pin Read Hits is the percentage of pin read requests that hit the file system cache, i.e., did not require a disk read in order to provide access to the page in the file system cache. While pinned, a page's physical address in the file system cache will not be altered. The LAN Redirector uses this method for retrieving data from the cache, as does the LAN Server for small transfers. This is usually the method used by the disk file systems as well.

Detail Level: Expert
Counter Type: PERF_SAMPLE_BASE

Copy Reads/sec

Copy Reads/sec is the frequency of reads from pages of the file system cache that involve a memory copy of the data from the cache to the application's buffer. The LAN Redirector uses this method for retrieving information from the file system cache, as does the LAN Server for small transfers. This is a method used by the disk file systems as well.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Sync Copy Reads/sec

Sync Copy Reads/sec is the frequency of reads from pages of the file system cache that involve a memory copy of the data from the cache to the application's buffer. The file system will not regain control until the copy operation is complete, even if the disk must be accessed to retrieve the page.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Async Copy Reads/sec

Async Copy Reads/sec is the frequency of reads from pages of the file system cache that involve a memory copy of the data from the cache to the application's buffer. The application will regain control immediately even if the disk must be accessed to retrieve the page.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Copy Read Hits %

Copy Read Hits is the percentage of cache copy read requests that hit the cache, that is, they did not require a disk read in order to provide access to the page in the cache. A copy read is a file read operation that is satisfied by a memory copy from a page in the cache to the application's buffer. The LAN Redirector uses this method for retrieving information from the cache, as does the LAN Server for small transfers. This is a method used by the disk file systems as well.

Detail Level: Expert
Counter Type: PERF_SAMPLE_FRACTION

Copy Read Hits %

Copy Read Hits is the percentage of cache copy read requests that hit the cache, that is, they did not require a disk read in order to provide access to the page in the cache. A copy read is a file read operation that is satisfied by a memory copy from a page in the cache to the application's buffer. The LAN Redirector uses this method for retrieving information from the cache, as does the LAN Server for small transfers. This is a method used by the disk file systems as well.

Detail Level: Expert
Counter Type: PERF_SAMPLE_BASE

MDL Reads/sec

MDL Reads/sec is the frequency of reads from the file system cache that use a Memory Descriptor List (MDL) to access the data. The MDL contains the physical address of each page involved in the transfer, and thus can employ a hardware Direct Memory Access (DMA) device to effect the copy. The LAN Server uses this method for large transfers out of the server.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Sync MDL Reads/sec

Sync MDL Reads/sec is the frequency of reads from the file system cache that use a Memory Descriptor List (MDL) to access the pages. The MDL contains the physical address of each page in the transfer, thus permitting Direct Memory Access (DMA) of the pages. If the accessed page(s) are not in main memory, the caller will wait for the pages to fault in from the disk.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Async MDL Reads/sec

Async MDL Reads/sec is the frequency of reads from the file system cache that use a Memory Descriptor List (MDL) to access the pages. The MDL contains the physical address of each page in the transfer, thus permitting Direct Memory Access (DMA) of the pages. If the accessed page(s) are not in main memory, the calling application program will not wait for the pages to fault in from disk.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

MDL Read Hits %

MDL Read Hits is the percentage of Memory Descriptor List (MDL) read requests to the file system cache that hit the cache, i.e., did not require disk accesses in order to provide memory access to the page(s) in the cache.

Detail Level: Expert
Counter Type: PERF_SAMPLE_FRACTION

MDL Read Hits %

MDL Read Hits is the percentage of Memory Descriptor List (MDL) read requests to the file system cache that hit the cache, i.e., did not require disk accesses in order to provide memory access to the page(s) in the cache.

Detail Level: Expert
Counter Type: PERF_SAMPLE_BASE

Read Aheads/sec

Read Aheads/sec is the frequency of reads from the file system cache in which the cache detects sequential access to a file. The read aheads permit the data to be transferred in larger blocks than those being requested by the application, reducing the overhead per access.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Fast Reads/sec

Fast Reads/sec is the frequency of reads from the file system cache that bypass the installed file system and retrieve the data directly from the cache. Normally, file I/O requests invoke the appropriate file system to retrieve data from a file, but this path permits direct retrieval of data from the cache without file system involvement if the data is in the cache. Even if the data is not in the cache, one invocation of the file system is avoided.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Sync Fast Reads/sec

Sync Fast Reads/sec is the frequency of reads from the file system cache that bypass the installed file system and retrieve the data directly from the cache. Normally, file I/O requests invoke the appropriate file system to retrieve data from a file, but this path permits direct retrieval of data from the cache without file system involvement if the data is in the cache. Even if the data is not in the cache, one invocation of the file system is avoided. If the data is not in the cache, the request (application program call) will wait until the data has been retrieved from disk.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Async Fast Reads/sec

Async Fast Reads/sec is the frequency of reads from the file system cache that bypass the installed file system and retrieve the data directly from the cache. Normally, file I/O requests will invoke the appropriate file system to retrieve data from a file, but this path permits data to be retrieved from the cache directly (without file system involvement) if the data is in the cache. Even if the data is not in the cache, one invocation of the file system is avoided. If the data is not in the cache, the request (application program call) will not wait until the data has been retrieved from disk, but will get control immediately.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Fast Read Resource Misses/sec

Fast Read Resource Misses/sec is the frequency of cache misses necessitated by the lack of available resources to satisfy the request.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Fast Read Not Possibles/sec

Fast Read Not Possibles/sec is the frequency of attempts by an Application Program Interface (API) function call to bypass the file system to get to data in the file system cache that could not be honored without invoking the file system.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Lazy Write Flushes/sec

Lazy Write Flushes/sec is the rate at which the Lazy Writer thread has written to disk. Lazy Writing is the process of updating the disk after the page has been changed in memory, so that the application that changed the file does not have to wait for the disk write to be complete before proceeding. More than one page can be transferred by each write operation.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Lazy Write Pages/sec

Lazy Write Pages/sec is the rate at which the Lazy Writer thread has written to disk. Lazy Writing is the process of updating the disk after the page has been changed in memory, so that the application that changed the file does not have to wait for the disk write to be complete before proceeding. More than one page can be transferred on a single disk write operation.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Data Flushes/sec

Data Flushes/sec is the rate at which the file system cache has flushed its contents to disk as the result of a request to flush or to satisfy a write-through file write request. More than one page can be transferred on each flush operation.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Data Flush Pages/sec

Data Flush Pages/sec is the number of pages the file system cache has flushed to disk as a result of a request to flush or to satisfy a write-through file write request. More than one page can be transferred on each flush operation.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER


Client Service For NetWare Object

The Client Service For NetWare performance object consists of counters that measure packet transmission rates, logons, and connections.

Bytes Total/sec

Bytes Total/sec is the rate the Redirector is processing data bytes. This includes all application and file data in addition to protocol information such as packet headers.

Detail Level: Novice
Counter Type: PERF_COUNTER_BULK_COUNT

File Data Operations/sec

File Data Operations/sec is the rate the Redirector is processing data operations. One operation includes (hopefully) many bytes. We say hopefully here because each operation has overhead. You can determine the efficiency of this path by dividing the Bytes/sec by this counter to determine the average number of bytes transferred/operation.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Packets/sec

Packets/sec is the rate the Redirector is processing data packets. One packet includes (hopefully) many bytes. We say hopefully here because each packet has protocol overhead. You can determine the efficiency of this path by dividing the Bytes/sec by this counter to determine the average number of bytes transferred/packet. You can also divide this counter by Operations/sec to determine the average number of packets per operation, another measure of efficiency.

Detail Level: Novice
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Received/sec

Bytes Received/sec is the rate of bytes coming in to the Redirector from the network. It includes all application data as well as network protocol information (such as packet headers.)

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Packets Received/sec

Packets Received/sec is the rate at which the Redirector is receiving packets (also called SMBs or Server Message Blocks). Network transmissions are divided into packets. The average number of bytes received in a packet can be obtained by dividing Bytes Received/sec by this counter. Some packets received might not contain incoming data, for example an acknowledgment to a write made by the Redirector would count as an incoming packet.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Transmitted/sec

Bytes Transmitted/sec is the rate at which bytes are leaving the Redirector to the network. It includes all application data as well as network protocol information (such as packet headers and the like.)

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Packets Transmitted/sec

Packets Transmitted/sec is the rate at which the Redirector is sending packets (also called SMBs or Server Message Blocks). Network transmissions are divided into packets. The average number of bytes transmitted in a packet can be obtained by dividing Bytes Transmitted/sec by this counter.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

File Read Operations/sec

File Read Operations/sec is the rate at which applications are asking the Redirector for data. Each call to a file system or similar Application Program Interface (API) call counts as one operation.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Read Operations Random/sec

Read Operations Random/sec counts the rate at which, on a file-by-file basis, reads are made that are not sequential. If a read is made using a particular file handle, and then is followed by another read that is not immediately the contiguous next byte, this counter is incremented by one.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Read Packets/sec

Read Packets/sec is the rate at which read packets are being placed on the network. Each time a single packet is sent with a request to read data remotely, this counter is incremented by one.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

File Write Operations/sec

File Write Operations/sec is the rate at which applications are sending data to the Redirector. Each call to a file system or similar Application Program Interface (API) call counts as one operation.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Write Operations Random/sec

Write Operations Random/sec is the rate at which, on a file-by-file basis, writes are made that are not sequential. If a write is made using a particular file handle, and then is followed by another write that is not immediately the next contiguous byte, this counter is incremented by one.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Write Packets/sec

Write Packets/sec is the rate at which writes are being sent to the network. Each time a single packet is sent with a request to write remote data, this counter is incremented by one.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Server Sessions

Server Sessions counts the total number of security objects the Redirector has managed. For example, a logon to a server followed by a network access to the same server will establish one connection, but two sessions.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Server Reconnects

Server Reconnects counts the number of times your Redirector has had to reconnect to a server in order to complete a new active request. You can be disconnected by the Server if you remain inactive for too long. Locally even if all your remote files are closed, the Redirector will keep your connections intact for (nominally) ten minutes. Such inactive connections are called Dormant Connections. Reconnecting is expensive in time.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connect NetWare 2.x

Connect NetWare 2.x counts connections to NetWare 2.x servers.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connect NetWare 3.x

Connect NetWare 3.x counts connections to NetWare 3.x servers.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connect NetWare 4.x]

Connect NetWare 4.x counts connections to NetWare 4.x servers.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Server Disconnects

Server Disconnects counts the number of times a Server has disconnected your Redirector. See also Server Reconnects.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Packet Burst Read NCP Count/sec

Packet Burst Read NCP Count/sec is the rate of NetWare Core Protocol requests for Packet Burst Read. Packet Burst is a windowing protocol that improves performance.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Packet Burst Read Timeouts/sec

Packet Burst Read Timeouts/sec is the rate the NetWare Service needs to retransmit a Burst Read Request because the NetWare server took too long to respond.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Packet Burst Write NCP Count/sec

Packet Burst Write NCP Count/sec is the rate of NetWare Core Protocol requests for Packet Burst Write. Packet Burst is a windowing protocol that improves performance.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Packet Burst Write Timeouts/sec

Packet Burst Write Timeouts/sec is the rate the NetWare Service needs to retransmit a Burst Write Request because the NetWare server took too long to respond.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Packet Burst IO/sec

Packet Burst IO/sec is the sum of Packet Burst Read NCPs/sec and Packet Burst Write NCPs/sec.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER


ICMP Object

The ICMP performance object consists of counters that measure the rates at which ICMP messages are sent and received by using the ICMP protocols. It also includes counters that monitor ICMP protocol errors.

Messages/sec

Messages/sec is the total rate at which ICMP messages are sent and received by the entity. The rate includes those messages received or sent in error.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Messages Received/sec

Messages Received/sec is the rate at which ICMP messages are received by the entity. The rate includes those messages received in error.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Messages Received Errors

Messages Received Errors is the number of ICMP messages that the entity received but determined as having errors (bad ICMP checksums, bad length, etc.).

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Received Dest. Unreachable

Received Destination Unreachable is the number of ICMP Destination Unreachable messages received.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Received Time Exceeded

Received Time Exceeded is the number of ICMP Time Exceeded messages received.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Received Parameter Problem

Received Parameter Problem is the number of ICMP Parameter Problem messages received.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Received Source Quench

Received Source Quench is the number of ICMP Source Quench messages received.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Received Redirect/sec

Received Redirect/sec is the rate of ICMP Redirect messages received.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Received Echo/sec

Received Echo/sec is the rate of ICMP Echo messages received.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Received Echo Reply/sec

Received Echo Reply/sec is the rate of ICMP Echo Reply messages received.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Received Timestamp/sec

Received Timestamp/sec is the rate of ICMP Timestamp (request) messages received.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Received Timestamp Reply/sec

Received Timestamp Reply/sec is the rate of ICMP Timestamp Reply messages received.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Received Address Mask

Received Address Mask is the number of ICMP Address Mask Request messages received.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Received Address Mask Reply

Received Address Mask Reply is the number of ICMP Address Mask Reply messages received.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Messages Sent/sec

Messages Sent/sec is the rate at which ICMP messages are attempted to be sent by the entity. The rate includes those messages sent in error.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Messages Outbound Errors

Messages Outbound Errors is the number of ICMP messages that this entity did not send due to problems discovered within ICMP such as lack of buffers. This value does not include errors discovered outside the ICMP layer, such as those recording the failure of IP to route the resultant datagram. In some implementations, none of the error types are included in the value of this counter.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Sent Destination Unreachable

Sent Destination Unreachable is the number of ICMP Destination Unreachable messages sent.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Sent Time Exceeded

Sent Time Exceeded is the number of ICMP Time Exceeded messages sent.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Sent Parameter Problem

Sent Parameter Problem is the number of ICMP Parameter Problem messages sent.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Sent Source Quench

Sent Source Quench is the number of ICMP Source Quench messages sent.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Sent Redirect/sec

Sent Redirect/sec is the rate of ICMP Redirect messages sent.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Sent Echo/sec

Sent Echo/sec is the rate of ICMP Echo messages sent.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Sent Echo Reply/sec

Sent Echo Reply/sec is the rate of ICMP Echo Reply messages sent.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Sent Timestamp/sec

Sent Timestamp/sec is the rate of ICMP Timestamp (request) messages sent.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Sent Timestamp Reply/sec

Sent Timestamp Reply/sec is the rate of ICMP Timestamp Reply messages sent.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Sent Address Mask

Sent Address Mask is the number of ICMP Address Mask Request messages sent.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Sent Address Mask Reply

Sent Address Mask Reply is the number of ICMP Address Mask Reply messages sent.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT


Image Object

The Image performance object consists of counters that monitor virtual address usage of images executed by processes on the computer.

No Access

Image Space is the virtual address space in use by the selected image with this protection. No Access protection prevents a process from writing or reading these pages and will generate an access violation if either is attempted.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Read Only

Image Space is the virtual address space in use by the selected image with this protection. Read Only protection prevents the contents of these pages from being modified. Any attempts to write or modify these pages will generate an access violation.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Read/Write

Image Space is the virtual address space in use by the selected image with this protection. Read/Write protection allows a process to read, modify and write to these pages.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Write Copy

Image Space is the virtual address space in use by the selected image with this protection. Write Copy protection is used when memory is shared for reading but not for writing. When processes are reading this memory, they can share the same memory, however, when a sharing process wants to have read/write access to this shared memory, a copy of that memory is made for writing to.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Executable

Image Space is the virtual address space in use by the selected image with this protection. Executable memory is memory that can be executed by programs, but cannot be read or written. This type of protection is not supported by all processor types.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Exec Read Only

Image Space is the virtual address space in use by the selected image with this protection. Execute/Read Only memory is memory that can be executed as well as read.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Exec Read/Write

Image Space is the virtual address space in use by the selected image with this protection. Execute/Read/Write memory is memory that can be executed by programs as well as read and written.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Exec Write Copy

Image Space is the virtual address space in use by the selected image with this protection. Execute Write Copy is memory that can be executed by programs as well as read and written. This type of protection is used when memory needs to be shared between processes. If the sharing processes only read the memory, then they will all use the same memory. If a sharing process desires write access, then a copy of this memory will be made for that process.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT


IP Object

The IP performance object includes those counters that describe the rates at which IP datagrams are sent and received by a certain computer using the IP protocol. It also describes various error counts for the IP protocol.

Datagrams/sec

Datagrams/sec is the rate at which IP datagrams are received from or sent to the interfaces, including those in error. Any forwarded datagrams are not included in this rate.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagrams Received/sec

Datagrams Received/sec is the rate at which IP datagrams are received from the interfaces, including those in error.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagrams Received Header Errors

Datagrams Received Header Errors is the number of input datagrams discarded due to errors in their IP headers, including bad checksums, version number mismatch, other format errors, time-to-live exceeded, errors discovered in processing their IP options, etc.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Datagrams Received Address Errors

Datagrams Received Address Errors is the number of input datagrams discarded because the IP address in their IP header's destination field was not a valid address to be received at this entity. This count includes invalid addresses (e.g., 0.0. 0.0) and addresses of unsupported Classes (e.g., Class E). For entities that are not IP Gateways and therefore do not forward datagrams, this counter includes datagrams discarded because the destination address was not a local address.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Datagrams Forwarded/sec

Datagrams Forwarded/sec is the rate of input datagrams for that this entity was not their final IP destination, as a result of which an attempt was made to find a route to forward them to that final destination. In entities that do not act as IP Gateways, this rate will include only those packets that were Source-Routed via this entity, and the Source-Route option processing was successful.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagrams Received Unknown Protocol

Datagrams Received Unknown Protocol is the number of locally-addressed datagrams received successfully but discarded because of an unknown or unsupported protocol.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Datagrams Received Discarded

Datagrams Received Discarded is the number of input IP datagrams for which no problems were encountered to prevent their continued processing, but which were discarded (e.g., for lack of buffer space). This counter does not include any datagrams discarded while awaiting re-assembly.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Datagrams Received Delivered/sec

Datagrams Received Delivered/sec is the rate at which input datagrams are successfully delivered to IP user-protocols (including ICMP).

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagrams Sent/sec

Datagrams Sent/sec is the rate at which IP datagrams are supplied to IP for transmission by local IP user-protocols (including ICMP). That this counter does not include any datagrams counted in Datagrams Forwarded.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagrams Outbound Discarded

Datagrams Outbound Discarded is the number of output IP datagrams for which no problems were encountered to prevent their transmission to their destination, but which were discarded (e.g., for lack of buffer space.) This counter would include datagrams counted in Datagrams Forwarded if any such packets met this (discretionary) discard criterion.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Datagrams Outbound No Route

Datagrams Outbound No Route is the number of IP datagrams discarded because no route could be found to transmit them to their destination. This counter includes any packets counted in Datagrams Forwarded that meet this `no route' criterion.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Fragments Received/sec

Fragments Received/sec is the rate at which IP fragments that need to be re-assembled at this entity are received.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Fragments Re-assembled/sec

Fragments Re-assembled/sec is the rate at which IP fragments are successfully re-assembled.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Fragment Re-assembly Failures

Fragment Re-assembly Failures is the number of failures detected by the IP re-assembly algorithm (for whatever reason: timed out, errors, etc.) This is not necessarily a count of discarded IP fragments since some algorithms (notably RFC 815) can lose track of the number of fragments by combining them as they are received.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Fragmented Datagrams/sec

Fragmented Datagrams/sec is the rate at which datagrams are successfully fragmented at this entity.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Fragmentation Failures

Fragmentation Failures is the number of IP datagrams that have been discarded because they needed to be fragmented at this entity but could not be, e.g., because their `Don't Fragment' flag was set.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Fragments Created/sec

Fragments Created/sec is the rate at which IP datagram fragments have been generated as a result of fragmentation at this entity.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER


Logical Disk Object

The Logical Disk performance object consists of counters that monitor logical partitions of a hard or fixed disk drives. Performance Monitor identifies logical disks by their a drive letter, such as C.

Free Space

Percent Free Space is the ratio of the free space available on the logical disk unit to the total usable space provided by the selected logical disk drive

Detail Level: Novice
Counter Type: PERF_RAW_FRACTION

% Free Space

Percent Free Space is the ratio of the free space available on the logical disk unit to the total usable space provided by the selected logical disk drive

Detail Level: Novice
Counter Type: PERF_RAW_BASE

Free Megabytes

Free Megabytes displays the unallocated space on the disk drive in megabytes. One megabyte = 1,048,576 bytes.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Current Disk Queue Length

Current Disk Queue Length is the number of requests outstanding on the disk at the time the performance data is collected. It includes requests in service at the time of the snapshot. This is an instantaneous length, not an average over the time interval. Multi-spindle disk devices can have multiple requests active at one time, but other concurrent requests are awaiting service. This counter might reflect a transitory high or low queue length, but if there is a sustained load on the disk drive, it is likely that this will be consistently high. Requests are experiencing delays proportional to the length of this queue minus the number of spindles on the disks. This difference should average less than 2 for good performance.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

% Disk Time

Disk Time is the percentage of elapsed time that the selected disk drive is busy servicing read or write requests.

Detail Level: Novice
Counter Type: PERF_COUNTER_TIMER

Avg. Disk Queue Length

Avg. Disk Queue Length is the average number of both read and write requests that were queued for the selected disk during the sample interval.

Detail Level: Novice
Counter Type: 0x450500,

% Disk Read Time

Disk Read Time is the percentage of elapsed time that the selected disk drive is busy servicing read requests.

Detail Level: Novice
Counter Type: PERF_COUNTER_TIMER

Avg. Disk Read Queue Length

Avg. Disk Read Queue Length is the average number of read requests that were queued for the selected disk during the sample interval.

Detail Level: Novice
Counter Type: 0x450500,

% Disk Write Time

Avg. Disk Read Queue Length is the average number of read requests that were queued for the selected disk during the sample interval.

Detail Level: Novice
Counter Type: PERF_COUNTER_TIMER

Avg. Disk Write Queue Length

Avg. Disk Write Queue Length is the average number of write requests that were queued for the selected disk during the sample interval.

Detail Level: Novice
Counter Type: 0x450500,

Avg. Disk sec/Transfer

Avg. Disk sec/Transfer is the time in seconds of the average disk transfer.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_TIMER

Avg. Disk sec/Transfer

Avg. Disk sec/Transfer is the time in seconds of the average disk transfer.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_BASE

Avg. Disk sec/Read

Avg. Disk sec/Read is the average time in seconds of a read of data from the disk.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_TIMER

Avg. Disk sec/Read

Avg. Disk sec/Read is the average time in seconds of a read of data from the disk.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_BASE

Avg. Disk sec/Write

Avg. Disk sec/Write is the average time in seconds of a write of data to the disk.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_TIMER

Avg. Disk sec/Write

Avg. Disk sec/Write is the average time in seconds of a write of data to the disk.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_BASE

Disk Transfers/sec

Disk Transfers/sec is the rate of read and write operations on the disk.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Disk Reads/sec

Disk Reads/sec is the rate of read operations on the disk.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Disk Writes/sec

Disk Writes/sec is the rate of write operations on the disk.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Disk Bytes/sec

Disk Bytes/sec is the rate bytes are transferred to or from the disk during write or read operations.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Disk Read Bytes/sec

Disk Read Bytes/sec is the rate bytes are transferred from the disk during read operations.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Disk Write Bytes/sec

Disk Write Bytes is rate bytes are transferred to the disk during write operations.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Avg. Disk Bytes/Transfer

Avg. Disk Bytes/Transfer is the average number of bytes transferred to or from the disk during write or read operations.

Detail Level: Expert
Counter Type: PERF_AVERAGE_BULK

Avg. Disk Bytes/Transfer

Avg. Disk Bytes/Transfer is the average number of bytes transferred to or from the disk during write or read operations.

Detail Level: Expert
Counter Type: PERF_AVERAGE_BASE

Avg. Disk Bytes/Read

Avg. Disk Bytes/Read is the average number of bytes transferred from the disk during read operations.

Detail Level: Expert
Counter Type: PERF_AVERAGE_BULK

Avg. Disk Bytes/Read

Avg. Disk Bytes/Read is the average number of bytes transferred from the disk during read operations.

Detail Level: Expert
Counter Type: PERF_AVERAGE_BASE

Avg. Disk Bytes/Write

Avg. Disk Bytes/Write is the average number of bytes transferred to the disk during write operations.

Detail Level: Expert
Counter Type: PERF_AVERAGE_BULK

Avg. Disk Bytes/Write

Avg. Disk Bytes/Write is the average number of bytes transferred to the disk during write operations.

Detail Level: Expert
Counter Type: PERF_AVERAGE_BASE


Memory Object

The Memory performance object consists of counters that describe the behavior of physical and virtual memory on the computer. Physical memory is the amount of random access memory on the computer. Virtual memory consists of space in physical memory and on disk. Many of the memory counters monitor paging, which is the movement of pages of code and data between disk and physical memory. Excessive paging, a symptom of a memory shortage, can cause delays which interfere will all system processes.

Available Bytes

Available Bytes is the amount of physical memory available to processes running on the computer, in bytes. It is calculated by summing space on the Zeroed, Free, and Standby memory lists. Free memory is ready for use; Zeroed memory is pages of memory filled with zeros to prevent later processes from seeing data used by a previous process. Standby memory is memory removed from a process's working set (its physical memory) on route to disk, but is still available to be recalled.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Committed Bytes

Committed Bytes is the amount of committed virtual memory, in bytes. (Committed memory is physical memory for which space has been reserved on the disk paging file in case it needs to be written back to disk.)

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Commit Limit

Commit Limit is the amount of virtual memory that can be committed without having to extend the paging file(s). It is measured in bytes. (Committed memory is physical memory for which space has been reserved on the disk paging files. There can be one paging file on each physical drive.)If the paging file(s) are be expanded, this limit increases accordingly.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Page Faults/sec

Page Faults/sec is overall rate at which of faulted pages are handled by the processor. It is measured in numbers of pages faulted. A page fault occurs when a process requires code or data that is not in its working set (its space in physical memory) in main memory. This counter includes both hard faults (those that require disk access) and soft faults (where the faulted page is found elsewhere in physical memory.) Most processors can handle large numbers of soft faults without consequence. However, hard faults can cause significant delays.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Write Copies/sec

Write Copies/sec is the number of page faults caused by attempts to write that have been satisfied by coping of the page from elsewhere in physical memory. This is an economical way of sharing data since pages are only copied when they are written to; otherwise, the page is shared. This counter counts the number of copies, without regard for the number of pages copied in each operation.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Transition Faults/sec

Transition Faults/sec is the number of page faults resolved by recovering pages that were on the modified page list, on the standby list, or being written to disk at the time of the page fault. The pages were recovered without additional disk activity. Transition faults are counted in numbers of faults, without regard for the number of pages faulted in each operation.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Cache Faults/sec

Cache Faults/sec is the number of faults which occur when a page sought in the file system cache is not found there and must be retrieved from elsewhere in memory (a soft fault) or from disk (a hard fault). The file system cache is an area of physical memory that stores recently used pages of data for applications. Cache activity is a reliable indicator of most application I/O operations. This counter counts the number of faults, without regard for the number of pages faulted in each operation.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Demand Zero Faults/sec

Demand Zero Faults/sec is the number of page faults that require a zeroed page to satisfy the fault. Zeroed pages, pages emptied of previously stored data and filled with zeros, are a security feature of Windows NT. They prevent processes from seeing data stored by earlier processes that used the memory space. Windows NT maintains a list of zeroed pages to accelerate this process. This counter counts numbers of faults, without regard to the numbers of pages retrieved to satisfy the fault.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Pages/sec

Pages/sec is the number of pages read from or written to disk to resolve hard page faults. (Hard page faults occur when a process requires code or data that is not in its working set or elsewhere in physical memory, and must be retrieved from disk.) This counter was designed as a primary indicator of the kinds of faults that cause system-wide delays. It is the sum of Memory: Pages Input/sec and Memory: Pages Output/sec. It is counted in numbers of pages, so it can be compared to other counts of pages, such as Memory: Page Faults/sec, without conversion. It includes pages retrieved to satisfy faults in the file system cache (usually requested by applications) non-cached mapped memory files.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Pages Input/sec

Pages Input/sec is the number of pages read from disk to resolve hard page faults. (Hard page faults occur when a process requires code or data that is not in its working set or elsewhere in physical memory, and must be retrieved from disk.) This counter was designed as a primary indicator of the kinds of faults that cause system-wide delays. It includes pages retrieved to satisfy faults in the file system cache (usually requested by applications) and in non-cached mapped memory files. This counter counts numbers of pages, and can be compared to other counts of pages, such as Memory: Page Faults/sec, without conversion.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Page Reads/sec

Page Reads/sec is the number of times the disk was read to resolve hard page faults. (Hard page faults occur when a process requires code or data that is not in its working set or elsewhere in physical memory, and must be retrieved from disk.) This counter was designed as a primary indicator of the kinds of faults that cause system-wide delays. It includes reads to satisfy faults in the file system cache (usually requested by applications) and in non-cached mapped memory files. This counter counts numbers of read operations, without regard to the numbers of pages retrieved by each operation.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Pages Output/sec

Pages Output/sec is the number of pages written to disk to free up space in physical memory. Pages are written back to disk only if they are changed in physical memory, so they are likely to hold data, not code. A high rate of pages output might indicate a memory shortage. Windows NT writes more pages back to disk to free up space when physical memory is in short supply. This counter counts numbers of pages, and can be compared to other counts of pages, without conversion.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Page Writes/sec

Page Writes/sec is the number of times pages were written to disk to free up space in physical memory. Pages are written to disk only if they are changed while in physical memory, so they are likely to hold data, not code. This counter counts write operations, without regard to the number of pages written in each operation.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Pool Paged Bytes

Pool Paged Bytes is the number of bytes in the paged pool, an area of system memory (physical memory used by the operating system) for objects that can be written to disk when they are not being used. Memory: Pool Paged Bytes is calculated differently than Process: Pool Paged Bytes, so it might not equal Process: Pool Paged Bytes: _Total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Pool Nonpaged Bytes

Pool Nonpaged Bytes is the number of bytes in the nonpaged pool, an area of system memory (physical memory used by the operating system) for objects that cannot be written to disk, but must remain in physical memory as long as they are allocated. Memory: Pool Nonpaged Bytes is calculated differently than Process: Pool Nonpaged Bytes, so it might not equal Process: Pool Nonpaged Bytes: _Total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Pool Paged Allocs

Pool Paged Allocs is the number of calls to allocate space in the paged pool. The paged pool is an area of system memory (physical memory used by the operating system) for objects that can be written to disk when they are not being used. It is measured in numbers of calls to allocate space, regardless of the amount of space allocated in each call.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Pool Nonpaged Allocs

Pool Nonpaged Allocs is the number of calls to allocate space in the nonpaged pool. The nonpaged pool is an area of system memory area for objects that cannot be written to disk, and must remain in physical memory as long as they are allocated. It is measured in numbers of calls to allocate space, regardless of the amount of space allocated in each call.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Free System Page Table Entries

The number of Page Table Entries not currently in use by the system.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Cache Bytes

Cache Bytes is the number of bytes currently being used by the file system cache. The file system cache is an area of physical memory that stores recently used pages of data for applications. Windows NT continually adjusts the size of the cache, making it as large as it can while still preserving the minimum required number of available bytes for processes.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Cache Bytes Peak

Cache Bytes Peak is the maximum number of bytes used by the file system cache since the system was last restarted. This might be larger than the current size of the cache. Cache. The file system cache is an area of physical memory that stores recently used pages of data for applications. Windows NT continually adjusts the size of the cache, making it as large as it can while still preserving the minimum required number of available bytes for processes.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Pool Paged Resident Bytes

Pool Paged Resident Bytes is the current size of paged pool in bytes. The paged pool is an area of system memory (physical memory used by the operating system) for objects that can be written to disk when they are not being used. Space used by the paged and nonpaged pools are taken from physical memory, so a pool that is too large denies memory space to processes.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

System Code Total Bytes

System Code Total Bytes is the number of bytes of pageable operating system code currently in virtual memory. It is a measure of the amount of physical memory being used by the operating system that can be written to disk when not in use. This value is calculated by summing the bytes in Ntoskrnl.exe, Hal.dll, the boot drivers, and file systems loaded by Ntldr/osloader. This counter does not include code that must remain in physical memory and cannot be written to disk.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

System Code Resident Bytes

System Code Resident Bytes is the number of bytes of operating system code currently in physical memory that can be written to disk when not in use. This value is a component of System Code Total Bytes, which also includes operating system code on disk. System Code Resident Bytes (and System Code Total Bytes) does not include code that must remain in physical memory and cannot be written to disk.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

System Driver Total Bytes

System Driver Total Bytes is the number of bytes of pageable virtual memory currently being used by device drivers. (Pageable memory can be written to disk when it is not being used.) It includes physical memory (Memory: System Driver Resident Bytes) and code and data written to disk. It is a component of Memory: System Code Total Bytes.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

System Driver Resident Bytes

System Driver Resident Bytes is the number of bytes of pageable physical memory being used by device drivers. It is the working set (physical memory area) of the drivers. This value is a component of Memory: System Driver Total Bytes, which also includes driver memory that has been written to disk. Neither System Driver Resident Bytes nor System Driver Total Bytes includes memory that cannot be written to disk.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

System Cache Resident Bytes

System Cache Resident Bytes is the number of bytes of pageable operating system code in the file system cache. This value is a component of Memory: System Code Resident Bytes which represents all pageable operating system code that is currently in physical memory.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

% Committed Bytes In Use

% Committed Bytes In Use is the ratio of Memory: Committed Bytes to the Memory: Commit Limit. (Committed memory is physical memory in use for which space has been reserved in the paging file should it need to be written to disk. The commit limit is determined by the size of the paging file. If the paging file is enlarged, the commit limit increases, and the ratio is reduced.)

Detail Level: Expert
Counter Type: PERF_RAW_FRACTION

% Committed Bytes In Use

% Committed Bytes In Use is the ratio of the Committed Bytes to the Commit Limit. This represents the amount of available virtual memory in use. Note that the Commit Limit might change if the paging file is extended. This is an instantaneous value, not an average.

Detail Level: Expert
Counter Type: PERF_RAW_BASE


NBT Connection Object

The NBT Connection performance object consists of counters that measure the rates at which bytes are sent and received over the NBT connection between the local computer and a remote computer. The connection is identified by the name of the remote computer.

Bytes Received/sec

Bytes Received/sec is the rate at which bytes are received by the local computer over an NBT connection to some remote computer. All the bytes received by the local computer over the particular NBT connection are counted.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Sent/sec

Bytes Sent/sec is the rate at which bytes are sent by the local computer over an NBT connection to some remote computer. All the bytes sent by the local computer over the particular NBT connection are counted.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Total/sec

Total Bytes/sec is the rate at which bytes are sent or received by the local computer over an NBT connection to some remote computer. All the bytes sent or received by the local computer over the particular NBT connection are counted.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT


NetBEUI Object

The NetBEUI performance object consists of counters that measure data transmission for network activity which conforms to the NetBIOS End User Interface standard.

Datagrams/sec

Datagrams/sec is the rate at which datagrams are processed by the computer. This counter displays the sum of datagrams sent and datagrams received. A datagram is a connectionless packet whose delivery to a remote is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagram Bytes/sec

Datagram Bytes/sec is the rate at which datagram bytes are processed by the computer. This counter is the sum of datagram bytes that are sent as well as received. A datagram is a connectionless packet whose delivery to a remote is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Packets/sec

Packets/sec is the rate at which packets are processed by the computer. This count is the sum of Packets Sent and Packets Received per second. This counter includes all packets processed: control as well as data packets.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frames/sec

Frames/sec is the rate at which data frames (or packets) are processed by the computer. This counter is the sum of data frames sent and data frames received. This counter only counts those frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes/sec

Frame Bytes/sec is the rate at which data bytes are processed by the computer. This counter is the sum of data frame bytes sent and received. This counter only counts the byte in frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Total/sec

Bytes Total/sec is the sum of Frame Bytes/sec and Datagram Bytes/sec. This is the total rate of bytes sent to or received from the network by the protocol, but only counts the bytes in frames (i.e., packets) which carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Connections Open

Connections Open is the number of connections currently open for this protocol. This counter shows the current count only and does not accumulate over time.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections No Retries

Connections No Retries is the total count of connections that were successfully made on the first try. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections With Retries

Connections With Retries is the total count of connections that were made after retrying the attempt. A retry occurs when the first connection attempt failed. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Disconnects Local

Disconnects Local is the number of session disconnections that were initiated by the local computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Disconnects Remote

Disconnects Remote is the number of session disconnections that were initiated by the remote computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Link

Failures Link is the number of connections that were dropped due to a link failure. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Adapter

Failures Adapter is the number of connections that were dropped due to an adapter failure. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connection Session Timeouts

Connection Session Timeouts is the number of connections that were dropped due to a session time out. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections Canceled

Connections Canceled is the number of connections that were canceled. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Resource Remote

Failures Resource Remote is the number of connections that failed because of resource problems or shortages on the remote computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Resource Local

Failures Resource Local is the number of connections that failed because of resource problems or shortages on the local computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Not Found

Failures Not Found is the number of connection attempts that failed because the remote computer could not be found. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures No Listen

Failures No Listen is the number of connections that were rejected because the remote computer was not listening for connection requests.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Datagrams Sent/sec

Datagrams Sent/sec is the rate at which datagrams are sent from the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagram Bytes Sent/sec]

Datagram Bytes Sent/sec is the rate at which datagram bytes are sent from the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Datagrams Received/sec

Datagrams Received/sec is the rate at which datagrams are received by the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagram Bytes Received/sec

Datagram Bytes Received/sec is the rate at which datagram bytes are received by the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Packets Sent/sec

Packets Sent/sec is the rate at which packets are sent by the computer. This counter counts all packets sent by the computer, i.e. control as well as data packets.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Packets Received/sec

Packets Received/sec is the rate at which packets are received by the computer. This counter counts all packets processed, control as well as data packets.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Frames Sent/sec

Frames Sent/sec is the rate at which data frames are sent by the computer. This counter only counts the frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Sent/sec

Frame Bytes Sent/sec is the rate at which data bytes are sent by the computer. This counter only counts the bytes in frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Frames Received/sec

Frames Received/sec is the rate at which data frames are received by the computer. This counter only counts the frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Received/sec

Frame Bytes Received/sec is the rate at which data bytes are received by the computer. This counter only counts the frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Frames Re-Sent/sec

Frames Re-Sent/sec is the rate at which data frames (packets) are re-sent by the computer. This counter only counts the frames or packets that carry data.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Re-Sent/sec

Frame Bytes Re-Sent/sec is the rate at which data bytes are re-sent by the computer. This counter only counts the bytes in frames that carry data.

Detail Level: Wizard
Counter Type: PERF_COUNTER_BULK_COUNT

Frames Rejected/sec

Frames Rejected/sec is the rate at which data frames are rejected. This counter only counts the frames (packets) that carry data.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Rejected/sec

Frame Bytes Rejected/sec is the rate at which data bytes are rejected. This counter only counts the bytes in data frames (packets) that carry data.

Detail Level: Expert
Counter Type: PERF_COUNTER_BULK_COUNT

Expirations Response

Expirations Response is the count of T1 timer expirations.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Expirations Ack

Expirations Ack is the count of T2 timer expirations.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Window Send Maximum

Window Send Maximum is the maximum number of bytes of data that will be sent before waiting for an acknowledgment from the remote computer.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Window Send Average

Window Send Average is the running average number of data bytes that were sent before waiting for an acknowledgment from the remote computer.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Piggyback Ack Queued/sec

Piggyback Ack Queued/sec is the rate at which piggybacked acknowledgments are queued. Piggyback acknowledgments are acknowledgments to received packets that are to be included in the next outgoing packet to the remote computer.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Piggyback Ack Timeouts

Piggyback Ack Timeouts is the number of times that a piggyback acknowledgment could not be sent because there was no outgoing packet to the remote on which to piggyback. A piggyback ack is an acknowledgment to a received packet that is sent along in an outgoing data packet to the remote computer. If no outgoing packet is sent within the time-out period, then an ack packet is sent and this counter is incremented.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT


NetBEUI Resource Object

The NetBEUI Resource performance object consists of counters that track the use of buffers by the NetBEUI protocol.

Used Maximum

Used Maximum is the maximum number of NetBEUI resources (buffers) in use at any point in time. This value is useful in sizing the maximum resources provided. The number in parentheses following the resource name is used to identify the resource in Event Log messages.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Used Average

Used Average is the current number of resources (buffers) in use at this time. The number in parentheses following the resource name is used to identify the resource in Event Log messages.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Times Exhausted

Times Exhausted is the number of times all the resources (buffers) were in use. The number in parentheses following the resource name is used to identify the resource in Event Log messages.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT


Network Interface Object

The Network Interface performance object consists of counters that measure the rates at which bytes and packets are sent and received over a TCP/IP connection. It includes counters that monitor connection errors.

Bytes Total/sec

Bytes Total/sec is the rate at which bytes are sent and received on the interface, including framing characters.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Packets/sec

Packets/sec is the rate at which packets are sent and received on the network interface.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Packets Received/sec

Packets Received/sec is the rate at which packets are received on the network interface.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Packets Sent/sec

Packets Sent/sec is the rate at which packets are sent on the network interface.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Current Bandwidth

Current Bandwidth is an estimate of the interface's current bandwidth in bits per second (BPS). For interfaces that do not vary in bandwidth or for those where no accurate estimation can be made, this value is the nominal bandwidth.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Bytes Received/sec

Bytes Received/sec is the rate at which bytes are received on the interface, including framing characters.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Packets Received Unicast/sec

Packets Received Unicast/sec is the rate at which (subnet) unicast packets are delivered to a higher-layer protocol.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Packets Received Non-Unicast/sec

Packets Received Non-Unicast/sec is the rate at which non-unicast (i.e., subnet broadcast or subnet multicast) packets are delivered to a higher-layer protocol.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Packets Received Discarded

Packets Received Discarded is the number of inbound packets that were chosen to be discarded even though no errors had been detected to prevent their being deliverable to a higher-layer protocol. One possible reason for discarding such a packet could be to free up buffer space.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Packets Received Errors

Packets Received Errors is the number of inbound packets that contained errors preventing them from being deliverable to a higher-layer protocol.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Packets Received Unknown

Packets Received Unknown is the number of packets received via the interface that were discarded because of an unknown or unsupported protocol.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Bytes Sent/sec

Bytes Sent/sec is the rate at which bytes are sent on the interface, including framing characters.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Packets Sent Unicast/sec

Packets Sent Unicast/sec is the rate at which packets are requested to be transmitted to subnet-unicast addresses by higher-level protocols. The rate includes the packets that were discarded or not sent.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Packets Sent Non-Unicast/sec

Packets Sent Non-Unicast/sec is the rate at which packets are requested to be transmitted to non-unicast (i.e., subnet broadcast or subnet multicast) addresses by higher-level protocols. The rate includes the packets that were discarded or not sent.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Packets Outbound Discarded

Packets Outbound Discarded is the number of outbound packets that were chosen to be discarded even though no errors had been detected to prevent their being transmitted. One possible reason for discarding such a packet could be to free up buffer space.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Packets Outbound Errors

Packets Outbound Errors is the number of outbound packets that could not be transmitted because of errors.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Output Queue Length

Output Queue Length is the length of the output packet queue (in packets.) If this is longer than 2, delays are being experienced and the bottleneck should be found and eliminated if possible. Since the requests are queued by NDIS in this implementations, this will always be 0.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT


Network Segment Object

The network segment performance object provides network statistics for the local network segment via the Network Monitor service.

Total frames received/second

The total number of frames received per second on this network segment.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Total bytes received/second

The number of bytes received per second on this network segment.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Broadcast frames received/second

The number of Broadcast frames received per second on this network segment.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Multicast frames received/second

The number of Multicast frames received per second on this network segment.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

% Network utilization

Percentage of network bandwidth in use on this network segment.

Detail Level: Advanced
Counter Type: PERF_COUNTER_MULTI_TIMER

(null)

Detail Level: Advanced
Counter Type: PERF_COUNTER_MULTI_BASE

% Broadcast Frames

Percentage of network bandwidth which is made up of broadcast traffic on this network segment.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_BULK

% Broadcast Frames

Percentage of network bandwidth which is made up of broadcast traffic on this network segment.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_BASE

% Multicast Frames

Percentage of network bandwidth which is made up of multicast traffic on this network segment.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_BULK

% Multicast Frames

Percentage of network bandwidth which is made up of multicast traffic on this network segment.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_BASE


NWLink IPX Object

The NWLink IPX performance object consists of counter that measure datagram transmission to and from computers using the IPX protocol.

Datagrams/sec

Datagrams/sec is the rate at which datagrams are processed by the computer. This counter displays the sum of datagrams sent and datagrams received. A datagram is a connectionless packet whose delivery to a remote is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagram Bytes/sec

Datagram Bytes/sec is the rate at which datagram bytes are processed by the computer. This counter is the sum of datagram bytes that are sent as well as received. A datagram is a connectionless packet whose delivery to a remote is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Packets/sec

Packets/sec is the rate at which packets are processed by the computer. This count is the sum of Packets Sent and Packets Received per second. This counter includes all packets processed: control as well as data packets.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frames/sec

Frames/sec is the rate at which data frames (or packets) are processed by the computer. This counter is the sum of data frames sent and data frames received. This counter only counts those frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes/sec

Frame Bytes/sec is the rate at which data bytes are processed by the computer. This counter is the sum of data frame bytes sent and received. This counter only counts the byte in frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Total/sec

Bytes Total/sec is the sum of Frame Bytes/sec and Datagram Bytes/sec. This is the total rate of bytes sent to or received from the network by the protocol, but only counts the bytes in frames (i.e., packets) which carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Connections Open

Connections Open is the number of connections currently open for this protocol. This counter shows the current count only and does not accumulate over time.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections No Retries

Connections No Retries is the total count of connections that were successfully made on the first try. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections With Retries

Connections With Retries is the total count of connections that were made after retrying the attempt. A retry occurs when the first connection attempt failed. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Disconnects Local

Disconnects Local is the number of session disconnections that were initiated by the local computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Disconnects Remote

Disconnects Remote is the number of session disconnections that were initiated by the remote computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Link

Failures Link is the number of connections that were dropped due to a link failure. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Adapter

Failures Adapter is the number of connections that were dropped due to an adapter failure. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connection Session Timeouts

Connection Session Timeouts is the number of connections that were dropped due to a session time out. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections Canceled

Connections Canceled is the number of connections that were canceled. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Resource Remote

Failures Resource Remote is the number of connections that failed because of resource problems or shortages on the remote computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Resource Local

Failures Resource Local is the number of connections that failed because of resource problems or shortages on the local computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Not Found

Failures Not Found is the number of connection attempts that failed because the remote computer could not be found. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures No Listen

Failures No Listen is the number of connections that were rejected because the remote computer was not listening for connection requests.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Datagrams Sent/sec

Datagrams Sent/sec is the rate at which datagrams are sent from the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagram Bytes Sent/sec

Datagram Bytes Sent/sec is the rate at which datagram bytes are sent from the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Datagrams Received/sec

Datagrams Received/sec is the rate at which datagrams are received by the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagram Bytes Received/sec

Datagram Bytes Received/sec is the rate at which datagram bytes are received by the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Packets Sent/sec

Packets Sent/sec is the rate at which packets are sent by the computer. This counter counts all packets sent by the computer, i.e. control as well as data packets.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Packets Received/sec

Packets Received/sec is the rate at which packets are received by the computer. This counter counts all packets processed: control as well as data packets.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Frames Sent/sec

Frames Sent/sec is the rate at which data frames are sent by the computer. This counter only counts the frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Sent/sec

Frame Bytes Sent/sec is the rate at which data bytes are sent by the computer. This counter only counts the bytes in frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Frames Received/sec

Frames Received/sec is the rate at which data frames are received by the computer. This counter only counts the frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Received/sec

Frame Bytes Received/sec is the rate at which data bytes are received by the computer. This counter only counts the frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Frames Re-Sent/sec

Frames Re-Sent/sec is the rate at which data frames (packets) are re-sent by the computer. This counter only counts the frames or packets that carry data.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Re-Sent/sec

Frame Bytes Re-Sent/sec is the rate at which data bytes are re-sent by the computer. This counter only counts the bytes in frames that carry data.

Detail Level: Wizard
Counter Type: PERF_COUNTER_BULK_COUNT

Frames Rejected/sec

Frames Rejected/sec is the rate at which data frames are rejected. This counter only counts the frames (packets) that carry data.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Rejected/sec

Frame Bytes Rejected/sec is the rate at which data bytes are rejected. This counter only counts the bytes in data frames (packets) that carry data.

Detail Level: Expert
Counter Type: PERF_COUNTER_BULK_COUNT

Expirations Response

Expirations Response is the count of T1 timer expirations.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Expirations Ack

Expirations Ack is the count of T2 timer expirations

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Window Send Maximum

Window Send Maximum is the maximum number of bytes of data that will be sent before waiting for an acknowledgment from the remote computer.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Window Send Average

Window Send Average is the running average number of data bytes that were sent before waiting for an acknowledgment from the remote computer.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Piggyback Ack Queued/sec

Piggyback Ack Queued/sec is the rate at which piggybacked acknowledgments are queued. Piggyback acknowledgments are acknowledgments to received packets that are to be included in the next outgoing packet to the remote computer.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Piggyback Ack Timeouts

Piggyback Ack Timeouts is the number of times that a piggyback acknowledgment could not be sent because there was no outgoing packet to the remote on which to piggyback. A piggyback ack is an acknowledgment to a received packet that is sent along in an outgoing data packet to the remote computer. If no outgoing packet is sent within the time-out period, then an ack packet is sent and this counter is incremented.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT


NWLink NetBIOS Object

The NWLink NetBIOS performance object consists of counters that monitor IPX transport rates and connections.

Datagrams/sec

Datagrams/sec is the rate at which datagrams are processed by the computer. This counter displays the sum of datagrams sent and datagrams received. A datagram is a connectionless packet whose delivery to a remote is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagram Bytes/sec

Datagram Bytes/sec is the rate at which datagram bytes are processed by the computer. This counter is the sum of datagram bytes that are sent as well as received. A datagram is a connectionless packet whose delivery to a remote is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Packets/sec

Packets/sec is the rate at which packets are processed by the computer. This count is the sum of Packets Sent and Packets Received per second. This counter includes all packets processed: control as well as data packets.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frames/sec

Frames/sec is the rate at which data frames (or packets) are processed by the computer. This counter is the sum of data frames sent and data frames received. This counter only counts those frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes/sec

Frame Bytes/sec is the rate at which data bytes are processed by the computer. This counter is the sum of data frame bytes sent and received. This counter only counts the byte in frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Total/sec

Bytes Total/sec is the sum of Frame Bytes/sec and Datagram Bytes/sec. This is the total rate of bytes sent to or received from the network by the protocol, but only counts the bytes in frames (i.e., packets) which carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Connections Open

Connections Open is the number of connections currently open for this protocol. This counter shows the current count only and does not accumulate over time.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections No Retries

Connections No Retries is the total count of connections that were successfully made on the first try. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections With Retries

Connections With Retries is the total count of connections that were made after retrying the attempt. A retry occurs when the first connection attempt failed. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Disconnects Local

Disconnects Local is the number of session disconnections that were initiated by the local computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Disconnects Remote

Disconnects Remote is the number of session disconnections that were initiated by the remote computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Link

Failures Link is the number of connections that were dropped due to a link failure. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Adapter

Failures Adapter is the number of connections that were dropped due to an adapter failure. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connection Session Timeouts

Connection Session Timeouts is the number of connections that were dropped due to a session time out. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections Canceled

Connections Canceled is the number of connections that were canceled. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Resource Remote

Failures Resource Remote is the number of connections that failed because of resource problems or shortages on the remote computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Resource Local

Failures Resource Local is the number of connections that failed because of resource problems or shortages on the local computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Not Found

Failures Not Found is the number of connection attempts that failed because the remote computer could not be found. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures No Listen

Failures No Listen is the number of connections that were rejected because the remote computer was not listening for connection requests.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Datagrams Sent/sec

Datagrams Sent/sec is the rate at which datagrams are sent from the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagram Bytes Sent/sec

Datagram Bytes Sent/sec is the rate at which datagram bytes are sent from the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Datagrams Received/sec

Datagrams Received/sec is the rate at which datagrams are received by the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagram Bytes Received/sec

Datagram Bytes Received/sec is the rate at which datagram bytes are received by the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Packets Sent/sec

Packets Sent/sec is the rate at which packets are sent by the computer. This counter counts all packets sent by the computer, i.e. control as well as data packets.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Packets Received/sec

Packets Received/sec is the rate at which packets are received by the computer. This counter counts all packets processed: control as well as data packets.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Frames Sent/sec

Frames Sent/sec is the rate at which data frames are sent by the computer. This counter only counts the frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Sent/sec

Frame Bytes Sent/sec is the rate at which data bytes are sent by the computer. This counter only counts the bytes in frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Frames Received/sec

Frames Received/sec is the rate at which data frames are received by the computer. This counter only counts the frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Received/sec

Frame Bytes Received/sec is the rate at which data bytes are received by the computer. This counter only counts the frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Frames Re-Sent/sec

Frames Re-Sent/sec is the rate at which data frames (packets) are re-sent by the computer. This counter only counts the frames or packets that carry data.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Re-Sent/sec

Frame Bytes Re-Sent/sec is the rate at which data bytes are re-sent by the computer. This counter only counts the bytes in frames that carry data.

Detail Level: Wizard
Counter Type: PERF_COUNTER_BULK_COUNT

Frames Rejected/sec

Frames Rejected/sec is the rate at which data frames are rejected. This counter only counts the frames (packets) that carry data.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Rejected/sec

Frame Bytes Rejected/sec is the rate at which data bytes are rejected. This counter only counts the bytes in data frames (packets) that carry data.

Detail Level: Expert
Counter Type: PERF_COUNTER_BULK_COUNT

Expirations Response

Expirations Response is the count of T1 timer expirations.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Expirations Ack

Expirations Ack is the count of T2 timer expirations.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Window Send Maximum

Window Send Maximum is the maximum number of bytes of data that will be sent before waiting for an acknowledgment from the remote computer.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Window Send Average

Window Send Average is the running average number of data bytes that were sent before waiting for an acknowledgment from the remote computer.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Piggyback Ack Queued/sec

Piggyback Ack Queued/sec is the rate at which piggybacked acknowledgments are queued. Piggyback acknowledgments are acknowledgments to received packets that are to be included in the next outgoing packet to the remote computer.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Piggyback Ack Timeouts

Piggyback Ack Timeouts is the number of times that a piggyback acknowledgment could not be sent because there was no outgoing packet to the remote on which to piggyback. A piggyback ack is an acknowledgment to a received packet that is sent along in an outgoing data packet to the remote computer. If no outgoing packet is sent within the time-out period, then an ack packet is sent and this counter is incremented.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT


NWLink SPX Object

The NWLink SPX performance object consists of counters that measure data transmission and session connections for computers using the SPX protocol.

Datagrams/sec

Datagrams/sec is the rate at which datagrams are processed by the computer. This counter displays the sum of datagrams sent and datagrams received. A datagram is a connectionless packet whose delivery to a remote is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagram Bytes/sec

Datagram Bytes/sec is the rate at which datagram bytes are processed by the computer. This counter is the sum of datagram bytes that are sent as well as received. A datagram is a connectionless packet whose delivery to a remote is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Packets/sec

Packets/sec is the rate at which packets are processed by the computer. This count is the sum of Packets Sent and Packets Received per second. This counter includes all packets processed: control as well as data packets.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frames/sec

Frames/sec is the rate at which data frames (or packets) are processed by the computer. This counter is the sum of data frames sent and data frames received. This counter only counts those frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes/sec

Frame Bytes/sec is the rate at which data bytes are processed by the computer. This counter is the sum of data frame bytes sent and received. This counter only counts the byte in frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Total/sec

Bytes Total/sec is the sum of Frame Bytes/sec and Datagram Bytes/sec. This is the total rate of bytes sent to or received from the network by the protocol, but only counts the bytes in frames (i.e., packets) which carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Connections Open

Connections Open is the number of connections currently open for this protocol. This counter shows the current count only and does not accumulate over time.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections No Retries

Connections No Retries is the total count of connections that were successfully made on the first try. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections With Retries

Connections With Retries is the total count of connections that were made after retrying the attempt. A retry occurs when the first connection attempt failed. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Disconnects Local

Disconnects Local is the number of session disconnections that were initiated by the local computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Disconnects Remote

Disconnects Remote is the number of session disconnections that were initiated by the remote computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Link

Failures Link is the number of connections that were dropped due to a link failure. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Adapter

Failures Adapter is the number of connections that were dropped due to an adapter failure. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connection Session Timeouts

Connection Session Timeouts is the number of connections that were dropped due to a session time out. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections Canceled

Connections Canceled is the number of connections that were canceled. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Resource Remote

Failures Resource Remote is the number of connections that failed because of resource problems or shortages on the remote computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Resource Local

Failures Resource Local is the number of connections that failed because of resource problems or shortages on the local computer. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures Not Found

Failures Not Found is the number of connection attempts that failed because the remote computer could not be found. This number is an accumulator and shows a running total.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Failures No Listen

Failures No Listen is the number of connections that were rejected because the remote computer was not listening for connection requests.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Datagrams Sent/sec

Datagrams Sent/sec is the rate at which datagrams are sent from the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagram Bytes Sent/sec

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Datagrams Received/sec

Datagrams Received/sec is the rate at which datagrams are received by the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagram Bytes Received/sec

Datagram Bytes Received/sec is the rate at which datagram bytes are received by the computer. A datagram is a connectionless packet whose delivery to a remote computer is not guaranteed.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Packets Sent/sec

Packets Sent/sec is the rate at which packets are sent by the computer. This counter counts all packets sent by the computer, i.e. control as well as data packets.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Packets Received/sec

Packets Received/sec is the rate at which packets are received by the computer. This counter counts all packets processed: control as well as data packets.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Frames Sent/sec

Frames Sent/sec is the rate at which data frames are sent by the computer. This counter only counts the frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Sent/sec

Frame Bytes Sent/sec is the rate at which data bytes are sent by the computer. This counter only counts the bytes in frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Frames Received/sec

Frames Received/sec is the rate at which data frames are received by the computer. This counter only counts the frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Received/sec

Frame Bytes Received/sec is the rate at which data bytes are received by the computer. This counter only counts the frames (packets) that carry data.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Frames Re-Sent/sec

Frames Re-Sent/sec is the rate at which data frames (packets) are re-sent by the computer. This counter only counts the frames or packets that carry data.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Re-Sent/sec

Frame Bytes Re-Sent/sec is the rate at which data bytes are re-sent by the computer. This counter only counts the bytes in frames that carry data.

Detail Level: Wizard
Counter Type: PERF_COUNTER_BULK_COUNT

Frames Rejected/sec

Frames Rejected/sec is the rate at which data frames are rejected. This counter only counts the frames (packets) that carry data.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Frame Bytes Rejected/sec

Frame Bytes Rejected/sec is the rate at which data bytes are rejected. This counter only counts the bytes in data frames (packets) that carry data.

Detail Level: Expert
Counter Type: PERF_COUNTER_BULK_COUNT

Expirations Response

Expirations Response is the count of T1 timer expirations.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Expirations Ack

Expirations Ack is the count of T2 timer expirations

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Window Send Maximum

Window Send Maximum is the maximum number of bytes of data that will be sent before waiting for an acknowledgment from the remote computer.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Window Send Average

Window Send Average is the running average number of data bytes that were sent before waiting for an acknowledgment from the remote computer.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Piggyback Ack Queued/sec

Piggyback Ack Queued/sec is the rate at which piggybacked acknowledgments are queued. Piggyback acknowledgments are acknowledgments to received packets that are to be included in the next outgoing packet to the remote computer.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Piggyback Ack Timeouts

Piggyback Ack Timeouts is the number of times that a piggyback acknowledgment could not be sent because there was no outgoing packet to the remote on which to piggyback. A piggyback ack is an acknowledgment to a received packet that is sent along in an outgoing data packet to the remote computer. If no outgoing packet is sent within the time-out period, then an ack packet is sent and this counter is incremented.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT


Objects Object

The Objects performance object consists of counters that monitor logical objects in the system, such as processes, threads, mutexes, and semaphores. This information can be used to detect the unnecessary consumption of computer resources. Each object requires memory to store basic information about the object.

Processes

Processes is the number of processes in the computer at the time of data collection. Notice that this is an instantaneous count, not an average over the time interval. Each process represents the running of a program.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Threads

Threads is the number of threads in the computer at the time of data collection. Notice that this is an instantaneous count, not an average over the time interval. A thread is the basic executable entity that can execute instructions in a processor.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Events

Events is the number of events in the computer at the time of data collection. Notice that this is an instantaneous count, not an average over the time interval. An event is used when two or more threads wish to synchronize execution.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Semaphores

Semaphores is the number of semaphores in the computer at the time of data collection. Notice that this is an instantaneous count, not an average over the time interval. Threads use semaphores to obtain exclusive access to data structures that they share with other threads.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Mutexes

Mutexes counts the number of mutexes in the computer at the time of data collection. This is an instantaneous count, not an average over the time interval. Mutexes are used by threads to assure only one thread is executing some section of code.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Sections

Sections is the number of sections in the computer at the time of data collection. Notice that this is an instantaneous count, not an average over the time interval. A section is a portion of virtual memory created by a process for a storing data. A process might share sections with other processes.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT


Paging File Object

The Paging File performance object consists of counters that monitor the paging file(s) on the computer. The paging file is a reserved space on disk that backs up committed physical memory on the computer.

Usage

The amount of the Page File instance in use in percent. See also Process:Page File Bytes.

Detail Level: Advanced
Counter Type: PERF_RAW_FRACTION

% Usage

The amount of the Page File instance in use in percent. See also Process:Page File Bytes.

Detail Level: Advanced
Counter Type: PERF_RAW_BASE

% Usage Peak

The peak usage of the Page File instance in percent. See also Process:Page File Bytes Peak.

Detail Level: Advanced
Counter Type: PERF_RAW_FRACTION

% Usage Peak

The peak usage of the Page File instance in percent. See also Process:Page File Bytes Peak.

Detail Level: Advanced
Counter Type: PERF_RAW_BASE


Physical Disk Object

The Physical Disk performance object consists of counters that monitor hard or fixed disk drive on a computer. Disks are used to store file, program, and paging data and are read to retrieve these items, and written to record changes to them. The values of physical disk counters are sums of the values of the logical disks (or partitions) into which they are divided.

Current Disk Queue Length

Current Disk Queue Length is the number of requests outstanding on the disk at the time the performance data is collected. It includes requests in service at the time of the snapshot. This is an instantaneous length, not an average over the time interval. Multi-spindle disk devices can have multiple requests active at one time, but other concurrent requests are awaiting service. This counter might reflect a transitory high or low queue length, but if there is a sustained load on the disk drive, it is likely that this will be consistently high. Requests are experiencing delays proportional to the length of this queue minus the number of spindles on the disks. This difference should average less than 2 for good performance.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

% Disk Time

Disk Time is the percentage of elapsed time that the selected disk drive is busy servicing read or write requests.

Detail Level: Novice
Counter Type: PERF_COUNTER_TIMER

Avg. Disk Queue Length

Avg. Disk Queue Length is the average number of both read and write requests that were queued for the selected disk during the sample interval.

Detail Level: Novice
Counter Type: 0x450500,

% Disk Read Time

Disk Read Time is the percentage of elapsed time that the selected disk drive is busy servicing read requests.

Detail Level: Novice
Counter Type: PERF_COUNTER_TIMER

Avg. Disk Read Queue Length

Avg. Disk Read Queue Length is the average number of read requests that were queued for the selected disk during the sample interval.

Detail Level: Novice
Counter Type: 0x450500,

% Disk Write Time

Disk Write Time is the percentage of elapsed time that the selected disk drive is busy servicing write requests.

Detail Level: Novice
Counter Type: PERF_COUNTER_TIMER

Avg. Disk Write Queue Length

Avg. Disk Write Queue Length is the average number of write requests that were queued for the selected disk during the sample interval.

Detail Level: Novice
Counter Type: 0x450500,

Avg. Disk sec/Transfer

Avg. Disk sec/Transfer is the time in seconds of the average disk transfer.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_TIMER

Avg. Disk sec/Transfer

Avg. Disk sec/Transfer is the time in seconds of the average disk transfer.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_BASE

Avg. Disk sec/Read

Avg. Disk sec/Read is the average time in seconds of a read of data from the disk.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_TIMER

Avg. Disk sec/Read

Avg. Disk sec/Read is the average time in seconds of a read of data from the disk.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_BASE

Avg. Disk sec/Write

Avg. Disk sec/Write is the average time in seconds of a write of data to the disk.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_TIMER

Avg. Disk sec/Write

Avg. Disk sec/Write is the average time in seconds of a write of data to the disk.

Detail Level: Advanced
Counter Type: PERF_AVERAGE_BASE

Disk Transfers/sec

Disk Transfers/sec is the rate of read and write operations on the disk.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Disk Reads/sec

Disk Reads/sec is the rate of read operations on the disk.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Disk Writes/sec

Disk Writes/sec is the rate of write operations on the disk.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Disk Bytes/sec

Disk Bytes/sec is the rate bytes are transferred to or from the disk during write or read operations.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Disk Read Bytes/sec

Disk Read Bytes/sec is the rate bytes are transferred from the disk during read operations.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Disk Write Bytes/sec

Disk Write Bytes is rate bytes are transferred to the disk during write operations.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Avg. Disk Bytes/Transfer

Avg. Disk Bytes/Transfer is the average number of bytes transferred to or from the disk during write or read operations.

Detail Level: Expert
Counter Type: PERF_AVERAGE_BULK

Avg. Disk Bytes/Transfer

Avg. Disk Bytes/Transfer is the average number of bytes transferred to or from the disk during write or read operations.

Detail Level: Expert
Counter Type: PERF_AVERAGE_BASE

Avg. Disk Bytes/Read

Avg. Disk Bytes/Read is the average number of bytes transferred from the disk during read operations.

Detail Level: Expert
Counter Type: PERF_AVERAGE_BULK

Avg. Disk Bytes/Read

Avg. Disk Bytes/Read is the average number of bytes transferred from the disk during read operations.

Detail Level: Expert
Counter Type: PERF_AVERAGE_BASE

Avg. Disk Bytes/Write

Avg. Disk Bytes/Write is the average number of bytes transferred to the disk during write operations.

Detail Level: Expert
Counter Type: PERF_AVERAGE_BULK

Avg. Disk Bytes/Write

Avg. Disk Bytes/Write is the average number of bytes transferred to the disk during write operations.

Detail Level: Expert
Counter Type: PERF_AVERAGE_BASE


Process Object

The Process performance object consists of counters that monitor running application program and system processes. All the threads in a process share the same address space and have access to the same data.

Processor Time

Processor Time is the percentage of elapsed time that all of the threads of this process used the processor to execute instructions. An instruction is the basic unit of execution in a computer, a thread is the object that executes instructions, and a process is the object created when a program is run. Code executed to handle some hardware interrupts and trap conditions are included in this count.

Detail Level: Novice
Counter Type: PERF_100NSEC_TIMER

% User Time

User Time is the percentage of elapsed time that this process's threads have spent executing code in user mode. Applications, environment subsystems, and integral subsystems execute in user mode. Code executing in User Mode cannot damage the integrity of the Windows NT Executive, Kernel, and device drivers. Unlike some early operating systems, Windows NT uses process boundaries for subsystem protection in addition to the traditional protection of user and privileged modes. These subsystem processes provide additional protection. Therefore, some work done by Windows NT on behalf of your application might appear in other subsystem processes in addition to the privileged time in your process.

Detail Level: Advanced
Counter Type: PERF_100NSEC_TIMER

% Privileged Time

Privileged Time is the percentage of elapsed time that the threads of the process have spent executing code in privileged mode. When a Windows NT system service is called, the service will often run in Privileged Mode to gain access to system-private data. Such data is protected from access by threads executing in user mode. Calls to the system can be explicit or implicit, such as page faults or interrupts. Unlike some early operating systems, Windows NT uses process boundaries for subsystem protection in addition to the traditional protection of user and privileged modes. These subsystem processes provide additional protection. Therefore, some work done by Windows NT on behalf of your application might appear in other subsystem processes in addition to the privileged time in your process.

Detail Level: Advanced
Counter Type: PERF_100NSEC_TIMER

Virtual Bytes Peak

Virtual Bytes Peak is the maximum number of bytes of virtual address space the process has used at any one time. Use of virtual address space does not necessarily imply corresponding use of either disk or main memory pages. Virtual space is however finite, and by using too much, the process might limit its ability to load libraries.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Virtual Bytes

Virtual Bytes is the current size in bytes of the virtual address space the process is using. Use of virtual address space does not necessarily imply corresponding use of either disk or main memory pages. Virtual space is finite, and by using too much, the process can limit its ability to load libraries.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Page Faults/sec

Page Faults/sec is the rate of Page Faults by the threads executing in this process. A page fault occurs when a thread refers to a virtual memory page that is not in its working set in main memory. This will not cause the page to be fetched from disk if it is on the standby list and hence already in main memory, or if it is in use by another process with whom the page is shared.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Working Set Peak

Working Set Peak is the maximum number of bytes in the Working Set of this process at any point in time. The Working Set is the set of memory pages touched recently by the threads in the process. If free memory in the computer is above a threshold, pages are left in the Working Set of a process even if they are not in use. When free memory falls below a threshold, pages are trimmed from Working Sets. If they are needed they will then be soft-faulted back into the Working Set before they leave main memory.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Working Set

Working Set is the current number of bytes in the Working Set of this process. The Working Set is the set of memory pages touched recently by the threads in the process. If free memory in the computer is above a threshold, pages are left in the Working Set of a process even if they are not in use. When free memory falls below a threshold, pages are trimmed from Working Sets. If they are needed they will then be soft-faulted back into the Working Set before they leave main memory.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Page File Bytes Peak

Page File Bytes Peak is the maximum number of bytes this process has used in the paging file(s). Paging files are used to store pages of memory used by the process that are not contained in other files. Paging files are shared by all processes, and lack of space in paging files can prevent other processes from allocating memory.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Page File Bytes

Page File Bytes is the current number of bytes this process has used in the paging file(s). Paging files are used to store pages of memory used by the process that are not contained in other files. Paging files are shared by all processes, and lack of space in paging files can prevent other processes from allocating memory.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Private Bytes

Private Bytes is the current number of bytes this process has allocated that cannot be shared with other processes.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Thread Count

The number of threads currently active in this process. An instruction is the basic unit of execution in a processor, and a thread is the object that executes instructions. Every running process has at least one thread.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Priority Base

The current base priority of this process. Threads within a process can raise and lower their own base priority relative to the process's base priority.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Elapsed Time

The total elapsed time (in seconds) this process has been running.

Detail Level: Advanced
Counter Type: PERF_ELAPSED_TIME

ID Process

ID Process is the unique identifier of this process. ID Process numbers are reused, so they only identify a process for the lifetime of that process.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Pool Paged Bytes

Pool Paged Bytes is the number of bytes in the Paged Pool, a system memory area where space is acquired by operating system components as they accomplish their appointed tasks. Paged Pool pages can be paged out to the paging file when not accessed by the system for sustained periods of time.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Pool Nonpaged Bytes

Pool Nonpaged Bytes is the number of bytes in the nonpaged pool, a system memory area where space is acquired by operating system components as they accomplish their appointed tasks. Nonpaged pool pages cannot be paged out to the paging file, but instead remain in main memory as long as they are allocated.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Handle Count

The total number of handles currently open by this process. This number is the sum of the handles currently open by each thread in this process.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT


Process Address Space Object

The Process Address Space performance object consists of counters that monitor memory allocation and use for a selected process.

Bytes Image Reserved

Bytes Image Reserved is the sum of all virtual memory reserved by images run within this process.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

ID Process

ID Process is the unique identifier of this process. ID Process numbers are reused, so they only identify a process for the lifetime of that process.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Bytes Image Free

Bytes Image Free is the amount of virtual address space that is not in use or reserved by images within this process.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Bytes Reserved

Bytes Reserved is the total amount of virtual memory reserved for future use by this process.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Bytes Free

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Bytes Free is the total unused virtual address space of this process.

Mapped Space No Access

Mapped Space is virtual memory that has been mapped to a specific virtual address (or range of virtual addresses) in the process's virtual address space. No Access protection prevents a process from writing to or reading from these pages and will generate an access violation if either is attempted.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Mapped Space Read Only

Mapped Space is virtual memory that has been mapped to a specific virtual address (or range of virtual addresses) in the process's virtual address space. Read Only protection prevents the contents of these pages from being modified. Any attempts to write or modify these pages will generate an access violation.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Mapped Space Read/Write

Mapped Space is virtual memory that has been mapped to a specific virtual address (or range of virtual addresses) in the process's virtual address space. Read/Write protection allows a process to read, modify and write to these pages.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Mapped Space Write Copy

Mapped Space is virtual memory that has been mapped to a specific virtual address (or range of virtual addresses) in the process's virtual address space. Write Copy protection is used when memory is shared for reading but not for writing. When processes are reading this memory, they can share the same memory, however, when a sharing process wants to have write access to this shared memory, a copy of that memory is made.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Mapped Space Executable

Mapped Space is virtual memory that has been mapped to a specific virtual address (or range of virtual addresses) in the process's virtual address space. Executable memory is memory that can be executed by programs, but cannot be read or written. This type of protection is not supported by all processor types.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Mapped Space Exec Read Only

Mapped Space is virtual memory that has been mapped to a specific virtual address (or range of virtual addresses) in the process's virtual address space. Execute/Read Only memory is memory that can be executed as well as read.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Mapped Space Exec Read/Write

Mapped Space is virtual memory that has been mapped to a specific virtual address (or range of virtual addresses) in the process's virtual address space. Execute/Read/Write memory is memory that can be executed by programs as well as read and modified.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Mapped Space Exec Write Copy

Mapped Space is virtual memory that has been mapped to a specific virtual address (or range of virtual addresses) in the process's virtual address space. Execute Write Copy is memory that can be executed by programs as well as read and written. This type of protection is used when memory needs to be shared between processes. If the sharing processes only read the memory, then they will all use the same memory. If a sharing process desires write access, then a copy of this memory will be made for that process.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Reserved Space No Access

Reserved Space is virtual memory that has been reserved for future use by a process, but has not been mapped or committed. No Access protection prevents a process from writing to or reading from these pages and will generate an access violation if either is attempted.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Reserved Space Read Only

Reserved Space is virtual memory that has been reserved for future use by a process, but has not been mapped or committed. Read Only protection prevents the contents of these pages from being modified. Any attempts to write or modify these pages will generate an access violation.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Reserved Space Read/Write

Reserved Space is virtual memory that has been reserved for future use by a process, but has not been mapped or committed. Read/Write protection allows a process to read, modify and write to these pages.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Reserved Space Write Copy

Reserved Space is virtual memory that has been reserved for future use by a process, but has not been mapped or committed. Write Copy protection is used when memory is shared for reading but not for writing. When processes are reading this memory, they can share the same memory, however, when a sharing process wants to have read/write access to this shared memory, a copy of that memory is made.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Reserved Space Executable

Reserved Space is virtual memory that has been reserved for future use by a process, but has not been mapped or committed. Executable memory is memory that can be executed by programs, but cannot be read or written. This type of protection is not supported by all processor types.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Reserved Space Exec Read Only

Reserved Space is virtual memory that has been reserved for future use by a process, but has not been mapped or committed. Execute/Read Only memory is memory that can be executed as well as read.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Reserved Space Exec Read/Write

Reserved Space is virtual memory that has been reserved for future use by a process, but has not been mapped or committed. Execute/Read/Write memory is memory that can be executed by programs as well as read and modified.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Reserved Space Exec Write Copy

Reserved Space is virtual memory that has been reserved for future use by a process, but has not been mapped or committed. Execute Write Copy is memory that can be executed by programs as well as read and written. This type of protection is used when memory needs to be shared between processes. If the sharing processes only read the memory, then they will all use the same memory. If a sharing process desires write access, then a copy of this memory will be made for that process.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Unassigned Space No Access

Unassigned Space is mapped and committed virtual memory in use by the process that is not attributable to any particular image being executed by that process. No Access protection prevents a process from writing to or reading from these pages and will generate an access violation if either is attempted.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Unassigned Space Read Only

Unassigned Space is mapped and committed virtual memory in use by the process that is not attributable to any particular image being executed by that process. Read Only protection prevents the contents of these pages from being modified. Any attempts to write or modify these pages will generate an access violation.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Unassigned Space Read/Write

Unassigned Space is mapped and committed virtual memory in use by the process that is not attributable to any particular image being executed by that process. Read/Write protection allows a process to read, modify and write to these pages.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Unassigned Space Write Copy

Unassigned Space is mapped and committed virtual memory in use by the process that is not attributable to any particular image being executed by that process. Write Copy protection is used when memory is shared for reading but not for writing. When processes are reading this memory, they can share the same memory, however, when a sharing process wants to have read/write access to this shared memory, a copy of that memory is made for writing to.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Unassigned Space Executable

Unassigned Space is mapped and committed virtual memory in use by the process that is not attributable to any particular image being executed by that process. Executable memory is memory that can be executed by programs, but cannot be read or written. This type of protection is not supported by all processor types.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Unassigned Space Exec Read Only

Unassigned Space is mapped and committed virtual memory in use by the process that is not attributable to any particular image being executed by that process. Execute/Read Only memory is memory that can be executed as well as read.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Unassigned Space Exec Read/Write

Unassigned Space is mapped and committed virtual memory in use by the process that is not attributable to any particular image being executed by that process. Execute/Read/Write memory is memory that can be executed by programs as well as read and written.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Unassigned Space Exec Write Copy

Unassigned Space is mapped and committed virtual memory in use by the process that is not attributable to any particular image being executed by that process. Execute Write Copy is memory that can be executed by programs as well as read and written. This type of protection is used when memory needs to be shared between processes. If the sharing processes only read the memory, then they will all use the same memory. If a sharing process desires write access, then a copy of this memory will be made for that process.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Image Space No Access

Image Space is the virtual address space in use by the images being executed by the process. This is the sum of all the address space with this protection allocated by images run by the selected process No Access protection prevents a process from writing to or reading from these pages and will generate an access violation if either is attempted.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Image Space Read Only

Image Space is the virtual address space in use by the images being executed by the process. This is the sum of all the address space with this protection allocated by images run by the selected process Read Only protection prevents the contents of these pages from being modified. Any attempts to write or modify these pages will generate an access violation.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Image Space Read/Write

Image Space is the virtual address space in use by the images being executed by the process. This is the sum of all the address space with this protection allocated by images run by the selected process Read/Write protection allows a process to read, modify and write to these pages.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Image Space Write Copy

Image Space is the virtual address space in use by the images being executed by the process. This is the sum of all the address space with this protection allocated by images run by the selected process Write Copy protection is used when memory is shared for reading but not for writing. When processes are reading this memory, they can share the same memory, however, when a sharing process wants to have read/write access to this shared memory, a copy of that memory is made for writing to.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Image Space Executable

Image Space is the virtual address space in use by the images being executed by the process. This is the sum of all the address space with this protection allocated by images run by the selected process Executable memory is memory that can be executed by programs, but cannot be read or written. This type of protection is not supported by all processor types.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Image Space Exec Read Only

Image Space is the virtual address space in use by the images being executed by the process. This is the sum of all the address space with this protection allocated by images run by the selected process Execute/Read Only memory is memory that can be executed as well as read.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Image Space Exec Read/Write

Image Space is the virtual address space in use by the images being executed by the process. This is the sum of all the address space with this protection allocated by images run by the selected process Execute/Read/Write memory is memory that can be executed by programs as well as read and written and modified.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Image Space Exec Write Copy

Image Space is the virtual address space in use by the images being executed by the process. This is the sum of all the address space with this protection allocated by images run by the selected process Execute Write Copy is memory that can be executed by programs as well as read and written. This type of protection is used when memory needs to be shared between processes. If the sharing processes only read the memory, then they will all use the same memory. If a sharing process desires write access, then a copy of this memory will be made for that process.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT


Processor Object

The Processor performance object consists of counters that measure aspects of processor activity The processor is the part of the computer that performs arithmetic and logical computations, initiates operations on peripherals, and runs the threads of processes. A computer can have multiple processors. The processor object represents each processor as an instance of the object.

%Processor Time

%Processor Time is the percentage of time that the processor is executing a non-Idle thread. This counter was designed as a primary indicator of processor activity. It is calculated by measuring the time that the processor spends executing the thread of the Idle process in each sample interval, and subtracting that value from 100%. (Each processor has an Idle thread which consumes cycles when no other threads are ready to run.) It can be viewed as the fraction of the time spent doing useful work.

Detail Level: Novice
Counter Type: PERF_100NSEC_TIMER_INV

%User Time

%User Time is the percentage of non-idle processor time spent in user mode. (User mode is a restricted processing mode designed for applications, environment subsystems, and integral subsystems. The alternative, privileged mode, is designed for operating system components and allows direct access to hardware and all memory. The operating system switches application threads to privileged mode to obtain operating system services.)

Detail Level: Advanced
Counter Type: PERF_100NSEC_TIMER

% Privileged Time

Privileged Time is the percentage of non-idle processor time spent in privileged mode. (Privileged mode is a processing mode designed for operating system components and hardware-manipulating drivers. It allows direct access to hardware and all memory. The alternative, user mode, is a restricted processing mode designed for applications, environment subsystems, and integral subsystems. The operating system switches application threads to privileged mode to obtain operating system services.) % Privileged Time includes time servicing interrupts and DPCs. A high rate of privileged time might be attributable to a large number of interrupts generated by a failing device.

Detail Level: Advanced
Counter Type: PERF_100NSEC_TIMER

Interrupts/sec

Interrupts/sec is the average number of hardware interrupts the processor is receiving and servicing in each second. It does not include DPCs, which are counted separately. This value is an indirect indicator of the activity of devices that generate interrupts, such as the system clock, the mouse, disk drivers, data communication lines, network interface cards and other peripheral devices. These devices normally interrupt the processor when they have completed a task or require attention. Normal thread execution is suspended during interrupts. Most system clocks interrupt the processor every 10 milliseconds, creating a background of interrupt activity.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

% DPC Time

% DPC Time is the percentage of time that the processor spent receiving and servicing deferred procedure calls (DPCs) during the sample interval.(DPCs are interrupts that run at a lower priority than standard interrupts.) % DPC Time is a component of % Privileged Time because DPCs are executed in privileged mode. They are counted separately and are not a component of the interrupt counters.

Detail Level: Advanced
Counter Type: PERF_100NSEC_TIMER

% Interrupt Time

% Interrupt Time is the percentage of time the processor spent receiving and servicing hardware interrupts during the sample interval. This value is an indirect indicator of the activity of devices that generate interrupts, such as the system clock, the mouse, disk drivers, data communication lines, network interface cards and other peripheral devices. These devices normally interrupt the processor when they have completed a task or require attention. Normal thread execution is suspended during interrupts. Most system clocks interrupt the processor every 10 milliseconds, creating a background of interrupt activity.

Detail Level: Advanced
Counter Type: PERF_100NSEC_TIMER

DPCs Queued/sec

DPCs Queued/sec is the overall rate at which deferred procedure calls (DPC) are added to the processor's DPC queue. (DPCs are interrupts that run at a lower priority than standard interrupts. Each processor has its own DPC queue.) This counter measures the rate at which DPCs are added to the queue, not the number of DPCs in the queue.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

DPC Rate

DPC Rate is the rate at which deferred procedure calls (DPC) are added to the processor's DPC queue between the timer tics of the processor clock. DPC objects are queued to this processor's DPC queue per clock tick. (DPCs are interrupts that run at a lower priority than standard interrupts. Each processor has its own DPC queue.) This counter measures the rates at which DPCs are added to the queue, not the number of DPCs in the queue.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

DPC Bypasses/sec

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

DPC Bypasses/sec is the rate at which deferred procedure calls (DPC) on all processors were avoided. (DPCs are interrupts that run at a lower priority than standard interrupts.

APC Bypasses/sec

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

APC Bypasses/sec is the rate at which kernel APC interrupts were avoided. APC Bypasses/sec is the rate at which kernel APC interrupts were short-circuited. .


RAS Port Object

The RAS Port performance object consists of counters that monitor individual Remote Access Service (RAS) ports of the RAS device on the system.

Bytes Transmitted

The number of bytes transmitted total for this connection.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Bytes Received

The number of bytes received total for this connection.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Frames Transmitted

The number of data frames transmitted total for this connection.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Frames Received

The number of data frames received total for this connection.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Percent Compression Out

The compression ratio for bytes being transmitted.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Percent Compression In

The compression ratio for bytes being received.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

CRC Errors

The total number of CRC Errors for this connection. CRC Errors occur when the frame received contains erroneous data.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Timeout Errors

The total number of Timeout Errors for this connection. Timeout Errors occur when an expected is not received in time.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Serial Overrun Errors

The total number of Serial Overrun Errors for this connection. Serial Overrun Errors occur when the hardware cannot handle the rate at which data is received.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Alignment Errors

The total number of Alignment Errors for this connection. Alignment Errors occur when a byte received is different from the byte expected.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Buffer Overrun Errors

The total number of Buffer Overrun Errors for this connection. Buffer Overrun Errors when the software cannot handle the rate at which data is received.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Total Errors

The total number of CRC, Timeout, Serial Overrun, Alignment, and Buffer Overrun Errors for this connection.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Bytes Transmitted/Sec

The number of bytes transmitted per second.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Bytes Received/Sec

The number of bytes received per second.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Frames Transmitted/Sec

The number of frames transmitted per second.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Frames Received/Sec

The number of frames received per second.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Total Errors/Sec

The total number of CRC, Timeout, Serial Overrun, Alignment, and Buffer Overrun Errors per second.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER


RAS Total Object

The RAS Total performance object consists of counters that combine values for all ports of the Remote Access Service (RAS) device on the computer.

Bytes Transmitted

The number of bytes transmitted total for this connection.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Bytes Received

The number of bytes received total for this connection.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Frames Transmitted

The number of data frames transmitted total for this connection.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Frames Received

The number of data frames received total for this connection.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Percent Compression Out

The compression ratio for bytes being transmitted.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Percent Compression In

The compression ratio for bytes being received.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

CRC Errors

The total number of CRC Errors for this connection. CRC Errors occur when the frame received contains erroneous data.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Timeout Errors

The total number of Timeout Errors for this connection. Timeout Errors occur when an expected is not received in time.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Serial Overrun Errors

The total number of Serial Overrun Errors for this connection. Serial Overrun Errors occur when the hardware cannot handle the rate at which data is received.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Alignment Errors

The total number of Alignment Errors for this connection. Alignment Errors occur when a byte received is different from the byte expected.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Buffer Overrun Errors

The total number of Buffer Overrun Errors for this connection. Buffer Overrun Errors when the software cannot handle the rate at which data is received.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Total Errors

The total number of CRC, Timeout, Serial Overrun, Alignment, and Buffer Overrun Errors for this connection.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Bytes Transmitted/Sec

The number of bytes transmitted per second.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Bytes Received/Sec

The number of bytes received per second.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Frames Transmitted/Sec

The number of frames transmitted per second.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Frames Received/Sec

The number of frames received per second.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Total Errors/Sec

The total number of CRC, Timeout, Serial Overrun, Alignment, and Buffer Overrun Errors per second.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Total Connections

The total number of Remote Access connections.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT


Redirector Object

The Redirector performance object consists of counter that monitor network connections originating at the local computer.

Bytes Total/sec

Bytes Total/sec is the rate the Redirector is processing data bytes. This includes all application and file data in addition to protocol information such as packet headers.

Detail Level: Novice
Counter Type: PERF_COUNTER_BULK_COUNT

File Data Operations/sec

File Data Operations/sec is the rate the Redirector is processing data operations. One operation includes (hopefully) many bytes. We say hopefully here because each operation has overhead. You can determine the efficiency of this path by dividing the Bytes/sec by this counter to determine the average number of bytes transferred/operation.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Packets/sec

Packets/sec is the rate the Redirector is processing data packets. One packet includes (hopefully) many bytes. We say hopefully here because each packet has protocol overhead. You can determine the efficiency of this path by dividing the Bytes/sec by this counter to determine the average number of bytes transferred/packet. You can also divide this counter by Operations/sec to determine the average number of packets per operation, another measure of efficiency.

Detail Level: Novice
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Received/sec

Bytes Received/sec is the rate of bytes coming in to the Redirector from the network. It includes all application data as well as network protocol information (such as packet headers.)

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Packets Received/sec

Packets Received/sec is the rate at which the Redirector is receiving packets (also called SMBs or Server Message Blocks). Network transmissions are divided into packets. The average number of bytes received in a packet can be obtained by dividing Bytes Received/sec by this counter. Some packets received might not contain incoming data, for example an acknowledgment to a write made by the Redirector would count as an incoming packet.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Read Bytes Paging/sec

Read Bytes Paging/sec is the rate at which the Redirector is attempting to read bytes in response to page faults. Page faults are caused by loading of modules (such as programs and libraries), by a miss in the Cache (see Read Bytes Cache/sec), or by files directly mapped into the address space of applications (a high-performance feature of Windows NT.)

Detail Level: Expert
Counter Type: PERF_COUNTER_BULK_COUNT

Read Bytes Non-Paging/sec

Read Bytes Non-Paging/sec are those bytes read by the Redirector in response to normal file requests by an application when they are redirected to come from another computer. In addition to file requests, this counter includes other methods of reading across the network such as Named Pipes and Transactions. This counter does not count network protocol information, just application data.

Detail Level: Expert
Counter Type: PERF_COUNTER_BULK_COUNT

Read Bytes Cache/sec

Read Bytes Cache/sec is the rate at which applications are accessing the file system cache by using the Redirector. Some of these data requests are satisfied by retrieving the data from the cache. Requests that miss the cache cause a page fault (see Read Bytes Paging/sec).

Detail Level: Expert
Counter Type: PERF_COUNTER_BULK_COUNT

Read Bytes Network/sec

Read Bytes Network/sec is the rate at which applications are reading data across the network. This occurs when data sought in the file system cache is not found there and must be retrieved from the network. Dividing this value by Bytes Received/sec indicates the proportion of application data traveling across the network (see Bytes Received/sec.)

Detail Level: Novice
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Transmitted/sec

Bytes Transmitted/sec is the rate at which bytes are leaving the Redirector to the network. It includes all application data as well as network protocol information (such as packet headers and the like.)

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Packets Transmitted/sec

Packets Transmitted/sec is the rate at which the Redirector is sending packets (also called SMBs or Server Message Blocks). Network transmissions are divided into packets. The average number of bytes transmitted in a packet can be obtained by dividing Bytes Transmitted/sec by this counter.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Write Bytes Paging/sec

Write Bytes Paging/sec is the rate at which the Redirector is attempting to write bytes changed in the pages being used by applications. The program data changed by modules (such as programs and libraries) that were loaded over the network are 'paged out' when no longer needed. Other output pages come from the cache (see Write Bytes Cache/sec).

Detail Level: Expert
Counter Type: PERF_COUNTER_BULK_COUNT

Write Bytes Non-Paging/sec

Write Bytes Non-Paging/sec is the rate at which bytes are written by the Redirector in response to normal file outputs by an application when they are redirected to another computer. In addition to file requests this counter includes other methods of writing across the network such as Named Pipes and Transactions. This counter does not count network protocol information, just application data.

Detail Level: Expert
Counter Type: PERF_COUNTER_BULK_COUNT

Write Bytes Cache/sec

Write Bytes Cache/sec is the rate at which applications on your computer are writing to the file system cache using the Redirector. The data might not leave your computer immediately; it can be retained in the cache for further modification before being written to the network. This saves network traffic. Each write of a byte into the cache is counted here.

Detail Level: Expert
Counter Type: PERF_COUNTER_BULK_COUNT

Write Bytes Network/sec

Write Bytes Network/sec is the rate at which applications are writing data across the network. This occurs when the file system cache is, such as for named pipes or transactions, or else the cache writes the bytes to disk to make room for other data. Dividing this counter by Bytes Transmitted/sec will indicate the proportion of application data being written to the network (see Transmitted Bytes/sec.)

Detail Level: Novice
Counter Type: PERF_COUNTER_BULK_COUNT

File Read Operations/sec

File Read Operations/sec is the rate at which applications are asking the Redirector for data. Each call to a file system or similar Application Program Interface (API) call counts as one operation.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Read Operations Random/sec

Read Operations Random/sec counts the rate at which, on a file-by-file basis, reads are made that are not sequential. If a read is made using a particular file handle, and then is followed by another read that is not immediately the contiguous next byte, this counter is incremented by one.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Read Packets/sec

Read Packets/sec is the rate at which read packets are being placed on the network. Each time a single packet is sent with a request to read data remotely, this counter is incremented by one.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Reads Large/sec

Reads Large/sec is the rate at which reads over 2 times the server's negotiated buffer size are made by applications. Too many of these could place a strain on server resources. This counter is incremented once for each read. It does not count packets.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Read Packets Small/sec

Read Packets Small/sec is the rate at which reads less than one-fourth of the server's negotiated buffer size are made by applications. Too many of these could indicate a waste of buffers on the server. This counter is incremented once for each read. It does not count packets.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

File Write Operations/sec

File Write Operations/sec is the rate at which applications are sending data to the Redirector. Each call to a file system or similar Application Program Interface (API) call counts as one operation.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Write Operations Random/sec

Write Operations Random/sec is the rate at which, on a file-by-file basis, writes are made that are not sequential. If a write is made using a particular file handle, and then is followed by another write that is not immediately the next contiguous byte, this counter is incremented by one.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Write Packets/sec

Write Packets/sec is the rate at which writes are being sent to the network. Each time a single packet is sent with a request to write remote data, this counter is incremented by one.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Writes Large/sec

Writes Large/sec is the rate at which writes are made by applications that are over 2 times the server's negotiated buffer size. Too many of these could place a strain on server resources. This counter is incremented once for each write: it counts writes, not packets.

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Write Packets Small/sec

Write Packets Small/sec is the rate at which writes are made by applications that are less than one-fourth of the server's negotiated buffer size. Too many of these could indicate a waste of buffers on the server. This counter is incremented once for each write: it counts writes, not packets!

Detail Level: Expert
Counter Type: PERF_COUNTER_COUNTER

Reads Denied/sec

Reads Denied/sec is the rate at which the server is unable to accommodate requests for Raw Reads. When a read is much larger than the server's negotiated buffer size, the Redirector requests a Raw Read which, if granted, would permit the transfer of the data without lots of protocol overhead on each packet. To accomplish this the server must lock out other requests, so the request is denied if the server is really busy.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Writes Denied/sec

Writes Denied/sec is the rate at which the server is unable to accommodate requests for Raw Writes. When a write is much larger than the server's negotiated buffer size, the Redirector requests a Raw Write which, if granted, would permit the transfer of the data without lots of protocol overhead on each packet. To accomplish this the server must lock out other requests, so the request is denied if the server is really busy.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Network Errors/sec

Network Errors/sec counts serious unexpected errors that generally indicate the Redirector and one or more Servers are having serious communication difficulties. For example an SMB (Server Manager Block) protocol error will generate a Network Error. These result in an entry in the system Event Log, so look there for details.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Server Sessions

Server Sessions counts the total number of security objects the Redirector has managed. For example, a logon to a server followed by a network access to the same server will establish one connection, but two sessions.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Server Reconnects

Server Reconnects counts the number of times your Redirector has had to reconnect to a server in order to complete a new active request. You can be disconnected by the Server if you remain inactive for too long. Locally even if all your remote files are closed, the Redirector will keep your connections intact for (nominally) ten minutes. Such inactive connections are called Dormant Connections. Reconnecting is expensive in time.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connects Core

Connects Core counts the number of connections you have to servers running the original MS-Net SMB protocol, including MS-Net itself and Xenix and VAXs.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connects LAN Manager 2.0

Connects LAN Manager 2.0 counts connections to LAN Manager 2.0 servers, including LMX servers.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connects LAN Manager 2.1

Connects LAN Manager 2.1 counts connections to LAN Manager 2.1 servers, including LMX servers.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connects Windows NT

Connects Windows NT counts the connections to Windows NT computers.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Server Disconnects

Server Disconnects counts the number of times a Server has disconnected your Redirector. See also Server Reconnects.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Server Sessions Hung

Server Sessions Hung counts the number of active sessions that are timed out and unable to proceed due to a lack of response from the remote server.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Current Commands

Current Commands counts the number of requests to the Redirector that are currently queued for service. If this number is much larger than the number of network adapter cards installed in the computer, then the network(s) and/or the server(s) being accessed are seriously bottlenecked.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT


Server Object

The Server performance object consists of counters that measure communication between the local computer and the network.

Bytes Total/sec

The number of bytes the server has sent to and received from the network. This value provides an overall indication of how busy the server is.

Detail Level: Novice
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Received/sec

The number of bytes the server has received from the network. Indicates how busy the server is.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Transmitted/sec

The number of bytes the server has sent on the network. Indicates how busy the server is.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Sessions Timed Out

The number of sessions that have been closed due to their idle time exceeding the AutoDisconnect parameter for the server. Shows whether the AutoDisconnect setting is helping to conserve resources.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Sessions Errored Out

The number of sessions that have been closed due to unexpected error conditions. Indicates how frequently network problems are causing dropped sessions on the server.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Sessions Logged Off

The number of sessions that have terminated normally. Useful in interpreting the Sessions Times Out and Sessions Errored Out statistics--allows percentage calculations.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Sessions Forced Off

The number of sessions that have been forced to logoff. Can indicate how many sessions were forced to logoff due to logon time constraints.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Errors Logon

The number of failed logon attempts to the server. Can indicate whether password guessing programs are being used to crack the security on the server.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Errors Access Permissions

The number of times opens on behalf of clients have failed with STATUS_ACCESS_DENIED. Can indicate whether somebody is randomly attempting to access files in hopes of getting at something that was not properly protected.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Errors Granted Access

The number of times accesses to files opened successfully were denied. Can indicate attempts to access files without proper access authorization.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Errors System

The number of times an internal Server Error was detected. Unexpected errors usually indicate a problem with the Server.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Blocking Requests Rejected

The number of times the server has rejected blocking SMBs due to insufficient count of free work items. Indicates whether the MaxWorkItem or MinFreeWorkItems server parameters might need tuning.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Work Item Shortages

The number of times STATUS_DATA_NOT_ACCEPTED was returned at receive indication time. This occurs when no work item is available or can be allocated to service the incoming request. Indicates whether the InitWorkItems or MaxWorkItems parameters might need to be adjusted.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Files Opened Total

The number of successful open attempts performed by the server of behalf of clients. Useful in determining the amount of file I/O, determining overhead for path-based operations, and for determining the effectiveness of open locks.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Files Open

The number of files currently opened in the server. Indicates current server activity.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

Server Sessions

The number of sessions currently active in the server. Indicates current server activity.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT

File Directory Searches

The number of searches for files currently active in the server. Indicates current server activity.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Pool Nonpaged Bytes

The number of bytes of non-pageable computer memory the server is currently using. This value is useful for determining good values for the MaxNonpagedMemoryUsage parameter.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Pool Nonpaged Failures

The number of times allocations from nonpaged pool have failed. Indicates that the computer's physical memory is too small.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Pool Nonpaged Peak

The maximum number of bytes of nonpaged pool the server has had in use at any one point. Indicates how much physical memory the computer should have.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Pool Paged Bytes

The number of bytes of pageable computer memory the server is currently using. Can help in determining good values for the MaxPagedMemoryUsage parameter.

Detail Level: Expert
Counter Type: PERF_COUNTER_RAWCOUNT

Pool Paged Failures

The number of times allocations from paged pool have failed. Indicates that the computer's physical memory or page file are too small.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Pool Paged Peak

The maximum number of bytes of paged pool the server has had allocated. Indicates the proper sizes of the Page File(s) and physical memory.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Context Blocks Queued/sec

Context Blocks Queued per second is the rate at which work context blocks had to be placed on the server's FSP queue to await server action.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Logon/sec

Logon/sec includes the rate of all interactive logons, network logons, service logons, successful logon, and failed logons.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

Logon Total

Logon Total includes all interactive logons, network logons, service logons, successful logon, and failed logons since the machine is last rebooted.

Detail Level: Novice
Counter Type: PERF_COUNTER_RAWCOUNT


Server Work Queues Object

The Server Work Queues performance object consists of counters that monitor the length of the queues and objects in the queues.

Queue Length

Queue Length is the current length of the server work queue for this CPU. A sustained queue length greater than four might indicate processor congestion. This is an instantaneous count, not an average over time.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Active Threads

Active Threads is the number of threads currently working on a request from the server client for this CPU. The system keeps this number as low as possible to minimize unnecessary context switching. This is an instantaneous count for the CPU, not an average over time.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Available Threads

Available Threads is the number of server threads on this CPU not currently working on requests from a client. The server dynamically adjusts the number of threads to maximize server performance.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Available Work Items

Every request from a client is represented in the server as a 'work item,' and the server maintains a pool of available work items per CPU to speed processing. This is the instantaneous number of available work items for this CPU. A sustained near-zero value indicates the need to increase the MinFreeWorkItems registry value for the Server service. This value will always be 0 in the Blocking Queue instance.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Borrowed Work Items

Every request from a client is represented in the server as a 'work item,' and the server maintains a pool of available work items per CPU to speed processing. When a CPU runs out of work items, it borrows a free work item from another CPU. An increasing value of this running counter might indicate the need to increase the 'MaxWorkItems' or 'MinFreeWorkItems' registry values for the Server service. This value will always be 0 in the Blocking Queue instance.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Work Item Shortages

Every request from a client is represented in the server as a 'work item,' and the server maintains a pool of available work items per CPU to speed processing. A sustained value greater than zero indicates the need to increase the 'MaxWorkItems' registry value for the Server service. This value will always be 0 in the Blocking Queue instance.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Current Clients

Current Clients is the instantaneous count of the clients being serviced by this CPU. The server actively balances the client load across all of the CPU's in the system. This value will always be 0 in the Blocking Queue instance.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Bytes Received/sec

The rate at which the Server is receiving bytes from the network clients on this CPU. This value is a measure of how busy the Server is.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Sent/sec

The rate at which the Server is sending bytes to the network clients on this CPU. This value is a measure of how busy the Server is.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Bytes Transferred/sec

The rate at which the Server is sending and receiving bytes with the network clients on this CPU. This value is a measure of how busy the Server is.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Read Operations/sec

Read Operations/sec is the rate the server is performing file read operations for the clients on this CPU. This value is a measure of how busy the Server is. This value will always be 0 in the Blocking Queue instance.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Read Bytes/sec

Read Bytes/sec is the rate the server is reading data from files for the clients on this CPU. This value is a measure of how busy the Server is.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Write Operations/sec

Write Operations/sec is the rate the server is performing file write operations for the clients on this CPU. This value is a measure of how busy the Server is. This value will always be 0 in the Blocking Queue instance.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Write Bytes/sec

Write Bytes/sec is the rate the server is writing data to files for the clients on this CPU. This value is a measure of how busy the Server is.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Total Bytes/sec

Total Bytes/sec is the rate the Server is reading and writing data to and from the files for the clients on this CPU. This value is a measure of how busy the Server is.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Total Operations/sec

Total Operations/sec is the rate the Server is performing file read and file write operations for the clients on this CPU. This value is a measure of how busy the Server is. This value will always be 0 in the Blocking Queue instance.

Detail Level: Advanced
Counter Type: PERF_COUNTER_BULK_COUNT

Context Blocks Queued/sec

Context Blocks Queued per second is the rate at which work context blocks had to be placed on the server's FSP queue to await server action.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER


System Object

The System performance object consists of those counters that apply to more than one component on the computer

File Read Operations/sec

File Read Operations/sec is the combined rate of file system read requests to all devices on the computer, including requests to read from the file system cache. It is measured in numbers of reads.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

File Write Operations/sec

File Write Operations/sec is the combined rate of the file system write requests to all devices on the computer, including requests to write to data in the file system cache. It is measured in numbers of writes.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

File Control Operations/sec

File Control Operations/sec is the combined rate of file system operations that are neither reads nor writes, such as file system control requests and requests for information about device characteristics or status. This is the inverse of System: File Data Operations/sec and is measured in numbers of operations.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

File Read Bytes/sec

File Read Bytes/sec is the overall rate at which bytes are read to satisfy file system read requests to all devices on the computer, including reads from the file system cache. It is measured in numbers of bytes.

Detail Level: Expert
Counter Type: PERF_COUNTER_BULK_COUNT

File Write Bytes/sec

File Write Bytes/sec is the overall rate at which bytes are written to satisfy file system write requests to all devices on the computer, including writes to the file system cache. It is measured in numbers of bytes.

Detail Level: Expert
Counter Type: PERF_COUNTER_BULK_COUNT

File Control Bytes/sec

File Control Bytes/sec is the overall rate at which bytes are transferred for all file system operations that are neither reads nor writes, including file system control requests and requests for information about device characteristics or status. It is measured in numbers of bytes.

Detail Level: Wizard
Counter Type: PERF_COUNTER_BULK_COUNT

Context Switches/sec

Context Switches/sec is the combined rate at which all processors on the computer are switched from one thread to another. Context switches occur when a running thread voluntarily relinquishes the processor, is preempted by a higher priority ready thread, or switches between user-mode and privileged (kernel) mode to use an Executive or subsystem service. It is the sum of Thread: Context Switches/sec for all threads running on all processors in the computer and is measured in numbers of switches. There are context switch counters on the System and Thread objects.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

System Calls/sec

Systems Calls/sec is the combined rate of calls to Windows NT system service routines by all processes running on the computer. These routines perform all of the basic scheduling and synchronization of activities on the computer, and provide access to non-graphic devices, memory management, and name space management.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Total Processor Time

% Total Processor Time is the average percentage of time that all processors on the computer are executing non-idle threads. This counter was designed as the primary indicator of processor activity on multiprocessor computers. It is equal to the sum of Process: % Processor Time for all processors, divided by the number of processors. It is calculated by summing the time that all processors spend executing the thread of the Idle process in each sample interval, subtracting that value from 100%, and dividing the difference by the number of processors on the computer. (Each processor has an Idle thread which consumes cycles when no other threads are ready to run.) For example, on a multiprocessor computer, a value of 50% means that all processors are busy for half of the sample interval, or that half of the processors are busy for all of the sample interval.

Detail Level: Novice
Counter Type: PERF_100NSEC_TIMER_INV

Total User Time

% Total User Time is the average percentage of non-idle time all processors spent in User mode. It is the sum of Processor: % User Time for all processors on the computer, divided by the number of processors. System: % Total User Time and System: % Total Privileged Time sum to % Total Processor Time, but not always to 100%. (User mode is a restricted processing mode designed for applications, environment subsystems, and integral subsystems. The alternative, privileged mode, is designed for operating system components and allows direct access to hardware and all memory. The operating system switches application threads to privileged mode to obtain operating system services.)

Detail Level: Advanced
Counter Type: PERF_100NSEC_TIMER

Total Privileged Time

% Total Privileged Time is the average percentage of non-idle time all processors spent in privileged (kernel) mode. It is the sum of Processor: % Privileged Time for all processors on the computer, divided by the number of processors. System: % Total User Time and System: % Total Privileged Time sum to % Total Processor Time, but not always to 100%. (Privileged mode is an processing mode designed for operating system components which allows direct access to hardware and all memory. The operating system switches application threads to privileged mode to obtain operating system services. The alternative, user mode, is a restricted processing mode designed for applications and environment subsystems.)

Detail Level: Advanced
Counter Type: PERF_100NSEC_TIMER

Total Interrupts/sec

Total Interrupts/sec is the combined rate of hardware interrupts received and serviced by all processors on the computer It is the sum of Processor: Interrupts/sec for all processors, and divided by the number of processors, and is measured in numbers of interrupts. It does not include DPCs, which are counted separately. This value is an indirect indicator of the activity of devices that generate interrupts, such as the system timer, the mouse, disk drivers, data communication lines, network interface cards and other peripheral devices. These devices normally interrupt the processor when they have completed a task or require attention. Normal thread execution is suspended during interrupts. Most system clocks interrupt the processor every 10 milliseconds, creating a background of interrupt activity.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

File Data Operations/sec

File Data Operations/sec is the combined rate of read and write operations on all logical disks on the computer. This is the inverse of System: File Control Operations/sec.

Detail Level: Novice
Counter Type: PERF_COUNTER_COUNTER

System Up Time

Total Time (in seconds) that the computer has been operational since it was last started.

Detail Level: Novice
Counter Type: PERF_ELAPSED_TIME

Processor Queue Length

Processor Queue Length is the number of threads in the processor queue. There is a single queue for processor time even on computers with multiple processors. Unlike the disk counters, this counter counts ready threads only, not threads that are running. A sustained processor queue of greater than two threads generally indicates processor congestion.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Alignment Fixups/sec

Alignment Fixups/sec is the rate of alignment faults fixed by the system.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Exception Dispatches/sec

Exception Dispatches/sec is the rate of exceptions dispatched by the system.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

Floating Emulations/sec

Floating Emulations/sec is the rate of floating emulations performed by the system.

Detail Level: Wizard
Counter Type: PERF_COUNTER_COUNTER

% Total DPC Time

% Total DPC Time is the average percentage of time that all processors spent receiving and servicing deferred procedure calls (DPC). (DPCs are interrupts that run at a lower priority than the standard interrupts.) it is the sum of Processor: %DPC Time for all processors on the computer, divided by the number of processors. System: %Total DPC Time is a component of System: %Total Privileged Time because DPCs are executed in privileged mode. DPCs are counter separately and are not a component of the interrupt count.

Detail Level: Advanced
Counter Type: PERF_100NSEC_TIMER

% Total Interrupt Time

% Total Interrupt Time is the average percentage of time that all processors spent servicing interrupts. It is the sum of Processor: % Interrupt Time for of all processors on the computer, divided by the number of processors. DPCs are counted separately and are not a component of the interrupt count. This value is an indirect indicator of the activity of devices that generate interrupts, such as the system timer, the mouse, disk drivers, data communication lines, network interface cards and other peripheral devices.

Detail Level: Advanced
Counter Type: PERF_100NSEC_TIMER

Total DPCs Queued/sec

Total DPCs Queued/sec is the combined rate at which deferred procedure calls (DPC) are added to the DPC queue of all processors on the computer. (DPCs are interrupts that run at a lower priority than standard interrupts.) Each processor has its own DPC queue. This counter measures the rates at which DPCs are added to the queue, not the number of DPCs in the queue. It is the sum of Processor: DPCs Queued/sec for all processors on the computer, divided by the number of processors.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Total DPC Rate

Total DPC Rate is the combined rate at which deferred procedure calls (DPCs) are added to the DPC queues of all processors between timer tics of each processor's system clock. (DPCs are interrupts that run at a lower priority than standard interrupts.) Each processor has its own DPC queue. clock on the processor. This counter measures the rate at which DPCs are added to the queue, not the number of DPCs in the queue. It is the sum of Processor: DPC Rate for all processors on the computer, divided by the number of processors.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Total DPC Bypasses/sec

Total DPC Bypasses/sec is the combined rate at which deferred procedure calls (DPCs) on all processors were avoided. (DPCs are interrupts that run at a lower priority than standard interrupts.) . This value is the sum of Processor: DPC Bypasses/sec for all processors, divided by the number of processors.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Total APC Bypasses/sec

Total APC Bypasses/sec is the combined rate at which kernel asynchronous procedure call (APC) interrupts on all processors were avoided. This value is the sum of Processor: APC Bypasses/sec for all processors, divided by the number of processors.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

%Registry Quota In Use

% Registry Quota In Use is the percentage of the Total Registry Quota Allowed that is currently being used by the system.

Detail Level: Advanced
Counter Type: PERF_RAW_FRACTION

Registry Quota In Use

% Registry Quota In Use indicates the percentage of the Total Registry Quota Allowed currently in use by the system.

Detail Level: Advanced
Counter Type: PERF_RAW_BASE


TCP Object

The TCP performance object consists of counters that measure the rates at which TCP Segments are sent and received by using the TCP protocol. It includes counters that monitor the number of TCP connections in each TCP connection state.

Segments/sec

Segments/sec is the rate at which TCP segments are sent or received using the TCP protocol.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Connections Established

Connections Established is the number of TCP connections for which the current state is either ESTABLISHED or CLOSE-WAIT.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections Active

Connections Active is the number of times TCP connections have made a direct transition to the SYN-SENT state from the CLOSED state.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections Passive

Connections Passive is the number of times TCP connections have made a direct transition to the SYN-RCVD state from the LISTEN state.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connection Failures

Connection Failures is the number of times TCP connections have made a direct transition to the CLOSED state from the SYN-SENT state or the SYN-RCVD state, plus the number of times TCP connections have made a direct transition to the LISTEN state from the SYN-RCVD state.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Connections Reset

Connections Reset is the number of times TCP connections have made a direct transition to the CLOSED state from either the ESTABLISHED state or the CLOSE-WAIT state.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Segments Received/sec

Segments Received/sec is the rate at which segments are received, including those received in error. This count includes segments received on currently established connections.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Segments Sent/sec

Segments Sent/sec is the rate at which segments are sent, including those on current connections, but excluding those containing only retransmitted bytes.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Segments Retransmitted/sec

Segments Retransmitted/sec is the rate at which segments are retransmitted, that is, segments transmitted containing one or more previously transmitted bytes.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER


Thread Object

The Thread performance object consists of counters that measure aspects of thread behavior. A thread is the basic object that executes instructions on a processor. All running processes have at least one thread.

Processor Time

Processor Time is the percentage of elapsed time that this thread used the processor to execute instructions. An instruction is the basic unit of execution in a processor, and a thread is the object that executes instructions. Code executed to handle some hardware interrupts and trap conditions are included in this count.

Detail Level: Novice
Counter Type: PERF_100NSEC_TIMER

% User Time

User Time is the percentage of elapsed time that this thread has spent executing code in user mode. Applications, environment subsystems, and integral subsystems execute in user mode. Code executing in user mode cannot damage the integrity of the Windows NT Executive, Kernel, and device drivers. Unlike some early operating systems, Windows NT uses process boundaries for subsystem protection in addition to the traditional protection of user and privileged modes. These subsystem processes provide additional protection. Therefore, some work done by Windows NT on behalf of your application might appear in other subsystem processes in addition to the privileged time in your process.

Detail Level: Advanced
Counter Type: PERF_100NSEC_TIMER

% Privileged Time

Privileged Time is the percentage of elapsed time that this thread has spent executing code in privileged mode. When a Windows NT system service is called, the service will often run in privileged mode in order to gain access to system-private data. Such data is protected from access by threads executing in user mode. Calls to the system can be explicit or implicit, such as page faults or interrupts. Unlike some early operating systems, Windows NT uses process boundaries for subsystem protection in addition to the traditional protection of user and privileged modes. These subsystem processes provide additional protection. Therefore, some work done by Windows NT on behalf of your application might appear in other subsystem processes in addition to the privileged time in your process.

Detail Level: Advanced
Counter Type: PERF_100NSEC_TIMER

Context Switches/sec

Context Switches/sec is the rate of switches from one thread to another. Thread switches can occur either inside of a single process or across processes. A thread switch can be caused either by one thread asking another for information, or by a thread being preempted by another, higher priority thread becoming ready to run. Unlike some early operating systems, Windows NT uses process boundaries for subsystem protection in addition to the traditional protection of user and privileged modes. These subsystem processes provide additional protection. Therefore, some work done by Windows NT on behalf of an application might appear in other subsystem processes in addition to the privileged time in the application. Switching to the subsystem process causes one context switch in the application thread. Switching back causes another context switch in the subsystem thread.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Elapsed Time

The total elapsed time (in seconds) this thread has been running.

Detail Level: Advanced
Counter Type: PERF_ELAPSED_TIME

Priority Current

The current dynamic priority of this thread. The system can raise the thread's dynamic priority above the base priority if the thread is handling user input, or lower it towards the base priority if the thread becomes compute bound.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Priority Base

The current base priority of this thread. The system can raise the thread's dynamic priority above the base priority if the thread is handling user input, or lower it towards the base priority if the thread becomes compute bound.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Start Address

Starting virtual address for this thread.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Thread State

Thread State is the current state of the thread. It is 0 for Initialized, 1 for Ready, 2 for Running, 3 for Standby, 4 for Terminated, 5 for Wait, 6 for Transition, 7 for Unknown. A Running thread is using a processor; a Standby thread is about to use one. A Ready thread wants to use a processor, but is waiting for a processor because none are free. A thread in Transition is waiting for a resource in order to execute, such as waiting for its execution stack to be paged in from disk. A Waiting thread has no use for the processor because it is waiting for a peripheral operation to complete or a resource to become free.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

Thread Wait Reason

Thread Wait Reason is only applicable when the thread is in the Wait state (see Thread State.) It is 0 or 7 when the thread is waiting for the Executive, 1 or 8 for a Free Page, 2 or 9 for a Page In, 3 or 10 for a Pool Allocation, 4 or 11 for an Execution Delay, 5 or 12 for a Suspended condition, 6 or 13 for a User Request, 14 for an Event Pair High, 15 for an Event Pair Low, 16 for an LPC Receive, 17 for an LPC Reply, 18 for Virtual Memory, 19 for a Page Out; 20 and higher are not assigned at the time of this writing. Event Pairs are used to communicate with protected subsystems (see Context Switches.)

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

ID Process

ID Process is the unique identifier of this process. ID Process numbers are reused, so they only identify a process for the lifetime of that process.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT

ID Thread

ID Thread is the unique identifier of this thread. ID Thread numbers are reused, so they only identify a thread for the lifetime of that thread.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT


Thread Details Object

Thread Details performance object consists of counters that measure aspects of thread behavior that are difficult or time-consuming to collect. These counters are distinguished from those in the Thread performance object by their high overhead.

User PC

Current User Program Counter for this thread.

Detail Level: Wizard
Counter Type: PERF_COUNTER_RAWCOUNT


UDP Object

The UDP performance object consists of counters that measure the rates at which UDP datagrams are sent and received by using the UDP protocol. It includes counters that monitor UDP protocol errors.

Datagrams/sec

Datagrams/sec is the rate at which UDP datagrams are sent or received by the entity.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagrams Received/sec

Datagrams Received/sec is the rate at which UDP datagrams are delivered to UDP users.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagrams No Port/sec

Datagrams No Port/sec is the rate of received UDP datagrams for which there was no application at the destination port.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER

Datagrams Received Errors

Datagrams Received Errors is the number of received UDP datagrams that could not be delivered for reasons other than the lack of an application at the destination port.

Detail Level: Advanced
Counter Type: PERF_COUNTER_RAWCOUNT

Datagrams Sent/sec

Datagrams Sent/sec is the rate at which UDP datagrams are sent from the entity.

Detail Level: Advanced
Counter Type: PERF_COUNTER_COUNTER


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.