File Installation Library

The Win32 API includes a file installation library that makes it easier for applications to install files properly and enables setup programs to analyze files currently installed.


About File Installation

The functions included in the file installation library determine where a file should be installed, identify conflicts with currently installed files, and perform the installation process. These functions enable installation programs to avoid the following problems:

  • Installing older versions of components over newer versions
  • Changing the language in a mixed-language system without notification
  • Installing multiple copies of a library in different directories
  • Copying files to network directories shared by multiple users

The file installation library also includes functions that enable applications to query a version resource for file information and present the information in a clear format. This information includes the file's purpose, author, version number, and so on.

Version information can be added to any file that can have Windows resources, such as a dynamic-link library (DLL), an executable file, or a font file. To add the information, a developer must create a version resource and add the resource to the file by using a resource compiler and specifying VS_FILE_INFO as the resource type.


Creating an Installation Program

An installation program typically has the following goals:

  • To place files in the correct location.
  • To notify the user if the installation program is replacing an existing file with a version that is significantly different — for example, replacing a German-language file with an English-language file, or replacing a newer file with an older file.

When writing the installation program, the developer must have the following information for each file on the installation disk(s):

  • The name and location of the file (referred to as the source file).
  • The name of the equivalent file on the user's hard disk (referred to as the destination file). This name is usually the same as the filename on the installation disk.
  • The sharing status of the file — that is, whether the file is private to the application being installed or could be shared by multiple applications.

For each file on the installation disk(s), the installation program must, at a minimum, call the VerFindFile and VerInstallFile functions. These functions are described briefly in the following paragraphs.

The installation program can use VerFindFile with the destination-file name to determine where the file should be copied on the disk. This function can also be used to specify whether the file is private to the application or can be shared. If a problem occurs in finding the file, VerFindFile returns an error value. For example, if the system is using the destination file, VerFindFile returns VFF_FILEINUSE. The installation program must notify the user of the problem and respond to the user's decision to continue or to end the installation.

VerInstallFile copies the source file to a temporary file in the directory specified by VerFindFile. If necessary, VerInstallFile expands the file by using the functions in the data decompression library.

VerInstallFile compares the version information of the temporary file to that of the destination file. If the two differ, VerInstallFile returns one or more error values. For example, it returns VIF_SRCOLD if the temporary file is older than the destination file and VIF_DIFFLANG if the files have different language identifiers or code-page values. The installation program must notify the user of the problem and respond to the user's decision to continue or to end the installation.

Some VerInstallFile errors are recoverable. That is, the installation program can call VerInstallFile again, specifying the VIFF_FORCEINSTALL option, to install the file regardless of the version conflict. If VerInstallFile returns VIF_TEMPFILE and the user chooses not to force the installation, the installation program should delete the temporary file.

VerInstallFile could encounter a nonrecoverable error when attempting to force installation, even though the error did not exist previously. For example, the file could be locked by another user before the installation program attempted to force installation. If an installation program attempts to force installation after a non-recoverable error, VerInstallFile fails. The installation program must contain routines to recover from this type of error.

The recommended solution is to display for all errors a common dialog box with the buttons Install, Skip, and Install All. (Another solution is a dialog box with the buttons Yes, Yes to All, Skip, and Cancel.) The Install All button should prevent the installation program from prompting the user about similar errors by including the VIFF_FORCEINSTALL option in all subsequent uses of VerInstallFile. For nonrecoverable errors, the Install and Install All buttons should be disabled.

To display a useful error message to the user, the installation program usually must retrieve information from the version resources of the conflicting files. The file installation library provides four functions the installation program can use for this purpose: GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue, and VerLanguageName. GetFileVersionInfoSize returns the size of the version information. GetFileVersionInfo uses information retrieved by GetFileVersionInfoSize to retrieve a structure that contains the version information. VerQueryValue retrieves a specific member from that structure.

For example, if VerInstallFile returns the VIF_DIFFTYPE error, the installation program should use the GetFileVersionInfoSize, GetFileVersionInfo, and VerQueryValue functions on the temporary and destination files to obtain the general type of each file. If the languages of the files conflict, the installation program should also use VerLanguageName to translate the binary language identifier into a text representation of the language. (For example, 0x040C translates to the string "French.")

If VerInstallFile returns a file error, such as VIF_ACCESSVIOLATION, the installation program should use the GetLastError function to retrieve the most recent error value. The program should translate this value into an informative message to display to the user. The program must not yield control between the calls to VerInstallFile and GetLastError.


File Installation Library Reference

The following elements are used with file installation library.

  • File Installation Library Functions
  • File Installation Library Structures


File Installation Library Functions

The following functions are used for file installation.

GetFileVersionInfo
GetFileVersionInfoSize
VerFindFile
VerInstallFile
VerLanguageName
VerQueryValue


GetFileVersionInfo

The GetFileVersionInfo function returns version information about a specified file.

As with other file installation functions, GetFileVersionInfo works only with Win32 file images. It does not work with 16-bit Windows file images.

BOOL GetFileVersionInfo(
  LPTSTR lptstrFilename,  // pointer to filename string
  DWORD dwHandle,         // ignored
  DWORD dwLen,            // size of buffer
  LPVOID lpData           // pointer to buffer to receive
                          // file-version info.
);

Parameters

lptstrFilename
Pointer to a null-terminated filename string that specifies the file of interest.

Windows 95 and Windows 98: The short path form of the specified file name must be less than 126 characters.

dwHandle
This parameter is ignored.
dwLen
Specifies the size, in bytes, of the buffer pointed to by the lpData member.

Call the GetFileVersionInfoSize function first to determine the size, in bytes, of a file's version information. The dwLen member should be equal to or greater than that value.

If the buffer pointed to by lpData is not large enough, the function truncates the file's version information to the size of the buffer.

lpData
Pointer to a buffer to receive file-version information.

You can use this value in a subsequent call to the VerQueryValue function to retrieve data from the buffer.

The file version information is always in Unicode 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.

Remarks

Call the GetFileVersionInfoSize function before calling the GetFileVersionInfo function. The file-version information has the format indicated by the VS_VERSIONINFO structure.

QuickInfo

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

See Also

File Installation Library Overview, File Installation Library Functions, GetFileVersionInfoSize, VerQueryValue, VS_VERSIONINFO


GetFileVersionInfoSize

The GetFileVersionInfoSize function determines whether the operating system can obtain version information about a specified file. If version information is available, GetFileVersionInfoSize returns the size, in bytes, of that information.

As with other file installation functions, GetFileVersionInfoSize works only with Win32 file images. It does not work with 16-bit Windows file images.

DWORD GetFileVersionInfoSize(
  LPTSTR lptstrFilename,  // pointer to filename string
  LPDWORD lpdwHandle      // pointer to variable to receive zero
);

Parameters

lptstrFilename
Pointer to a null-terminated filename string that specifies the file of interest.

Windows 95 and Windows 98: The short path form of the specified file name must be less than 126 characters.

lpdwHandle
Pointer to a variable that the function sets to zero.

Return Values

If the function succeeds, the return value is the size, in bytes, of the file's version information.

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

Remarks

Call the GetFileVersionInfoSize function before calling the GetFileVersionInfo function. The size returned by GetFileVersionInfoSize indicates the buffer size required for the version information returned by GetFileVersionInfo.

QuickInfo

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

See Also

File Installation Library Overview, File Installation Library Functions, GetFileVersionInfo, VS_VERSIONINFO, VerQueryValue


VerFindFile

The VerFindFile function determines where to install a file based on whether it locates another version of the file in the system. The values VerFindFile returns in the specified buffers are used in a subsequent call to the VerInstallFile function.

As with the other file installation functions, VerFindFile works only with Win32 file images. It does not work with 16-bit Windows file images.

DWORD VerFindFile(
  DWORD dwFlags,      // bit flags that condition function behavior
  LPTSTR szFileName,  // file to be installed
  LPTSTR szWinDir,    // Windows directory
  LPTSTR szAppDir,    // directory where related files are being
                      // installed
  LPTSTR szCurDir,    // receives path of directory where file is
                      // currently installed
  PUINT lpuCurDirLen, // size of string in szCurDir
  LPTSTR szDestDir,   // receives path of recommended destination
                      // directory
  PUINT lpuDestDirLen
                      // size of string in szDestDir
);

Parameters

dwFlags
Contains a bitmask of flags. This parameter can be the following value:
Flag | Description
VFFF_ISSHAREDFILE | The source file can be shared by multiple applications. An application can use this information to determine where the file should be copied.

All other values are reserved.

szFileName
Pointer to the name of the file to be installed. The filename can include only the filename and extension, not a path.
szWinDir
Pointer to the directory in which Windows is running or will be run. This string is returned by the GetWindowsDirectory function.
szAppDir
Pointer to the directory where the installation program is installing a set of related files. If the installation program is installing an application, this is the directory where the application will reside. This parameter also points to the application's current directory unless otherwise specified.
szCurDir
Pointer to a buffer that receives the path to a current version of the file being installed. The path is a zero-terminated string. If a current version is not installed, the buffer will contain a zero-length string. The buffer should be at least _MAX_PATH characters long, although this is not required.
lpuCurDirLen
Pointer to a variable that contains the length of the szCurDir buffer. This pointer must not be NULL.

When the function returns, lpuCurDirLen contains the size, in characters, of the data returned in szCurDir, including the terminating null character. If the buffer is too small to contain all the data, lpuCurDirLen will be the size of the buffer required to hold the path.

szDestDir
Pointer to a buffer that receives the path to the installation location recommended by VerFindFile. The path is a zero-terminated string. The buffer should be at least _MAX_PATH characters long, although this is not required.
lpuDestDirLen
Pointer to a variable that contains the length of the szDestDir buffer. This pointer must not be NULL.

When the function returns, lpuDestDirLen contains the size, in characters, of the data returned in szDestDir, including the terminating null character. If the buffer is too small to contain all the data, lpuDestDirLen will be the size of the buffer needed to hold the path.

Return Values

The return value is a bitmask that indicates the status of the file. It can be one or more of the following values:

Value | Meaning
VFF_CURNEDEST | The currently installed version of the file is not in the recommended destination.
VFF_FILEINUSE | The system is using the currently installed version of the file; therefore, the file cannot be overwritten or deleted.
VFF_BUFFTOOSMALL | At least one of the buffers was too small to contain the corresponding string. An application should check the output buffers to determine which buffer was too small.

All other values are reserved.

Remarks

VerFindFile searches for a copy of the specified file by using the OpenFile function. However, it determines the system directory from the specified Windows directory, or searches the path.

If the dwFlags parameter indicates that the file is private to this application (not VFFF_ISSHAREDFILE), VerFindFile recommends installing the file in the application's directory. Otherwise, if the system is running a shared copy of the system, the function recommends installing the file in the Windows directory. If the system is running a private copy of the system, the function recommends installing the file in the system directory.

QuickInfo

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

See Also

File Installation Library Overview, File Installation Library Functions, GetWindowsDirectory, OpenFile, VerInstallFile


VerInstallFile

The VerInstallFile function attempts to install the specified file based on information returned from the VerFindFile function. VerInstallFile decompresses the file, if necessary, assigns a unique filename, and checks for errors, such as outdated files.

As with the other file installation functions, VerInstallFile works only with Win32 file images. It does not work with 16-bit Windows file images.

DWORD VerInstallFile(
  DWORD uFlags,          // bit flags that condition function
                         // behavior
  LPTSTR szSrcFileName,  // file to install
  LPTSTR szDestFileName, // new name of file to install
  LPTSTR szSrcDir,       // source directory of file to install
  LPTSTR szDestDir,      // directory in which to install file
  LPTSTR szCurDir,       // directory where file is currently
                         // installed
  LPTSTR szTmpFile,      // receives name of temporary copy of file
                         // used during installation
  PUINT lpuTmpFileLen    // size of string in szTmpFile
);

Parameters

uFlags
Contains a bitmask of flags. This parameter can be one of the following values:
Flag | Description
VIFF_FORCEINSTALL | Installs the file regardless of mismatched version numbers. The function checks only for physical errors during installation.
VIFF_DONTDELETEOLD | Installs the file without deleting the previously installed file, if the previously installed file is not in the destination directory.

All other values are reserved.

szSrcFileName
Pointer to the name of the file to be installed. This is the filename in the directory pointed to by the szSrcDir parameter; the filename can include only the filename and extension, not a path.
szDestFileName
Pointer to the name VerInstallFile will give the new file upon installation. This filename may be different from the filename in the szSrcFileName directory. The new name should include only the filename and extension, not a path.
szSrcDir
Pointer to a buffer that contains the name of the directory where the new file is found.
szDestDir
Pointer to a buffer that contains the name of the directory where the new file should be installed. VerFindFile returns this value in its szDestDir parameter.
szCurDir
Pointer to a buffer that contains the name of the directory where the preexisting version of this file is found. VerFindFile returns this value in its szCurDir parameter.
szTmpFile
Pointer to a buffer that should be empty upon the initial call to VerInstallFile. The function fills the buffer with the name of a temporary copy of the source file. The buffer should be at least _MAX_PATH characters long, although this is not required.
lpuTmpFileLen
Pointer to a variable that contains the length of the szTmpFile buffer. This pointer must not be NULL.

When the function returns, lpuTmpFileLen contains the size, in characters, of the data returned in szTmpFile, including the terminating null character. If the buffer is too small to contain all the data, lpuTmpFileLen will be the size of the buffer required to hold the data.

Return Values

The return value is a bitmask that indicates exceptions. It can be one or more of the following values:

Value | Meaning
VIF_TEMPFILE | The temporary copy of the new file is in the destination directory. The cause of failure is reflected in other flags.
VIF_MISMATCH | The new and preexisting files differ in one or more attributes. This error can be overridden by calling VerInstallFile again with the VIFF_FORCEINSTALL flag set.
VIF_SRCOLD | The file to install is older than the preexisting file. This error can be overridden by calling VerInstallFile again with the VIFF_FORCEINSTALL flag set.
VIF_DIFFLANG | The new and preexisting files have different language or code-page values. This error can be overridden by calling VerInstallFile again with the VIFF_FORCEINSTALL flag set.
VIF_DIFFCODEPG | The new file requires a code page that cannot be displayed by the version of the system currently running. This error can be overridden by calling VerInstallFile with the VIFF_FORCEINSTALL flag set.
VIF_DIFFTYPE | The new file has a different type, subtype, or operating system from the preexisting file. This error can be overridden by calling VerInstallFile again with the VIFF_FORCEINSTALL flag set.
VIF_WRITEPROT | The preexisting file is write-protected. This error can be overridden by calling VerInstallFile again with the VIFF_FORCEINSTALL flag set.
VIF_FILEINUSE | The preexisting file is in use by the system and cannot be deleted.
VIF_OUTOFSPACE | The function cannot create the temporary file due to insufficient disk space on the destination drive.
VIF_ACCESSVIOLATION | A read, create, delete, or rename operation failed due to an access violation.
VIF_SHARINGVIOLATION | A read, create, delete, or rename operation failed due to a sharing violation.
VIF_CANNOTCREATE | The function cannot create the temporary file. The specific error may be described by another flag.
VIF_CANNOTDELETE | The function cannot delete the destination file, or cannot delete the existing version of the file located in another directory. If the VIF_TEMPFILE bit is set, the installation failed, and the destination file probably cannot be deleted.
VIF_CANNOTDELETECUR | The existing version of the file could not be deleted and VIFF_DONTDELETEOLD was not specified.
VIF_CANNOTRENAME | The function cannot rename the temporary file, but already deleted the destination file.
VIF_OUTOFMEMORY | The function cannot complete the requested operation due to insufficient memory. Generally, this means the application ran out of memory attempting to expand a compressed file.
VIF_CANNOTREADSRC | The function cannot read the source file. This could mean that the path was not specified properly.
VIF_CANNOTREADDST | The function cannot read the destination (existing) files. This prevents the function from examining the file's attributes.
VIF_BUFFTOOSMALL | The szTmpFile buffer was too small to contain the name of the temporary source file. When the function returns, lpuTmpFileLen contains the size of the buffer required to hold the filename.

All other values are reserved.

Remarks

VerInstallFile copies the file from the source directory to the destination directory. If szCurDir indicates that a previous version of the file exists on the system, VerInstallFile compares the files' version stamp information. If the previously installed version of the file is more recent than the new version, or if the files' attributes are significantly different, for example, if they are in different languages, then VerInstallFile returns with one or more recoverable error codes.

VerInstallFile leaves the temporary file in the destination directory. The application can either override the error or delete the temporary file. If the application overrides the error, VerInstallFile deletes the previously installed version and renames the temporary file with the original filename.

QuickInfo

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

See Also

File Installation Library Overview, File Installation Library Functions, VerFindFile


VerLanguageName

The VerLanguageName function retrieves a description string for the language associated with a specified binary Microsoft language identifier.

DWORD VerLanguageName(
  DWORD wLang,    // Microsoft language identifier
  LPTSTR szLang,  // pointer to buffer for language description
                  // string
  DWORD nSize     // size of buffer
);

Parameters

wLang
Specifies the binary Microsoft language identifier. For a complete list of the language identifiers supported by Win32, see Language Identifiers.

For example, the description string associated with the language identifier 0x040A is "Spanish (Traditional Sort)". If the identifier is unknown, the szLang parameter points to a default string ("Language Neutral").

szLang
Pointer to the buffer to receive the null-terminated string representing the language specified by the wLang parameter.
nSize
Indicates the size of the buffer, in characters, pointed to by szLang.

Return Values

If the return value is less than or equal to the buffer size, the return value is the size, in characters, of the string returned in the buffer. This value does not include the terminating null character.

If the return value is greater than the buffer size, the return value is the size of the buffer required to hold the entire string. The string is truncated to the length of the existing buffer.

If an error occurs, the return value is zero. Unknown language identifiers do not produce errors.

Remarks

Typically, an installation program uses this function to translate a language identifier returned by the VerQueryValue function. The text string may be used in a dialog box that asks the user how to proceed in the event of a language conflict.

QuickInfo

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

See Also

File Installation Library Overview, File Installation Library Functions, VerQueryValue


VerQueryValue

The VerQueryValue function returns selected version information from the specified version-information resource. To retrieve the appropriate resource, before you call VerQueryValue, you must first call the GetFileVersionInfoSize function, and then the GetFileVersionInfo function.

As with the other file installation functions, VerQueryValue works only with Win32 file images. It does not work with 16-bit Windows file images.

BOOL VerQueryValue(
  const LPVOID pBlock, // address of buffer for version resource
  LPTSTR lpSubBlock,   // address of value to retrieve
  LPVOID *lplpBuffer,  // address of buffer for version value pointer
  PUINT puLen          // address of length buffer
);

Parameters

pBlock
Pointer to the buffer containing the version-information resource returned by the GetFileVersionInfo function.
lpSubBlock
Pointer to a zero-terminated string specifying which version-information value to retrieve. The string must consist of names separated by backslashes (\) and it must have one of the following forms:
Form | Description
\ Specifies the root block. The function retrieves a pointer to the VS_FIXEDFILEINFO structure for the version-information resource.
\VarFileInfo\Translation | Specifies the translation array in a Var variable information structure. The function retrieves a pointer to an array of language and code page identifiers. An application can use these identifiers to access a language-specific StringTable structure in the version-information resource.
\StringFileInfo\lang-codepage\string-name | Specifies a value in a language-specific StringTable structure. The lang-codepage name is a concatenation of a language and code page identifier pair found as a DWORD in the translation array for the resource. Here the lang-codepage name must be specified as a hexadecimal string. The string-name name must be one of the predefined strings described in the following Remarks section. The function retrieves a string value specific to the language and code page indicated.

lplpBuffer
Pointer to a variable that receives a pointer to the requested version information in the buffer pointed to by pBlock. The memory pointed to by *lplpBuffer is freed when the associated pBlock memory is freed.
puLen
Pointer to a buffer that receives the length, in characters, of the version-information value.

Return Values

If the specified version-information structure exists, and version information is available, the return value is nonzero. If the address of the length buffer is zero, no value is available for the specified version-information name.

If the specified name does not exist or the specified resource is not valid, the return value is zero.

Remarks

The Win32 API contains the following predefined version information Unicode strings:

CompanyName FileDescription FileVersion InternalName LegalCopyright OriginalFilename ProductName ProductVersion Comments LegalTrademarks PrivateBuild SpecialBuild

The following example shows how to retrieve the FileDescription string-value from a block of version information, if the language is U.S. English and the code page is Windows Multilingual:

VerQueryValue(pBlock,
              TEXT("\\StringFileInfo\\040904E4\\FileDescription"),
              &lpBuffer,
              &dwBytes);

Call the GetFileVersionInfoSize and GetFileVersionInfo functions before calling the VerQueryValue function to properly initialize the pBlock buffer.

QuickInfo

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

See Also

File Installation Library Overview, File Installation Library Functions, GetFileVersionInfo, VarFileInfo, Var, StringFileInfo, StringTable, String, GetFileVersionInfoSize, VS_FIXEDFILEINFO, VS_VERSIONINFO


File Installation Library Structures

The following structures are used for file installation.

String
StringFileInfo
StringTable
Var
VarFileInfo
VS_FIXEDFILEINFO
VS_VERSIONINFO


String

The String structure depicts the organization of data in a file-version resource. This structure is not a true C-language structure because it contains variable-length members. This structure was created solely to depict the organization of data in a version resource and does not appear in any of the header files shipped with the Microsoft® Platform Software Development Kit (SDK).

The String structure contains a string that describes a specific aspect of a file, for example, a file's version, its copyright notices, or its trademarks.

String {
    WORD   wLength;
    WORD   wValueLength;
    WORD   wType;
    WCHAR  szKey[];
    WORD   Padding[];
    WORD   Value[];
} String;

Members

wLength
Specifies the length, in bytes, of this String structure.
wValueLength
Specifies the size, in words, of the Value member.
wType
Specifies the type of data in the version resource. This member is 1 if the version resource contains text data and 0 if the version resource contains binary data.
szKey
Specifies an arbitrary Unicode string. The szKey member can be one or more of the following values. These values are guidelines only.
String | Meaning
Comments | The Value member contains any additional information that should be displayed for diagnostic purposes. This string can be an arbitrary length.
CompanyName | The Value member identifies the company that produced the file. For example, "Microsoft Corporation" or "Standard Microsystems Corporation, Inc."
FileDescription | The Value member describes the file in such a way that it can be presented to users. This string may be presented in a list box when the user is choosing files to install. For example, "Keyboard driver for AT-style keyboards" or "Microsoft Word for Windows".
FileVersion | The Value member identifies the version of this file. For example, Value could be "3.00A" or "5.00.RC2".
InternalName | The Value member identifies the file's internal name, if one exists. For example, this string could contain the module name for a dynamic-link library (DLL), a virtual device name for a Windows virtual device, or a device name for an MS-DOS device driver.
LegalCopyright | The Value member describes all copyright notices, trademarks, and registered trademarks that apply to the file. This should include the full text of all notices, legal symbols, copyright dates, trademark numbers, and so on. In English, this string should be in the format "Copyright Microsoft Corp. 1990–1994".
LegalTrademarks | The Value member describes all trademarks and registered trademarks that apply to the file. This should include the full text of all notices, legal symbols, trademark numbers, and so on. In English, this string should be in the format "Windows is a trademark of Microsoft Corporation".
OriginalFilename | The Value member identifies the original name of the file, not including a path. This enables an application to determine whether a file has been renamed by a user. This name may not be MS-DOS 8.3-format if the file is specific to a non-FAT file system.
PrivateBuild | The Value member describes by whom, where, and why this private version of the file was built. This string should only be present if the VS_FF_PRIVATEBUILD flag is set in the dwFileFlags member of the VS_FIXEDFILEINFO structure. For example, Value could be "Built by OSCAR on \OSCAR2".
ProductName | The Value member identifies the name of the product with which this file is distributed. For example, this string could be "Microsoft Windows".
ProductVersion | The Value member identifies the version of the product with which this file is distributed. For example, Value could be "3.00A" or "5.00.RC2".
SpecialBuild | The Value member describes how this version of the file differs from the normal version. This entry should only be present if the VS_FF_SPECIALBUILD flag is set in the dwFileFlags member of the VS_FIXEDFILEINFO structure. For example, Value could be "Private build for Olivetti solving mouse problems on M250 and M250E computers".

Padding
Contains as many zero words as necessary to align the Value member on a 32-bit boundary.
Value
Specifies a zero-terminated string. See the szKey member description for more information.

Remarks

A String structure may have an szKey value of, for example, "CompanyName" and a Value of "Microsoft Corporation". Another String structure with the same szKey value could contain a Value of "Microsoft GmbH". This might occur if the second String structure were associated with a StringTable structure whose szKey value is 040704b0 — that is, German/Unicode.

QuickInfo

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

See Also

File Installation Library Overview, File Installation Library Structures, StringTable, VS_FIXEDFILEINFO, StringFileInfo, VS_VERSIONINFO


StringFileInfo

The StringFileInfo structure depicts the organization of data in a file-version resource. This structure is not a true C-language structure because it contains variable-length members. This structure was created solely to depict the organization of data in a version resource and does not appear in any of the header files shipped with the Microsoft Platform Software Development Kit (SDK).

The StringFileInfo structure contains version information that can be displayed for a particular language and code page.

StringFileInfo {
    WORD        wLength;
    WORD        wValueLength;
    WORD        wType;
    WCHAR       szKey[];
    WORD        Padding[];
    StringTable Children[];
};

Members

wLength
Specifies the length, in bytes, of the entire StringFileInfo block, including all structures indicated by the Children member.
wValueLength
This member is always equal to zero.
wType
Specifies the type of data in the version resource. This member is 1 if the version resource contains text data and 0 if the version resource contains binary data.
szKey
Contains the Unicode string "StringFileInfo".
Padding
Contains as many zero words as necessary to align the Children member on a 32-bit boundary.
Children
Contains an array of one or more StringTable structures. Each StringTable structure's szKey member indicates the appropriate language and code page for displaying the text in that StringTable structure.

Remarks

The Children member of the VS_VERSIONINFO structure may contain zero or more StringFileInfo structures.

QuickInfo

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

See Also

File Installation Library Overview, File Installation Library Structures, StringTable, String, VS_VERSIONINFO


StringTable

The StringTable structure depicts the organization of data in a file-version resource. This structure is not a true C-language structure because it contains variable-length members. This structure was created solely to depict the organization of data in a version resource and does not appear in any of the header files shipped with the Microsoft Platform Software Development Kit (SDK).

The StringTable structure contains language and code page formatting information for the strings specified by the Children member. A code page is an ordered character set.

StringTable {
    WORD   wLength;
    WORD   wValueLength;
    WORD   wType;
    WCHAR  szKey[];
    WORD   Padding[];
    String Children[];
};

Members

wLength
Specifies the length, in bytes, of this StringTable structure, including all structures indicated by the Children member.
wValueLength
This member is always equal to zero.
wType
Specifies the type of data in the version resource. This member is 1 if the version resource contains text data and 0 if the version resource contains binary data.
szKey
Specifies an 8-digit hexadecimal number stored as a Unicode string. The four most significant digits represent the language identifier. The four least significant digits represent the code page for which the data is formatted.

Each Microsoft Standard Language identifier contains two parts: the low-order 10 bits specify the major language, and the high-order 6 bits specify the sublanguage. For a table of valid identifiers see Language Identifiers.

Padding
Contains as many zero words as necessary to align the Children member on a 32-bit boundary.
Children
Specifies an array of one or more String structures.

Remarks

The Children member of the StringFileInfo structure contains at least one StringTable structure.

Set the code page portion of the szKey member to the hexadecimal value 0x04b0 to indicate the Unicode code page, or to the hexadecimal value of the code page that is appropriate for the language component. After you choose the value for the code page you should continue to use the same value in later revisions to the file.

An executable file or dynamic-link library (DLL) that supports multiple languages should have a version resource for each language, rather than a single version resource that contains strings in several languages. However, if you use the Var structure to list the languages that your application supports, the number of StringTable structures in the version resource is directly related to the number of language/code page identifier pairs in the Value member of the Var structure.

QuickInfo

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

See Also

File Installation Library Overview, File Installation Library Structures, String, StringFileInfo, Var, VarFileInfo, VS_VERSIONINFO


Var

The Var structure depicts the organization of data in a file-version resource. This structure is not a true C-language structure because it contains variable-length members. This structure was created solely to depict the organization of data in a version resource and does not appear in any of the header files shipped with the Microsoft Platform Software Development Kit (SDK).

The Var structure typically contains a list of language and code page identifier pairs that the version of the application or dynamic-link library (DLL) supports.

Var {
    WORD  wLength;
    WORD  wValueLength;
    WORD  wType;
    WCHAR szKey[];
    WORD  Padding[];
    DWORD Value[];
};

Members

wLength
Specifies the length, in bytes, of the Var structure.
wValueLength
Specifies the length, in bytes, of the Value member.
wType
Specifies the type of data in the version resource. This member is 1 if the version resource contains text data and 0 if the version resource contains binary data.
szKey
Contains the Unicode string "Translation".
Padding
Contains as many zero words as necessary to align the Value member on a 32-bit boundary.
Value
Specifies an array of one or more values that are language and code page identifier pairs. For additional information, see the following Remarks section.

Remarks

If you use the Var structure to list the languages your application or DLL supports instead of using multiple version resources, use the Value member to contain an array of DWORD values indicating the language and code page combinations supported by this file. The low-order word of each DWORD must contain a Microsoft language identifier, and the high-order word must contain the IBM® code page number. Either high-order or low-order word can be zero, indicating that the file is language or code page independent. If the Var structure is omitted, the file will be interpreted as both language and code page independent.

QuickInfo

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

See Also

File Installation Library Overview, File Installation Library Structures, VarFileInfo, StringFileInfo, StringTable, VS_VERSIONINFO


VarFileInfo

The VarFileInfo structure depicts the organization of data in a file-version resource. This structure is not a true C-language structure because it contains variable-length members. This structure was created solely to depict the organization of data in a version resource and does not appear in any of the header files shipped with the Microsoft Platform Software Development Kit (SDK).

The VarFileInfo structure contains version information not dependent on a particular language and code page combination.

VarFileInfo {
    WORD  wLength;
    WORD  wValueLength;
    WORD  wType;
    WCHAR szKey[];
    WORD  Padding[];
    Var   Children[];
};

Members

wLength
Specifies the length, in bytes, of the entire VarFileInfo block, including all structures indicated by the Children member.
wValueLength
This member is always equal to zero.
wType
Specifies the type of data in the version resource. This member is 1 if the version resource contains text data and 0 if the version resource contains binary data.
szKey
Contains the Unicode string "VarFileInfo".
Padding
Contains as many zero words as necessary to align the Children member on a 32-bit boundary.
Children
Specifies a Var structure that typically contains a list of languages that the application or DLL supports.

Remarks

The Children member of the VS_VERSIONINFO structure may contain zero or one VarFileInfo structures.

QuickInfo

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

See Also

File Installation Library Overview, File Installation Library Structures, Var, VS_VERSIONINFO


VS_FIXEDFILEINFO

The VS_FIXEDFILEINFO structure contains version information about a file. This information is language and code page independent.

typedef struct _VS_FIXEDFILEINFO {  // vsffi
    DWORD dwSignature;
    DWORD dwStrucVersion;
    DWORD dwFileVersionMS;
    DWORD dwFileVersionLS;
    DWORD dwProductVersionMS;
    DWORD dwProductVersionLS;
    DWORD dwFileFlagsMask;
    DWORD dwFileFlags;
    DWORD dwFileOS;
    DWORD dwFileType;
    DWORD dwFileSubtype;
    DWORD dwFileDateMS;
    DWORD dwFileDateLS;
} VS_FIXEDFILEINFO;

Members

dwSignature
Contains the value 0xFEEFO4BD. This is used with the szKey member of the VS_VERSIONINFO structure when searching a file for the VS_FIXEDFILEINFO structure.
dwStrucVersion
Specifies the binary version number of this structure. The high-order word of this member contains the major version number, and the low-order word contains the minor version number.
dwFileVersionMS
Specifies the most significant 32 bits of the file's binary version number. This member is used with dwFileVersionLS to form a 64-bit value used for numeric comparisons.
dwFileVersionLS
Specifies the least significant 32 bits of the file's binary version number. This member is used with dwFileVersionMS to form a 64-bit value used for numeric comparisons.
dwProductVersionMS
Specifies the most significant 32 bits of the binary version number of the product with which this file was distributed. This member is used with dwProductVersionLS to form a 64-bit value used for numeric comparisons.
dwProductVersionLS
Specifies the least significant 32 bits of the binary version number of the product with which this file was distributed. This member is used with dwProductVersionMS to form a 64-bit value used for numeric comparisons.
dwFileFlagsMask
Contains a bitmask that specifies the valid bits in dwFileFlags. A bit is valid only if it was defined when the file was created.
dwFileFlags
Contains a bitmask that specifies the Boolean attributes of the file. This member can include one or more of the following values:
Flag | Description
VS_FF_DEBUG | The file contains debugging information or is compiled with debugging features enabled.
VS_FF_INFOINFERRED | The file's version structure was created dynamically; therefore, some of the members in this structure may be empty or incorrect. This flag should never be set in a file's VS_VERSIONINFO data.
VS_FF_PATCHED | The file has been modified and is not identical to the original shipping file of the same version number.
VS_FF_PRERELEASE | The file is a development version, not a commercially released product.
VS_FF_PRIVATEBUILD | The file was not built using standard release procedures. If this flag is set, the StringFileInfo structure should contain a PrivateBuild entry.
VS_FF_SPECIALBUILD | The file was built by the original company using standard release procedures but is a variation of the normal file of the same version number. If this flag is set, the StringFileInfo structure should contain a SpecialBuild entry.

dwFileOS
Specifies the operating system for which this file was designed. This member can be one of the following values:
Flag | Description
VOS_DOS | The file was designed for MS-DOS.
VOS_NT | The file was designed for Windows NT.
VOS__WINDOWS16 | The file was designed for 16-bit Windows.
VOS__WINDOWS32 | The file was designed for the Win32 API.
VOS_OS216 | The file was designed for 16-bit OS/2.
VOS_OS232 | The file was designed for 32-bit OS/2.
VOS__PM16 | The file was designed for 16-bit Presentation Manager.
VOS__PM32 | The file was designed for 32-bit Presentation Manager.
VOS_UNKNOWN | The operating system for which the file was designed is unknown to the system.

An application can combine these values to indicate that the file was designed for one operating system running on another. The following dwFileOS values are examples of this, but are not a complete list:
Flag | Description
VOS_DOS_WINDOWS16 | The file was designed for 16-bit Windows running on MS-DOS.
VOS_DOS_WINDOWS32 | The file was designed for the Win32 API running on MS-DOS.
VOS_NT_WINDOWS32 | The file was designed for the Win32 API running on Windows NT.
VOS_OS216_PM16 | The file was designed for 16-bit Presentation Manager running on 16-bit OS/2.
VOS_OS232_PM32 | The file was designed for 32-bit Presentation Manager running on 32-bit OS/2.

dwFileType
Specifies the general type of file. This member can be one of the following values:
Flag | Description
VFT_UNKNOWN | The file type is unknown to the system.
VFT_APP | The file contains an application.
VFT_DLL | The file contains a dynamic-link library (DLL).
VFT_DRV | The file contains a device driver. If dwFileType is VFT_DRV, dwFileSubtype contains a more specific description of the driver.
VFT_FONT | The file contains a font. If dwFileType is VFT_FONT, dwFileSubtype contains a more specific description of the font file.
VFT_VXD | The file contains a virtual device.
VFT_STATIC_LIB | The file contains a static-link library.

All other values are reserved for future use by Microsoft.

dwFileSubtype
Specifies the function of the file. The possible values depend on the value of dwFileType. For all values of dwFileType not described in the following list, dwFileSubtype is zero.

If dwFileType is VFT_DRV, dwFileSubtype can be one of the following values:
Flag | Description
VFT2_UNKNOWN | The driver type is unknown by the system.
VFT2_DRV_COMM | The file contains a communications driver.
VFT2_DRV_PRINTER | The file contains a printer driver.
VFT2_DRV_KEYBOARD | The file contains a keyboard driver.
VFT2_DRV_LANGUAGE | The file contains a language driver.
VFT2_DRV_DISPLAY | The file contains a display driver.
VFT2_DRV_MOUSE | The file contains a mouse driver.
VFT2_DRV_NETWORK | The file contains a network driver.
VFT2_DRV_SYSTEM | The file contains a system driver.
VFT2_DRV_INSTALLABLE | The file contains an installable driver.
VFT2_DRV_SOUND | The file contains a sound driver.

If dwFileType is VFT_FONT, dwFileSubtype can be one of the following values:
Flag | Description
VFT2_UNKNOWN | The font type is unknown by the system.
VFT2_FONT_RASTER | The file contains a raster font.
VFT2_FONT_VECTOR | The file contains a vector font.
VFT2_FONT_TRUETYPE | The file contains a TrueType font.

If dwFileType is VFT_VXD, dwFileSubtype contains the virtual device identifier included in the virtual device control block.

All dwFileSubtype values not listed here are reserved for future use by Microsoft.

dwFileDateMS
Specifies the most significant 32 bits of the file's 64-bit binary creation date and time stamp.
dwFileDateLS
Specifies the least significant 32 bits of the file's 64-bit binary creation date and time stamp.

Remarks

The Value member of the VS_VERSIONINFO structure is a VS_FIXEDFILEINFO structure.

QuickInfo

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

See Also

File Installation Library Overview, File Installation Library Structures, StringFileInfo, String, VS_VERSIONINFO


VS_VERSIONINFO

The VS_VERSIONINFO structure depicts the organization of data in a file-version resource. This structure is not a true C-language structure because it contains variable-length members. This structure was created solely to depict the organization of data in a version resource and does not appear in any of the header files shipped with the Microsoft Platform Software Development Kit (SDK).

The VS_VERSIONINFO structure is the root structure that contains all other file-version information structures.

VS_VERSIONINFO {
    WORD  wLength;
    WORD  wValueLength;
    WORD  wType;
    WCHAR szKey[];
    WORD  Padding1[];
    VS_FIXEDFILEINFO Value;
    WORD  Padding2[];
    WORD  Children[];
};

Members

wLength
Specifies the length, in bytes, of the VS_VERSIONINFO structure. This length does not include any padding that aligns any subsequent version resource data on a 32-bit boundary.
wValueLength
Specifies the length, in bytes, of the Value member. This value is zero if there is no Value member associated with the current version structure.
wType
Specifies the type of data in the version resource. This member is 1 if the version resource contains text data and 0 if the version resource contains binary data.
szKey
Contains the Unicode string "VS_VERSION_INFO".
Padding1
Contains as many zero words as necessary to align the Value member on a 32-bit boundary.
Value
Contains a VS_FIXEDFILEINFO structure that specifies arbitrary data associated with this VS_VERSIONINFO structure. The wValueLength member specifies the length of this member; if wValueLength is zero, this member does not exist.
Padding2
Contains as many zero words as necessary to align the Children member on a 32-bit boundary. These bytes are not included in wValueLength. This member is optional.
Children
Specifies an array of zero or one StringFileInfo structures, and zero or one VarFileInfo structures that are children of the current VS_VERSIONINFO structure.

QuickInfo

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

See Also

File Installation Library Overview, File Installation Library Structures, StringFileInfo, VerQueryValue, VarFileInfo, VS_FIXEDFILEINFO


License Service Application Programming Interface

Software metering and license-tracking technology are available to Windows applications running on Microsoft® Windows® 95 and Windows NT® if they make calls to the License Service Application Programming Interface (LSAPI) version 1.10, a standard set of seven functions that provides licensing services. The LSAPI has been jointly developed with the cooperation, input, and support from a number of companies and associations.


About the LSAPI

License systems provide a management layer that can track the rights to use purchased software. You can incorporate license verification in your product by using the License Service Application Programming Interface (LSAPI) version 1.10, a set of functions that provides licensing services within applications. The LSAPI specification provides a standard interface between LSAPI-enabled software and LSAPI-compliant software licensing products. An LSAPI-enabled application is one that uses calls to the LSAPI function layer to register license usage. An LSAPI-compliant licensing system is one that conforms to the LSAPI standard. Applications can gain access to the LSAPI interface through the dynamic-link library, LSAPI32.DLL.

The LSAPI-compliant model includes the following basic components:

  • An LSAPI-enabled desktop application
  • The standard LSAPI function layer
  • An LSAPI-compliant license product that includes a database for storing license data, and access "tokens" that serve as digital license certificates

The standard LSAPI functions are listed following.

Function | Description
LSEnumProviders | Returns a unique string for each installed license system service provider.
LSFreeHandle | Frees the handle to the license context.
LSGetMessage | Returns the message string associated with a license service function status code.
LSQuery | Returns information about the service provider or the license system context associated with the specified handle obtained by the LSRequest call.
LSRelease | Requests that the license system release the licensing resources associated with a specific license context.
LSRequest | Requests that the license system grant the licensing resources so the calling application can execute.
LSUpdate | Updates the synchronization between the licensed application and the license system.

The LSAPI standardizes access to, and use of, the primary features common to many licensing products. These include the ability to request that the licensing system grant the application software rights to run, release those rights when they are no longer needed, and update the state of the licensing resources granted to the software product.

The LSAPI also provides a standard software development approach to software license management. Because all LSAPI-compliant license service providers support the same API, applications can use one interface to communicate with all LSAPI-compliant license servers. Developers can isolate code from license policy; the policy can be handled by the licensing system rather than by the application. The LSAPI allows you to develop a single package that cooperates with multiple licensing systems. You only need to change existing product code once to incorporate the licensing functions; the platform and the networking environment can change, but you do not need to rewrite the desktop application. This provides license system independence, and multiple license providers can be used at one time.

LSAPI-enabled Windows applications running on Windows 95 and Windows NT will also interface with other LSAPI-compliant license servers, without modifications.


License System Security

It is not possible to guarantee complete protection against the unauthorized use of software. A licensed application is only as secure as the steps the software publisher takes to prevent code modifications that could result in bypassing license requirements. However, if you incorporate the License Service Application Programming Interface (LSAPI) functions in your application, you can deter license system tampering and reveal when tampering occurs. The measure of security the LSAPI functions provide is not tamperproof, but intruders must use an overt act of programming to compromise it.

Much of the security provided by the LSAPI functions is accomplished by including a challenge/response protocol in the calls to the LSAPI functions. The purpose of the protocol is to ensure that a valid license is present. It provides a reasonably reliable way for both the license system and the application to verify that the other has an identical secret value. Applications can use the protocol to authenticate both the license and the path from the application to the license.

The LSAPI functions use the MD4 Message-Digest Algorithm from RSA Data Security, Inc., to meet basic LSAPI security goals. This algorithm does not require patented cryptographic techniques. Knowledge of the algorithm neither compromises the secrets the application passes through it, nor the level of security the LSAPI offers. If you use a more complex challenge/response algorithm, it may not raise the level of security, and if you use a more sophisticated challenge/response protocol, all license systems may not support it. Maintaining the privacy of the shared secret values, however, is essential to the reliability of the LSAPI security protocol.


Challenge/Response Protocols

The LSAPI functions support multiple challenge/response protocols for license authentication. Every challenge/response protocol has an assigned 32-bit protocol identifier. Protocols in the range of zero through 0x0000FFFF, and 0xFFFFFFFF, are reserved for LSAPI. LSAPI tags the application challenge with the protocol identifier, and the license system tags the response with the protocol that answers the challenge.

Because the LSAPI standard provides for multiple challenge/response protocols, it requires a tag field that identifies the protocol the application uses. LSAPI defines a standard basic challenge protocol that all LSAPI-compliant license systems support, the LS_BASIC_PROTOCOL.

The LSAPI standard also requires a basic data structure format. The main structure in the basic challenge protocol is LS_CHALLENGE. All challenge/response protocols support this structure. The LSRequest and LSUpdate functions use it for both the application challenge and the license system response.

The LSAPI also recognizes another protocol: LS_OUT_OF_BAND_PROTOCOL. This protocol permits the license server to authenticate itself to the application, using an out-of-band challenge/response protocol that is available to an application by means external to the LSAPI, when such means are available. When the protocol specified is LS_OUT_OF_BAND_PROTOCOL, there is no challenge and no response.

For additional information about these protocols, see LSAPI Constants.


Basic Challenge Protocol

The basic challenge protocol provides the means for an LSAPI-enabled application to verify that an LSAPI-compliant license system has given it legitimate permission to run.

Every license has one or more keys, called secrets, that the software publisher chooses. The publisher typically encrypts the secrets within the license and only the license server has the means to decrypt them. The basic challenge protocol supported by all LSAPI-compliant license systems works on the principle of shared secrets: the application and the license server share a secret value.

An LSAPI-compliant license system requires a minimum of four secrets, each 4 bytes (32 bits) in length. The application challenges the authenticity of a license by requiring the license system to prove that it has one of the secrets. The server can compute the correct response to the challenge only if it has the secret. It must return a mathematical function of the challenge plus the shared secret. Since the application also has the secrets on the license, it can compute the correct expected response to the challenge and check that the server's response was appropriate for the challenge. The secret itself never passes between the application and the license system in plain text.

The basic challenge protocol includes a level of mutual authentication to prove to the license system that the application has the selected secret. The protocol also helps ensure that an intruder cannot modify the parameters the application sends to the license system, or the parameters the license system returns to the application.

Additional information about the steps in the basic challenge protocol is provided in the following topics:

  • The Application Challenge
  • The License System Response
  • The Application Verification


The Application Challenge

To initiate a challenge, your application must perform the following steps:

  1. Generate a 32-bit random number.
  2. Select the index of the application secret you choose to challenge, and look up the actual application secret.
  3. Compute a message digest with the MD4 Message-Digest Algorithm supplied by RSA Data Security, Inc. For information about creating the algorithm input, see LS_CHALLDATA.
  4. Pass the algorithm output in the LS_CHALLDATA structure to the license system with a call to the LSRequest or the LSUpdate function.

For additional information about coding the challenge, see Anti-Tampering Guidelines.


The License System Response

The license system first attempts to authenticate the message digest that the application sends as the challenge by performing the following steps:

  1. Look up the secret stored within the license.
  2. Compute a message digest with the MD4 Message-Digest Algorithm supplied by RSA Data Security, Inc.
  3. Compare this message digest to the one passed by the application initiating the challenge.
  4. Compute another message digest and passes it in the LS_MSG_DIGEST structure as the challenge response back to the application. The result of this encryption scheme is unique. For additional information about the format of this message digest, see LS_CHALLDATA.

The server cannot respond correctly to the challenge if it does not have the secrets associated with a particular license. The license system does not return a challenge response if either a license request or an update is unsuccessful.


The Application Verification

Your application must perform the following steps to verify the license system's response to the challenge:

  1. Receive the output parameters of the call to the LSRequest or the LSUpdate function, and the license system's response.
  2. Compute a second message digest with the MD4 Message-Digest Algorithm supplied by RSA Data Security, Inc. For additional information about the format of this message digest, see LS_CHALLDATA.
  3. Compare this message digest to the license system's message digest.
  4. Accept the result only if the two are equal.

There are two different methods you can use to verify a challenge response:

  • You can either incorporate the secrets and the algorithm in the code (Algorithmic Method), or
  • You can precompute a table containing a number of random challenges with their expected responses (Table Lookup Method).

For additional information about coding the challenge, see Anti-Tampering Guidelines.

Algorithmic Method

With this method, you incorporate the challenge algorithm and the actual secret values in the program code. This method requires that you take steps to obscure the code and to ensure that the secrets themselves are not readily detectable. These steps are described in Anti-Tampering Guidelines.

Table Lookup Method

With this method, you incorporate a precomputed table of valid challenge responses in the program code. The table should contain a row for each possible challenge and a column for each unique secret response. Your application can verify a challenge by examining the appropriate challenge/response intersection in the table. This method requires that you choose the challenge values in addition to the secrets when you code the application.

If intruders successfully duplicate an application's challenge and response table, they can also circumvent and replace the legitimate license provider. If all the data in the table is known, the application's secrets are vulnerable. It becomes more difficult to copy the entire table while inspecting the data exchanges between the application and the license provider as the size of the table increases. Therefore, if you use the table lookup method, compute a large number of random number values to ensure that there are a large number of possible challenges and responses.

At the beginning of each run time, your application must select one of the challenge values from your table. It must then pass this value in a call to the LSRequest function. When the call returns, the application must compare the actual challenge response to the expected response for that challenge value.

A sample table follows. The format and size of the values are examples only.

Challenge Value | Secret 1 Response | Secret 2 Response | Secret 3 Response | Secret 4 Response
1. 8675309 | 783ndmw732 | 3487dn262 | 367dkb37 | 476dndk263
2. 63JSk23 | 63387d6b36 | 7b6b5u8b7 | 8hn65bv4g7 | 076bb856v6
3. 833jh26 | 73d83m29s | 8N7GJ829n8 | 89bn73nBH | 89348nUU7
4. 8LES654 | 733nbV8 | 8H8hu8 | B73h0dn39 | 7590nd73n
5. 28gHjB4 | 39834nd83 | 93n3d93n38 | 393n3ed83n | 983n38db38

If an application used the preceding sample table and challenged Secret 3 with the second challenge value, 63JSk23, it would then pass this value in a call to the LSRequest function. A legitimate license system would respond with a challenge response of 8hn65bv4g7 and a status of success. The application would then examine the entry at the appropriate challenge/response intersection in the table and compare it to the value 8hn65bv4g7. In this case it would find a match, so the challenge response would be valid.

In addition to including a table such as the preceding example, your application could also include a similar table of challenge responses for use with calls to the LSUpdate function.

For additional information about coding the challenge, see Anti-Tampering Guidelines.


Anti-Tampering Guidelines

The security that the LSAPI provides is only as good as the security of the application code and the secret values themselves.

Distribution of application code to end users means that an intruder can recover the shared secrets and use them to create a license system flow that appears to be correct for whatever challenge the application issues. An intruder can also locate and modify the code that compares and then validates the license system's challenge response.

You should take defensive steps by using antivirus programming techniques and other measures to prevent code modification, and also to make it difficult to circumvent the basic challenge protocol. Following are guidelines that you can use when you develop an application that includes calls to the LSAPI functions. For additional information, see Table Lookup Method.

When you select the license secrets

  • Choose unique secrets for each one of your company's applications.
  • Choose unique secrets for each application version.

When you code the application

  • If you include the secrets in the application, obscure them by encrypting them or scattering them throughout the code.
  • Place most of the challenge code and data in discardable overlays, if possible.
  • Incorporate an obscure internal checksum over the code that interfaces with the license system and with the challenge verification.
  • Use different challenge values for calls to the LSRequest and LSUpdate functions.
  • Verify the code offset when your application calls the challenge algorithm, at the entry point to the algorithm, if applicable.
  • Avoid simple comparisons and obscure critical comparisons.
  • Save the challenge response that the license system returns. Do not compare it for equality immediately after a call to the LSRequest or LSUpdate function.
  • Perform a meaningless comparison immediately after a call to the LSRequest or LSUpdate function.
  • Verify the challenge result more than once.
  • Perform mathematical operations with the challenge response, and compute another result that your application verifies later in the code.
  • Perform multiple operations with the challenge response, like meaningless read, comparison, and subtraction operations, before doing a final comparison. If the intruder uses a hardware monitor, this strategy can increase the number of hardware breakpoints that occur and thereby cause additional confusion for the intruder.
  • To verify that the current license is still valid, call the LSUpdate function periodically.


How to Incorporate the LSAPI in an Application

This section provides an example of how to incorporate the License Service Application Programming Interface (LSAPI) functions in your application, using the basic challenge protocol. For additional programming suggestions, see Anti-Tampering Guidelines.

Before you begin coding your application, you will need to choose four secrets and create values for the PublisherName, ProductName, and Version parameters in the LSRequest function, as follows:

  • Create four secret values. You will need these secrets to initiate the basic challenge, and to verify the license system's response. For additional information, see The Application Challenge and The Application Verification.
  • Create a unique publisher name. This name can be up to 32 characters long. It should be a trademarked name and the same for all applications that your company develops.
  • Create a unique product name within the publisher domain. This name must be unique within the first 32 characters.
  • Create a unique version string within the product domain. The version string is used to differentiate multiple versions.

You will also need to select the specific LSAPI-compliant license systems for which you want to issue licenses. You can expand the set of license systems you support on platforms that allow shared or dynamically linked libraries after the software product has shipped, provided the application does not require functionality specific to one license system.

When you code the application, use calls to the LSAPI function layer to register license usage and include code that implements the functionality of the basic challenge protocol.

To code the application
  1. Add calls to the LSRequest, LSRelease and LSFreeHandle functions in your application to grant and release license resources.
  2. Incorporate the code to prepare the challenge. For additional information about the steps required to initiate the challenge, see The Application Challenge.
  3. Select and implement the method to verify the challenge response. For additional information about the steps required to verify the response, see The Application Verification, Algorithmic Method, and Table Lookup Method.
  4. Include periodic calls to the LSUpdate function to verify that the current license is still valid.
  5. Choose and implement your license strategy. For examples, see License Strategies.
  6. Incorporate code to handle errors. Use a call to the LSGetMessage function to return a message string that describes the error.

You will also need to locate the following files on your hard disk in the location specified by your environment variable during application development. Note that the dynamic-link libraries must also be installed on all computers on which your application runs, so you should include their installation in your application's setup procedure.

  • LSAPI.H, in your %INCLUDE% path
  • LSAPI32.LIB, in your %LIB% path

For Windows NT:

  • LSAPI32.DLL and MSLSP32.DLL in %WinDir%\System32

For Windows 95:

  • LSAPI32.DLL and MSLSP32.DLL in %WinDir%\System


License Strategies

You can customize your application to respond to the situation when a valid license is unavailable. Following are examples of license strategies.

Announcement only. Use the LSAPI functions to announce when your application begins and when it terminates. This announcement can be logged by a license system to record or meter the number of software applications in use at any one time.

Authorization desired. Use the LSAPI functions to obtain authorization from the license system for your application to run. If there is no license or license system, the software can display a warning message but continue to run.

Authorization required. Use the LSAPI functions to obtain authorization from the license system for your application to run. If no valid license is available, the software will not run.


LSAPI Reference

The following elements are used with LSAPI.

  • LSAPI Functions
  • LSAPI Structures
  • LSAPI Constants
  • LSAPI Data Type Definitions
  • LSAPI Status Code Constants


LSAPI Functions

The following functions are used with LSAPI.

LSEnumProviders
LSFreeHandle
LSGetMessage
LSQuery
LSRelease
LSRequest
LSUpdate


LSEnumProviders

Notice:This is preliminary documentation for technology that will be supported in future releases of Microsoft Windows.

The LSEnumProviders function returns a unique string for each installed license system service provider.

LS_STATUS_CODE LS_API_ENTRY LSEnumProviders(
  LS_ULONG Index, // index of the service provider
  LS_STR *Buffer  // pointer to string identifying the service
                  // provider
);

Parameters

Index
[in] Specifies the index of the service provider. The first provider has an index of zero, the second has an index of one, and so forth. This index should be incremented by the caller for each successive call to LSEnumProviders until it returns the LS_BAD_INDEX status code.
Buffer
[out] Points to a buffer in which the unique null-terminated string identifying the license system service provider is to be placed. The buffer pointed to by the Buffer parameter must be at least 255 bytes long. The value of LS_ANY indicates that the current index is not in use, but it is not the last index to obtain.

Return Values

If the function succeeds, the return value is LS_SUCCESS.

If the function fails, the return value is a status code. For extended error information, call LSGetMessage to return the status text corresponding to the status code. The LSGetMessage function may return one of the following status codes:

Value | Meaning
LS_BAD_INDEX | An invalid index was specified in a call to the LSEnumProviders or the LSQuery function.
LS_BUFFER_TOO_SMALL | The buffer that the Buffer parameter points to is too small to accommodate the text string to be returned; or the challenge data structure is too small to accommodate the challenge response.

Remarks

The LSEnumProviders function returns a unique string for each installed provider. The unique null-terminated string typically identifies the vendor, product, and version of the license system. This value is the same as the one returned by an appropriate call to the LSQuery function. In a networked environment, it returns the version of the client, not the server.

An application can enumerate the installed license system service providers by calling LSEnumProviders successively. The value specified in the Index parameter is passed in and the calling application should increment it in each call until it returns the LS_BAD_INDEX status code. This code indicates that the value of the Index parameter is higher than the number of providers currently installed.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lsapi.h.
Import Library: Use lsapi32.lib.

See Also

License Service Application Programming Interface Overview, LSAPI Functions, LSGetMessage, LSQuery


LSFreeHandle

Notice:This is preliminary documentation for technology that will be supported in future releases of Microsoft Windows.

The LSFreeHandle function frees the licensing handle context.

LS_VOID LS_API_ENTRY LSFreeHandle(
  LS_HANDLE  LicenseHandle  // handle to the license context
);

Parameter

LicenseHandle
[in] Specifies the handle to a license context that is no longer valid. This parameter must be a handle created with the LSRequest function.

Return Values

None.

Remarks

Call the LSFreeHandle function after calling the LSRelease function, or after LSRequest returns an error.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lsapi.h.
Import Library: Use lsapi32.lib.

See Also

License Service Application Programming Interface Overview, LSAPI Functions, LSRelease, LSRequest


LSGetMessage

Notice:This is preliminary documentation for technology that will be supported in future releases of Microsoft Windows.

The LSGetMessage function returns the message string associated with a license service function status code.

LS_STATUS_CODE LS_API_ENTRY LSGetMessage(
  LS_HANDLE LicenseHandle,  // handle to the license context
  LS_STATUS_CODE Value,  // any status code returned by a license
                         // service function
  LS_STR *Buffer,        // pointer to buffer returning error
                         // message string
  LS_ULONG BufferSize    // maximum size of buffer string
);

Parameters

LicenseHandle
[in] Specifies the handle to the license context. This parameter must be a handle created with the LSRequest function.
Value
[in] Specifies any status code returned by a license service function.
Buffer
[out] Points to a buffer in which a localized error message string will be returned.
BufferSize
[in] Specifies, in bytes, the maximum size of the string returned in the Buffer parameter.

Return Values

If the function succeeds, the return value is LS_SUCCESS.

If the function fails, the return value is a status code. For extended error information, call LSGetMessage to return the status text corresponding to the status code. The LSGetMessage function may return one of the following status codes:

Value | Meaning
LS_BAD_HANDLE | The handle used on the call does not describe a valid licensing system context.
LS_RESOURCES_UNAVAILABLE | The request cannot be completed because of insufficient resources, such as memory.
LS_TEXT_UNAVAILABLE | A warning occurred while looking up an error message string with the LSGetMessage function.
LS_UNKNOWN_STATUS | An unrecognized status code was passed to the LSGetMessage function.
LS_BUFFER_TOO_SMALL | The buffer that the Buffer parameter points to is too small to accommodate the text string to be returned; or the challenge data structure is too small to accommodate the challenge response.
LS_BAD_ARG | One or more of the arguments is incorrect.

Remarks

The LSGetMessage function returns a string describing a specific error, and possibly a suggested action to be taken in response to it. If the value specified in the Value parameter is the constant LS_USE_LAST, then the last error associated with the supplied licensing handle, plus its associated data, is returned. Otherwise, the function uses the supplied error code.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lsapi.h.
Import Library: Use lsapi32.lib.

See Also

License Service Application Programming Interface Overview, LSAPI Functions, LSRequest


LSQuery

Notice:This is preliminary documentation for technology that will be supported in future releases of Microsoft Windows.

The LSQuery function returns information about the service provider or the license system context associated with the specified handle obtained by a call to the LSRequest function.

LS_STATUS_CODE LS_API_ENTRY LSQuery(
  LS_HANDLE LicenseHandle,  // handle to the license context
  LS_ULONG Information,     // index that identifies the license
                            // information
  LS_VOID *InfoBuffer,      // pointer to buffer for returning
                            // license information
  LS_ULONG BufferSize,      // maximum size of buffer
  LS_ULONG *ActualBufferSize  // pointer to actual count of
                              // characters returned in buffer
);

Parameters

LicenseHandle
[in] Specifies the handle to the license context. This parameter must be a handle created with the LSRequest function.
Information
[in] Specifies the index that identifies the information to be returned.
InfoBuffer
[out] Points to a buffer in which the resulting information is to be placed.
BufferSize
[in] Specifies, in bytes, the maximum size of the buffer pointed to by the InfoBuffer parameter.
ActualBufferSize
[out] Points to an LS_ULONG value that specifies the actual number of characters returned in the buffer, not including the trailing NULL byte.

Return Values

If the function succeeds, the return value is LS_SUCCESS.

If the function fails, the return value is a status code. For extended error information, call LSGetMessage to return the status text corresponding to the status code. The LSGetMessage function may return one of the following status codes:

Value | Meaning
LS_BAD_HANDLE | The handle used on the call does not describe a valid licensing system context.
LS_RESOURCES_UNAVAILABLE | The request cannot be completed because of insufficient resources, such as memory.
LS_BAD_INDEX | An invalid index was specified in a call to the LSEnumProviders or the LSQuery function.
LS_BUFFER_TOO_SMALL | The buffer that the Buffer parameter points to is too small to accommodate the text string to be returned; or the challenge data structure is too small to accommodate the challenge response.
LS_BAD_ARG | One or more of the arguments is incorrect.

Remarks

The LSQuery function is used to obtain information about the license obtained from a call to the LSRequest function. For example, an application can determine the license type (demo, concurrent, personal, and so forth) and time restrictions.

The buffer should be large enough to accommodate the expected data. If the buffer is too small, then the status code LS_BUFFER_TOO_SMALL is returned and only the number of bytes specified in the parameter BufferSize is returned.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lsapi.h.
Import Library: Use lsapi32.lib.

See Also

License Service Application Programming Interface Overview, LSAPI Functions, LSEnumProviders, LSGetMessage, LSRequest


LSRelease

Notice:This is preliminary documentation for technology that will be supported in future releases of Microsoft Windows.

The LSRelease function requests that the license system release the licensing resources associated with the license context identified by the LicenseHandle parameter.

LS_STATUS_CODE LS_API_ENTRY LSRelease(
  LS_HANDLE LicenseHandle,  // handle to the license context
  LS_ULONG TotUnitsConsumed,  // units consumed in this handle
                              // context
  LS_STR *LogComment        // pointer to optional comment
                            // associated with the request
);

Parameters

LicenseHandle
[in] Specifies the handle to the license context. This parameter must be a handle created with the LSRequest function.
TotUnitsConsumed
[in] Specifies the total number of units consumed in this handle context since the initial call to the LSRequest function. You can specify this license policy attribute within the application. A value of LS_DEFAULT_UNITS indicates that the license system should determine the appropriate value using its own license policy mechanisms.
LogComment
[in] Points to an optional string indicating a comment that will be associated with the request. The license system can log the comment if logging is supported and enabled. If an error is returned, the license system can log both the error and the comment, but this is not guaranteed. If you do not specify a string, the value must be LS_NULL.

Return Values

If the function succeeds, the return value is LS_SUCCESS.

If the function fails, the return value is a status code. For extended error information, call LSGetMessage to return the status text corresponding to the status code. The LSGetMessage function may return one of the following status codes:

Value | Meaning
LS_BAD_HANDLE | The handle used on the call does not describe a valid licensing system context.
LS_INSUFFICIENT_UNITS | The licensing system cannot locate enough available licensing resources to complete the request.
LS_NETWORK_UNAVAILABLE | The network is unavailable.
LS_BAD_ARG | One or more of the arguments is incorrect.

Remarks

Use the LSRelease function to release licensing resources associated with the license context identified by the LicenseHandle parameter. If a policy that consumes licenses is in effect, and if you choose to implement such a license policy in the application, then you can pass the license units to be consumed in the TotUnitsConsumed parameter.

The LSRelease function does not free the license handle context. See the reference topic for LSFreeHandle.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lsapi.h.
Import Library: Use lsapi32.lib.

See Also

License Service Application Programming Interface Overview, LSAPI Functions, LSFreeHandle, LSGetMessage, LSRequest


LSRequest

Notice:This is preliminary documentation for technology that will be supported in future releases of Microsoft Windows.

The LSRequest function asks that the license system grant the licensing resources so the calling application can execute.

LS_STATUS_CODE LS_API_ENTRY LSRequest(
  LS_STR *LicenseSystem,  // pointer to string identifying the
                          // license system
  LS_STR *PublisherName,  // pointer to publisher of product
                          // requesting licensing resources
  LS_STR *ProductName,    // pointer to name of product requesting
                          // licensing resources
  LS_STR *Version,        // pointer to version number of product
                          // requesting licensing resources
  LS_ULONG TotUnitsReserved,  // units required to run the
                              // application
  LS_STR *LogComment,     // pointer to optional comment associated
                          // with the request
  LS_CHALLENGE *Challenge,  // pointer to a challenge structure
  LS_ULONG *TotUnitsGranted,  // pointer to total number of units
                              // granted
  LS_HANDLE *LicenseHandle  // pointer to handle to the license
                            // context
);

Parameters

LicenseSystem
[in] Points to a string that uniquely identifies the particular license system. You can obtain this string by using the LSEnumProviders function. If the constant LS_ANY is specified, all license system providers will be searched for a license match.
PublisherName
[in] Points to a string containing the name of the publisher of the software product requesting licensing resources. The first 32 characters of the string must be unique. It is recommended that a company name and trademark be used. This string cannot be null, nor can it be LS_ANY.
ProductName
[in] Points to a string containing the name of the software product requesting licensing resources. The first 32 characters of the string must be unique within the PublisherName domain. This string cannot be null, nor can it be LS_ANY.
Version
[in] Points to a string containing the version number of the product. The first 12 characters of the string must be unique within the PublisherName domain. This string cannot be null, nor can it be LS_ANY.
TotUnitsReserved
[in] Specifies the number of units required to run the application. The software publisher may choose to specify this policy attribute within the application. The recommended value of LS_DEFAULT_UNITS allows the license system to determine the proper value using information provided by the license system or the license itself. The license system verifies that the requested number of units exist and it may reserve those units, but no units are actually consumed at this time. The number of units available is returned in the TotUnitsGranted parameter.
LogComment
[in] Points to an optional string indicating a comment that will be associated with the request. The license system can log the comment if logging is supported and enabled. If an error is returned, the license system can log both the error and the comment, but this is not guaranteed. If you do not specify a string, the value must be LS_NULL.
Challenge
[in/out] Points to a challenge structure. The challenge response will also be returned in this structure.
TotUnitsGranted
[out] Points to an LS_ULONG value in which the total number of units granted is returned. The following table describes the TotUnitsGranted return value, given the TotUnitsReserved parameter input value, and the status code returned:
TotUnitsReserved
Status code returned | LS_DEFAULT_UNITS Other (specific count)
LS_SUCCESS | (A) (C)
LS_INSUFFICIENT_UNITS | (B) (D)
Other errors | (E) (E)

TotUnitsGranted return values:

(A) The default number of units commensurate with the license granted.

(B) The maximum number of units available to the requesting software. This can be less than the normal default.

(C) The number of units used to grant the request. This value can be greater than or equal to the actual units requested. For example, the license policy may allow only allow increments of five units; therefore, a request of seven units would result in a grant of 10 units.

(D) The maximum number of units available to the requesting software. This can be more or less than the units requested.

(E) Zero is returned.

LicenseHandle
[out] Points to an LS_HANDLE in which a handle to the license context is returned.

Return Values

If the function succeeds, the return value is LS_SUCCESS.

If the function fails, the return value is a status code. For extended error information, call LSGetMessage to return the status text corresponding to the status code. The LSGetMessage function may return one of the following status codes:

Value | Meaning
LS_INSUFFICIENT_UNITS | The licensing system cannot locate enough available licensing resources to complete the request.
LS_SYSTEM_UNAVAILABLE | A licensing system cannot be found to perform the function invoked.
LS_AUTHORIZATION_UNAVAILABLE | The licensing system has no licensing resources to complete the request.
LS_LICENSE_UNAVAILABLE | The licensing system has licensing resources that could satisfy the request, but they are not available at the time of the request.
LS_RESOURCES_UNAVAILABLE | The request cannot be completed because of insufficient resources, such as memory.
LS_NETWORK_UNAVAILABLE | The network is unavailable.
LS_BAD_ARG | One or more of the arguments is incorrect.

Remarks

Use the LSRequest function to request licensing resources to authorize the identified product to execute. If a valid license is found, the challenge response is computed and LS_SUCCESS is returned. At minimum, the PublisherName, ProductName, and Version strings are used to identify a matching license or licenses. Note that an underlying license system service provider may ascertain additional information for the license request — for example, the current user name, computer name, and so forth.

If all service providers cannot satisfy a call to the LSRequest function, then LSRequest returns the handle associated with the last service provider response. Therefore, regardless of whether valid licensing resources are granted, LSRequest always returns a valid license handle. This handle must always be released with the LSFreeHandle function when the application has finished running. If licensing resources are granted, the application must also call LSRelease to free the licensing resources, before calling LSFreeHandle.

A challenge response is not returned unless the license request completes successfully — that is, unless it returns a status code of LS_SUCCESS.

If the number of units requested is greater than the number of units available, the license request is not granted. Upon successful completion, the value returned in the TotUnitsReserved parameter indicates the number of units granted. This is greater than or equal to the number of units requested unless LS_DEFAULT_UNITS was specified. In the case of failure, the value returned in the TotUnitsGranted parameter is zero.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lsapi.h.
Import Library: Use lsapi32.lib.

See Also

License Service Application Programming Interface Overview, LSAPI Functions, LS_CHALLENGE, LSEnumProviders, LSFreeHandle, LSGetMessage, LSRelease


LSUpdate

Notice:This is preliminary documentation for technology that will be supported in future releases of Microsoft Windows.

The LSUpdate function updates the synchronization between the licensed application software and the license system.

LS_STATUS_CODE LS_API_ENTRY LSUpdate(
  LS_HANDLE LicenseHandle,    // handle to the license context
  LS_ULONG TotUnitsConsumed,  // units consumed in this handle
                              // context
  LS_ULONG TotUnitsReserved,  // units required to run the
                              // application
  LS_STR *LogComment,         // pointer to optional comment
                              // associated with the request
  LS_CHALLENGE *Challenge,    // pointer to a challenge structure
  LS_ULONG *TotUnitsGranted   // pointer to total number of units
                              // granted
);

Parameters

LicenseHandle
[in] Specifies the handle to the license context. This parameter must be a handle created with the LSRequest function.
TotUnitsConsumed
[in] Specifies the total number of units consumed in this handle context since the initial call to the LSRequest function. You can specify this license policy attribute within the application. A value of LS_DEFAULT_UNITS indicates that the license system should determine the appropriate value using its own license policy mechanisms. If an error is returned, no units are consumed.

If the TotUnitsConsumed exceeds the number of units reserved, the error LS_INSUFFICIENT_UNITS is returned and the remaining units are consumed.

TotUnitsReserved
[in] Specifies the total number of units to be reserved. If no additional units are required since the initial call to the LSRequest function or the last call to the LSUpdate function, then this parameter should be the current total returned in the TotUnitsGranted parameter. The total reserved includes the units consumed. That is, if an application requests 100 units, and then consumes 20 units, there are still 100 units reserved but only 80 available for consumption.

If additional units are required, the application must calculate a new total for TotUnitsReserved. You can specify the constant LS_DEFAULT_UNITS, but this does not allocate any additional units.

The license system verifies that the requested number of units exist, and it may reserve those units, but these units are not consumed at this time. This value may be smaller than the original number requested by LSRequest to indicate that fewer units are needed than originally anticipated.

LogComment
[in] Points to an optional string indicating a comment that the license system will associate with the request. The license system can log the comment if logging is supported and enabled. If an error is returned, the license system can log both the error and the comment, but this is not guaranteed. If you do not specify a string, the value must be LS_NULL.
Challenge
[in/out] Points to a challenge structure. The challenge response will also be returned in this structure.
TotUnitsGranted
[out] Points to an LS_ULONG value that returns the total number of units granted since the initial license request. The following table describes the TotUnitsGranted return value, given the TotUnitsReserved parameter input value, and the status code returned:
TotUnitsReserved
Status code returned | LS_DEFAULT_UNITS Other (specific count)
LS_SUCCESS | (A) (C)
LS_INSUFFICIENT_UNITS | (B) (D)
Other errors | (E) (E)

TotUnitsGranted return values:

(A) The default number of units commensurate with the license granted.

(B) The maximum number of units available to the requesting software. This can be less than the normal default.

(C) The number of units used to grant the request. This value can differ from the actual units requested. For example, the license policy may only allow only increments of five units; therefore, a request of seven units would result in a grant of 10 units.

(D) The maximum number of units available to the requesting software. This can be more or less than the units requested.

(E) Zero is returned.

Return Values

If the function succeeds, the return value is LS_SUCCESS.

If the function fails, the return value is a status code. For extended error information, call LSGetMessage to return the status text corresponding to the status code. The LSGetMessage function may return one of the following status codes:

Value | Meaning
LS_BAD_HANDLE | The handle used on the call does not describe a valid licensing system context.
LS_INSUFFICIENT_UNITS | The licensing system cannot locate enough available licensing resources to complete the request.
LS_LICENSE_TERMINATED | The licensing system has determined that the resources used to satisfy a previous request are no longer granted to the calling software.
LS_AUTHORIZATION_UNAVAILABLE | The licensing system has no licensing resources to complete the request.
LS_LICENSE_UNAVAILABLE | The licensing system has licensing resources that could satisfy the request, but they are not available at the time of the request.
LS_RESOURCES_UNAVAILABLE | The request cannot be completed because of insufficient resources, such as memory.
LS_NETWORK_UNAVAILABLE | The network is unavailable.
LS_LICENSE_EXPIRED | The license associated with the current context has expired. This may be due to a time-restriction on the license.
LS_BAD_ARG | One or more of the arguments is incorrect.

Remarks

Your application should periodically call the LSUpdate function to verify that the current license is still valid. The application can use the LSQuery function to determine the proper time interval for the current licensing context. A guideline of once an hour may be appropriate, with a minimum interval of 15 minutes. Consult your license system vendor for more information.

The LSUpdate function verifies that the license system context has not changed from the one expected by the licensed software. The LSUpdate function can determine if the licensing resources granted to the specified handle are still reserved for this application. In a distributed license system, an error might indicate a temporary network interruption. It can also determine if the license system has released the licensing resources granted to the specified handle. An error indicates the software no longer has authorization to execute in a typical manner.

The call to the LSUpdate function can also indicate that the current licensing context has expired. For example, in the case of a time-restricted license policy, it returns the warning status LS_LICENSE_EXPIRED.

If the number of new units requested in the TotUnitsReserved parameter is greater than the number available, then the update request fails and it returns the error LS_INSUFFICIENT_UNITS.

If the call completes successfully, the value returned in the TotUnitsGranted parameter indicates the current total of units granted.

If LSUpdate returns an error, it does not return a challenge response. Application software should be prepared to handle vendor-specific error conditions if they arise. If any error is returned, a call to the LSRelease function is still required.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lsapi.h.
Import Library: Use lsapi32.lib.

See Also

License Service Application Programming Interface Overview, LSAPI Functions, LS_CHALLENGE, LSGetMessage, LSQuery, LSRelease, LSRequest


LSAPI Structures

The following structures are used with LSAPI.

LS_CHALLDATA
LS_CHALLENGE
LS_MSG_DIGEST


LS_CHALLDATA

Notice:This is preliminary documentation for technology that will be supported in future releases of Microsoft Windows.

The LS_CHALLDATA structure is passed in the LS_CHALLENGE structure. The LS_CHALLDATA structure passes the challenge from the application to the license system, and passes the response from the license system back to the application.

typedef struct _LS_CHALLDATA {
    LS_ULONG SecretIndex;
    LS_ULONG Random;
    LS_MSG_DIGEST MsgDigest;
} LS_CHALLDATA;

Members

SecretIndex
Specifies the index of the secret value to be challenged. Note: The secret index is 1-based, so the first secret must have an index of 1.
Random
Specifies a random 32-bit value.
MsgDigest
Structure that contains the message digest that is computed by the MD4 Message-Digest Algorithm from RSA Data Security, Inc.

Remarks

In the basic challenge protocol, the application must choose the index of the secret to be challenged, and it must generate a random number. It must then compute a message digest using the MD4 Message-Digest Algorithm. The input to the algorithm is formed by concatenating the input parameters to the function being called, the random number, the index of the secret to be challenged, and the actual secret value. The first input parameter should be the name of the license service function being called, either LSRequest or LSUpdate. All parameters should be in the order specified in the prototypes for those functions, and you should exclude the values of the Challenge and LicenseHandle parameters. Copy string parameters without null terminators. The application then passes the algorithm output to the license system.

The license system authenticates the message digest and computes a new message digest consisting of the input parameters to the license service function, the output parameters, the random number, the index of the secret to be challenged, and the actual secret value. The last output parameter should be the returned status. This new message digest is passed back to the application, which, in turn, authenticates it. All parameters should be in the order specified in the prototypes for the LSRequest or LSUpdate function, and you should exclude the values of the Challenge and LicenseHandle parameters. Note that the actual secret value never passes between the application and the license system in plain text.

If the function h(x) is the algorithm that, given input x, returns the output of the MD4 Message-Digest Algorithm, then the following briefly illustrates the basic protocol.

The application passes the LS_CHALLDATA structure to the license system:

R, X, h(in + R + X + SX)

The license system passes a new LS_MSG_DIGEST to the application:

h(in + out + R + X + SX)

where R is the random number, X is the index of the secret to be challenged, in is a byte stream that encodes the input parameters, S indicates a secret, SX is the actual secret value, out is a byte stream that encodes the output parameters, and + denotes concatenation.

This data format can be invalid if the Protocol specified in the LS_CHALLENGE structure is not LS_BASIC_PROTOCOL. Other protocols may define their own LS_CHALLDATA format.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lsapi.h.

See Also

License Service Application Programming Interface Overview, LSAPI Structures, LS_CHALLENGE, LS_MSG_DIGEST


LS_CHALLENGE

Notice:This is preliminary documentation for technology that will be supported in future releases of Microsoft Windows.

The LS_CHALLENGE structure is used for both the challenge and the response of the LSRequest and LSUpdate license service functions. It is the main structure in the challenge/response mechanism, and it is supported by all challenge/response protocols.

typedef struct _LS_CHALLENGE {
    LS_ULONG Protocol;
    LS_ULONG Size;
    LS_CHALLDATA ChallengeData;
} LS_CHALLENGE;

Members
Protocol
Specifies the protocol setting for license authentication.
Size
Specifies the size, in bytes, of the ChallengeData (LS_CHALLDATA ) structure.
ChallengeData
Structure that contains the challenge that the application passes to the license system, and the response the license system returns to the application.

Remarks

Use the LS_CHALLDATA structure to pass the challenge to the license system. The license system also returns the challenge response in the LS_CHALLDATA structure. Therefore, the number of bytes specified in the Size member on entry must be large enough to accommodate the challenge response. If the structure is not large enough to accommodate it, the error LS_BUFFER_TOO_SMALL is returned.

Because the LS_CHALLDATA structure can vary depending on the protocol specified in the Protocol member, this structure must be a single contiguous entity in memory, and must not exceed the number of bytes specified in the Size member. It cannot contain any pointers.

LSAPI passes the Protocol, the Size of the LS_CHALLDATA structure, and the actual data contained in the structure to the license system. The license system, in turn, casts the byte sequence into the appropriate structure based on the Protocol specified.

The constant value LS_BASIC_PROTOCOL specifies a standard basic challenge protocol that is supported by all LSAPI-compliant license systems. When the Protocol specified is LS_OUT_OF_BAND_PROTOCOL, there is no challenge and no response.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lsapi.h.

See Also

License Service Application Programming Interface Overview, LSAPI Structures, LS_CHALLDATA, LS_MSG_DIGEST


LS_MSG_DIGEST

Notice:This is preliminary documentation for technology that will be supported in future releases of Microsoft Windows.

The LS_MSG_DIGEST structure is passed in the LS_CHALLDATA structure. The MD4 Message-Digest Algorithm from RSA Data Security, Inc., computes the LS_MSG_DIGEST structure by using the following elements as input: the input and output parameters to the LSRequest or LSUpdate license service functions; a random number; the index of an application secret; and the actual application secret.

typedef struct _LS_MSG_DIGEST {
    LS_STR MessageDigest[16];
} LS_MSG_DIGEST;

Members

MessageDigest[16]
Specifies a 128-bit message digest that is the output of the MD4 Message-Digest Algorithm.

QuickInfo

Windows NT: Requires version 3.51 or later.
Windows: Requires Windows 95 or later.
Windows CE: Unsupported.
Header: Declared in lsapi.h.

See Also

License Service Application Programming Interface Overview, LSAPI Structures, LS_CHALLDATA, LS_CHALLENGE


LSAPI Constants

This section describes the standard LSAPI C constants. They are listed in alphabetic order.

Constant/Value | Type | Meaning
LS_ANY null string | LS_STR FAR * | Indicates that all license system providers should be searched for a license match.
LS_BASIC_PROTOCOL 0x00000001 | LS_ULONG | Specifies the basic challenge protocol that is supported by all LSAPI-compliant license systems.
LS_DEFAULT_UNITS 0xFFFFFFFF | LS_ULONG | Indicates that the license system and the associated license policy should determine the number of license units.
LS_INFO_DATA 2 | LS_ULONG | Returns a vendor-defined block of data contained on the license. The first ULONG value in this data buffer indicates the size, in bytes, of the data following it. The space allocated for this data can vary on each license system, or might not be available at all.
LS_INFO_NONE 0 | LS_ULONG | Reserved.
LS_INFO_SYSTEM 1 | LS_ULONG | Returns the unique identification of the license system supplying the current license context. The value is a null-terminated string, and it is the same as that returned by a call to the LSEnumProviders function.
LS_LICENSE_CONTEXT 4 | LS_ULONG | Returns a value that uniquely identifies the license context within the specific license service provider identified by the LicenseHandle parameter. The bytes returned are specific to the license system. When license-system – specific functionality is being used, you can use this sequence of bytes to identify the current license context.
LS_MAX_PROVIDER _NAME 255 | LS_ULONG | Specifies the maximum length of a provider name that the LSEnumProviders function returns.
LS_NO _RECOMMENDATION 0xFFFFFFFF | LS_ULONG | Indicates that the license system cannot supply an interval recommendation when a call to the LSQuery function using LS_UPDATE_PERIOD returns this value.
LS_NULL NULL | LS_VOID FAR * | Specifies a null value for all optional pointer arguments. LS_NULL must be used to indicate the absence of a value.
LS_OUT_OF_BAND _PROTOCOL 0xFFFFFFFF | LS_ULONG | Specifies an out-of-band challenge/response protocol, one that is available to an application by means external to the LSAPI.
LS_UPDATE_PERIOD 3 | LS_ULONG | Returns the recommended interval, in minutes, at which an application should call the LSUpdate function. If a value of 0xFFFFFFFF is returned, the license system cannot supply a recommendation.
LS_USE_LAST 0x0800FFFF | LS_ULONG | Indicates that the LSGetMessage function should use as input the last status value returned for the current process.


LSAPI Data Type Definitions

This section describes the standard LSAPI C data types. They are listed in alphabetic order.

Data type | Definition | Description
LS_HANDLE | unsigned long | Defines the handle to the license context used by the license service function calls.
LS_LONG | long | Defines a 32-bit signed integer type.
LS_STATUS_CODE | unsigned long | Indicates the result of a license service function call that is a 32-bit unsigned integer type.
LS_STR | char | Defines a null-terminated string of characters in ASCII format.
LS_ULONG | unsigned long | Defines a 32-bit unsigned integer type.
LS_VOID | void | Refers to an unspecified type that usually indicates a data buffer.


LSAPI Status Code Constants

This section describes the standard LSAPI status code constants. They are listed in alphabetic order.

Constant | Status Value | Meaning
LS_AUTHORIZATION_ UNAVAILABLE | 0xC0001005 | The license system has no license resources to complete the request.
LS_BAD_ARG | 0xC000100E | One or more of the arguments is incorrect.
LS_BAD_HANDLE | 0xC0001001 | The handle used on the call does not describe a valid license system context.
LS_BAD_INDEX | 0xC000100B | An invalid index was specified in a call to the LSEnumProviders or the LSQuery function.
LS_BUFFER_TOO_SMALL | 0xC000100D | Either the buffer pointed to by the Buffer parameter in the LSGetMessage function is too small to accommodate the text string to be returned, or the challenge data structure is too small to accommodate the challenge response.
LS_INSUFFICIENT_UNITS | 0xC0001002 | The license system cannot locate enough available license resources to complete the request.
LS_LICENSE_EXPIRED | 0x8000100C | The license associated with the current context has expired. This may be due to a time restriction on the license.
LS_LICENSE_TERMINATED | 0xC0001004 | The license system has determined that the resources used to complete a previous request are no longer granted to the calling software.
LS_LICENSE_UNAVAILABLE | 0xC0001006 | The license system has license resources that could complete the request, but they were not available at the time of the request.
LS_NETWORK_ UNAVAILABLE | 0xC0001008 | The network is unavailable.
LS_RESOURCES_ UNAVAILABLE | 0xC0001007 | The request cannot be completed because of insufficient resources, such as memory.
LS_SUCCESS | 0x0 | The function completed successfully.
LS_SYSTEM_UNAVAILABLE | 0xC0001003 | A license system cannot be found to carry out the called function.
LS_TEXT_UNAVAILABLE | 0x80001009 | An error occurred while looking up an error message string with the LSGetMessage function.
LS_UNKNOWN_STATUS | 0xC000100A | An unrecognized status code was passed to the LSGetMessage function.

These values are 32-bit unsigned values. The value is divided into 3 fields. The format of these fields with their bit positions are shown following.

Field | Meaning
31 - 30 | The high-order 2 bits indicate a severity code. Possible values include the following:
 | 00 success
 | 01 information
 | 10 warning
 | 11 error
29 - 16 | The middle 14 bits are reserved, and must equal zero.
15 - 0 | The low-order 16 bits are a unique value LSAPI assigns to indicate the area responsible for the condition, error, or warning.


System Information

The Microsoft® Win32® API includes functions that describe or change the system configuration, settings, and attributes.


About System Information

The functions described in this overview retrieve a variety of data. The system configuration information describes the computer hardware, computer name, and user name. The operating system configuration information describes the operating system version, key directories, and environment variables. The system parameters describe system attributes. The system metrics provide the dimensions of the elements in the display area.

The following sections describes how to obtain these types of information:

  • System Configuration
  • Operating System Configuration
  • System Parameters
  • System Metrics


System Configuration

Several functions are specifically intended to describe or change the system configuration. At startup, for example, a computer is assigned the name listed in the registry. An application can retrieve this name by using the GetComputerName function and can change the name by using the SetComputerName function. SetComputerName changes the registry, not the current computer name. As a result, the new name is not assigned until the computer is restarted. For more information about the registry, see Registry.

The GetUserName function retrieves the name of the user currently logged onto the system. The user name is either the logon name or the user's full name, if the latter is included in the registry.

The GetSystemInfo function retrieves processor and memory information, such as the page size, original equipment manufacturer (OEM) identifier, number and type of processors, application address range, and so on. The IsProcessorFeaturePresent function retrieves information about the floating-point operations and instruction sets supported by the processor.

The GetCurrentHwProfile function retrieves information about the hardware profile. The hardware profile includes information such as the docking state, globally unique identifier (GUID), and display name for the profile. The GetKeyboardType function retrieves such information as the type of keyboard and the number of function keys on the current keyboard.


Operating System Configuration

Several functions are specifically intended to describe the operating system configuration. The GetVersionEx function retrieves the major and minor revision numbers of the installed version of the operating system. For more information, see Getting the system version.

The Windows directory is the directory that contains Win32-based applications, initialization files, and help files. The GetWindowsDirectory function retrieves the path to this directory. Applications that create files should do so in the Windows directory. This is the only directory guaranteed to be private to a user running a shared version of the operating system. The system directory is the directory that contains dynamic-link libraries, drivers, and font files. The GetSystemDirectory function retrieves the path to this directory.

An environment variable is a symbolic variable that represents some element of the system, such as a path, a filename, or other literal data. For example, the environment variable PATH represents the directories in which to search for executable files. When a user logs on, the system initializes environment variables based on the environment section of the registry. The ExpandEnvironmentStrings function retrieves the values of specified environment variables.


System Parameters

The SystemParametersInfo function retrieves or sets various system attributes, such as double-click time, screen saver time-out, window border width, and desktop pattern. When an application uses SystemParametersInfo to set a parameter, the change takes place immediately. This function also enables applications to update the user profile, so changes to the system will be preserved when the system is restarted.


System Metrics

Display elements are the parts of a window and the display that appear on the system display screen. System metrics are the dimensions of various display elements. Typical system metrics include the window border width, icon height, and so on. System metrics also describe other aspects of the system, such as whether a mouse is installed, double-byte characters are supported, or a debugging version of the operating system is installed. The GetSystemMetrics function retrieves the specified system metric.

Applications can also retrieve and set the color of window elements such as menus, scroll bars, and buttons by using the GetSysColor and SetSysColors functions, respectively.


Using System Information

  • Getting system information
  • Getting the system version
  • Getting hardware information
  • Changing the colors of window elements


Getting System Configuration Information

Getting System Information

The following example uses the GetComputerName, GetUserName, GetSystemDirectory, GetWindowsDirectory, and ExpandEnvironmentStrings functions to get information that describes the system configuration. This example displays the information in a window's client area.

LPTSTR lpszSystemInfo;     // pointer to system information string
DWORD cchBuff = 256;       // size of computer or user name
TCHAR tchBuffer2[BUFFER];  // buffer for concatenated string

DWORD dwResult;            // function return value

SYSTEM_INFO siSysInfo;     // structure for hardware information
int aTabs[1] = {260};      // tab stop for TabbedTextOut

TCHAR tchBuffer[BUFFER];   // buffer for expanded string
int nSize;                 // size of string

lpszSystemInfo = tchBuffer2;

// Get and display the name of the computer.

GetComputerName(lpszSystemInfo, &cchBuff);

nSize = sprintf(tchBuffer, "Computer name:  %s",
    lpszSystemInfo);
TextOut(hdc, 15, 20, tchBuffer, nSize);

// Get and display the user name.

GetUserName(lpszSystemInfo, &cchBuff);

nSize = sprintf(tchBuffer, "User name:  %s",
    lpszSystemInfo);
TextOut(hdc, 15, 40, tchBuffer, nSize);

// Get and display the system directory.

nSize = GetSystemDirectory(lpszSystemInfo, MAX_PATH);

nSize = sprintf(tchBuffer, "System directory:  %s",
    lpszSystemInfo);
TextOut(hdc, 15, 60, tchBuffer, nSize);

// Get and display the Windows directory.

nSize = GetWindowsDirectory(lpszSystemInfo, MAX_PATH);

nSize = sprintf(tchBuffer, "Windows directory:  %s",
    lpszSystemInfo);
TextOut(hdc, 15, 80, tchBuffer, nSize);

// Display the "environment variables" header.

nSize = sprintf(tchBuffer,
    "Environment variables (partial list):");
TextOut(hdc, 15, 105, tchBuffer, nSize);

// Expand the OS and NTVERSION environment variables.

dwResult = ExpandEnvironmentStrings(
               "OS=%OS%     NTVERSION=%NTVERSION%",
               lpszSystemInfo,
               BUFFER);

TextOut(hdc, 25, 120, (LPCTSTR) lpszSystemInfo,
    dwResult - 1);

// Expand the PATH environment variable.

dwResult = ExpandEnvironmentStrings(
               "PATH=%PATH%",
               lpszSystemInfo,
               BUFFER);

TextOut(hdc, 25, 135, (LPCTSTR) lpszSystemInfo,
    dwResult - 1);

// Expand the LIBPATH environment variable.

dwResult = ExpandEnvironmentStrings(
               "LIBPATH=%LIBPATH%",
               lpszSystemInfo,
               BUFFER);

TextOut(hdc, 25, 150, (LPCTSTR) lpszSystemInfo,
    dwResult - 1);

// Expand the TMP environment variable.

dwResult = ExpandEnvironmentStrings(
               "TMP=%TMP%",
               lpszSystemInfo,
               BUFFER);

TextOut(hdc, 25, 165, (LPCTSTR) lpszSystemInfo,
    dwResult - 1);


Getting the System Version

The following example uses the GetVersionEx function to retrieve version information about the currently running operating system.

OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;

// Try calling GetVersionEx using the OSVERSIONINFOEX structure,
// which is supported on Windows NT versions 5.0 and later.
// If that fails, try using the OSVERSIONINFO structure,
// which is supported on earlier versions of Windows and Windows NT

ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

if (! (bOsVersionInfoEx = GetVersionEx ( (OSVERSIONINFO *) &osvi) ) ) {

   // If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.

   osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
   if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
      return 0;
}

switch (osvi.dwPlatformId) {

   case VER_PLATFORM_WIN32_NT:

      printf ("Microsoft Windows NT ");
      break;

   case VER_PLATFORM_WIN32_WINDOWS:

      if ((osvi.dwMajorVersion > 4) ||
         ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion > 0)))
             printf ("Microsoft Windows 98 ");
      else
             printf ("Microsoft Windows 95 ");
      break;

   case VER_PLATFORM_WIN32s:

      printf ("Microsoft Win32s ");
      break;
}

printf ("version %d.%d (Build %d)\n",
            osvi.dwMajorVersion,
            osvi.dwMinorVersion,
            osvi.dwBuildNumber & 0xFFFF);

if (bOsVersionInfoEx)
    printf ("Service Pack %d.%d\n",
                osvi.wServicePackMajor,
                osvi.wServicePackMinor);


Getting Hardware Information

The following example uses the GetSystemInfo function to obtain hardware information such as the OEM identifier, processor type, page size, and so on. The example displays the information in a window's client area.

SYSTEM_INFO siSysInfo;   // struct. for hardware information
int aTabs[1] = {260};    // tab stop for TabbedTextOut

TCHAR tchBuffer[BUFFER]; // buffer for expanded string
int nSize;               // size of string

// Display the "hardware information" header.

nSize = sprintf(tchBuffer,
    "Hardware information:");
TextOut(hdc, 15, 20, tchBuffer, nSize);

// Copy the hardware information to the SYSTEM_INFO structure.

GetSystemInfo(&siSysInfo);

// Display the contents of the SYSTEM_INFO structure.

nSize = sprintf(tchBuffer,
    "OEM ID: %u\tNumber of Processors: %u",
    siSysInfo.dwOemId,
    siSysInfo.dwNumberOfProcessors);
TabbedTextOut(hdc, 25, 40, tchBuffer,
    nSize, 1, aTabs, 25);

nSize = sprintf(tchBuffer,
    "Page size: %u\tProcessor Type: %u",
    siSysInfo.dwPageSize,
    siSysInfo.dwProcessorType);
TabbedTextOut(hdc, 25, 60, tchBuffer,
    nSize, 1, aTabs, 25);

nSize = sprintf(tchBuffer,
    "Minimum app address: %lx\tMaximum app address: %lx",
    siSysInfo.lpMinimumApplicationAddress,
    siSysInfo.lpMaximumApplicationAddress);
TabbedTextOut(hdc, 25, 80, tchBuffer,
    nSize, 1, aTabs, 25);

nSize = sprintf(tchBuffer,
    "Active processor mask: %u",
    siSysInfo.dwActiveProcessorMask);
TextOut(hdc, 25, 100, tchBuffer, nSize);

The following example uses the GetSystemMetrics function to determine whether a mouse is installed and whether the mouse buttons are swapped. The example also uses the SystemParametersInfo function to retrieve the mouse threshold and speed. It displays the information in a message box.

TCHAR tchBuffer[BUFFER]; // buffer for expanded string
int nSize;               // size of string

BOOL fResult;            // system shutdown flag

int aMouseInfo[3];       // array for mouse information

// Is there a mouse?

fResult = GetSystemMetrics(SM_MOUSEPRESENT);

if (fResult == 0)
{
    // Indicate if there is no mouse.

    nSize = sprintf(tchBuffer, "No mouse installed.");
}
else
{
    // If there is a mouse, determine whether its buttons are swapped.

    fResult = GetSystemMetrics(SM_SWAPBUTTON);

    if (fResult == 0)
    {
        nSize = sprintf(tchBuffer, "Buttons not swapped.\r");
    }
    else
    {
        nSize = sprintf(tchBuffer, "Buttons swapped.\r");
    }

    // Get the mouse speed and the threshold values.

    SystemParametersInfo(SPI_GETMOUSE, // get mouse information
        NULL,                          // not used
        &aMouseInfo,                   // holds mouse information
        NULL);                         // not used

    nSize += sprintf(tchBuffer + nSize,
        "Speed: %d\r", aMouseInfo[2]);
    sprintf(tchBuffer + nSize,
        "Threshold (x,y): %d,%d",
        aMouseInfo[0], aMouseInfo[1]);
}

// Display the mouse information.

MessageBox(NULL, tchBuffer, "Mouse information",
    MB_ICONINFORMATION);

This next example uses SystemParametersInfo to double the mouse speed and update the MouseSpeed value in the WIN.INI file.

TCHAR tchBuffer[BUFFER]; // buffer for expanded string
int nSize;               // size of string

int aMouseInfo[3];       // array for mouse information

// Get the current mouse speed.

SystemParametersInfo(SPI_GETMOUSE, // get mouse information
    NULL,                          // not used
    &aMouseInfo,                   // holds mouse information
    NULL);                         // not used

// Double it.

aMouseInfo[2] = 2 * aMouseInfo[2];

// Change the mouse speed to the new value and update WIN.INI.

SystemParametersInfo(SPI_SETMOUSE, // set mouse information
    NULL,                          // not used
    aMouseInfo,                    // mouse information
    SPIF_UPDATEINIFILE);           // update win.ini


Changing the Colors of Window Elements

The following example uses the SetSysColors function to change the color of active window borders to dark purple, of active title bars to dark cyan, and of the window background to light gray.

// window elements to change
int aiElements[3] = {COLOR_ACTIVEBORDER,
                     COLOR_ACTIVECAPTION,
                     COLOR_WINDOW};

// array of RGB values
DWORD aColors[3];

// Define the new colors.

aColors[0] = RGB(0x80, 0x00, 0x80);  // dark purple
aColors[1] = RGB(0x00, 0x80, 0x80);  // dark cyan
aColors[2] = RGB(0xC0, 0xC0, 0xC0);  // light gray

// Set the window elements in aiElements to the colors
// specified in aColors.

SetSysColors(3, aiElements, aColors);

The next example uses the GetSysColor function to retrieve the color of the window background and displays the red, green, blue (RGB) value, in hexadecimal notation, in a message box.

DWORD dwResult;           // function return value

TCHAR tchBuffer[BUFFER];  // buffer for expanded string
int nSize;                // size of string

// Get the color of the window background.

dwResult = GetSysColor(COLOR_WINDOW);

nSize = sprintf(tchBuffer,
    "Window color: {%x, %x, %x}",
    GetRValue(dwResult),
    GetGValue(dwResult),
    GetBValue(dwResult));

MessageBox(NULL, tchBuffer, "GetSysColor", MB_ICONINFORMATION);


System Information Reference

The following elements are used with system information.

  • System Information Functions
  • System Information Structures


System Information Functions

The following functions are used to retrieve or set system information.

ExpandEnvironmentStrings
GetComputerName
GetCurrentHwProfile
GetKeyboardType
GetSysColor
GetSystemDirectory
GetSystemInfo
GetSystemMetrics
GetUserName
GetVersionEx
GetWindowsDirectory
IsProcessorFeaturePresent
SetComputerName
SetSysColors
SystemParametersInfo

Obsolete Functions

GetVersion


ExpandEnvironmentStrings

The ExpandEnvironmentStrings function expands environment-variable strings and replaces them with their defined values.

DWORD ExpandEnvironmentStrings(
  LPCTSTR lpSrc, // pointer to string with environment variables
  LPTSTR lpDst,  // pointer to string with expanded environment
                 // variables
  DWORD nSize    // maximum characters in expanded string
);

Parameters

lpSrc
Pointer to a null-terminated string that might contain references to environment-variable strings of the form:
%variableName%

For each such reference, the %variableName% portion is replaced with the current value of that environment variable.

The replacement rules are the same as those used by the command interpreter. Case is ignored when looking up the environment-variable name. If the name is not found, the %variableName% portion is left undisturbed.

lpDst
Pointer to a buffer to receive a copy of the source buffer, after all environment-variable name substitutions have been performed.
nSize
Specifies the maximum number of characters that can be stored in the buffer pointed to by the lpDst parameter, including the terminating null character.

Return Values

If the function succeeds, the return value is the number of bytes (ANSI version) or characters (Unicode version) stored in the destination buffer, including the terminating null character. If the destination buffer is too small to hold the expanded string, the return value is the required buffer size, in bytes or characters.

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

System Information Overview, System Information Functions


GetComputerName

The GetComputerName function retrieves the computer name of the current system. This name is established at system startup, when it is initialized from the registry.

BOOL GetComputerName(
  LPTSTR lpBuffer,  // address of name buffer
  LPDWORD nSize     // address of size of name buffer
);

Parameters

lpBuffer
Pointer to a buffer that receives a null-terminated string containing the computer name. The buffer size should be large enough to contain MAX_COMPUTERNAME_LENGTH + 1 characters.
nSize
Pointer to a DWORD variable. On input, the variable specifies the size, in bytes or characters, of the buffer. On output, the variable returns the number of bytes or characters copied to the destination buffer, not including the terminating null character.

If the buffer is too small, the function fails, GetLastError returns ERROR_BUFFER_OVERRUN, and the variable returns the required buffer size including the terminating null character.

Windows 95 and Windows 98: GetComputerName fails if the input size is less than MAX_COMPUTERNAME_LENGTH + 1.

Return Values

If 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

System Information Overview, System Information Functions, SetComputerName


GetCurrentHwProfile

The GetCurrentHwProfile function retrieves information about the current hardware profile for the local computer.

BOOL GetCurrentHwProfile(
  LPHW_PROFILE_INFO lpHwProfileInfo  // receives the hardware
                                     // profile information
);

Parameters

lpHwProfileInfo
Pointer to an HW_PROFILE_INFO structure in which the function returns information about the current hardware profile.

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 GetCurrentHwProfile function retrieves the display name and globally unique identifier (GUID) string for the hardware profile. The function also retrieves the reported docking state for portable computers with docking stations.

The system generates a GUID for each hardware profile and stores it as a string in the registry. You can use GetCurrentHwProfile to retrieve the GUID string to use as a registry subkey under your application's configuration settings key in HKEY_CURRENT_USER. This enables you to store each user's settings for each hardware profile. For example, the Colors control panel application could use the subkey to store each user's color preferences for different hardware profiles, such as profiles for the docked and undocked states. Applications that use this functionality can check the current hardware profile when they start up, and update their settings accordingly.

Windows 95: Applications can also update their settings when a system device message, such as DBT_CONFIGCHANGED, indicates that the hardware profile has changed.

Example

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
void main(void) {
   HW_PROFILE_INFO   HwProfInfo;
   if (!GetCurrentHwProfile(&HwProfInfo)) {
      _tprintf(TEXT("GetCurrentHwProfile failed with error %lx\n"),
                 GetLastError());
      return;
   }
   _tprintf(TEXT("DockInfo = %d\n"), HwProfInfo.dwDockInfo);
   _tprintf(TEXT("Profile Guid = %s\n"), HwProfInfo.szHwProfileGuid);
   _tprintf(TEXT("Friendly Name = %s\n"), HwProfInfo.szHwProfileName);
} // main

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 advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

System Information Overview, System Information Functions, DBT_CONFIGCHANGED, HW_PROFILE_INFO


GetKeyboardType

The GetKeyboardType function retrieves information about the current keyboard.

int GetKeyboardType(
  int nTypeFlag   // type of information to retrieve
);

Parameters

nTypeFlag
Specifies the type of keyboard information to be retrieved. This parameter can be one of the following values:
Value | Meaning
0 | Keyboard type
1 | Keyboard subtype
2 | Number of function keys on the keyboard

Return Values

If the function succeeds, the return value specifies the requested information.

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

Remarks

The subtype is an original equipment manufacturer (OEM)-dependent value. The type may be one of the following values:

Value | Meaning
1 | IBM PC/XT or compatible (83-key) keyboard
2 | Olivetti "ICO" (102-key) keyboard
3 | IBM PC/AT (84-key) or similar keyboard
4 | IBM enhanced (101- or 102-key) keyboard
5 | Nokia 1050 and similar keyboards
6 | Nokia 9140 and similar keyboards
7 | Japanese keyboard

The application can also determine the number of function keys on a keyboard from the keyboard type. Following are the number of function keys for each keyboard type:

Type | Number of function keys
1 | 10
2 | 12 (sometimes 18)
3 | 10
4 | 12
5 | 10
6 | 24
7 | Hardware dependent and specified by the OEM

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

System Information Overview, System Information Functions


GetSysColor

The GetSysColor function retrieves the current color of the specified display element. Display elements are the parts of a window and the display that appear on the system display screen.

DWORD GetSysColor(
  int nIndex   // display element
);

Parameters

nIndex
Specifies the display element whose color is to be retrieved. This parameter must be one of the following values:
Value | Meaning
COLOR_3DDKSHADOW | Dark shadow for three-dimensional display elements.
COLOR_3DFACE,
COLOR_BTNFACE 		Face color for three-dimensional display elements.
COLOR_3DHILIGHT, COLOR_3DHIGHLIGHT, COLOR_BTNHILIGHT, COLOR_BTNHIGHLIGHT | Highlight color for three-dimensional display elements (for edges facing the light source.)
COLOR_3DLIGHT | Light color for three-dimensional display elements (for edges facing the light source.)
COLOR_3DSHADOW, COLOR_BTNSHADOW | Shadow color for three-dimensional display elements (for edges facing away from the light source).
COLOR_ACTIVEBORDER | Active window border.
COLOR_ACTIVECAPTION Active window title bar.

Windows NT 5.0 and Windows 98: Specifies the left side color in the color gradient of an active window's title bar if the gradient effect is enabled.
COLOR_APPWORKSPACE | Background color of multiple document interface (MDI) applications.
COLOR_BACKGROUND, COLOR_DESKTOP | Desktop.
COLOR_BTNTEXT | Text on push buttons.
COLOR_CAPTIONTEXT | Text in caption, size box, and scroll bar arrow box.
COLOR_GRADIENTACTIVECAPTION | Windows NT 5.0 and Windows 98: Right side color in the color gradient of an active window's title bar. COLOR_ACTIVECAPTION specifies the left side color. Use SPI_GETGRADIENTCAPTIONS with the SystemParametersInfo function to determine whether the gradient effect is enabled.
COLOR_GRADIENTINACTIVECAPTION | Windows NT 5.0 and Windows 98: Right side color in the color gradient of an inactive window's title bar. COLOR_INACTIVECAPTION specifies the left side color.
COLOR_GRAYTEXT | Grayed (disabled) text. This color is set to 0 if the current display driver does not support a solid gray color.
COLOR_HIGHLIGHT | Item(s) selected in a control.
COLOR_HIGHLIGHTTEXT | Text of item(s) selected in a control.
COLOR_HOTLIGHT | Windows NT 5.0 and Windows 98: Color for a hot-tracked item. Single clicking a hot-tracked item executes the item.
COLOR_INACTIVEBORDER | Inactive window border.
COLOR_INACTIVECAPTION Inactive window caption.

Windows NT 5.0 and Windows 98: Specifies the left side color in the color gradient of an inactive window's title bar if the gradient effect is enabled.
COLOR_INACTIVECAPTIONTEXT | Color of text in an inactive caption.
COLOR_INFOBK | Background color for tooltip controls.
COLOR_INFOTEXT | Text color for tooltip controls.
COLOR_MENU | Menu background.
COLOR_MENUTEXT | Text in menus.
COLOR_SCROLLBAR | Scroll bar gray area.
COLOR_WINDOW | Window background.
COLOR_WINDOWFRAME | Window frame.
COLOR_WINDOWTEXT | Text in windows.

Return Values

The return value is the red, green, blue (RGB) color value that specifies the color of the given element.

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

Remarks

System colors for monochrome displays are usually interpreted as shades of gray.

Windows CE: Windows CE versions 2.0 and later support the following two values for the nIndex parameter:

COLOR_STATIC
Background color for static controls and dialogs.
COLOR_STATICTEXT
Text color for static controls.

Windows CE 1.0 only supports a 2 bit gray scale palette, so GetSysColor returns a palette index rather than an RGB value. Windows CE GDI functions that accept a COLORREF structure can use either a palette index or an RGB value. However, if the application attempts to interpret the color value, be aware of this difference.

Windows CE 2.0 supports 2 bits per pixel (2-bpp), 4 bits per pixel (4-bpp), and 8 bits per pixel (8-bpp) color devices, and can logically support 32 bits per pixel device independent bitmaps (DIBs). In Windows CE 2.0, GetSysColor returns an RGB 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 winuser.h.
Import Library: Use user32.lib.

See Also

System Information Overview, System Information Functions, SetSysColors, SystemParametersInfo


GetSystemDirectory

The GetSystemDirectory function retrieves the path of the system directory. The system directory contains such files as dynamic-link libraries, drivers, and font files.

UINT GetSystemDirectory(
  LPTSTR lpBuffer,  // address of buffer for system directory
  UINT uSize        // size of directory buffer
);

Parameters

lpBuffer
Pointer to the buffer to receive the null-terminated string containing the path. This path does not end with a backslash unless the system directory is the root directory. For example, if the system directory is named WINDOWS\SYSTEM on drive C, the path of the system directory retrieved by this function is C:\WINDOWS\SYSTEM.
uSize
Specifies the maximum size of the buffer, in characters. This value should be set to at least MAX_PATH.

Return Values

If the function succeeds, the return value is the length, in characters, of the string copied to the buffer, not including the terminating null character. If the length is greater than the size of the buffer, 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

Applications should not create files in the system directory. If the user is running a shared version of the operating system, the application does not have write access to the system directory. Applications should create files only in the directory returned by the GetWindowsDirectory 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

System Information Overview, System Information Functions, GetCurrentDirectory, GetWindowsDirectory, SetCurrentDirectory


GetSystemInfo

The GetSystemInfo function returns information about the current system.

VOID GetSystemInfo(
  LPSYSTEM_INFO lpSystemInfo   // address of system information
                               // structure
);

Parameters

lpSystemInfo
Pointer to a SYSTEM_INFO structure to be filled in by this function.

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

System Information Overview, System Information Functions, SYSTEM_INFO


GetSystemMetrics

The GetSystemMetrics function retrieves various system metrics (widths and heights of display elements) and system configuration settings. All dimensions retrieved by GetSystemMetrics are in pixels.

int GetSystemMetrics(
  int nIndex   // system metric or configuration setting to retrieve
);

Parameters

nIndex
Specifies the system metric or configuration setting to retrieve. All SM_CX* values are widths. All SM_CY* values are heights. The following values are defined.
Value | Meaning
SM_ARRANGE | Flags specifying how the system arranged minimized windows. For more information about minimized windows, see the following Remarks section.
SM_CLEANBOOT Value that specifies how the system was started:

0 Normal boot
1 Fail-safe boot
2 Fail-safe with network boot

Fail-safe boot (also called SafeBoot) bypasses the user's startup files.
SM_CMONITORS | Windows NT 5.0 and later; Windows 98 and later: Number of display monitors on the desktop.
SM_CMOUSEBUTTONS | Number of buttons on mouse, or zero if no mouse is installed.
SM_CXBORDER,
SM_CYBORDER 		Width and height, in pixels, of a window border. This is equivalent to the SM_CXEDGE value for windows with the 3-D look.
SM_CXCURSOR,
SM_CYCURSOR 		Width and height, in pixels, of a cursor. The system cannot create cursors of other sizes.
SM_CXDLGFRAME,
SM_CYDLGFRAME 		Same as SM_CXFIXEDFRAME and SM_CYFIXEDFRAME.
SM_CXDOUBLECLK,
SM_CYDOUBLECLK 		Width and height, in pixels, of the rectangle around the location of a first click in a double-click sequence. The second click must occur within this rectangle for the system to consider the two clicks a double-click. (The two clicks must also occur within a specified time.)
SM_CXDRAG,
SM_CYDRAG 		Width and height, in pixels, of a rectangle centered on a drag point to allow for limited movement of the mouse pointer before a drag operation begins. This allows the user to click and release the mouse button easily without unintentionally starting a drag operation.
SM_CXEDGE,
SM_CYEDGE 		Dimensions, in pixels, of a 3-D border. These are the 3-D counterparts of SM_CXBORDER and SM_CYBORDER.
SM_CXFIXEDFRAME,
SM_CYFIXEDFRAME 		Thickness, in pixels, of the frame around the perimeter of a window that has a caption but is not sizable. SM_CXFIXEDFRAME is the width of the horizontal border and SM_CYFIXEDFRAME is the height of the vertical border.

Same as SM_CXDLGFRAME and SM_CYDLGFRAME.
SM_CXFRAME,
SM_CYFRAME 		Same as SM_CXSIZEFRAME and SM_CYSIZEFRAME.
SM_CXFULLSCREEN, SM_CYFULLSCREEN | Width and height of the client area for a full-screen window on the primary display monitor. To get the coordinates of the portion of the screen not obscured by the system taskbar or by application desktop toolbars, call the SystemParametersInfo function with the SPI_GETWORKAREA value.
SM_CXHSCROLL, SM_CYHSCROLL | Width, in pixels, of the arrow bitmap on a horizontal scroll bar; and height, in pixels, of a horizontal scroll bar.
SM_CXHTHUMB | Width, in pixels, of the thumb box in a horizontal scroll bar.
SM_CXICON,
SM_CYICON 		The default width and height, in pixels, of an icon. The LoadIcon function can load only icons of these dimensions.
SM_CXICONSPACING, SM_CYICONSPACING | Dimensions, in pixels, of a grid cell for items in large icon view. Each item fits into a rectangle of this size when arranged. These values are always greater than or equal to SM_CXICON and SM_CYICON.
SM_CXMAXIMIZED,
SM_CYMAXIMIZED 		Default dimensions, in pixels, of a maximized top-level window on the primary display monitor.
SM_CXMAXTRACK,
SM_CYMAXTRACK 		Default maximum dimensions, in pixels, of a window that has a caption and sizing borders. This metric refers to the entire desktop. The user cannot drag the window frame to a size larger than these dimensions. A window can override these values by processing the WM_GETMINMAXINFO message.
SM_CXMENUCHECK,
SM_CYMENUCHECK 		Dimensions, in pixels, of the default menu check-mark bitmap.
SM_CXMENUSIZE,
SM_CYMENUSIZE 		Dimensions, in pixels, of menu bar buttons, such as the child window close button used in the multiple document interface.
SM_CXMIN,
SM_CYMIN 		Minimum width and height, in pixels, of a window.
SM_CXMINIMIZED,
SM_CYMINIMIZED 		Dimensions, in pixels, of a normal minimized window.
SM_CXMINSPACING
SM_CYMINSPACING 		Dimensions, in pixels, of a grid cell for minimized windows. Each minimized window fits into a rectangle this size when arranged. These values are always greater than or equal to SM_CXMINIMIZED and SM_CYMINIMIZED.
SM_CXMINTRACK, SM_CYMINTRACK | Minimum tracking width and height, in pixels, of a window. The user cannot drag the window frame to a size smaller than these dimensions. A window can override these values by processing the WM_GETMINMAXINFO message.
SM_CXSCREEN,
SM_CYSCREEN 		Width and height, in pixels, of the screen of the primary display monitor. These are the same values you obtain by calling GetDeviceCaps(hdcPrimaryMonitor, HORZRES/VERTRES).
SM_CXSIZE,
SM_CYSIZE 		Width and height, in pixels, of a button in a window's caption or title bar.
SM_CXSIZEFRAME,
SM_CYSIZEFRAME 		Thickness, in pixels, of the sizing border around the perimeter of a window that can be resized. SM_CXSIZEFRAME is the width of the horizontal border, and SM_CYSIZEFRAME is the height of the vertical border.

Same as SM_CXFRAME and SM_CYFRAME.
SM_CXSMICON,
SM_CYSMICON 		Recommended dimensions, in pixels, of a small icon. Small icons typically appear in window captions and in small icon view.
SM_CXSMSIZE
SM_CYSMSIZE 		Dimensions, in pixels, of small caption buttons.
SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN | Windows NT 5.0 and later; Windows 98 and later: Width and height, in pixels, of the virtual screen. The virtual screen is the bounding rectangle of all display monitors. The SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN metrics are the coordinates of the top left corner of the virtual screen.
SM_CXVSCROLL, SM_CYVSCROLL | Width, in pixels, of a vertical scroll bar; and height, in pixels, of the arrow bitmap on a vertical scroll bar.
SM_CYCAPTION | Height, in pixels, of a normal caption area.
SM_CYKANJIWINDOW | For double-byte character set versions of the system, this is the height, in pixels, of the Kanji window at the bottom of the screen.
SM_CYMENU | Height, in pixels, of a single-line menu bar.
SM_CYSMCAPTION | Height, in pixels, of a small caption.
SM_CYVTHUMB | Height, in pixels, of the thumb box in a vertical scroll bar.
SM_DBCSENABLED | TRUE or nonzero if the double-byte character set (DBCS) version of USER.EXE is installed; FALSE or zero otherwise.
SM_DEBUG | TRUE or nonzero if the debugging version of USER.EXE is installed; FALSE or zero otherwise.
SM_MENUDROPALIGNMENT | TRUE or nonzero if drop-down menus are right-aligned with the corresponding menu-bar item; FALSE or zero if the menus are left-aligned.
SM_MIDEASTENABLED | TRUE if the system is enabled for Hebrew and Arabic languages.
SM_MOUSEPRESENT | TRUE or nonzero if a mouse is installed; FALSE or zero otherwise.
SM_MOUSEWHEELPRESENT | Windows NT 4.0 and later, Windows 98: TRUE or nonzero if a mouse with a wheel is installed; FALSE or zero otherwise.
SM_NETWORK | The least significant bit is set if a network is present; otherwise, it is cleared. The other bits are reserved for future use.
SM_PENWINDOWS | TRUE or nonzero if the Microsoft Windows for Pen computing extensions are installed; FALSE or zero otherwise.
SM_SECURE | TRUE if security is present; FALSE otherwise.
SM_SAMEDISPLAYFORMAT | Windows NT 5.0 and later; Windows 98 and later: TRUE if all the display monitors have the same color format, FALSE otherwise. Note that two displays can have the same bit depth, but different color formats. For example, the red, green, and blue pixels can be encoded with different numbers of bits, or those bits can be located in different places in a pixel's color value.
SM_SHOWSOUNDS | TRUE or nonzero if the user requires an application to present information visually in situations where it would otherwise present the information only in audible form; FALSE, or zero, otherwise.
SM_SLOWMACHINE | TRUE if the computer has a low-end (slow) processor; FALSE otherwise.
SM_SWAPBUTTON | TRUE or nonzero if the meanings of the left and right mouse buttons are swapped; FALSE or zero otherwise.
SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN | Windows NT 5.0 and later; Windows 98 and later: Coordinates for the left side and the top of the virtual screen. The virtual screen is the bounding rectangle of all display monitors. The SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN metrics are the width and height of the virtual screen.

Return Values

If the function succeeds, the return value is the requested system metric or configuration setting.

If the function fails, the return value is zero. GetLastError does not provide extended error information.

Remarks

System metrics may vary from display to display.

The SM_ARRANGE setting specifies how the system arranges minimized windows, and consists of a starting position and a direction. The starting position can be one of the following values.

Value | Meaning
ARW_BOTTOMLEFT | Start at the lower-left corner of the screen (default position).
ARW_BOTTOMRIGHT | Start at the lower-right corner of the screen. Equivalent to ARW_STARTRIGHT.
ARW_HIDE | Hide minimized windows by moving them off the visible area of the screen.
ARW_TOPLEFT | Start at the upper-left corner of the screen. Equivalent to ARV_STARTTOP.
ARW_TOPRIGHT | Start at the upper-right corner of the screen. Equivalent to ARW_STARTTOP | SRW_STARTRIGHT.

The direction in which to arrange can be one of the following values.

Value | Meaning
ARW_DOWN | Arrange vertically, top to bottom.
ARW_LEFT | Arrange horizontally, left to right.
ARW_RIGHT | Arrange horizontally, right to left.
ARW_UP | Arrange vertically, bottom to top.

Windows CE: Windows CE does not support the following nIndex values:

SM_ARRANGE | SM_CXMINIMIZED
SM_CLEANBOOT | SM_CYMINIMIZED
SM_CMETRICS | SM_CXMINSPACING
SM_CMOUSEBUTTONS | SM_CYMINSPACING
SM_CXCURSOR | SM_CXMINTRACK
SM_CYCURSOR | SM_CYMINTRACK
SM_CXDRAG | SM_CXSIZE
SM_CYDRAG | SM_CYSIZE
SM_CXFRAME | SM_CXSIZEFRAME
SM_CYFRAME | SM_CYSIZEFRAME
SM_CXFULLSCREEN | SM_CXSMSIZE
SM_CYFULLSCREEN | SM_CYSMSIZE
SM_CXHTHUMB | SM_CYSMCAPTION
SM_CYKANJIWINDOW | SM_CYVTHUMB
SM_CXMAXIMIZED | SM_DBCSENABLED
SM_CYMAXIMIZED | SM_MENUDROPALIGNMENT
SM_CXMAXTRACK | SM_MIDEASTENABLED
SM_CYMAXTRACK | SM_NETWORK
SM_CXMENUCHECK | SM_PENWINDOWS
SM_CYMENUCHECK | SM_SECURE
SM_CXMENUSIZE | SM_SHOWSOUNDS
SM_CYMENUSIZE | SM_SLOWMACHINE
SM_CXMIN | SM_SWAPBUTTON
SM_CYMIN |

If the Windows CE-based device you are targetting supports a mouse cursor, you can use the SM_CXCURSOR or SM_CYCURSOR values in the nIndex parameter.

Note Windows CE versions that support mouse cursors include the Iconcurs and Mcursor components rather than the Icon and Cursor components.

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

System Information Overview, System Information Functions, SystemParametersInfo


GetUserName

The GetUserName function retrieves the user name of the current thread. This is the name of the user currently logged onto the system.

BOOL GetUserName(
  LPTSTR lpBuffer,  // address of name buffer
  LPDWORD nSize     // address of size of name buffer
);

Parameters

lpBuffer
Pointer to the buffer to receive the null-terminated string containing the user's logon name. If this buffer is not large enough to contain the entire user name, the function fails. A buffer size of (UNLEN + 1) characters will hold the maximum length user name including the terminating null character. UNLEN is defined in LMCONS.H.
nSize
Pointer to a DWORD variable that, on input, specifies the maximum size, in characters, of the buffer specified by the lpBuffer parameter. If the function succeeds, the variable receives the number of characters copied to the buffer. If the buffer is not large enough, the function fails and the variable receives the required buffer size, in characters, including the terminating null character.

Return Values

If the function succeeds, the return value is nonzero, and the variable pointed to by nSize contains the number of characters copied to the buffer specified by lpBuffer, including the terminating null character.

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

Remarks

If the current thread is impersonating another client, the GetUserName function returns the user name of the client that the thread is impersonating.

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 advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

System Information Overview, System Information Functions, LookupAccountName


GetVersion

The GetVersion function returns the current version number of the operating system.

This function has been superseded by GetVersionEx, which is the preferred method for obtaining system version number information. New applications should use GetVersionEx. The GetVersionEx function was developed because many existing applications err when examining the DWORD return value of a GetVersion function call, transposing the major and minor version numbers packed into that DWORD. The GetVersionEx function forces applications to explicitly examine each element of version information, and allows for future enhancements to that information.

DWORD GetVersion(VOID)

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is a DWORD value that contains the major and minor version numbers of the operating system in the low order word, and information about the operating system platform in the high order word.

For all platforms, the low order word contains the version number of the operating system. The low-order byte of this word specifies the major version number, in hexadecimal notation. The high-order byte specifies the minor version (revision) number, in hexadecimal notation.

To distinguish between operating system platforms, use the high order bit and the low order byte, as shown in the following table:

Platform | High order bit | Low order byte (major version number)
Windows NT | zero | 3 or 4
Windows 95 and Windows 98 | 1 | 4
Win32s with Windows 3.1 | 1 | 3

For Windows NT and Win32s, the remaining bits in the high order word specify the build number.

For Windows 95 and Windows 98, the remaining bits of the high order word are reserved.

Remarks

This function does not return the current version number of MS-DOS.

The following code fragment illustrates how to extract information from the GetVersion return value:

dwVersion = GetVersion();

// Get major and minor version numbers of Windows
dwWindowsMajorVersion =  (DWORD)(LOBYTE(LOWORD(dwVersion)));
dwWindowsMinorVersion =  (DWORD)(HIBYTE(LOWORD(dwVersion)));
// Get build numbers for Windows NT or Win32s
if (dwVersion < 0x80000000)                // Windows NT
    dwBuild = (DWORD)(HIWORD(dwVersion));
else if (dwWindowsMajorVersion < 4)        // Win32s
    dwBuild = (DWORD)(HIWORD(dwVersion) & ~0x8000);
else         // Windows 95 -- No build numbers provided
    dwBuild =  0;

See Also

System Information Overview, System Information Functions, GetVersionEx


GetVersionEx

The GetVersionEx function obtains extended information about the version of the operating system that is currently running.

BOOL GetVersionEx(
  LPOSVERSIONINFO lpVersionInformation   // pointer to version
                                         // information structure
);

Parameters

lpVersionInformation
Pointer to an OSVERSIONINFO data structure that the function fills with operating system version information.

Before calling the GetVersionEx function, set the dwOSVersionInfoSize member of the OSVERSIONINFO data structure to sizeof(OSVERSIONINFO).

Windows NT 5.0 and later: This member can be a pointer to an OSVERSIONINFOEX structure. Set the dwOSVersionInfoSize member to sizeof(OSVERSIONINFOEX) to identify the type of 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. The function fails if you specify an invalid value for the dwOSVersionInfoSize member of the OSVERSIONINFO or OSVERSIONINFOEX structure.

Remarks

When using the GetVersionEx function to determine whether your application is running on a particular version of the operating system, check for version numbers that are greater than or equal to the desired version numbers. This ensures that the test succeeds for later versions of the operating system. For example, if your application requires Windows 98, use the following test:

GetVersionEx (&osvi);
bIsWindows98orLater =
   (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
   ( (osvi.dwMajorVersion > 4) ||
   ( (osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion > 0) ) );

Identifying the current operating system is usually not the best way to determine whether a particular operating system feature is present. This is because the operating system may have had new features added in a redistributable DLL. Rather than using GetVersionEx to determine the operating system platform or version number, test for the presence of the feature itself.

To determine the best way to test for a feature, refer to the documentation for the feature of interest. The following list discusses some common techniques for feature detection:

  • You can test for the presence of the functions associated with a feature. To test for the presence of a function in a system DLL, call the LoadLibrary function to load the DLL. Then call the GetProcAddress function to determine whether the function of interest is present in the DLL. Use the pointer returned by GetProcAddress to call the function. Note that even if the function is present, it may be a stub that just returns an error code such as ERROR_CALL_NOT_IMPLEMENTED.
  • You can determine the presence of some features by using the GetSystemMetrics function. For example, you can detect multiple display monitors by calling GetSystemMetrics(SM_CMONITORS).
  • There are several versions of the redistributable DLLs that implement shell and common control features. For information about determining which versions are present on the system your application is running on, see the topic Shell Versions.

Windows CE: The value of the dwPlatformID member of the OSVERSIONINFO structure will be VER_PLATFORM_WIN32_CE.

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.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

System Information Overview, System Information Functions, OSVERSIONINFO, OSVERSIONINFOEX


GetWindowsDirectory

The GetWindowsDirectory function retrieves the path of the Windows directory. The Windows directory contains such files as Win32-based applications, initialization files, and help files.

UINT GetWindowsDirectory(
  LPTSTR lpBuffer,  // address of buffer for Windows directory
  UINT uSize        // size of directory buffer
);

Parameters

lpBuffer
Pointer to the buffer to receive the null-terminated string containing the path. This path does not end with a backslash unless the Windows directory is the root directory. For example, if the Windows directory is named WINDOWS on drive C, the path of the Windows directory retrieved by this function is C:\WINDOWS. If the system was installed in the root directory of drive C, the path retrieved is C:\.
uSize
Specifies the maximum size, in characters, of the buffer specified by the lpBuffer parameter. This value should be set to at least MAX_PATH to allow sufficient room in the buffer for the path.

Return Values

If the function succeeds, the return value is the length, in characters, of the string copied to the buffer, not including the terminating null character.

If the length is greater than the size of the buffer, 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

The Windows directory is the directory where an application should store initialization and help files. If the user is running a shared version of the system, the Windows directory is guaranteed to be private for each user.

If an application creates other files that it wants to store on a per-user basis, it should place them in the directory specified by the HOMEPATH environment variable. This directory will be different for each user, if so specified by an administrator, via the User Manager administrative tool. HOMEPATH always specifies either the user's home directory, which is guaranteed to be private for each user, or a default directory (for example, C:\USERS\DEFAULT) where the user will have all access.

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

System Information Overview, System Information Functions, GetCurrentDirectory, GetSystemDirectory


IsProcessorFeaturePresent

The IsProcessorFeaturePresent function determines whether the specified processor feature is supported by at least one processor on the current machine.

BOOL IsProcessorFeaturePresent(
  DWORD ProcessorFeature  // specifies the processor feature
);

Parameters

ProcessorFeature
Specifies the processor feature to be tested. This value can be one of the following:
Value | Meaning
PF_FLOATING_POINT_PRECISION_
ERRATA 		In rare circumstances, a floating-point precision error can occur (Pentium).
PF_FLOATING_POINT_EMULATED | Floating-point operations are emulated using a software emulator.
PF_COMPARE_EXCHANGE_DOUBLE | The compare and exchange double operation is available (Pentium, MIPS, and Alpha).
PF_MMX_INSTRUCTIONS_AVAILABLE | The MMX instruction set is available.
PF_ALPHA_BYTE_INSTRUCTIONS | Windows NT 5.0 and later: The Alpha byte load and byte store instructions are available.

Return Values

If at least one of the processors supports the feature, the return value is nonzero.

If no processor supports the feature, the return value is zero.

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

System Information Overview, System Information Functions


SetComputerName

The SetComputerName function sets the computer name to be used the next time the system is restarted.

BOOL SetComputerName(
  LPCTSTR lpComputerName   // address of new computer name
);

Parameters

lpComputerName
Pointer to a null-terminated character string that specifies the name that will be the computer name the next time the computer is started. The name must not be longer than MAX_COMPUTERNAME_LENGTH characters.

Windows 95: If this string contains one or more characters that are outside the standard character set, those characters are coerced into standard characters.

Windows NT: If this string contains one or more characters that are outside the standard character set, SetComputerName returns ERROR_INVALID_PARAMETER. It does not coerce the characters outside the standard set.

The standard character set includes letters, numbers, and the following symbols: ! @ # $ % ^ & ' ) ( . - _ { } ~ .

Return Values

If 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 using this function must have administrator rights.

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

System Information Overview, System Information Functions, GetComputerName


SetSysColors

The SetSysColors function sets the colors for one or more display elements. Display elements are the various parts of a window and the display that appear on the system display screen.

BOOL WINAPI SetSysColors(
  int cElements,                 // number of elements to change
  CONST INT *lpaElements,        // address of array of elements
  CONST COLORREF *lpaRgbValues   // address of array of RGB values
);

Parameters

cElements
Specifies the number of display elements in the array pointed to by the lpaElements parameter.
lpaElements
Pointer to an array of integers that specify the display elements to be changed. For a list of display elements, see GetSysColor.
lpaRgbValues
Pointer to an array of unsigned long integers that contains the new red, green, blue (RGB) color value for each display element in the array pointed to by the lpaElements 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 SetSysColors function sends a WM_SYSCOLORCHANGE message to all windows to inform them of the change in color. It also directs the system to repaint the affected portions of all currently visible windows.

The SetSysColors function changes the current session only. The new colors are not saved when the system terminates.

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

System Information Overview, System Information Functions, GetSysColor


SystemParametersInfo

The SystemParametersInfo function queries or sets systemwide parameters. This function can also update the user profile while setting a parameter.

BOOL SystemParametersInfo(
  UINT uiAction, // system parameter to query or set
  UINT uiParam,  // depends on action to be taken
  PVOID pvParam, // depends on action to be taken
  UINT fWinIni   // user profile update flag
);

Parameters

uiAction
Specifies the systemwide parameter to query or set. This parameter can be one of the following values:
Value | Meaning
SPI_GETACCESSTIMEOUT | Retrieves information about the time-out period associated with the accessibility features. The pvParam parameter must point to an ACCESSTIMEOUT structure that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(ACCESSTIMEOUT).
SPI_GETACTIVEWINDOWTRACKING | Windows NT 5.0 and later, Windows 98: Indicates whether active window tracking (activating the window the mouse is on) is on or off. The pvParam parameter must point to a BOOL variable that receives TRUE for on, or FALSE for off.
SPI_GETACTIVEWNDTRKZORDER | Windows NT 5.0 and later, Windows 98: Indicates whether windows activated through active window tracking will be brought to the top. The pvParam parameter must point to a BOOL variable that receives TRUE for on, or FALSE for off.
SPI_GETACTIVEWNDTRKTIMEOUT | Windows NT 5.0 and later, Windows 98: Indicates the active window tracking delay, in milliseconds. The pvParam parameter must point to a DWORD variable that receives the time.
SPI_GETANIMATION | Retrieves the animation effects associated with user actions. The pvParam parameter must point to an ANIMATIONINFO structure that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(ANIMATIONINFO).
SPI_GETBEEP Indicates whether the warning beeper is on.

The pvParam parameter must point to a BOOL variable that receives TRUE if the beeper is on, or FALSE if it is off.
SPI_GETBORDER | Retrieves the border multiplier factor that determines the width of a window's sizing border. The pvParam parameter must point to an integer variable that receives this value.
SPI_GETCOMBOBOXANIMATION | Windows NT 5.0 and later, Windows 98: Indicates whether the slide-open effect for combo boxes is enabled. The pvParam parameter must point to a BOOL variable that receives TRUE for enabled, or FALSE for disabled.
SPI_GETDEFAULTINPUTLANG | Returns the keyboard layout handle for the system default input language. The pvParam parameter must point to the 32-bit variable that receives this value.
SPI_GETDRAGFULLWINDOWS Determines whether dragging of full windows is enabled. The pvParam parameter must point to a BOOL variable that receives TRUE if enabled, or FALSE otherwise.

Windows 95: This flag is supported only if Windows Plus! is installed. See SPI_GETWINDOWSEXTENSION.
SPI_GETFASTTASKSWITCH | This flag is obsolete. Previous versions of the system use this flag to determine whether ALT+TAB fast task switching is enabled. For Windows 95, Windows 98, and Windows NT version 4.0, fast task switching is always enabled. See SPI_GETSWITCHTASKDISABLE.
SPI_GETFILTERKEYS | Retrieves information about the FilterKeys accessibility feature. The pvParam parameter must point to a FILTERKEYS structure that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(FILTERKEYS).
SPI_GETFONTSMOOTHING Indicates whether the font smoothing feature is enabled. This feature uses font anti-aliasing to make font curves appear smoother by painting pixels at different gray levels.

The pvParam parameter must point to a BOOL variable that receives TRUE if the feature is enabled, or FALSE if it is not.

Windows 95: This flag is supported only if Windows Plus! is installed. See SPI_GETWINDOWSEXTENSION.
SPI_GETFOREGROUNDFLASHCOUNT | Windows NT 5.0 and later, Windows 98: Indicates the number of times SetForegroundWindow will flash the taskbar button when rejecting a foreground switch request. The pvParam parameter must point to a DWORD variable that receives the value.
SPI_GETFOREGROUNDLOCKTIMEOUT | Windows NT 5.0 and later, Windows 98: Indicates the amount of time following user input, in milliseconds, during which the system will not allow applications to force themselves into the foreground. The pvParam parameter must point to a DWORD variable that receives the time.
SPI_GETGRADIENTCAPTIONS | Windows NT 5.0 and later, Windows 98: Indicates whether the gradient effect for window title bars is enabled. The pvParam parameter must point to a BOOL variable that receives TRUE for enabled, or FALSE for disabled. For more information about the gradient effect, see the GetSysColor function.
SPI_GETGRIDGRANULARITY | Retrieves the current granularity value of the desktop sizing grid. The pvParam parameter must point to an integer variable that receives the granularity.
SPI_GETHIGHCONTRAST | Windows 95 and later, Windows NT 5.0 and later: Retrieves information about the HighContrast accessibility feature. The pvParam parameter must point to a HIGHCONTRAST structure that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(HIGHCONTRAST).
SPI_GETICONMETRICS | Retrieves the metrics associated with icons. The pvParam parameter must point to an ICONMETRICS structure that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(ICONMETRICS).
SPI_GETICONTITLELOGFONT | Retrieves the logical font information for the current icon-title font. The uiParam parameter specifies the size of a LOGFONT structure, and the pvParam parameter must point to the LOGFONT structure to fill in.
SPI_GETICONTITLEWRAP | Determines whether icon-title wrapping is enabled. The pvParam parameter must point to a BOOL variable that receives TRUE if enabled, or FALSE otherwise.
SPI_GETKEYBOARDDELAY | Retrieves the keyboard repeat-delay setting, which is a value in the range from 0 (approximately 250 ms delay) through 3 (approximately 1 second delay). The actual delay associated with each value may vary depending on the hardware. The pvParam parameter must point to an integer variable that receives the setting.
SPI_GETKEYBOARDPREF | Windows 95 and later, Windows NT 5.0 and later: Determines whether the user relies on the keyboard instead of the mouse, and wants applications to display keyboard interfaces that would otherwise be hidden. The pvParam parameter must point to a BOOL variable that receives TRUE if the user relies on the keyboard; or FALSE otherwise.
SPI_GETKEYBOARDSPEED | Retrieves the keyboard repeat-speed setting, which is a value in the range from 0 (approximately 30 repetitions per second) through 31 (approximately 2.5 repetitions per second). The actual repeat rates are hardware-dependent and may vary from a linear scale by as much as 20%. The pvParam parameter must point to a DWORD variable that receives the setting.
SPI_GETLISTBOXSMOOTHSCROLLING | Windows NT 5.0 and later, Windows 98: Indicates whether the smooth-scrolling effect for list boxes is enabled. The pvParam parameter must point to a BOOL variable that receives TRUE for enabled, or FALSE for disabled.
SPI_GETLOWPOWERACTIVE Determines whether the low-power phase of screen saving is enabled. The pvParam parameter must point to a BOOL variable that receives TRUE if enabled, or FALSE if disabled.

Windows 98: This flag is supported for 16-bit and 32-bit applications.

Windows 95: This flag is supported for 16-bit applications only.

Windows NT: This flag is supported for 32-bit applications on Windows NT versions 5.0 and later. It is not supported for 16-bit applications.
SPI_GETLOWPOWERTIMEOUT Retrieves the time-out value for the low-power phase of screen saving. The pvParam parameter must point to an integer variable that receives the value.

Windows 98: This flag is supported for 16-bit and 32-bit applications.

Windows 95: This flag is supported for 16-bit applications only.

Windows NT: This flag is supported for 32-bit applications on Windows NT versions 5.0 and later. It is not supported for 16-bit applications.
SPI_GETMENUDROPALIGNMENT | Determines whether pop-up menus are left-aligned or right-aligned, relative to the corresponding menu-bar item. The pvParam parameter must point to a BOOL variable that receives TRUE if left-aligned, or FALSE otherwise.
SPI_GETMINIMIZEDMETRICS | Retrieves the metrics associated with minimized windows. The pvParam parameter must point to a MINIMIZEDMETRICS structure that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(MINIMIZEDMETRICS).
SPI_GETMOUSE | Retrieves the two mouse threshold values and the mouse acceleration. The pvParam parameter must point to an array of three integers that receives these values. See mouse_event for further information.
SPI_GETMOUSEHOVERHEIGHT | Windows NT 4.0 and later, Windows 98: Gets the height, in pixels, of the rectangle within which the mouse pointer has to stay for TrackMouseEvent to generate a WM_MOUSEHOVER message. The pvParam parameter must point to a UINT variable that receives the height.
SPI_GETMOUSEHOVERTIME | Windows NT 4.0 and later, Windows 98: Gets the time, in milliseconds, that the mouse pointer has to stay in the hover rectangle for TrackMouseEvent to generate a WM_MOUSEHOVER message. The pvParam parameter must point to a UINT variable that receives the time.
SPI_GETMOUSEHOVERWIDTH | Windows NT 4.0 and later, Windows 98: Gets the width, in pixels, of the rectangle within which the mouse pointer has to stay for TrackMouseEvent to generate a WM_MOUSEHOVER message. The pvParam parameter must point to a UINT variable that receives the width.
SPI_GETMOUSEKEYS | Retrieves information about the MouseKeys accessibility feature. The pvParam parameter must point to a MOUSEKEYS structure that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(MOUSEKEYS).
SPI_GETMOUSESPEED | Windows NT 5.0 and later, Windows 98: Retrieves the current mouse speed. The mouse speed determines how far the pointer will move based on the distance the mouse moves. The pvParam parameter must point to an integer that receives a value which ranges between 1 (slowest) and 20 (fastest). A value of 10 is the default. The value can be set by an end user using the mouse control panel application or by an application using SPI_SETMOUSESPEED.
SPI_GETMOUSETRAILS Windows 95 and later: Indicates whether the Mouse Trails feature is enabled. This feature improves the visibility of mouse cursor movements by briefly showing a trail of cursors and quickly erasing them.

The pvParam parameter must point to an integer variable that receives a value. If the value is zero or 1, the feature is disabled. If the value is greater than 1, the feature is enabled and the value indicates the number of cursors drawn in the trail. The uiParam parameter is not used.

SPI_GETNONCLIENTMETRICS | Retrieves the metrics associated with the nonclient area of nonminimized windows. The pvParam parameter must point to a NONCLIENTMETRICS structure that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(NONCLIENTMETRICS).
SPI_GETPOWEROFFACTIVE Determines whether the power-off phase of screen saving is enabled. The pvParam parameter must point to a BOOL variable that receives TRUE if enabled, or FALSE if disabled.

Windows 98: This flag is supported for 16-bit and 32-bit applications.

Windows 95: This flag is supported for 16-bit applications only.

Windows NT: This flag is supported for 32-bit applications on Windows NT versions 5.0 and later. It is not supported for 16-bit applications.
SPI_GETPOWEROFFTIMEOUT Retrieves the time-out value for the power-off phase of screen saving. The pvParam parameter must point to an integer variable that receives the value.

Windows 98: This flag is supported for 16-bit and 32-bit applications.

Windows 95: This flag is supported for 16-bit applications only.

Windows NT: This flag is supported for 32-bit applications on Windows NT versions 5.0 and later. It is not supported for 16-bit applications.
SPI_GETSCREENREADER Windows 95 and later, Windows NT 5.0 and later: Determines whether a screen reviewer utility is running. A screen reviewer utility directs textual information to an output device, such as a speech synthesizer or Braille display. When this flag is set, an application should provide textual information in situations where it would otherwise present the information graphically.

The pvParam parameter is a pointer to a BOOL variable that receives TRUE if a screen reviewer utility is running, or FALSE otherwise.
SPI_GETSCREENSAVEACTIVE | Determines whether screen saving is enabled. The pvParam parameter must point to a BOOL variable that receives TRUE if screen saving is enabled, or FALSE otherwise.
SPI_GETSCREENSAVERRUNNING | Windows NT 5.0 and later, Windows 98: Determines whether a screen saver is currently running on the window station of the calling process. The pvParam parameter must point to a BOOL variable that receives TRUE if a screen saver is currently running, or FALSE otherwise. Note that only the interactive window station, "WinSta0", can have a screen saver running.
SPI_GETSCREENSAVETIMEOUT | Retrieves the screen saver time-out value, in seconds. The pvParam parameter must point to an integer variable that receives the value.
SPI_GETSERIALKEYS | Windows 95 and later: Retrieves information about the SerialKeys accessibility feature. The pvParam parameter must point to a SERIALKEYS structure that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(SERIALKEYS).
SPI_GETSHOWSOUNDS Determines whether the Show Sounds accessibility flag is on or off. If it is on, the user requires an application to present information visually in situations where it would otherwise present the information only in audible form. The pvParam parameter must point to a BOOL variable that receives TRUE if the feature is on, or FALSE if it is off.

Using this value is equivalent to calling GetSystemMetrics (SM_SHOWSOUNDS). That is the recommended call.
SPI_GETSNAPTODEFBUTTON | Windows NT 4.0 and later, Windows 98: Determines whether the snap-to-default-button feature is enabled. If enabled, the mouse cursor automatically moves to the default button, such as "OK" or "Apply", of a dialog box. The pvParam parameter must point to a BOOL variable that receives TRUE if the feature is on, or FALSE if it is off.
SPI_GETSOUNDSENTRY | Retrieves information about the SoundSentry accessibility feature. The pvParam parameter must point to a SOUNDSENTRY structure that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(SOUNDSENTRY).
SPI_GETSTICKYKEYS | Retrieves information about the StickyKeys accessibility feature. The pvParam parameter must point to a STICKYKEYS structure that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(STICKYKEYS).
SPI_GETSWITCHTASKDISABLE | Windows NT 5.0 and later: Determines whether ALT+TAB and ALT+ESC task switching is enabled. The pvParam parameter must point to a UINT variable that receives 1 if task switching is disabled, or zero if it is enabled. By default, task switching is enabled.
SPI_GETTOGGLEKEYS | Retrieves information about the ToggleKeys accessibility feature. The pvParam parameter must point to a TOGGLEKEYS structure that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(TOGGLEKEYS).
SPI_GETWHEELSCROLLLINES | Windows NT 4.0 and later, Windows 98: Gets the number of lines to scroll when the mouse wheel is rotated. The pvParam parameter must point to a UINT variable that receives the number of lines. The default value is 3.
SPI_GETWINDOWSEXTENSION | Windows 95: Indicates whether the Windows extension, Windows Plus!, is installed. Set the uiParam parameter to 1. The pvParam parameter is not used. The function returns TRUE if the extension is installed, or FALSE if it is not.
SPI_GETWORKAREA Retrieves the size of the work area on the primary display monitor. The work area is the portion of the screen not obscured by the system taskbar or by application desktop toolbars. The pvParam parameter must point to a RECT structure that receives the coordinates of the work area, expressed in virtual screen coordinates.

To get the work area of a monitor other than the primary display monitor, call the GetMonitorInfo function.
SPI_ICONHORIZONTALSPACING | Sets the width of an icon cell. The uiParam parameter specifies the width, in pixels.
SPI_ICONVERTICALSPACING | Sets the height of an icon cell. The uiParam parameter specifies the height, in pixels.
SPI_LANGDRIVER | Not implemented.
SPI_SCREENSAVERRUNNING | Renamed to SPI_SETSCREENSAVERRUNNING.
SPI_SETACCESSTIMEOUT | Sets the time-out period associated with the accessibility features. The pvParam parameter must point to an ACCESSTIMEOUT structure that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(ACCESSTIMEOUT).
SPI_SETACTIVEWINDOWTRACKING | Windows NT 5.0 and later, Windows 98: Sets active window tracking (activating the window the mouse is on) either on or off. Set pvParam to TRUE for on or FALSE for off.
SPI_SETACTIVEWNDTRKZORDER | Windows NT 5.0 and later, Windows 98: Indicates whether or not windows activated through active window tracking should be brought to the top. Set pvParam to TRUE for on or FALSE for off.
SPI_SETACTIVEWNDTRKTIMEOUT | Windows NT 5.0 and later, Windows 98: Sets the active window tracking delay. Set pvParam to the number of milliseconds to delay before activating the window under the mouse pointer.
SPI_SETANIMATION | Sets the animation effects associated with user actions. The pvParam parameter must point to an ANIMATIONINFO structure that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(ANIMATIONINFO).
SPI_SETBEEP | Turns the warning beeper on or off. The uiParam parameter specifies TRUE for on, or FALSE for off.
SPI_SETBORDER | Sets the border multiplier factor that determines the width of a window's sizing border. The uiParam parameter specifies the new value.
SPI_SETCOMBOBOXANIMATION | Windows NT 5.0 and later, Windows 98: Enables or disables the slide-open effect for combo boxes. Set the pvParam parameter to TRUE to enable the gradient effect, or FALSE to disable it.
SPI_SETCURSORS | Reloads the system cursors. Set the uiParam parameter to zero and the pvParam parameter to NULL
SPI_SETDEFAULTINPUTLANG | Sets the default input language for the system shell and applications. The specified language must be displayable using the current system character set. The pvParam parameter must point to a DWORD variable that contains the keyboard layout handle for the default language.
SPI_SETDESKPATTERN | Sets the current desktop pattern by causing Windows to read the Pattern= setting from the WIN.INI file.
SPI_SETDESKWALLPAPER | Sets the desktop wallpaper. The pvParam parameter must point to a null-terminated string containing the name of a bitmap file.
SPI_SETDOUBLECLICKTIME | Sets the double-click time for the mouse to the value of the uiParam parameter. The double-click time is the maximum number of milliseconds that can occur between the first and second clicks of a double-click. You can also call the SetDoubleClickTime function to set the double-click time. To get the current double-click time, call the GetDoubleClickTime function.
SPI_SETDOUBLECLKHEIGHT Sets the height of the double-click rectangle to the value of the uiParam parameter.

The double-click rectangle is the rectangle within which the second click of a double-click must fall for it to be registered as a double-click.
SPI_SETDOUBLECLKWIDTH Sets the width of the double-click rectangle to the value of the uiParam parameter.

The double-click rectangle is the rectangle within which the second click of a double-click must fall for it to be registered as a double-click.
SPI_SETDRAGFULLWINDOWS Sets dragging of full windows either on or off. The uiParam parameter specifies TRUE for on, or FALSE for off.

Windows 95: This flag is supported only if Windows Plus! is installed. See SPI_GETWINDOWSEXTENSION.
SPI_SETDRAGHEIGHT Sets the height, in pixels, of the rectangle used to detect the start of a drag operation.

See SM_CXDRAG and SM_CYDRAG in the table under the nIndex parameter of GetSystemMetrics.
SPI_SETDRAGWIDTH Sets the width, in pixels, of the rectangle used to detect the start of a drag operation.

See SM_CXDRAG and SM_CYDRAG in the table under the nIndex parameter of GetSystemMetrics.
SPI_SETFASTTASKSWITCH | This flag is obsolete. Previous versions of the system use this flag to enable or disable ALT+TAB fast task switching. For Windows 95, Windows 98, and Windows NT version 4.0, fast task switching is always enabled. See SPI_SETSWITCHTASKDISABLE.
SPI_SETFILTERKEYS | Sets the parameters of the FilterKeys accessibility feature. The pvParam parameter must point to a FILTERKEYS structure that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(FILTERKEYS).
SPI_SETFONTSMOOTHING Enables or disables the font smoothing feature, which uses font anti-aliasing to make font curves appear smoother by painting pixels at different gray levels.

To enable the feature, set the uiParam parameter to TRUE. To disable the feature, set uiParam to FALSE.

Windows 95: This flag is supported only if Windows Plus! is installed. See SPI_GETWINDOWSEXTENSION.
SPI_SETFOREGROUNDFLASHCOUNT | Windows NT 5.0 and later, Windows 98: Sets the number of times SetForegroundWindow will flash the taskbar button when rejecting a foreground switch request. Set pvParam to the number of times to flash.
SPI_SETFOREGROUNDLOCKTIMEOUT | Windows NT 5.0 and later, Windows 98: Sets the amount of time following user input, in milliseconds, during which the system will not allow applications to force themselves into the foreground. Set pvParam to the new timeout value.
SPI_SETGRADIENTCAPTIONS | Windows NT 5.0 and later, Windows 98: Enables or disables the gradient effect for window title bars. Set the pvParam parameter to TRUE to enable it, or FALSE to disable it. For more information about the gradient effect, see the GetSysColor function.
SPI_SETGRIDGRANULARITY | Sets the granularity of the desktop sizing grid to the value of the uiParam parameter.
SPI_SETHANDHELD | Used internally; applications should not use this value.
SPI_SETHIGHCONTRAST | Windows 95 and later, Windows NT 5.0 and later: Sets the parameters of the HighContrast accessibility feature. The pvParam parameter must point to a HIGHCONTRAST structure that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(HIGHCONTRAST).
SPI_SETICONMETRICS | Sets the metrics associated with icons. The pvParam parameter must point to an ICONMETRICS structure that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(ICONMETRICS).
SPI_SETICONS | Reloads the system icons. Set the uiParam parameter to zero and the pvParam parameter to NULL
SPI_SETICONTITLELOGFONT | Sets the font that is used for icon titles. The uiParam parameter specifies the size of a LOGFONT structure, and the pvParam parameter must point to a LOGFONT structure.
SPI_SETICONTITLEWRAP | Turns icon-title wrapping on or off. The uiParam parameter specifies TRUE for on, or FALSE for off.
SPI_SETKEYBOARDDELAY | Sets the keyboard repeat-delay setting. The uiParam parameter must specify 0, 1, 2, or 3, where zero sets the shortest delay (approximately 250 ms) and 3 sets the longest delay (approximately 1 second). The actual delay associated with each value may vary depending on the hardware.
SPI_SETKEYBOARDPREF | Windows 95 and later, Windows NT 5.0 and later: Sets the keyboard preference. The uiParam parameter specifies TRUE if the user relies on the keyboard instead of the mouse, and wants applications to display keyboard interfaces that would otherwise be hidden; uiParam is FALSE otherwise.
SPI_SETKEYBOARDSPEED | Sets the keyboard repeat-speed setting. The uiParam parameter must specify a value in the range from 0 through 31, where zero sets the fastest speed (approximately 30 repetitions per second) and 31 sets the slowest speed (approximately 2.5 repetitions per second). The actual repeat rates are hardware-dependent and may vary from a linear scale by as much as 20%. If uiParam is greater than 31, the parameter is set to 31.
SPI_SETLANGTOGGLE | Sets the hot key set for switching between input languages. The uiParam and pvParam parameters are not used. The value sets the shortcut keys in the keyboard property sheets by reading the registry again. The registry must be set before this flag is used. the path in the registry is \HKEY_CURRENT_USER\keyboard layout\toggle. Valid values are "1" = alt+shift, "2" = ctrl+shift, and "3" = none.
SPI_SETLISTBOXSMOOTHSCROLLING | Windows NT 5.0 and later, Windows 98: Enables or disables the smooth-scrolling effect for list boxes. Set the pvParam parameter to TRUE to enable the smooth-scrolling effect, or FALSE to disable it.
SPI_SETLOWPOWERACTIVE Activates or deactivates the low-power phase of screen saving. Set uiParam to 1 to activate, or zero to deactivate. The pvParam parameter must be NULL.

Windows 98: This flag is supported for 16-bit and 32-bit applications.

Windows 95: This flag is supported for 16-bit applications only.

Windows NT: This flag is supported for 32-bit applications on Windows NT versions 5.0 and later. It is not supported for 16-bit applications.
SPI_SETLOWPOWERTIMEOUT Sets the time-out value, in seconds, for the low-power phase of screen saving. The uiParam parameter specifies the new value. The pvParam parameter must be NULL.

Windows 98: This flag is supported for 16-bit and 32-bit applications.

Windows 95: This flag is supported for 16-bit applications only.

Windows NT: This flag is supported for 32-bit applications on Windows NT versions 5.0 and later. It is not supported for 16-bit applications.
SPI_SETMENUDROPALIGNMENT | Sets the alignment value of pop-up menus. The uiParam parameter specifies TRUE for right alignment, or FALSE for left alignment.
SPI_SETMINIMIZEDMETRICS | Sets the metrics associated with minimized windows. The pvParam parameter must point to a MINIMIZEDMETRICS structure that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(MINIMIZEDMETRICS).
SPI_SETMOUSE | Sets the two mouse threshold values and the mouse acceleration. The pvParam parameter must point to an array of three integers that specifies these values. See mouse_event for further information.
SPI_SETMOUSEBUTTONSWAP | Swaps or restores the meaning of the left and right mouse buttons. The uiParam parameter specifies TRUE to swap the meanings of the buttons, or FALSE to to restore their original meanings.
SPI_SETMOUSEHOVERHEIGHT | Windows NT 4.0 and later, Windows 98: Sets the height, in pixels, of the rectangle within which the mouse pointer has to stay for TrackMouseEvent to generate a WM_MOUSEHOVER message. Set the uiParam parameter to the new height.
SPI_SETMOUSEHOVERTIME | Windows NT 4.0 and later, Windows 98: Sets the time, in milliseconds, that the mouse pointer has to stay in the hover rectangle for TrackMouseEvent to generate a WM_MOUSEHOVER message. This is used only if you pass HOVER_DEFAULT in the dwHoverTime parameter in the call to TrackMouseEvent. Set the uiParam parameter to the new time.
SPI_SETMOUSEHOVERWIDTH | Windows NT 4.0 and later, Windows 98: Sets the width, in pixels, of the rectangle within which the mouse pointer has to stay for TrackMouseEvent to generate a WM_MOUSEHOVER message. Set the uiParam parameter to the new width.
SPI_SETMOUSEKEYS | Sets the parameters of the MouseKeys accessibility feature. The pvParam parameter must point to a MOUSEKEYS structure that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(MOUSEKEYS).
SPI_SETMOUSESPEED | Windows NT 5.0 and later, Windows 98: Sets the current mouse speed. The pvParam parameter must point to an integer between 1 (slowest) and 20 (fastest). A value of 10 is the default. This value is typically set using the mouse control panel application.
SPI_SETMOUSETRAILS Windows 95 and later: Enables or disables the Mouse Trails feature, which improves the visibility of mouse cursor movements by briefly showing a trail of cursors and quickly erasing them.

To disable the feature, set the uiParam parameter to zero or 1. To enable the feature, set uiParam to a value greater than 1 to indicate the number of cursors drawn in the trail.

SPI_SETNONCLIENTMETRICS | Sets the metrics associated with the nonclient area of nonminimized windows. The pvParam parameter must point to a NONCLIENTMETRICS structure that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(NONCLIENTMETRICS).
SPI_SETPENWINDOWS | Windows 95 and later: Specifies that pen windows is being loaded or unloaded. The uiParam parameter is TRUE when loading and FALSE when unloading pen windows. The pvParam parameter is NULL.
SPI_SETPOWEROFFACTIVE Activates or deactivates the power-off phase of screen saving. Set uiParam to 1 to activate, or zero to deactivate. The pvParam parameter must be NULL.

Windows 98: This flag is supported for 16-bit and 32-bit applications.

Windows 95: This flag is supported for 16-bit applications only.

Windows NT: This flag is supported for 32-bit applications on Windows NT versions 5.0 and later. It is not supported for 16-bit applications.
SPI_SETPOWEROFFTIMEOUT Sets the time-out value, in seconds, for the power-off phase of screen saving. The uiParam parameter specifies the new value. The pvParam parameter must be NULL.

Windows 98: This flag is supported for 16-bit and 32-bit applications.

Windows 95: This flag is supported for 16-bit applications only.

Windows NT: This flag is supported for 32-bit applications on Windows NT versions 5.0 and later. It is not supported for 16-bit applications.
SPI_SETSCREENREADER | Windows 95 and later, Windows NT 5.0 and later: Indicates whether a screen review utility is running. The uiParam parameter specifies TRUE for on, or FALSE for off.
SPI_SETSCREENSAVEACTIVE | Sets the state of the screen saver. The uiParam parameter specifies TRUE to activate screen saving, or FALSE to deactivate it.
SPI_SETSCREENSAVERRUNNING | Windows 95 and later: Used internally; applications should not use this flag.
SPI_SETSCREENSAVETIMEOUT | Sets the screen saver time-out value to the value of the uiParam parameter. This value is the amount of time, in seconds, that the system must be idle before the screen saver activates.
SPI_SETSERIALKEYS | Windows 95 and later: Sets the parameters of the SerialKeys accessibility feature. The pvParam parameter must point to a SERIALKEYS structure that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(SERIALKEYS).
SPI_SETSHOWSOUNDS | Sets the ShowSounds accessibility feature as on or off. The uiParam parameter specifies TRUE for on, or FALSE for off.
SPI_SETSNAPTODEFBUTTON | Windows NT 4.0 and later, Windows 98: Enables or disables the snap-to-default-button feature. If enabled, the mouse cursor automatically moves to the default button, such as OK or Apply, of a dialog box. Set the uiParam parameter to TRUE to enable the feature, or FALSE to disable it.
SPI_SETSOUNDSENTRY | Sets the parameters of the SoundSentry accessibility feature. The pvParam parameter must point to a SOUNDSENTRY structure that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(SOUNDSENTRY).
SPI_SETSTICKYKEYS | Sets the parameters of the StickyKeys accessibility feature. The pvParam parameter must point to a STICKYKEYS structure that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(STICKYKEYS).
SPI_SETSWITCHTASKDISABLE | Windows NT 5.0 and later: Enables or disables ALT+TAB and ALT+ESC task switching. Set the uiParam parameter to 1 to enable the feature, or zero to disable it. By default, task switching is enabled.
SPI_SETTOGGLEKEYS | Sets the parameters of the ToggleKeys accessibility feature. The pvParam parameter must point to a TOGGLEKEYS structure that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(TOGGLEKEYS).
SPI_SETWHEELSCROLLLINES Windows NT 4.0 and later, Windows 98: Sets the number of lines to scroll when the mouse wheel is rotated. The number of lines is set from the uiParam parameter.

The number of lines is the suggested number of lines to scroll when the mouse wheel is rolled without using modifier keys. If the number is 0, then no scrolling should occur. If the number of lines to scroll is greater than the number of lines viewable, and in particular if it is WHEEL_PAGESCROLL (#defined as UINT_MAX), the scroll operation should be interpreted as clicking once in the page down or page up regions of the scroll bar.
SPI_SETWORKAREA Sets the size of the work area. The work area is the portion of the screen not obscured by the system taskbar or by application desktop toolbars. The pvParam parameter is a pointer to a RECT structure that specifies the new work area rectangle, expressed in virtual screen coordinates. In a system with multiple display monitors, the function sets the work area of the monitor that contains the specified rectangle.

If pvParam is NULL, the function sets the work area of the primary display monitor to the full screen.

uiParam
Depends on the system parameter being queried or set. For more information about systemwide parameters, see the uiAction parameter. If not otherwise indicated, you must specify zero for this parameter.
pvParam
Depends on the system parameter being queried or set. For more information about systemwide parameters, see the uiAction parameter. If not otherwise indicated, you must specify NULL for this parameter.
fWinIni
If a system parameter is being set, specifies whether the user profile is to be updated, and if so, whether the WM_SETTINGCHANGE message is to be broadcast to all top-level windows to notify them of the change. This parameter can be zero or can be one of the following values:
Value | Action
SPIF_UPDATEINIFILE | Writes the new system-wide parameter setting to the user profile.
SPIF_SENDCHANGE | Broadcasts the WM_SETTINGCHANGE message after updating the user profile.
SPIF_SENDWININICHANGE | Same as SPIF_SENDCHANGE.

Return Values

If 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 is intended for use with applications, such as the Control Panel, that allow the user to customize the Windows environment.

A keyboard layout name should be derived from the hexadecimal value of the language identifier corresponding to the layout. For example, U.S. English has a language identifier of 0x0409, so the primary U.S. English layout is named "00000409." Variants of U.S. English layout, such as the Dvorak layout, are named "00010409," "00020409" and so on. For a list of the primary language identifiers and sublanguage identifiers that make up a language identifier, see the MAKELANGID macro.

Windows CE: Windows CE supports only the following uiAction values:

SPI_GETBATTERYIDLETIMEOUT
Gets the amount of time that Windows CE will stay on with battery power before it suspends due to user inaction. The pvParam parameter points to a DWORD that returns the time in seconds. This flag is ignored if pvParam is zero.
SPI_GETEXTERNALIDLETIMEOUT
Gets the amount of time that Windows CE will stay on with AC power before it suspends due to user inaction. The pvParam parameter points to a DWORD that returns the time in seconds. This flag is ignored if pvParam is zero.
SPI_GETMOUSE
Retrieves the two mouse threshold values and the mouse speed.
SPI_GETOEMINFO
Returns a string containing the model number and manufacturer name. The uiParam parameter specifies the length of the buffer in pvParam, which on successful return contains the string in Unicode characters.
SPI_GETPLATFORMTYPE
Returns a string specifying the type of Windows CE device, such as "H/PC". The uiParam parameter specifies the length of the buffer in pvParam, which on successful return contains the string in Unicode characters. This string allows applications like H/PC Explorer to determine the device type.
SPI_GETWAKEUPIDLETIMEOUT
Gets the amount of time that Windows CE will stay on after a user notification that reactivates a suspended device. The pvParam parameter points to a DWORD that returns the time in seconds. This flag is ignored if pvParam is zero.
SPI_GETWORKAREA
Retrieves the size of the work area; the portion of the screen not obscured by the tray.
SPI_SETBATTERYIDLETIMEOUT
Sets the amount of time that Windows CE will stay on with battery power before it suspends due to user inaction. The Windows CE operating system will remain on, with battery power, as long as the keyboard or touch screen is active. The uiParam parameter specifies the time to set in seconds. This flag is ignored if uiParam is set to zero.
SPI_SETEXTERNALIDLETIMEOUT
Sets the amount of time that Windows CE will stay on with AC power before it suspends due to user inaction. The Windows CE operating system will remain on, with AC power, as long as the keyboard or touch screen is active. The uiParam parameter specifies the time in seconds. This flag is ignored if uiParam is set to zero.
SPI_SETMOUSE
Sets the two mouse threshold values and the mouse speed.
SPI_SETWAKEUPIDLETIMEOUT
Sets the amount of time that Windows CE will stay on after a user notification that reactivates the suspended device. The uiParam parameter specifies the time in seconds. This flag is ignored if uiParam is set to zero.
SPI_SETWORKAREA
Sets the size of the work area — the portion of the screen not obscured by the taskbar.

If the pvParam buffer used to get the platform type or OEM information string is too small, this function fails with ERROR_INSUFFICIENT_BUFFER in the last error.

Windows CE supports only the UNICODE version of this function.

Windows CE does not support the SPIF_SENDWININICHANGE value for the fWinIni 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.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

System Information Overview, System Information Functions, ACCESSTIMEOUT, ANIMATIONINFO, FILTERKEYS, GetLastError, GetSystemMetrics, HIGHCONTRAST, ICONMETRICS, LOGFONT, MAKELANGID, MINIMIZEDMETRICS, mouse_event, MOUSEKEYS, NONCLIENTMETRICS, RECT, SERIALKEYS, SetForegroundWindow, SOUNDSENTRY, STICKYKEYS, TOGGLEKEYS, TrackMouseEvent WM_SETTINGCHANGE


System Information Structures

The following structures are used with system information.

ANIMATIONINFO
HW_PROFILE_INFO
MINIMIZEDMETRICS
NONCLIENTMETRICS
OSVERSIONINFO
OSVERSIONINFOEX
SYSTEM_INFO


ANIMATIONINFO

The ANIMATIONINFO structure specifies the animation effects associated with user actions. This structure is used with the SystemParametersInfo function when the SPI_GETANIMATION or SPI_SETANIMATION action value is specified.

typedef struct tagANIMATIONINFO {
    UINT cbSize;
    int  iMinAnimate;
} ANIMATIONINFO, FAR *LPANIMATIONINFO;

Members

cbSize
Specifies the size of the structure, in bytes.
iMinAnimate
Indicates that minimize and restore animation is enabled (if the member is a nonzero value) or not enabled (if zero).

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

System Information Overview, System Information Structures, SystemParametersInfo


HW_PROFILE_INFO

The HW_PROFILE_INFO structure contains information about a hardware profile. The GetCurrentHwProfile function uses this structure to retrieve the current hardware profile for the local computer.

typedef struct tagHW_PROFILE_INFO {
    DWORD           dwDockInfo;
    TCHAR           szHwProfileGuid[HW_PROFILE_GUIDLEN];
    TCHAR           szHwProfileName[MAX_PROFILE_LEN];
} HW_PROFILE_INFO, *LPHW_PROFILE_INFO;

Members

dwDockInfo
A set of bit flags that indicate the docking state of the computer. This member can be a combination of the following values.
Value | Meaning
DOCKINFO_DOCKED | The computer is docked. This flag is always set for desktop systems that cannot be undocked.
DOCKINFO_UNDOCKED | The computer is undocked. This flag is always set for desktop systems that cannot be undocked.
DOCKINFO_USER_SUPPLIED If this flag is set, GetCurrentHwProfile retrieved the current docking state from information provided by the user in the Hardware Profiles page of the System control panel application.

Currently, Windows NT and Windows 95 are not able to detect the docking state. Consequently, this flag is always set.

DOCKINFO_USER_DOCKED | The computer is docked, according to information provided by the user. This value is a combination of the DOCKINFO_USER_SUPPLIED and DOCKINFO_DOCKED flags.
DOCKINFO_USER_UNDOCKED | The computer is undocked, according to information provided by the user. This value is a combination of the DOCKINFO_USER_SUPPLIED and DOCKINFO_UNDOCKED flags.

szHwProfileGuid
A null-terminated string that contains the globally unique identifier (GUID) string for the current hardware profile. The string returned by GetCurrentHwProfile encloses the GUID in curly braces "{}" and includes a null-terminator; for example:

"{12340001-4980-1920-6788-123456789012}"

You can use this string as a registry subkey under your application's configuration settings key in HKEY_CURRENT_USER. This enables you to store settings for each hardware profile.

szHwProfileName
A null-terminated string that contains the display name for the current hardware profile.

QuickInfo

Windows NT: Requires version 4.0 or later.
Windows: Requires Windows 95 OSR2 or later.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

System Information Overview, System Information Structures, GetCurrentHwProfile


MINIMIZEDMETRICS

The MINIMIZEDMETRICS structure contains the scalable metrics associated with minimized windows. This structure is used with the SystemParametersInfo function when the SPI_GETMINIMIZEDMETRICS or SPI_SETMINIMIZEDMETRICS action value is specified.

typedef struct tagMINIMIZEDMETRICS {
    UINT    cbSize;
    int     iWidth;
    int     iHorzGap;
    int     iVertGap;
    int     iArrange;
}   MINIMIZEDMETRICS, FAR *LPMINIMIZEDMETRICS;

Members

cbSize
Specifies the size of the structure, in bytes.
iWidth
Specifies the width, in pixels, of minimized windows.
iHorzGap and iVertGap
Specifies the amount of horizontal and vertical space, in pixels, between arranged minimized windows.
iArrange
Specifies the starting position and direction used when arranging minimized windows. The starting position must be one of the following values:
Value | Meaning
ARW_BOTTOMLEFT | Start at the lower-left corner of the work area.
ARW_BOTTOMRIGHT | Start at the lower-right corner of the work area.
ARW_TOPLEFT | Start at the upper-left corner of the work area.
ARW_TOPRIGHT | Start at the upper-right corner of the work area.

The direction must be one of the following values:
Value | Meaning
ARW_LEFT | Arrange left (valid with ARW_BOTTOMRIGHT and ARW_TOPRIGHT only).
ARW_RIGHT | Arrange right (valid with ARW_BOTTOMLEFT and ARW_TOPLEFT only).
ARW_UP | Arrange up (valid with ARW_BOTTOMLEFT and ARW_BOTTOMRIGHT only).
ARW_DOWN | Arrange down (valid with ARW_TOPLEFT and ARW_TOPRIGHT only).

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

System Information Overview, System Information Structures, SystemParametersInfo


NONCLIENTMETRICS

The NONCLIENTMETRICS structure contains the scalable metrics associated with the nonclient area of a nonminimized window. This structure is used by the SPI_GETNONCLIENTMETRICS and SPI_SETNONCLIENTMETRICS actions of SystemParametersInfo.

typedef struct tagNONCLIENTMETRICS {
    UINT    cbSize;
    int     iBorderWidth;
    int     iScrollWidth;
    int     iScrollHeight;
    int     iCaptionWidth;
    int     iCaptionHeight;
    LOGFONT lfCaptionFont;
    int     iSmCaptionWidth;
    int     iSmCaptionHeight;
    LOGFONT lfSmCaptionFont;
    int     iMenuWidth;
    int     iMenuHeight;
    LOGFONT lfMenuFont;
    LOGFONT lfStatusFont;
    LOGFONT lfMessageFont;
} NONCLIENTMETRICS, FAR* LPNONCLIENTMETRICS;

Members

cbSize
Specifies the size of the structure, in bytes.
iBorderWidth
Specifies the thickness, in pixels, of the sizing border.
iScrollWidth
Specifies the width, in pixels, of a standard vertical scroll bar.
iScrollHeight
Specifies the height, in pixels, of a standard horizontal scroll bar.
iCaptionWidth
Specifies the width, in pixels, of caption buttons.
iCaptionHeight
Specifies the height, in pixels, of caption buttons.
lfCaptionFont
Contains information about the caption font.
iSmCaptionWidth
Specifies the width, in pixels, of small caption buttons.
iSmCaptionHeight
Specifies the height, in pixels, of small captions.
iMenuWidth
Specifies the width, in pixels, of menu-bar buttons.
iMenuHeight
Specifies the height, in pixels, of a menu bar.
lfMenuFont
Contains information about the font used in menu bars.
lfStatusFont
Contains information about the font used in status bars and tooltips.
lfMessageFont
Contains information about the font used in message boxes.

QuickInfo

Windows NT: Requires version 3.5 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

System Information Overview, System Information Structures, SystemParametersInfo


OSVERSIONINFO

The OSVERSIONINFO data structure contains operating system version information. The information includes major and minor version numbers, a build number, a platform identifier, and descriptive text about the operating system. This structure is used with the GetVersionEx function.

typedef struct _OSVERSIONINFO{
    DWORD dwOSVersionInfoSize;
    DWORD dwMajorVersion;
    DWORD dwMinorVersion;
    DWORD dwBuildNumber;
    DWORD dwPlatformId;
    TCHAR szCSDVersion[ 128 ];
} OSVERSIONINFO;

Members

dwOSVersionInfoSize
Specifies the size, in bytes, of this data structure. Set this member to sizeof(OSVERSIONINFO) before calling the GetVersionEx function.
dwMajorVersion
Identifies the major version number of the operating system. For example, for Windows NT version 3.51, the major version number is 3; and for Windows NT version 4.0, the major version number is 4.
dwMinorVersion
Identifies the minor version number of the operating system. For example, for Windows NT version 3.51, the minor version number is 51; and for Windows NT version 4.0, the minor version number is 0.
dwBuildNumber
Windows NT: Identifies the build number of the operating system.

Windows 95: Identifies the build number of the operating system in the low-order word. The high-order word contains the major and minor version numbers.

dwPlatformId
Identifies the operating system platform. This member can be one of the following values:
Value | Platform
VER_PLATFORM_WIN32s | Win32s on Windows 3.1.
VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95 or Windows 98.

For Windows 95, dwMinorVersion is zero.

For Windows 98, dwMinorVersion is greater than zero.

VER_PLATFORM_WIN32_NT | Win32 on Windows NT.

szCSDVersion
Windows NT: Contains a null-terminated string, such as "Service Pack 3", that indicates the latest Service Pack installed on the system. If no Service Pack has been installed, the string is empty.

Windows 95: Contains a null-terminated string that provides arbitrary additional information about the operating system.

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.
Unicode: Defined as Unicode and ANSI structures.

See Also

System Information Overview, System Information Structures, GetVersionEx, OSVERSIONINFOEX


OSVERSIONINFOEX

[This is preliminary documentation and subject to change.]

The OSVERSIONINFOEX structure contains operating system version information. The information includes major and minor version numbers, a build number, a platform identifier, and information about the latest Service Pack installed on the system. This structure is used with the GetVersionEx function. OSVERSIONINFOEX is an extended version of the OSVERSIONINFO structure.

typedef struct _OSVERSIONINFOEXA {
    DWORD dwOSVersionInfoSize;
    DWORD dwMajorVersion;
    DWORD dwMinorVersion;
    DWORD dwBuildNumber;
    DWORD dwPlatformId;
    TCHAR szCSDVersion[ 128 ];
    WORD wServicePackMajor;
    WORD wServicePackMinor;
    WORD wReserved[2];
} OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA;

Members

dwOSVersionInfoSize
Specifies the size, in bytes, of this data structure. Set this member to sizeof(OSVERSIONINFOEX) before calling the GetVersionEx function.
dwMajorVersion
Identifies the major version number of the operating system. For example, for Windows NT version 5.0, the major version number is 5.
dwMinorVersion
Identifies the minor version number of the operating system. For example, for Windows NT version 5.0, the minor version number is 0.
dwBuildNumber
Identifies the build number of the operating system.
dwPlatformId
Identifies the operating system platform. This member can be one of the following values.
Value | Platform
VER_PLATFORM_WIN32s | Win32s on Windows 3.1.
VER_PLATFORM_WIN32_WINDOWS | Win32 on Windows 95 or Windows 98.
VER_PLATFORM_WIN32_NT | Win32 on Windows NT.

szCSDVersion
Contains a null-terminated string, such as "Service Pack 3", that indicates the latest Service Pack installed on the system. If no Service Pack has been installed, the string is empty.
wServicePackMajor
Identifies the major version number of the latest Service Pack installed on the system. If no Service Pack has been installed, the value is zero.
wServicePackMinor
Identifies the minor version number of the latest Service Pack installed on the system. If no Service Pack has been installed, the value is zero.
wReserved
Reserved for future use.

QuickInfo

Windows NT: Requires version 5.0 or later.
Windows: Unsupported.
Windows CE: Unsupported.
Header: Declared in winbase.h.
Unicode: Defined as Unicode and ANSI structures.

See Also

System Information Overview, System Information Structures, GetVersionEx, OSVERSIONINFO


SYSTEM_INFO

The SYSTEM_INFO structure contains information about the current computer system. This includes the architecture and type of the processor, the number of processors in the system, the page size, and other such information.

typedef struct _SYSTEM_INFO { // sinf
    union {
        DWORD  dwOemId;
        struct {
            WORD wProcessorArchitecture;
            WORD wReserved;
        };
    };
    DWORD  dwPageSize;
    LPVOID lpMinimumApplicationAddress;
    LPVOID lpMaximumApplicationAddress;
    DWORD  dwActiveProcessorMask;
    DWORD  dwNumberOfProcessors;
    DWORD  dwProcessorType;
    DWORD  dwAllocationGranularity;
    WORD  wProcessorLevel;
    WORD  wProcessorRevision;
} SYSTEM_INFO;

Members

dwOemId
An obsolete member that is retained for compatibility with previous versions of Windows NT. Beginning with Windows NT 3.51 and the initial release of Windows 95, use the wProcessorArchitecture branch of the union.

Windows 95: The system always sets this member to zero, the value defined for PROCESSOR_ARCHITECTURE_INTEL.

wProcessorArchitecture
Specifies the system's processor architecture. This value can be one of the following values:
Value
PROCESSOR_ARCHITECTURE_INTEL
Windows NT: PROCESSOR_ARCHITECTURE_MIPS
Windows NT: PROCESSOR_ARCHITECTURE_ALPHA
Windows NT: PROCESSOR_ARCHITECTURE_PPC
Windows NT: PROCESSOR_ARCHITECTURE_UNKNOWN

wReserved
Reserved for future use.
dwPageSize
Specifies the page size and the granularity of page protection and commitment. This is the page size used by the VirtualAlloc function.
lpMinimumApplicationAddress
Pointer to the lowest memory address accessible to applications and dynamic-link libraries (DLLs).
lpMaximumApplicationAddress
Pointer to the highest memory address accessible to applications and DLLs.
dwActiveProcessorMask
Specifies a mask representing the set of processors configured into the system. Bit 0 is processor 0; bit 31 is processor 31.
dwNumberOfProcessors
Specifies the number of processors in the system.
dwProcessorType
Windows 95:
Specifies the type of processor in the system.
Windows NT:
This member is no longer relevant, but is retained for compatibility with Windows 95 and previous versions of Windows NT. Use the wProcessorArchitecture, wProcessorLevel, and wProcessorRevision members to determine the type of processor.

This member is one of the following values:
Value
PROCESSOR_INTEL_386
PROCESSOR_INTEL_486
PROCESSOR_INTEL_PENTIUM
Windows NT: PROCESSOR_MIPS_R4000
Windows NT: PROCESSOR_ALPHA_21064

dwAllocationGranularity
Specifies the granularity with which virtual memory is allocated. For example, a VirtualAlloc request to allocate 1 byte will reserve an address space of dwAllocationGranularity bytes. This value was hard coded as 64K in the past, but other hardware architectures may require different values.
wProcessorLevel
Windows 95: This member is not used.

Windows NT: Specifies the system's architecture-dependent processor level.

If wProcessorArchitecture is PROCESSOR_ARCHITECTURE_INTEL, wProcessorLevel can be one of the following values:
Value | Meaning
3 | Intel 80386
4 | Intel 80486
5 | Pentium

If wProcessorArchitecture is PROCESSOR_ARCHITECTURE_MIPS, wProcessorLevel is of the form 00xx, where xx is an 8-bit implementation number (bits 8-15 of the PRId register). The member can be the following value:
Value | Meaning
0004 | MIPS R4000

If wProcessorArchitecture is PROCESSOR_ARCHITECTURE_ALPHA, wProcessorLevel is of the form xxxx, where xxxx is a 16-bit processor version number (the low-order 16 bits of a version number from the firmware). The member can be one of the following values:
Decimal Value | Meaning
21064 | Alpha 21064
21066 | Alpha 21066
21164 | Alpha 21164

If wProcessorArchitecture is PROCESSOR_ARCHITECTURE_PPC, wProcessorLevel is of the form xxxx, where xxxx is a 16-bit processor version number (the high-order 16 bits of the Processor Version Register). The member can be one of the following values:
Decimal Value | Meaning
1 | PPC 601
3 | PPC 603
4 | PPC 604
6 | PPC 603+
9 | PPC 604+
20 | PPC 620

wProcessorRevision
Windows 95: This member is not used.

Windows NT: Specifies an architecture-dependent processor revision. The following table shows how the revision value is assembled for each type of processor architecture.
Processor Architecture | Value
Intel 80386 or 80486 A value of the form xxyz.

If xx is equal to 0xFF, y - 0xA is the model number, and z is the stepping identifier. For example, an Intel 80486-D0 system returns 0xFFD0.

If xx is not equal to 0xFF, xx + 'A' is the stepping letter and yz is the minor stepping.

Intel Pentium,
Cyrix, or
NextGen 586 		A value of the form xxyy, where xx is the model number and yy is the stepping. For example, a value of 0x0201 indicates Model 2, Stepping 1.
MIPS | A value of the form 00xx, where xx is the 8-bit revision number of the processor (the low-order 8 bits of the PRId register).
ALPHA A value of the form xxyy, where xxyy is the low-order 16 bits of the processor revision number from the firmware. Display this value as follows:

Model 'A'+xx, Pass yy
PPC A value of the form xxyy, where xxyy is the low-order 16 bits of the Processor Version Register. Display this value as a fixed point number:

xx.yy

Remarks

Beginning with Windows NT 3.51 and the initial release of Windows 95, the SYSTEM_INFO structure has changed as follows:

  • The dwOemId member has been changed to a union. The union supports a new way to describe processor architecture used by Windows NT, while maintaining compatibility with Windows 95 and previous versions of Windows NT.
  • The dwProcessorType member is now obsolete on Windows NT. It is still used on Windows 95.
  • A previously reserved DWORD member at the end of the structure has been replaced by the wProcessorLevel and wProcessorRevision members. Windows 95 does not use these members.

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

System Information Overview, System Information Structures, GetSystemInfo, MapViewOfFile, MapViewOfFileEx


System Policies

System administrators can use system policies to control user and computer configurations from a single location on a network. System Policies propagate registry settings to a large number of computers without requiring the administrator to have detailed knowledge of the registry.


About System Policies

There are many settings in the registry, and multiple registry settings must often be manipulated to achieve a particular result. The System Policies feature provides a layer of abstraction that makes it easier to control registry settings.

Instead of changing individual registry settings, a system administrator can specify policies. Each policy has some text that describes its effect. Some examples of policies follow:

  • Disable file sharing.
  • Display a custom logon banner.
  • Remove the Run command from the Start menu.
  • Use user-level security.


Registry Settings

Each policy is associated with one or more registry settings. When the administrator chooses to enforce a policy, the System Policies tool identifies registry changes that must be made and then makes the changes to the registries of the users and computers for which the policy applies. The administrator can specify policies for individual users, user groups, and individual computers. Default values can also be specified.

Policies have been implemented for most of the registry settings that an administrator might want to control and propagate. Although System Policies control only a subset of the registry, they are extensible. Application developers are encouraged to supply template files and implement policies for registry settings used by their products so that customers can plug the template files into a policy editor and control policies for the application.


Policy Editors and Downloaders

There are two administrative components involved in specifying policies: a policy editor and a policy downloader. A policy editor is an application that lets administrators specify registry settings for particular computers, users, and user groups, and a policy downloader is a small program installed on every client computer that merges the administrator's settings into the local registry.

The policy editor uses a template file, which is a text file describing registry settings and specifying how the settings should appear in the policy editor's user interface. The policy editor creates a policy file, which is a single file containing policy settings for a number of computers, users, and user groups. The policy file is a registry hive that is created and manipulated using the Win32 API. Windows 95, Windows 98, Windows NT Server versions 4.0 and later, and the Microsoft Windows NT Resource Kit ship with a policy editor, the System Policy Editor (POLEDIT.EXE). You can create their own policy editors, but the editors must be able to read template files and be able to read and write policy files.

Windows NT versions 4.0 and later, Windows 95, and Windows 98 provide a policy downloader. Developers can also create their own policy downloaders. Policy downloaders may be installed so that the system will call the installed component to do the downloading rather than doing so itself. Because the policy file format allows for extensions, developers may provide additional functionality.


Architecture

A computer's configuration is defined in terms of policies. The policies are ultimately stored in the local computer's registry. Every component that provides a policy is responsible for reading the registry at appropriate times and acting accordingly. For example, the policy that removes the Run command from the Start menu requires the shell code that displays the Start menu to check the appropriate registry setting to determine whether or not it is supposed to display the Run command. The policies are generic data items; the administrative tools and components have no information about them besides their names, their associated data, and where they reside in the registry. The only responsibilities of the administrative components are to allow the administrator to make policy settings and propagate those settings to the user's registry.


Policy Primitives

The following definitions are important for a complete understanding of policies:

  • A policy is a permission or attribute for a particular item, action, or object. It is either enabled or disabled.
  • A part is a subcomponent of a policy. A policy may have zero or more parts. Policy parts may have various data types, including Boolean values, numeric values, and string values. The values of the parts apply only if the policy is enabled.
  • A category is a collection of similar policies.

Some policies do not need any parts. For instance, "Lock Desktop Links" could be a policy. For such a policy, it would be sufficient to say that it was either enabled or disabled. If it were enabled, the user could not modify his or her desktop links in any way. "Desktop Links" could be another policy, and it could have the Boolean parts "Create Links," "Delete Links," and "Modify Links." As another example, "Password Expiration" could be a policy, and "Number of days" (a numeric value) could be its part.

Policies and parts are analogous to a group of controls in a dialog box that are all enabled by a single check box. The check box, which corresponds to whether or not the policy is enabled, "turns on" the controls in the dialog box (the policy parts) and allows data to be entered into the controls. A policy with no parts (that is, no associated controls) is analogous to a single check box.

The following types of policies can be specified:

  • A user-specific policy can be specified for each user or group. A default set of policies can be specified for users or groups who do not have sets of policies defined for them explicitly. Most policies are user-specific. User-specific policies are always merged into the HKEY_CURRENT_USER key of the registry.
  • A machine-specific policy should not change according to user. A machine-specific policy applies to all users. It does not follow users as they move between different computers. Machine-specific policies are always merged into the HKEY_LOCAL_MACHINE key of the registry.


Policy Information

Any application or component can define a policy. The policy will appear in the administrator user interface, and information that the administrator sets about the policy will migrate to the local computer's registry. The application or component that defines a policy must check the registry appropriately to enforce its own policy.

Policy information is typically added to a local registry in the following sequence:

  1. Categories, policies, and parts are described in a template (.ADM) file. Windows 95 and Windows 98 ship with an ADMIN.ADM file containing all the policies that the system supports. The Microsoft Windows NT Resource Kit and Windows NT Server version 4.0 and later ship with three template files: WINNT.ADM, COMMON.ADM, and WINDOWS.ADM. Developers can also provide their own template files. For a description of the .ADM file format, see Template File Format.
  2. The administrator runs the policy editor, which reads one or more policies and lists the available categories and policies. The administrator sets up the desired policies, and the policy editor uses registry functions to save the work to a policy (.POL) file. For a description of the .POL file format, see Policy File Format.
  3. After the user logs on (and user profiles are reconciled if they are enabled), the policy downloader is activated. It determines where to find the file on the network, opens the policy file, and merges the appropriate computer, user, and user group policies into the local registry.


Default User and Computer Names

There is a standard user name called DEFAULT USER and a standard computer name called DEFAULT COMPUTER. When the policy downloader updates machine- and user-specific policies, it first tries to find an entry in the policy file for the local computer name or user name. If the downloader does not find an entry, it looks for the DEFAULT USER or DEFAULT COMPUTER entry and uses those entries for the update. If there are no entries for a particular user or computer and default entries do not exist, no update takes place.

The DEFAULT USER and DEFAULT COMPUTER entries are powerful because administrators can set policies for a large number of users and computers and then manage the exceptions by creating specific user and computer entries in a .POL file.


Policy Downloading

Policy downloading can be set in one of the following three states:

  • Off
  • Automatic
  • Manual

If policy downloading is off, no downloading takes place.

If policy downloading is set to automatic, the system asks the primary network provider to provide a place to look on the network for the policy file. Windows NT and Novell® NetWare® providers both support this capability. (For a Windows NT network, the system looks in the primary domain controller's NETLOGON directory for a file named CONFIG.POL. For a NetWare version 3..x network, the system looks on the preferred server's SYS\PUBLIC directory for a file named CONFIG.POL.) Any software vendor who provides a 32-bit network provider can support this capability by implementing the NPGetPolicyPath function. If policy downloading is set to automatic and the primary network provider does not support NPGetPolicyPath, no downloading takes place.

If policy downloading is set to manual, a specific path to the policy file must also be supplied. It can be either a Universal Naming Convention (UNC) path or a path beginning with a drive letter. (In the latter case, the drive letter must be appropriately mapped before downloading takes place.)

The default setting for policy downloading is automatic. No error messages are displayed if a policy file cannot be found in the location that the network provider suggests. This means that a site can install a number of Win32-based clients and then deploy the policies at a later date. To deploy them, the administrator just needs to place the policy file(s) in the appropriate location(s) on the network, and the clients will immediately begin using them the next time they log on.


Using the System Policy Editor

This section describes the user interface of the System Policy Editor (POLEDIT.EXE) that ships with Windows 95. The System Policy Editor also ships with the Microsoft Windows NT Resource Kit and Windows NT Server versions 4.0 and later. Other software vendors may, however, choose to use a different user interface.


Policy Editor User Interface

The System Policy Editor requires an .ADM file describing the available policies to use. The Windows 95 version of the editor uses the ADMIN.ADM file by default. The Windows NT version of the editor uses the WINNT.ADM and COMMON.ADM files by default. In addition, the policy editor's menus enable the user to specify different template files.

The main window of the System Policy Editor displays the users and computers that have entries in the policy file that is currently open. To create a new policy file, choose the New command on the File menu. A new policy file contains entries for the default user and default computer. To add entries for particular users or particular computers, use the Add User, Add Group, or Add Computer button. Note that policies for all of the entries shown in the main window are saved to one policy file. Typically, an administrator saves the policy file to the network location where the policy downloader looks by default.

The following illustration shows the main window of the System Policy Editor.

Double-clicking an entry, such as Default Computer, brings up a properties dialog box containing the policies for the entry. The Default Computer Properties dialog box shown in the following illustration has an upper section listing the policies and a lower section showing settings for a specific policy.

A check box in the properties dialog box has three states. If it is checked, the policy will be enforced; that is, the corresponding settings will be added to the registry when the policy is downloaded. If the check box is empty, the settings will be deleted from the registry when the policy is downloaded. If the check box is gray, the registry settings will not be changed when the policy is downloaded; that is, the user has the freedom to choose settings, assuming that the settings can be changed from the user interface.

For example, there is a user policy for desktop wallpaper. By checking that policy, the administrator specifies the particular wallpaper that the user will have. Even if the user uses the Display Control Panel application to change the wallpaper, the wallpaper specified by the administrator will appear the next time he or she logs on. If the administrator unchecks this policy, the wallpaper setting is deleted so that when the user logs on, there is no wallpaper. If the administrator makes the check box gray, nothing is enforced, and the user can choose the wallpaper.

As a second example, there is a user policy "Remove Run from Start menu" (under the Shell/Restrictions registry key). Checking this policy adds a registry setting that tells the shell not to include the Run command on the Start menu. By unchecking this policy, this registry key is deleted, and the shell displays the Run command. If the policy is left gray, the setting will not be changed. If the policy was already in force, it will stay that way, and the Run command will continue to be denied to the user. If the policy had not been applied already, the user would continue to see the Run command. Note that unlike the wallpaper example, the user cannot change this setting by using Control Panel or another user interface element.

The System Policy Editor can also operate directly on the local registry rather than on a policy file. This capability is useful for troubleshooting problems that may be policy-related, because it shows what policies are currently in place for a user on a particular computer. There is no policy file involved in this mode. To switch to the local registry view, use the Open Registry command on the File menu. Note that the check boxes will show only two states, checked and unchecked, because the registry settings for the policy are either present (the policy is on) or not present (the policy is off).


Template File Format

A template (.ADM) file describes a number of categories. Each category can contain zero or more policies, and each policy can contain zero or more parts. The following sections describe categories, policies, policy parts, and part types.

The ADM files identify strings that are important for an internal localization tool by using two exclamation points (!!). Each of these strings is explicitly defined in the [strings] section of the ADM file. You do not need to use this mechanism when you create a template file.


Categories

A category is specified as follows.

CATEGORY name TYPE category type
[KEYNAME key name]

[... policy definition statements ...]

END CATEGORY

name
Category name as it should appear in the System Policy Editor list box. It may optionally be enclosed by double quotation marks. (Names with spaces must be enclosed by double quotation marks.)
category type
Type, which must be USER or MACHINE. It specifies whether the category is user-specific or machine-specific.
key name
Optional registry key name to use for the category. If a key name is specified, it will be used by all child categories, policies, and parts, unless they specifically provide a key name of their own.

A policy definition statement may not appear more than once in a single category.


Policies

A policy is specified as follows.

POLICY name
[KEY key name]
[... part definition statements ...]
END POLICY

name
Policy name as it should appear in the System Policy Editor list box. It may optionally be enclosed by double quotation marks. (Names with spaces must be enclosed by double quotation marks.)
key name
Optional registry key name to use for the policy. If a key name is specified, it will be used by all child parts of the policy, unless they specifically provide a key name of their own.


Policy Parts

A policy part is specified as follows.

PART name part-type
type-dependent data
[KEYNAME key name ]
VALUENAME value name
END PART

name
Part name as it should appear in the System Policy Editor list box. It may optionally be enclosed by double quotation marks. (Names with spaces must be enclosed by double quotation marks.)
part-type
Policy part type. Part types are discussed individually in the following section.
type-dependent data
Information about the part. Type-dependent data is discussed in the following section.
key name
Optional key name to use. If no key name is specified, the previous key name in hierarchy is used.
value name
Value name to use to set the data for this part.


Part Types

The following policy part types are defined:

CHECKBOX | Displays a check box. The value is set in the registry with the REG_DWORD type. The value will be nonzero if the check box is checked by the user and zero if it is unchecked.
COMBOBOX | Displays a combo box.
DROPDOWNLIST | Displays a combo box with a drop-down list style. The user may only choose from one of the entries supplied. The main advantage of a combo box with a drop-down list is that a number of extra registry edits may be specified, based on the user's selection.
EDITTEXT | Displays an edit field that accepts alphanumeric text. The text is set in the registry with either the REG_SZ or the REG_EXPAND_SZ type.
LISTBOX | Displays a list box with "add" and "remove" buttons. This is the only part type that can be used to manage multiple values under one key.
NUMERIC | Displays an edit field with an optional spinner control (an up-down control) that accepts a numeric value. The value is set in the registry with the REG_DWORD type.
TEXT | Displays a line of static (label) text. There is no associated registry value with this part type.

Descriptions of these policy part types follow.

CHECKBOX Part Type

The CHECKBOX part type accepts the following options:

ACTIONLISTOFF | Specifies an optional action list to be used if the check box is turned off. For more information, see "Action Lists" later in this topic.
ACTIONLISTON | Specifies an optional action list to be used if the check box is turned on. For more information, see "Action Lists" later in this topic.
DEFCHECKED | Causes the check box to be initially checked.
VALUEOFF | Overrides the default "off" behavior of the check box if specified.
VALUEON | Overrides the default "on" behavior of the check box if specified.

The default behavior of a check box is to write the value 1 to the registry if it is checked and 0 if it is unchecked. VALUEON and VALUEOFF are used to override this behavior. For example, the following option writes "Fred" to the registry when the check box is checked.

VALUEON "Fred"

The following option writes the value 12 to the registry when the check box is unchecked.

VALUEOFF NUMERIC 12

COMBOBOX Part Type

The COMBOBOX part type accepts all the options that EDITTEXT does as well as the following option:

SUGGESTIONS Begins a list of suggestions to be placed in the drop-down list. Suggestions are separated with spaces and can be enclosed by double quotation marks. The list ends with END SUGGESTIONS. Following is an example:

SUGGESTIONS
Alaska Alabama Mississippi "New York"
END SUGGESTIONS

DROPDOWNLIST Part Type

The DROPDOWNLIST part type accepts the following options:

ITEMLIST | Begins a list of the items in the drop-down list. The list must end with END ITEMLIST.
REQUIRED | Specifies that the policy editor will not allow a policy containing this part to be enabled unless a value has been entered for the part.

Each item in the ITEMLIST option must be specified as follows.

NAME name VALUE value
[ACTIONLIST actionlist]
...

name
Text to be displayed in the drop-down list for this item.
value
Value to be written as the part's value if this item is selected. Values are assumed to be strings, unless they are preceded by NUMERIC. The following example shows both string and numeric values.
VALUE "Some value"
   VALUE NUMERIC 1

If VALUE is followed by DELETE (for example, VALUE DELETE), the registry valuename and value pair will be deleted.

actionlist
Optional action list to be used if this value is selected. For more information about action lists, see "Action Lists" later in this topic.

EDITTEXT Part Type

The EDITTEXT part type accepts the following options:

DEFAULT value | Specifies the initial string to place in the edit field. If this option is not specified, the field is initially empty.
MAXLEN value | Specifies the maximum length of a string. The string in the edit field is limited to this length.
REQUIRED | Specifies that the policy editor will not allow a policy containing this part to be enabled, unless a value has been entered for this part.
OEMCONVERT | Sets the ES_OEMCONVERT style in the edit field so that typed text is mapped from ANSI to OEM and back.
EXPANDABLETEXT | ADM files version 2 or greater support this option which specifies that the text is set in the registry with the REG_EXPAND_SZ type. By default, the text is set in the registry with the REG_SZ type.

LISTBOX Part Type

The VALUENAME option cannot be used with the LISTBOX part type, because there is no single value name associated with this type. By default, only one column appears in the list box, and for each entry a value is created whose name and value are the same. For instance, a "fred" entry in the list box would create a value named "fred" whose data was "fred".

The LISTBOX part type accepts the following options:

ADDITIVE | By default, the content of list boxes will "override" whatever values are set in the target registry. (That is, a control value is inserted in the policy file, which causes existing values to be deleted before the values set in the policy file are merged.) If this option is specified, existing values are not deleted, and the values set in the list box will be in addition to whatever values exist in the target registry.
EXPLICITVALUE | This option makes the user specify not only the value data, but the value name as well. The list box will show two columns for each item, one for the name and one for the data. This option cannot be used with the VALUEPREFIX option.
VALUEPREFIX prefix | The prefix specified is used in determining value names. If a prefix is specified, the prefix and an incremented integer will be used instead of the default value naming scheme described previously. For example, a prefix of "SomeName" will generate the value names "SomeName1", "SomeName2", and so on. The prefix can be empty (""), which will cause the value names to be "1", "2", and so on.

NUMERIC Part Type

The NUMERIC part type accepts the following options:

DEFAULT value | Specifies the initial numeric value for the edit field. If this option is not specified, the field is initially empty.
MAX value | Specifies the maximum value for the number. The default value is 9999.
MIN value | Specifies the minimum value for the number. The default value is 0.
REQUIRED | Specifies that the policy editor will not allow a policy containing this part to be enabled unless a value has been entered for this part.
SPIN value | Specifies increments to use for the spinner control. SPIN 0 removes the spinner control. SPIN 1 is the default.
TXTCONVERT | Writes values as REG_SZ strings ("1," "2," or "128") rather than as binary values.

TEXT Part Type

The TEXT part type accepts no type-specific data.


Action Lists

An action list is a set of arbitrary changes to the registry that are made in response to a control being in a certain state. For instance, if a check box is turned on, an application could install some virtual device drivers and record some other changes.

The syntax for an actionlist follows.

ACTIONLIST
[KEYNAME key name]
VALUENAME value name
VALUE value
[KEYNAME key name]
VALUENAME value name
VALUE value
....
END ACTIONLIST

The actionlist specifies a number of key name, value name, and value triplets. A key name is not required for every action, but if it is not listed, the key name from the previous action will be used. (This is useful for writing a number of values to one key.) Values are treated as strings unless they are preceded by NUMERIC, as in the following examples.

VALUE "Some value"
VALUE NUMERIC 1

If VALUE is followed by DELETE (for example, VALUE DELETE), the registry valuename and value pair will be deleted.


Comments

Comments can be added to a template (.ADM) file by preceding the line with two forward slashes (//) or a semicolon (;).


Conditional Expressions

Future policy editors may include new capabilities. If these new capabilities require revisions to the template file format, older versions of the System Policy Editor will not be able to read the new template files. You can use conditional expressions to ensure that any future template files you create will be compatible with older policy editors.

The System Policy Editor supports two conditional expressions. The first one allows you to include different parts of the template file, based on the version number. This expression has the following syntax.

#if VERSION operator version_number

.

.

.

[#else]

.

.

.

#endif

The operator can be one of the following symbols: >, >=, <, <=, ==, or !=. The version_number can be any integer. For the original template file format released with Windows 95, the version number is 1. Version 2 of the template file format was released with Windows NT version 4.0.

The other conditional expression is #ifdef. This expression has the following syntax.

[#ifdef | #ifndef] keyword

.

.

.

[#else]

.

.

.

#endif

Keywords are implicitly understood by the policy editor. For example, a fictitious company named PolicyCorp might implement its own policy editor that could recognize the POLICYCORP keyword. This company could use the #ifdef and #endif conditional expressions to make sure its template files can be recognized by the Windows System Policy Editor. (Because the Windows System Policy Editor does not currently recognize any keywords, #ifdef always evaluates to FALSE and #ifndef always evaluates to TRUE.)


Policy File Format

A policy (.POL) file is a registry hive, which is created by using the Win32 RegSaveKey function.

The following top-level keys are defined:

  • Computers
  • Groups
  • GroupData
  • Users
  • Misc

A policy downloader uses the following steps to download policies:

  1. Locates the appropriate computer key, if any, under Computers. Beneath that key is an image of the registry settings to be merged. The policy downloader should walk through all the subkeys and values and merge those settings into the HKEY_LOCAL_MACHINE key, paying attention to the control codes that are defined in the following section.
  2. Locates the appropriate groups key(s), if any, under Groups. Under the Groups keys is an image of the registry settings to be merged. These settings must be merged into the HKEY_CURRENT_USER key.
  3. Locates the appropriate user key, if any, under Users. Under the Users key is an image of the registry settings to be merged. These settings must be merged into the HKEY_CURRENT_USER key.


Control Codes

Control codes are used to signify that special processing of a value or key name must take place. All control codes are prefixes to a value or key name and take the form of the code name (that is, **code.) directly followed by value name or key name.

The following control codes are defined for use with value names.

**del. | Specifies that the value name following the control code should be deleted.
**delvals. | Deletes all values under this key in the local registry before propagating values under this key from the policy file. When processing a particular key, a downloader must look for and process this value first. This control code is inserted by a list box control so that existing values are removed before the new values are added.
**soft. | Specifies that it is a soft value. The downloader only propagates the value name following the control code if a value by that name does not exist in the local registry; that is, the downloader does not overwrite existing settings with soft values.

No control codes are currently defined for use with key names.

If a policy downloader encounters a control code that it does not understand, it must not process the key or value. If the control code is part of a value name, the policy downloader should skip that value in the hive file but continue to process other values under that key and its subkeys. If the control code is part of a key name, the downloader should ignore the key and not process any values under it or its subkeys. This behavior is important because it allows developers to create new control codes without breaking existing downloaders.

Developers may create new control codes in the same format as shown in the preceding table (that is, **code.). Developers who do so should notify Microsoft so that Microsoft can document the new codes.


Computers Key

Underneath the Computers key is a list of computers that have entries in the policy file. The steps to use in locating a Computers key follow:

  1. Determine whether there is a key that is the same as the computer name. If there is one, merge the registry image beneath it into the HKEY_LOCAL_MACHINE key.
  2. If the key is not there, determine whether there is a key called ".default". (This appears in the System Policy Editor user interface as Default Computer.) If a default key exists, merge the registry image beneath it.
  3. If neither of the two steps work, do nothing.


Groups and GroupData Keys

Underneath the Groups key is a list of user groups who have entries in the policy file. Since a user may belong to many groups and those groups may have conflicting settings, it is important to specify an order in which groups are processed. This order is contained in the GroupData\Priority key, which has values in the form "1"="group name", "2"="group name", and so on. "1" is highest priority, and the priority diminishes as the number in the value name increases. The downloader reads the group priority values and then processes groups from lowest priority to highest; that is, the downloader begins with the highest numbered value and works to the value "1".

For each group in the priority list, the downloader determines if the user is a member of the group. If the user is in the group, the downloader should try to find a key with the group name under the Groups key. If such a key exists, the downloader merges the registry image under that key into the HKEY_CURRENT_USER key. It is not an error if a group is specified in the priority list but does not have an entry under the Groups key; it simply means that nothing happens. This process is repeated for each group in the priority list. (If a group has an entry under the Groups key but does not have an entry in the priority list, it is never processed.)


Users Key

Underneath the Users key is a list of computers that have entries in the policy file. The steps to use in locating a Users key follow:

  1. Determine whether there is a key that is the same as the user name. If there is one, merge the registry image beneath it into the HKEY_CURRENT_USER key.
  2. If the key is not there, determine whether there is a key called ".default". This appears in the System Policy Editor user interface as Default User. If a default key exists, merge the registry image beneath it.
  3. If neither of the two steps work, do nothing.


Misc Key

The Misc key can be used by developers to store vendor-specific data. The naming convention for this key follows.

Misc\Vendor Name \Product Name\Version\ data

A software vendor may store any needed information in data. A key or value containing version information is highly recommended. As is recommended for the registry, Version should be "CurrentVersion" for the most current version of the product.


Installable Policy Downloaders

A policy downloader merges the administrator's policy settings into the local registry. Windows NT versions 4.0 and later, Windows 95, and Windows 98 provide a default policy downloader. You can install your own policy downloader that the system calls instead of the default policy downloader.

An installable policy downloader must be a Win32 dynamic-link library (DLL). The DLL must export a ProcessPolicies function, where ProcessPolicies is a placeholder for the library-defined function name. To install a policy downloader, you must record the name of the DLL and the name of the ProcessPolicies function in the registry under the following keys.

Windows NT:
HKEY_LOCAL_MACHINE\Software\Microsoft\
Windows NT\CurrentVersion\Winlogon
Windows 95 and Windows 98:
HKEY_LOCAL_MACHINE\Network\Logon

Under these keys, create a PolicyHandler value with the following format.

PolicyHandler = "dll name, function name"

In this example, dll name is the name of the policy downloader DLL, and function name is the exported name of the ProcessPolicies function.

For more information about policy downloaders, see Policy Editors and Downloaders, Policy Downloading, and Policy File Format.


System Policies Reference

The following elements are used with System Policies.


System Policies Functions

ProcessPolicies


ProcessPolicies

A ProcessPolicies function is a library-defined function exported by an installable policy downloader. The system calls the ProcessPolicies function of an installed policy downloader when a user logs on to the local computer. A ProcessPolicies function merges the information in a policy file into the local registry.

The PFNPROCESSPOLICIES type is a pointer to a ProcessPolicies function. ProcessPolicies is a placeholder for the library-defined function name.

BOOL PASCAL ProcessPolicies(
  HWND hwndOwner,              // handle to the parent window
  LPCTSTR lpszPolicyFilePath,  // path to the policy file
  LPCTSTR lpszUserName,        // name of the logged on user
  LPCTSTR lpszComputerName,    // name of the local computer
  DWORD dwFlags                // error handling flag
);

Parameters

hwndOwner
Handle to the parent window.
lpszPolicyFilePath
Pointer to a null-terminated string containing the full path and filename that the system would have used to look for the policy file. The downloader may use this parameter, or ignore it and use a different path.

Windows NT: This is a Unicode string.

Windows 95 and Windows 98: This is an ANSI string.

lpszUserName
Pointer to a null-terminated string containing the name of the logged on user.

Windows NT: This is a Unicode string.

Windows 95 and Windows 98: This is an ANSI string.

lpszComputerName
Pointer to a null-terminated string containing the name of the local computer.

Windows NT: This is a Unicode string.

Windows 95 and Windows 98: This is an ANSI string.

dwFlags
Flags. This parameter can include the following value.
Value | Meaning
PP_DISPLAYERRORS | If this flag is set, the function should display error messages about errors encountered during downloading (including the file is not found, the network resource is not found, and so on). If this flag is not set, the function should fail silently if there is an error.

Return Values

If the function returns a nonzero value, the system runs the default handler.

If the function returns zero, the system does not run the default handler.

See Also

System Policies Overview, System Policies Functions


System Shutdown

Microsoft® Windows® and Microsoft® Windows NT® provide functions and messages that allow applications to log off the current user, shut down the system, or lock the workstation.


About System Shutdown

System shutdown brings the system to a condition in which it is safe to turn off the computer. All file-system buffers are flushed to the disk, then a message box is displayed informing the user that the computer can be turned off. There is also a reboot option that will restart the computer, rather than display this system shutdown message box. For more information, see How to Shut Down the System.

Logging off stops all processes associated with the security context of the process that called the exit function, logs the current user off the system, and displays the logon dialog box. For more information, see How to Log Off the Current User.

Locking the workstation protects the display from unauthorized use whenever you leave your computer. To unlock the workstation, you must log in. For more information, see How to Lock the Workstation.


How to Shut Down the System

There are two ways for an application to shut down local or remote computers:

  • Shut down the system.
  • Shut down the system and restart it.

Windows NT: The calling process must have the SE_SHUTDOWN_NAME privilege to shut down the system.

To shut down the system, use the ExitWindowsEx function. The system sends the WM_QUERYENDSESSION message to each window, unless you called ExitWindowsEx with the EXW_FORCE flag. The applications perform any cleanup while processing WM_QUERYENDSESSION, and return TRUE to indicate that they can be terminated. If you use EXW_FORCE, applications may lose data. For more information, see Shutting Down.

Windows NT: The InitiateSystemShutdown function starts a timer and displays a dialog box that prompts the user to log off. While the dialog box is displayed, the AbortSystemShutdown function can stop the timer and prevent the computer from shutting down. However, if the timer expires, the computer is shut down. InitiateSystemShutdown can also restart the computer following a shutdown operation. For more information, see Displaying the Shutdown Dialog Box.


How to Log Off the Current User

To log off the current user, call the ExitWindows or ExitWindowsEx function.

By default, when an application uses ExitWindows or ExitWindowsEx to log off, the system sends the WM_QUERYENDSESSION message to each window. Applications agree to terminate by returning TRUE when they receive this message. If any application returns FALSE, the log-off operation is canceled.

Windows NT: When an application returns TRUE for WM_QUERYENDSESSION, it receives the WM_ENDSESSION message and it is terminated, regardless of how the other applications respond to the WM_QUERYENDSESSION message.

Windows 95: After all applications return TRUE for WM_QUERYENDSESSION, they receive the WM_ENDSESSION and they are terminated.

To force all applications to terminate, use ExitWindowsEx, and specify the EXW_FORCE flag. This prevents the system from sending WM_QUERYENDSESSION messages.

The system also sends the CTRL_LOGOFF_EVENT control signal to every process during a log-off operation. A console application can register a HandlerRoutine to process these messages.


How to Lock the Workstation

To lock the workstation, call the LockWorkStation function. The system displays the Lock Workstation dialog box. The dialog box text says that the workstation is in use and has been locked by the user. The workstation can be unlocked by the user or an administrator. To unlock the system, press Ctrl+Alt+Del and log in.

The LockWorkStation function is callable only by processes running on the interactive desktop. In addition, the user must be logged on, and the workstation cannot already be locked.


Using System Shutdown

  • Logging Off
  • Shutting Down
  • Displaying the Shutdown Dialog Box


Logging Off

The ExitWindows function logs off the current user. All applications must agree to terminate before the user logs off. If any application returns FALSE when it processes the WM_QUERYENDSESSION message, the user is not logged off. If your application handles the WM_QUERYENDSESSION message, you can allow the user to cancel the log-off operation, even if another application or the system originated the end-session request.

The following example logs off the current user, unless the user clicks the No button in the message box displayed when the application receives the WM_QUERYENDSESSION message.

// Log off the current user.

ExitWindows(0, 0);

// Process the message in the application's window procedure.

case WM_QUERYENDSESSION:
{
    int r;
    r = MessageBox(NULL, "Shut down?","WM_QUERYENDSESSION", MB_YESNO);

    // Return TRUE to allow shutdown, FALSE to stop.

    return r == IDYES;
    break;
}


Shutting Down

You can use the ExitWindowsEx function to shut down the system. Shutting down flushes file buffers to disk and brings the system to a condition in which it is safe to turn off the computer.

Windows NT: The following example enables the SE_SHUTDOWN_NAME privilege and then shuts down the system.

HANDLE hToken;
TOKEN_PRIVILEGES tkp;

// Get a token for this process.

if (!OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    error("OpenProcessToken");

// Get the LUID for the shutdown privilege.

LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
        &tkp.Privileges[0].Luid);

tkp.PrivilegeCount = 1;  // one privilege to set
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

// Get the shutdown privilege for this process.

AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
        (PTOKEN_PRIVILEGES)NULL, 0);

// Cannot test the return value of AdjustTokenPrivileges.

if (GetLastError() != ERROR_SUCCESS)
    error("AdjustTokenPrivileges");

// Shut down the system and force all applications to close.

if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, 0))
    error("ExitWindowsEx");

For more information about setting security privileges, see Privileges.


Displaying the Shutdown Dialog Box

Windows NT: The following example uses the InitiateSystemShutdown function to begin the system shutdown process on the computer on which is user is logged on. The application must first enable the SE_SHUTDOWN_NAME privilege.

HANDLE hToken;              // handle to process token
TOKEN_PRIVILEGES tkp;       // pointer to token structure

BOOL fResult;               // system shutdown flag

// Get the current process token handle so we can get shutdown
// privilege.

if (!OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    ErrorHandler("OpenProcessToken failed.");

// Get the LUID for shutdown privilege.

LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
        &tkp.Privileges[0].Luid);

tkp.PrivilegeCount = 1;  // one privilege to set
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

// Get shutdown privilege for this process.

AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
    (PTOKEN_PRIVILEGES) NULL, 0);

// Cannot test the return value of AdjustTokenPrivileges.

if (GetLastError() != ERROR_SUCCESS)
    ErrorHandler("AdjustTokenPrivileges enable failed.");

// Display the shutdown dialog box and start the time-out countdown.

fResult = InitiateSystemShutdown(
    NULL,                                  // shut down local computer
    "Click on the main window and press \
     the Escape key to cancel shutdown.",  // message to user
    20,                                    // time-out period
    FALSE,                                 // ask user to close apps
    TRUE);                                 // reboot after shutdown

if (!fResult)
{
    ErrorHandler("InitiateSystemShutdown failed.");
}

// Disable shutdown privilege.

tkp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
        (PTOKEN_PRIVILEGES) NULL, 0);

if (GetLastError() != ERROR_SUCCESS)
{
    ErrorHandler("AdjustTokenPrivileges disable failed.");
}

If the AbortSystemShutdown function is executed in the time-out period specified by InitiateSystemShutdown, the system does not shut down. In this example, the user can prevent the system from shutting down by clicking on the application's main window and pressing the esc key. The example processes the keystroke by calling AbortSystemShutdown.

HANDLE hToken;              // handle to process token
TOKEN_PRIVILEGES tkp;       // pointer to token structure

BOOL fResult;               // system shutdown flag

case WM_KEYDOWN:

    // Process only the Escape key.

    if (wParam != VK_ESCAPE)
    {
        break;
    }

    // Get the current process token handle  so we can get shutdown
    // privilege.

    if (!OpenProcessToken(GetCurrentProcess(),
            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        ErrorHandler("OpenProcessToken failed.");
    }

    // Get the LUID for shutdown privilege.

    LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
            &tkp.Privileges[0].Luid);

    tkp.PrivilegeCount = 1;  // one privilege to set
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    // Get shutdown privilege for this process.

    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
        (PTOKEN_PRIVILEGES)NULL, 0);

    // Cannot test the return value of AdjustTokenPrivileges.

    if (GetLastError() != ERROR_SUCCESS)
    {
        ErrorHandler("AdjustTokenPrivileges enable failed.");
    }

    // Prevent the system from shutting down.

    fResult = AbortSystemShutdown(NULL);

    if (!fResult)
    {
        ErrorHandler("AbortSystemShutdown failed.");
    }

    // Disable shutdown privilege.

    tkp.Privileges[0].Attributes = 0;
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
        (PTOKEN_PRIVILEGES) NULL, 0);

    if (GetLastError() != ERROR_SUCCESS)
    {
        ErrorHandler("AdjustTokenPrivileges disable failed.");
    }

    break;


System Shutdown Reference

The following elements are used with system shutdown.

  • System Shutdown Functions
  • System Shutdown Messages


System Shutdown Functions

The following functions are used with system shutdown.

AbortSystemShutdown
ExitWindows
ExitWindowsEx
InitiateSystemShutdown
LockWorkStation


AbortSystemShutdown

The AbortSystemShutdown function stops a system shutdown started by using the InitiateSystemShutdown function.

BOOL AbortSystemShutdown(
  LPTSTR lpMachineName   // pointer to name of computer to stop
                         // shutting down
);

Parameters

lpMachineName
Pointer to the null-terminated string that specifies the network name of the computer where the shutdown is to be stopped. If lpMachineName is NULL or points to an empty string, the function stops the shutdown on the local computer.

Return Values

If 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 InitiateSystemShutdown function displays a dialog box that notifies the user that the system is shutting down. During the InitiateSystemShutdown time-out period, the AbortSystemShutdown function can prevent the system from shutting down.

To stop the local computer from shutting down, the calling process must have the SE_SHUTDOWN_NAME privilege. To stop a remote computer from shutting down, the calling process must have the SE_REMOTE_SHUTDOWN_NAME privilege on the remote computer. By default, users can enable the SE_SHUTDOWN_NAME privilege on the computer they are logged onto, and administrators can enable the SE_REMOTE_SHUTDOWN_NAME privilege on remote computers.

Common reasons for failure include an invalid computer name, an inaccessible computer, or insufficient 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.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

System Shutdown Overview, System Shutdown Functions, InitiateSystemShutdown


ExitWindows

The ExitWindows function logs off the current user.

BOOL ExitWindows(
  DWORD dwReserved,  // reserved
  UINT uReserved     // reserved
);

Parameters

dwReserved
Reserved; must be zero.
uReserved
Reserved; 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.

Remarks

Windows NT: The ExitWindows function asks applications if they want to terminate by sending the WM_QUERYENDSESSION message to the main window of all running applications.

Windows 95: The ExitWindows function sends the WM_QUERYENDSESSION message to all applications except the one that called ExitWindows.

An application agrees to terminate by returning TRUE when it receives this message (or by allowing the DefWindowProc function to process the message). If any application returns FALSE when it receives the WM_QUERYENDSESSION message, the shutdown is canceled.

After the system processes the results of the WM_QUERYENDSESSION message, it sends the WM_ENDSESSION message with the wParam parameter set to TRUE if the system is shutting down and to FALSE if it is not.

The system does not allow new applications to start up during the shutdown process.

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

System Shutdown Overview, System Shutdown Functions, DefWindowProc, ExitWindowsEx


ExitWindowsEx

The ExitWindowsEx function either logs off the current user, shuts down the system, or shuts down and restarts the system. It sends the WM_QUERYENDSESSION message to all applications to determine if they can be terminated.

BOOL ExitWindowsEx(
  UINT uFlags,       // shutdown operation
  DWORD dwReserved   // reserved
);

Parameters

uFlags
Specifies the type of shutdown. This parameter must include one of the following values:
Value | Meaning
EWX_LOGOFF | Shuts down all processes running in the security context of the process that called the ExitWindowsEx function. Then it logs the user off.
EWX_POWEROFF Shuts down the system and turns off the power. The system must support the power-off feature.

Windows NT: The calling process must have the SE_SHUTDOWN_NAME privilege. For more information, see the following Remarks section.

EWX_REBOOT Shuts down the system and then restarts the system.

Windows NT: The calling process must have the SE_SHUTDOWN_NAME privilege. For more information, see the following Remarks section.

EWX_SHUTDOWN Shuts down the system to a point at which it is safe to turn off the power. All file buffers have been flushed to disk, and all running processes have stopped.

Windows NT: The calling process must have the SE_SHUTDOWN_NAME privilege. For more information, see the following Remarks section.

This parameter can optionally include the following values:
Value | Meaning
EWX_FORCE | Forces processes to terminate. When this flag is set, the system does not send the WM_QUERYENDSESSION and WM_ENDSESSION messages. This can cause the applications to lose data. Therefore, you should only use this flag in an emergency.
EWX_FORCEIFHUNG | Windows NT 5.0 and later: Forces processes to terminate if they do not respond to the WM_QUERYENDSESSION or WM_ENDSESSION message. This flag is ignored if EWX_FORCE is used.

dwReserved
Reserved; this 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.

Remarks

The ExitWindowsEx function returns as soon as it has initiated the shutdown. The shutdown or logoff then proceeds asynchronously.

During a shutdown or log-off operation, applications that are shut down are allowed a specific amount of time to respond to the shutdown request. If the time expires, the system displays a dialog box that allows the user to forcibly shut down the application, to retry the shutdown, or to cancel the shutdown request. If the EWX_FORCE value is specified, the system always forces applications to close and does not display the dialog box. If the EWX_FORCEIFHUNG value is specified, the system forces hung applications to close and does not display the dialog box.

Console processes receive a separate notification message, CTRL_SHUTDOWN_EVENT or CTRL_LOGOFF_EVENT, as the situation warrants. A console process routes these messages to its HandlerRoutine functions, which are added and removed by calls to the SetConsoleCtrlHandler function. ExitWindowsEx sends these notification messages asynchronously; thus, an application cannot assume that the console notification messages have been handled when a call to ExitWindowsEx returns.

Windows NT: To shut down or restart the system, the calling process must use the AdjustTokenPrivileges function to enable the SE_SHUTDOWN_NAME privilege. For more information about security privileges, see Privileges.

Windows 95: ExitWindowEx does not work from a console application, as it does on Windows NT.

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

System Shutdown Overview, System Shutdown Functions, AdjustTokenPrivileges, HandlerRoutine, SetConsoleCtrlHandler


InitiateSystemShutdown

The InitiateSystemShutdown function initiates a shutdown and optional restart of the specified computer.

BOOL InitiateSystemShutdown(
  LPTSTR lpMachineName,   // pointer to name of computer to shut down
  LPTSTR lpMessage,          // pointer to message to display in
                             // dialog box
  DWORD dwTimeout,           // time to display dialog box
  BOOL bForceAppsClosed,     // force applications closed flag
  BOOL bRebootAfterShutdown  // reboot flag
);

Parameters

lpMachineName
Pointer to the null-terminated string that specifies the network name of the computer to shut down. If lpMachineName is NULL or points to an empty string, the function shuts down the local computer.
lpMessage
Pointer to a null-terminated string that specifies a message to display in the shutdown dialog box. This parameter can be NULL if no message is required.
dwTimeout
Specifies the time (in seconds) that the dialog box should be displayed. While this dialog box is displayed, the shutdown can be stopped by the AbortSystemShutdown function.

If dwTimeout is not zero, InitiateSystemShutdown displays a dialog box on the specified computer. The dialog box displays the name of the user who called the function, displays the message specified by the lpMessage parameter, and prompts the user to log off. The dialog box beeps when it is created and remains on top of other windows in the system. The dialog box can be moved but not closed. A timer counts down the remaining time before a forced shutdown. If the user logs off, the system shuts down immediately. Otherwise, the computer is shut down when the timer expires.

If dwTimeout is zero, the computer shuts down without displaying the dialog box, and the shutdown cannot be stopped by AbortSystemShutdown.

bForceAppsClosed
Specifies whether applications with unsaved changes are to be forcibly closed. If this parameter is TRUE, such applications are closed. If this parameter is FALSE, a dialog box is displayed prompting the user to close the applications.
bRebootAfterShutdown
Specifies whether the computer is to restart immediately after shutting down. If this parameter is TRUE, the computer is to restart. If this parameter is FALSE, the system flushes all caches to disk, clears the screen, and displays a message indicating that it is safe to power down.

Return Values

If 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 shut down the local computer, the calling process must have the SE_SHUTDOWN_NAME privilege. To shut down a remote computer, the calling process must have the SE_REMOTE_SHUTDOWN_NAME privilege on the remote computer. By default, users can enable the SE_SHUTDOWN_NAME privilege on the computer they are logged onto, and administrators can enable the SE_REMOTE_SHUTDOWN_NAME privilege on remote computers.

Common reasons for failure include an invalid or inaccessible computer name or insufficient 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.
Unicode: Implemented as Unicode and ANSI versions on Windows NT.

See Also

System Shutdown Overview, System Shutdown Functions, AbortSystemShutdown


LockWorkStation

[This is preliminary documentation and subject to change.]

The LockWorkStation function locks the workstation's display, protecting it from unauthorized use.

BOOL LockWorkStation(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

This function has the same result as pressing Ctrl+Alt+Del and clicking Lock Workstation. To unlock the workstation, the user must log in.

Common reasons for failure include no user is logged on, the workstation is already locked, the process is not running on the interactive desktop, or the request is denied by the Graphical Identification and Authentication (GINA) DLL.

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

System Shutdown Overview, System Shutdown Functions


System Shutdown Messages

The following messages are used with system shutdown.

WM_ENDSESSION
WM_QUERYENDSESSION


WM_ENDSESSION

The WM_ENDSESSION message is sent to an application after the system processes the results of the WM_QUERYENDSESSION message. The WM_ENDSESSION message informs the application whether the session is ending.

WM_ENDSESSION
fEndSession = (BOOL) wParam;     // end-session flag
fLogOff =  lParam                // logoff flag

Parameters

fEndSession
Value of wParam. Specifies whether the session is being ended. If the session is being ended, this parameter is TRUE; otherwise, it is FALSE.
fLogOff
Value of lParam. Indicates whether the user is logging off or shutting down the system. Supported values include: ENDSESSION_LOGOFF.

Return Values

If an application processes this message, it should return zero.

Remarks

If the fEndSession parameter is TRUE, the session can end any time after all applications have returned from processing this message. Therefore, an application should perform all tasks required for termination before returning from this message.

The application need not call the DestroyWindow or PostQuitMessage function when the session is ending.

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

System Shutdown Overview, System Shutdown Messages, DestroyWindow, PostQuitMessage, WM_QUERYENDSESSION


WM_QUERYENDSESSION

The WM_QUERYENDSESSION message is sent when the user chooses to end the session or when an application calls the ExitWindows function. If any application returns zero, the session is not ended. The system stops sending WM_QUERYENDSESSION messages as soon as one application returns zero.

After processing this message, the system sends the WM_ENDSESSION message with the wParam parameter set to the results of the WM_QUERYENDSESSION message.

WM_QUERYENDSESSION
nSource = (UINT) wParam;    // source of end-session request
fLogOff = lParam            // logoff flag

Parameters

nSource
Reserved for future use.
fLogOff
Value of lParam. Indicates whether the user is logging off or shutting down the system. Supported values include: ENDSESSION_LOGOFF.

Return Values

If an application can terminate conveniently, it should return TRUE; otherwise, it should return FALSE.

Remarks

By default, the DefWindowProc function returns TRUE for this message.

Windows NT: When an application returns TRUE for this message, it receives the WM_ENDSESSION message and it is terminated, regardless of how the other applications respond to the WM_QUERYENDSESSION message.

Windows 95: After all applications return TRUE for this message, they receive the WM_ENDSESSION and they are terminated.

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

System Shutdown Overview, System Shutdown Messages, DefWindowProc, ExitWindows, WM_ENDSESSION


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.