My Training Period: xx hours. Before you begin, read someinstruction here. The pre-requirement for this Module arestructure,function,pointer andarray.
Some Basic Background Story of The Win32 APIs
|
Because of the update issue and the various Windows OS versions, using the same Windows header file doesn’t mean you will be provided with the same functionalities. This issue will be solved by using macros.
Later on we will concentrate on the file management functions that available in Win32 APIs by collecting the required and related information and then try building simple working programs.
These functions used to deal with volumes, disks, directories (including paths) and files management. The file system used in the discussion is NTFS.
The not so understandable stories about Windows file system and storage can be found Supplementary for Windows file system.
There is no new constructs you will find in this Module except functions, arrays, pointers and structures.
The data types supported by Microsoft Windows are used to define function return values, function and message parameters, structure members and variables. They define the size and meaning of these elements.
The following Table contains types of character, integer, Boolean, pointer, and handle. The character, integer, and Boolean types are common to most C/C++ compilers. The types also include the 64 bits size.
If you have noticed, many types actually are derived from the basic types with new name using thetypedef or #define and some are specific for the graphic functions.
Most of the pointer-type names begin with a prefix of P or LP (long pointer) and handle with H.
Handles refer to a resource that has been loaded into memory and will be discussed in another Module.
Well, we have so many data types here :o).
These various data types defined in several header files such as windef.h, basetsd.h,ddeml.h, shellapi.h, winuser.h, winsvc.h andwinnt.h.
Keyword | Description |
ATOM | Atom. This type is declared in windef.h as follows: typedef WORD ATOM; |
BOOL | Boolean variable (should be TRUE or FALSE). This type is declared in windef.h as follows: typedef int BOOL; |
BOOLEAN | Boolean variable (should be TRUE or FALSE). This type is declared in winnt.h as follows: typedef BYTE BOOLEAN; |
BYTE | Byte (8 bits). This type is declared in windef.h as follows: typedef unsigned char BYTE; |
CALLBACK | Calling convention for callback functions. This type is declared in windef.h as follows: #define CALLBACK __stdcall |
CHAR | 8-bit Windows (ANSI) character. This type is declared in winnt.h as follows: typedef char CHAR; |
COLORREF | Red, green, blue (RGB) color value (32 bits). This type is declared inwindef.h as follows: typedef DWORD COLORREF; |
CONST | Variable whose value is to remain constant during execution. This type is declared in windef.h as follows: #define CONST const |
DWORD | 32-bit unsigned integer. This type is declared in windef.h as follows: typedef unsigned long DWORD; |
DWORDLONG | 64-bit unsigned integer. This type is declared in winnt.h as follows: typedef ULONGLONG DWORDLONG; |
DWORD_PTR | Unsigned long type for pointer precision. Use when casting a pointer to a long type to perform pointer arithmetic. Also commonly used for general 32-bit parameters that have been extended to 64 bits in 64-bit Windows. This type is declared in basetsd.h as follows: typedef ULONG_PTR DWORD_PTR; |
DWORD32 | 32-bit unsigned integer. This type is declared in basetsd.h as follows: typedef unsigned int DWORD32; |
DWORD64 | 64-bit unsigned integer. This type is declared in basetsd.h as follows: typedef unsigned __int64 DWORD64; |
FLOAT | Floating-point variable. This type is declared in windef.h as follows: typedef float FLOAT; |
HACCEL | Handle to an accelerator table. This type is declared in windef.h as follows: typedef HANDLE HACCEL; |
HANDLE | Handle to an object. This type is declared in winnt.h as follows: typedef PVOID HANDLE; |
HBITMAP | Handle to a bitmap. This type is declared in windef.h as follows: typedef HANDLE HBITMAP; |
HBRUSH | Handle to a brush. This type is declared in windef.h as follows: typedef HANDLE HBRUSH; |
HCOLORSPACE | Handle to a color space. This type is declared in windef.h as follows: if(WINVER >= 0x0400) typedef HANDLE HCOLORSPACE; |
HCONV | Handle to a dynamic data exchange (DDE) conversation. This type is declared inddeml.h as follows: typedef HANDLE HCONV; |
HCONVLIST | Handle to a DDE conversation list. This type is declared in ddeml.h as follows: typedef HANDLE HCONVLIST; |
HCURSOR | Handle to a cursor. This type is declared in windef.h as follows: typedef HICON HCURSOR; |
HDC | Handle to a device context (DC). This type is declared in windef.h as follows: typedef HANDLE HDC; |
HDDEDATA | Handle to DDE data. This type is declared in ddeml.h as follows: typedef HANDLE HDDEDATA; |
HDESK | Handle to a desktop. This type is declared in windef.h as follows: typedef HANDLE HDESK; |
HDROP | Handle to an internal drop structure. This type is declared in shellapi.h as follows: typedef HANDLE HDROP; |
HDWP | Handle to a deferred window position structure. This type is declared in winuser.h as follows: typedef HANDLE HDWP; |
HENHMETAFILE | Handle to an enhanced metafile. This type is declared in windef.h as follows: typedef HANDLE HENHMETAFILE; |
HFILE | Handle to a file opened by OpenFile(), not CreateFile(). This type is declared in windef.h as follows: typedef int HFILE; |
HFONT | Handle to a font. This type is declared in windef.h as follows: typedef HANDLE HFONT; |
HGDIOBJ | Handle to a GDI object. This type is declared in windef.h as follows: typedef HANDLE HGDIOBJ; |
HGLOBAL | Handle to a global memory block. This type is declared in windef.h as follows: typedef HANDLE HGLOBAL; |
HHOOK | Handle to a hook. This type is declared in windef.h as follows: typedef HANDLE HHOOK; |
HICON | Handle to an icon. This type is declared in windef.h as follows: typedef HANDLE HICON; |
HINSTANCE | Handle to an instance. This type is declared in windef.h as follows: typedef HANDLE HINSTANCE; |
HKEY | Handle to a registry key. This type is declared in windef.h as follows: typedef HANDLE HKEY; |
HKL | Input locale identifier. This type is declared in windef.h as follows: typedef HANDLE HKL; |
HLOCAL | Handle to a local memory block. This type is declared in windef.h as follows: typedef HANDLE HLOCAL; |
HMENU | Handle to a menu. This type is declared in windef.h as follows: typedef HANDLE HMENU; |
HMETAFILE | Handle to a metafile. This type is declared in windef.h as follows: typedef HANDLE HMETAFILE; |
HMODULE | Handle to a module. The value is the base address of the module. This type is declared in windef.h as follows: typedef HINSTANCE HMODULE; |
HMONITOR | Handle to a display monitor. This type is declared in windef.h as follows: if(WINVER >= 0x0500) typedef HANDLE HMONITOR; |
HPALETTE | Handle to a palette. This type is declared in windef.h as follows: typedef HANDLE HPALETTE; |
HPEN | Handle to a pen. This type is declared in windef.h as follows: typedef HANDLE HPEN; |
HRESULT | Return code used by interfaces. It is zero upon success and nonzero to represent an error code or status information. This type is declared in winnt.h as follows: typedef LONG HRESULT; |
HRGN | Handle to a region. This type is declared in windef.h as follows: typedef HANDLE HRGN; |
HRSRC | Handle to a resource. This type is declared in windef.h as follows: typedef HANDLE HRSRC; |
HSZ | Handle to a DDE string. This type is declared in ddeml.h as follows: typedef HANDLE HSZ; |
HWINSTA | Handle to a window station. This type is declared in windef.h as follows: typedef HANDLE WINSTA; |
HWND | Handle to a window. This type is declared in windef.h as follows: typedef HANDLE HWND; |
INT | 32-bit signed integer. This type is declared in windef.h as follows: typedef int INT; |
INT_PTR | Signed integral type for pointer precision. Use when casting a pointer to an integer to perform pointer arithmetic. This type is declared in basetsd.h as follows: #if defined(_WIN64) typedef __int64 INT_PTR; #else typedef int INT_PTR; |
INT32 | 32-bit signed integer. This type is declared in basetsd.h as follows: typedef signed int INT32; |
INT64 | 64-bit signed integer. This type is declared in basetsd.h as follows: typedef signed __int64 INT64; |
LANGID | Language identifier. This type is declared in winnt.h as follows: typedef WORD LANGID; |
LCID | Locale identifier. This type is declared in winnt.h as follows: typedef DWORD LCID; |
LCTYPE | Locale information type. This type is declared in winnls.h as follows: typedef DWORD LCTYPE; |
LGRPID | Language group identifier. This type is declared in winnls.h as follows: typedef DWORD LGRPID; |
LONG | 32-bit signed integer. This type is declared in winnt.h as follows: typedef long LONG; |
LONGLONG | 64-bit signed integer. This type is declared in winnt.h as follows: typedef __int64 LONGLONG; #else typedef double LONGLONG; |
LONG_PTR | Signed long type for pointer precision. Use when casting a pointer to a long to perform pointer arithmetic. This type is declared inbasetsd.h as follows: #if defined(_WIN64) typedef __int64 LONG_PTR; #else typedef long LONG_PTR; |
LONG32 | 32-bit signed integer. This type is declared in basetsd.h as follows: typedef signed int LONG32; |
LONG64 | 64-bit signed integer. This type is declared in basetsd.h as follows: typedef __int64 LONG64; |
LPARAM | Message parameter. This type is declared in windef.h as follows: typedef LONG_PTR LPARAM; |
LPBOOL | Pointer to a bool. This type is declared in windef.h as follows: typedef BOOL *LPBOOL; |
LPBYTE | Pointer to aBYTE. This type is declared in windef.h as follows: typedef BYTE *LPBYTE; |
LPCOLORREF | Pointer to aCOLORREF value. This type is declared in windef.h as follows: typedef DWORD *LPCOLORREF; |
LPCSTR | Pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters. This type is declared in winnt.h as follows: typedef CONST CHAR *LPCSTR; |
LPCTSTR | An LPCWSTR if UNICODE is defined, an LPCSTR otherwise. This type is declared in winnt.h as follows: #ifdef UNICODE typedef LPCWSTR LPCTSTR; #else typedef LPCSTR LPCTSTR; |
LPCVOID | Pointer to a constant of any type. This type is declared in windef.h as follows: typedef CONST void *LPCVOID; |
LPCWSTR | Pointer to a constant null-terminated string of 16-bit Unicode characters. This type is declared in winnt.h as follows: typedef CONST WCHAR *LPCWSTR; |
LPDWORD | Pointer to aDWORD. This type is declared in windef.h as follows: typedef DWORD *LPDWORD; |
LPHANDLE | Pointer to aHANDLE. This type is declared in windef.h as follows: typedef HANDLE *LPHANDLE; |
LPINT | Pointer to an int. This type is declared in windef.h as follows: typedef int *LPINT; |
LPLONG | Pointer to aLONG. This type is declared in windef.h as follows: typedef long *LPLONG; |
LPSTR | Pointer to a null-terminated string of 8-bit Windows (ANSI) characters. This type is declared in winnt.h as follows: typedef CHAR *LPSTR; |
LPTSTR | An LPWSTR if UNICODE is defined, an LPSTR otherwise. This type is declared in winnt.h as follows: #ifdef UNICODE typedef LPWSTR LPTSTR; #else typedef LPSTR LPTSTR; |
LPVOID | Pointer to any type. This type is declared in windef.h as follows: typedef void *LPVOID; |
LPWORD | Pointer to aWORD. This type is declared in windef.h as follows: typedef WORD *LPWORD; |
LPWSTR | Pointer to a null-terminated string of 16-bit Unicode characters. This type is declared in winnt.h as follows: typedef WCHAR *LPWSTR; |
LRESULT | Signed result of message processing. This type is declared in windef.h as follows: typedef LONG_PTR LRESULT; |
PBOOL | Pointer to a bool. This type is declared in windef.h as follows: typedef BOOL *PBOOL; |
PBOOLEAN | Pointer to abool. This type is declared in winnt.h as follows: typedef BOOLEAN *PBOOLEAN; |
PBYTE | Pointer to aBYTE. This type is declared in windef.h as follows: typedef BYTE *PBYTE; |
PCHAR | Pointer to aCHAR. This type is declared in winnt.h as follows: typedef CHAR *PCHAR; |
PCSTR | Pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters. This type is declared in winnt.h as follows: typedef CONST CHAR *PCSTR; |
PCTSTR | A PCWSTR if UNICODE is defined, a PCSTR otherwise. This type is declared in winnt.h as follows: #ifdef UNICODE typedef LPCWSTR PCTSTR; #else typedef LPCSTR PCTSTR; |
PCWSTR | Pointer to a constant null-terminated string of 16-bit Unicode characters. This type is declared in winnt.h as follows: typedef CONST WCHAR *PCWSTR; |
PDWORD | Pointer to aDWORD. This type is declared in windef.h as follows: typedef DWORD *PDWORD; |
PDWORDLONG | Pointer to aDWORDLONG. This type is declared in winnt.h as follows: typedef DWORDLONG *PDWORDLONG; |
PDWORD_PTR | Pointer to aDWORD_PTR. This type is declared in basetsd.h as follows: typedef DWORD_PTR *PDWORD_PTR; |
PDWORD32 | Pointer to aDWORD32. This type is declared in basetsd.h as follows: typedef DWORD32 *PDWORD32; |
PDWORD64 | Pointer to aDWORD64. This type is declared in basetsd.h as follows: typedef DWORD64 *PDWORD64; |
PFLOAT | Pointer to aFLOAT. This type is declared in windef.h as follows: typedef FLOAT *PFLOAT; |
PHANDLE | Pointer to aHANDLE. This type is declared in winnt.h as follows: typedef HANDLE *PHANDLE; |
PHKEY | Pointer to anHKEY. This type is declared in windef.h as follows: typedef HKEY *PHKEY; |
PINT | Pointer to anint. This type is declared in windef.h as follows: typedef int *PINT; |
PINT_PTR | Pointer to anINT_PTR. This type is declared in basetsd.h as follows: typedef INT_PTR *PINT_PTR; |
PINT32 | Pointer to anINT32. This type is declared in basetsd.h as follows: typedef INT32 *PINT32; |
PINT64 | Pointer to anINT64. This type is declared in basetsd.h as follows:typedef INT64 *PINT64; |
PLCID | Pointer to anLCID. This type is declared in winnt.h as follows: typedef PDWORD PLCID; |
PLONG | Pointer to aLONG. This type is declared in winnt.h as follows: typedef LONG *PLONG; |
PLONGLONG | Pointer to aLONGLONG. This type is declared in winnt.h as follows: typedef LONGLONG *PLONGLONG; |
PLONG_PTR | Pointer to aLONG_PTR. This type is declared in basetsd.h as follows: typedef LONG_PTR *PLONG_PTR; |
PLONG32 | Pointer to aLONG32. This type is declared in basetsd.h as follows: typedef LONG32 *PLONG32; |
PLONG64 | Pointer to aLONG64. This type is declared in basetsd.h as follows: typedef LONG64 *PLONG64; |
POINTER_32 | 32-bit pointer. On a 32-bit system, this is a native pointer. On a 64-bit system, this is a truncated 64-bit pointer. This type is declared in basetsd.h as follows: #if defined(_WIN64) #define POINTER_32 __ptr32 #else #define POINTER32 |
POINTER_64 | 64-bit pointer. On a 64-bit system, this is a native pointer. On a 32-bit system, this is a sign-extended 32-bit pointer. This type is declared in basetsd.h as follows: #define POINTER_64 __ptr64 |
PSHORT | Pointer to aSHORT. This type is declared in winnt.h as follows: typedef SHORT *PSHORT; |
PSIZE_T | Pointer to aSIZE_T. This type is declared in basetsd.h as follows: typedef SIZE_T *PSIZE_T; |
PSSIZE_T | Pointer to aSSIZE_T. This type is declared in basetsd.h as follows: typedef SSIZE_T *PSSIZE_T; |
PSTR | Pointer to a null-terminated string of 8-bit Windows (ANSI) characters. This type is declared in winnt.h as follows: typedef CHAR *PSTR; |
PTBYTE | Pointer to aTBYTE. This type is declared in winnt.h as follows: typedef TBYTE *PTBYTE; |
PTCHAR | Pointer to aTCHAR. This type is declared in winnt.h as follows: typedef TCHAR *PTCHAR; |
PTSTR | A PWSTR if UNICODE is defined, a PSTR otherwise. This type is declared in winnt.h as follows: #ifdef UNICODE typedef LPWSTR PTSTR; #else typedef LPSTR PTSTR; |
PUCHAR | Pointer to aUCHAR. This type is declared in windef.h as follows: typedef UCHAR *PUCHAR; |
PUINT | Pointer to aUINT. This type is declared in windef.h as follows: typedef UINT *PUINT; |
PUINT_PTR | Pointer to aUINT_PTR. This type is declared in basetsd.h as follows: typedef UINT_PTR *PUINT_PTR; |
PUINT32 | Pointer to aUINT32. This type is declared in basetsd.h as follows: typedef UINT32 *PUINT32; |
PUINT64 | Pointer to aUINT64. This type is declared in basetsd.h as follows: typedef UINT64 *PUINT64; |
PULONG | Pointer to aULONG. This type is declared in windef.h as follows: typedef ULONG *PULONG; |
PULONGLONG | Pointer to aULONGLONG. This type is declared in windef.h as follows: typedef ULONGLONG *PULONGLONG; |
PULONG_PTR | Pointer to aULONG_PTR. This type is declared in basetsd.h as follows: typedef ULONG_PTR *PULONG_PTR; |
PULONG32 | Pointer to aULONG32. This type is declared in basetsd.h as follows: typedef ULONG32 *PULONG32; |
PULONG64 | Pointer to aULONG64. This type is declared in basetsd.h as follows: typedef ULONG64 *PULONG64; |
PUSHORT | Pointer to aUSHORT. This type is declared in windef.h as follows: typedef USHORT *PUSHORT; |
PVOID | Pointer to any type. This type is declared in winnt.h as follows: typedef void *PVOID; |
PWCHAR | Pointer to aWCHAR. This type is declared in winnt.h as follows: typedef WCHAR *PWCHAR; |
PWORD | Pointer to aWORD. This type is declared in windef.h as follows: typedef WORD *PWORD; |
PWSTR | Pointer to a null- terminated string of 16-bit Unicode characters. This type is declared in winnt.h as follows: typedef WCHAR *PWSTR; |
SC_HANDLE | Handle to a service control manager database. This type is declared in winsvc.h as follows: typedef HANDLE SC_HANDLE; |
SC_LOCK | Lock to a service control manager database. This type is declared in winsvc.h as follows: typedef LPVOID SC_LOCK; |
SERVICE_STATUS_HANDLE | Handle to a service status value. This type is declared in winsvc.h as follows: typedef HANDLE SERVICE_STATUS_HANDLE; |
SHORT | Short integer (16 bits). This type is declared in winnt.h as follows:typedef short SHORT; |
SIZE_T | The maximum number of bytes to which a pointer can point. Use for a count that must span the full range of a pointer. This type is declared in basetsd.h as follows: typedef ULONG_PTR SIZE_T; |
SSIZE_T | Signed SIZE_T. This type is declared in basetsd.h as follows: typedef LONG_PTR SSIZE_T; |
TBYTE | A WCHAR if UNICODE is defined, a CHAR otherwise. This type is declared in winnt.h as follows: #ifdef UNICODE typedef WCHAR TBYTE; #else typedef unsigned char TBYTE; |
TCHAR | A WCHAR if UNICODE is defined, a CHAR otherwise. This type is declared in winnt.h as follows: #ifdef UNICODE typedef WCHAR TCHAR; #else typedef char TCHAR; |
UCHAR | UnsignedCHAR. This type is declared in windef.h as follows: typedef unsigned char UCHAR; |
UINT | Unsignedint. This type is declared in windef.h as follows: typedef unsigned int UINT; |
UINT_PTR | UnsignedINT_PTR. This type is declared in basetsd.h as follows: #if defined(_WIN64) typedef unsigned __int64 UINT_PTR; #else typedef unsigned int UINT_PTR; |
UINT32 | UnsignedINT32. This type is declared in basetsd.h as follows: typedef unsigned int UINT32; |
UINT64 | UnsignedINT64. This type is declared in basetsd.h as follows: typedef unsigned __int 64 UINT64; |
ULONG | UnsignedLONG. This type is declared in windef.h as follows: typedef unsigned long ULONG; |
ULONGLONG | 64-bit unsigned integer. This type is declared in winnt.h as follows: typedef unsigned __int64 ULONGLONG; #else typedef double ULONGLONG |
ULONG_PTR | UnsignedLONG_PTR. This type is declared in basetsd.h as follows: #if defined(_WIN64) typedef unsigned __int64 ULONG_PTR; #else typedef unsigned long ULONG_PTR; |
ULONG32 | UnsignedLONG32. This type is declared in basetsd.h as follows: typedef unsigned int ULONG32; |
ULONG64 | UnsignedLONG64. This type is declared in basetsd.h as follows: typedef unsigned __int64 ULONG64; |
USHORT | Unsigned SHORT. This type is declared in windef.h as follows: typedef unsigned short USHORT; |
USN | Update sequence number (USN). This type is declared in winnt.h as follows: typedef LONGLONG USN; |
VOID | Any type. This type is declared in winnt.h as follows: #define VOID void |
WCHAR | 16-bit Unicode character. This type is declared in winnt.h as follows: typedef wchar_t WCHAR; |
WINAPI | Calling convention for system functions. This type is declared in windef.h as follows: #define WINAPI __stdcall |
WORD | 16-bit unsigned integer. This type is declared in windef.h as follows: typedef unsigned short WORD; |
WPARAM | Message parameter. This type is declared in windef.h as follows: typedef UINT_PTR WPARAM; |
Table 1: Windows data types. |
This topic describes the support for operations on large (64-bit) integers provided by 32-bit Windows. Applications can multiply signed or unsigned 32-bit integers, generating 64-bit results, by using the Int32x32To64() and UInt32x32To64() functions. Applications can shift bits in 64-bit values to the left or right by using the Int64ShllMod32(), Int64ShraMod32(), and Int64ShrlMod32() functions. These functions provide logical and arithmetic shifting.
Applications can also multiply and divide 32-bit values in a single operation by using the MulDiv() function. Although the result of the operation is a 32-bit value, the function stores the intermediate result as a 64-bit value, so that information is not lost when large 32-bit values are multiplied and divided.
Some Windows functions use the LARGE_INTEGER structure to represent 64-bit signed integer values, and the ULARGE_INTEGER structure to specify 64-bit unsigned integer values. Your C compiler may support 64-bit integers natively. For example, Microsoft® Visual C++® supports the __int64 sized integer type.
The New Data Types
|
Fixed-precision data types are the same length in both 32- and 64-bit Windows. To help you remember this, their precision is part of the name of the data type. The following are the fixed-precision data types.
Type | Definition |
DWORD32 | 32-bit unsigned integer |
DWORD64 | 64-bit unsigned integer |
INT32 | 32-bit signed integer |
INT64 | 64-bit signed integer |
LONG32 | 32-bit signed integer |
LONG64 | 64-bit signed integer |
UINT32 | UnsignedINT32 |
UINT64 | UnsignedINT64 |
ULONG32 | UnsignedLONG32 |
ULONG64 | UnsignedLONG64 |
Table 2: Fixed precision data types |
As the pointer precision changes (that is, as it becomes 32 bits on 32-bit Windows and 64 bits with 64-bit Windows), these data types reflect the precision accordingly. Therefore, it is safe to cast a pointer to one of these types when performing pointer arithmetic; if the pointer precision is 64 bits, the type is 64 bits. The count types also reflect the maximum size to which a pointer can refer. The following are the pointer-precision and count types.
Type | Definition |
DWORD_PTR | Unsigned long type for pointer precision. |
HALF_PTR | Half the size of a pointer. Use within a structure that contains a pointer and two small fields. |
INT_PTR | Signed integral type for pointer precision. |
LONG_PTR | Signed long type for pointer precision. |
SIZE_T | The maximum number of bytes to which a pointer can refer. Use for a count that must span the full range of a pointer. |
SSIZE_T | SignedSIZE_T. |
UHALF_PTR | UnsignedHALF_PTR. |
UINT_PTR | UnsignedINT_PTR. |
ULONG_PTR | UnsignedLONG_PTR. |
Table 3: Pointer precision |
There are also new pointer types that explicitly size the pointer. Be cautious when using pointers in 64-bit code: If you declare the pointer using a 32-bit type, the operating system creates the pointer by truncating a 64-bit pointer. All pointers are 64 bits on 64-bit Windows.
Type | Definition |
POINTER_32 | A 32-bit pointer. On 32-bit Windows, this is a native pointer. On 64-bit Windows, this is a truncated 64-bit pointer. |
POINTER_64 | A 64-bit pointer. On 64-bit Windows, this is a native pointer. On 32-bit Windows, this is a sign-extended 32-bit pointer. Note that it is not safe to assume the state of the high pointer bit. |
Table 4: Another pointer precision types. |
Header files for the Windows API enable you to create 32- and 64-bit applications that run on various Microsoft Windows versions.
They use data types that allow you to build both 32- and 64-bit versions of your application from a single source code base.
Microsoft Visual C++ includes copies of the Windows header files that were current at the time Visual C++ was released. Therefore, if you install updated header files from an SDK, you may end up with multiple versions of the Windows header files on your computer.
If you do not sure that you are using the latest version of the SDK header files, you will receive the following error code when compiling code that uses features that were introduced after Visual C++ was released:error C2065: undeclared identifier.
Certain functions that depend on a particular version of Windows are declared using conditional code. This enables you to use the compiler to detect whether your application uses functions that are not supported on its target version(s) of Windows.
To compile an application that uses these functions, you must define the appropriate macros. Otherwise, you will receive the C2065 error message.
The following table indicates the common macros you must define to target each major operating system release.
Individual header files may use different macros; therefore, if header files related compilation problems occur, check the header file that contains the definition for conditional definitions directly.
Minimum system required | Macros to define |
... | ... |
Windows Server 2003 family | _WIN32_WINNT >= 0x0502 WINVER >= 0x0502 |
Windows XP | _WIN32_WINNT >= 0x0501 WINVER >= 0x0501 |
Windows 2000 | _WIN32_WINNT >= 0x0500 WINVER >= 0x0500 |
Windows NT 4.0 | _WIN32_WINNT >= 0x0400 WINVER >= 0x0400 |
Windows Me | _WIN32_WINDOWS = 0x0500 WINVER >= 0x0500 |
Windows 98 | _WIN32_WINDOWS >= 0x0410 WINVER >= 0x0410 |
Windows 95 | _WIN32_WINDOWS >= 0x0400 WINVER >= 0x0400 |
Internet Explorer 6.0 | _WIN32_IE >= 0x0600 |
Internet Explorer 5.6 | _WIN32_IE >= 0x0560 |
Internet Explorer 5.01, 5.5 | _WIN32_IE >= 0x0501 |
Internet Explorer 5.0, 5.0a, 5.0b | _WIN32_IE >= 0x0500 |
Internet Explorer 4.01 | _WIN32_IE >= 0x0401 |
Internet Explorer 4.0 | _WIN32_IE >= 0x0400 |
Internet Explorer 3.0, 3.01, 3.02 | _WIN32_IE >= 0x0300 |
Table 5: Macros for different Windows header file versions and different Windows OS. |
Some features introduced in the latest version of Windows may be added to a service pack for a previous version of Windows. Therefore, to target a service pack, you may need to define_WIN32_WINNT with the value for the next major operating system release.
For example, the GetDllDirectory() function was introduced in Windows Server 2003 and is conditionally defined if _WIN32_WINNT is 0x0502 or greater. This function was also added to Windows XP SP1. Therefore, if you were to define _WIN32_WINNT 0x0501 to target Windows XP, you would miss features that are defined in Windows XP SP1.
You can define these symbols by using the #define statement in each source file, or by specifying the /D compiler option supported by Visual C++.
For Visual C++ 7.0: To specify compiler options, go to theProjects menu and click Properties.
For Visual C++ 6.0: To specify compiler options, go to theProjects menu and click Settings, then select the C/C++ tab.
The error codes returned by a function are not part of the Windows API specification and can vary by operating system or device driver. For this reason, there are functions whose documentation does not include a list of error codes that can be returned.
You should call the GetLastError() function immediately when a function's return value indicates that such a call will return useful data. That is because some functions call SetLastError() with a zero when they succeed, wiping out the error code set by the most recently failed function.
Most functions that set the thread's last error code value set it when they fail; a few functions set it when they succeed.
Function failure is typically indicated by a return value error code such as zero, NULL, or –1. Some functions callSetLastError() under conditions of success.
Error codes are 32-bit values (bit 31 is the most significant bit). Bit 29 is reserved for application-defined error codes; no system error code has this bit set.
If you are defining an error code for your application, set this bit to one. That indicates that the error code has been defined by an application, and ensures that your error code does not conflict with any error codes defined by the system.
A complete list of error codes provided by the operating system can be found at Windows error codes. To obtain an error string for system error codes, you can use the FormatMessage() function.
In Windows, an object is a data structure that represents a system resource, such as a file, thread, or graphic image. So, in Windows we are dealing with objects.
An application cannot directly access (communicate or interact with) object data or the system resource that an object represents.
Instead, an application must obtain an object’s handle, which will be use to access, examine or modify the system resource.
Each handle has an entry in an internally maintained table. These entries contain the addresses of the resources (memory addresses?) and the means to identify the resource type.
In Windows, system provides three categories of objects: user,graphics device interface (GDI), and kernel.
The system uses:
User objects to support window management.
GDI objects to support graphics, and
Kernel objects to support memory management, process execution, and interprocess communications (IPC).
The following Tables are the list of the Windows object categories and in this Tutorial we will focus on some of the kernel objects.
User object | Icon, Caret, Cursor, Dynamic Data Exchange (DDE) conversation, Hook, Accelerator table, Menu, Window, Window position. |
Graphic Device Interface (GDI) object | Bitmap, Brush, Device Context (DC), Enhanced metafile, Enhanced-metafile DC, Font, Memory DC, Metafile, Metafile DC, Palette, Region, Pen and extended pen. |
Kernel object | Access token, Change notification, Communications device, Console input, Console screen buffer, Desktop, Event, Event log, File, File mapping, Heap, Job, Mailslot, Module, Mutex, Pipe, Process, Semaphore, Socket, Thread, Timer, Timer queue, Window station, Update resource, Timer-queue timer. |
Table 6: Windows object categories. |
The following functions are used with handles and objects.
Function | Description |
GetHandleInformation() | Retrieves certain properties of an object handle. |
SetHandleInformation() | Sets certain properties of an object handle. |
CloseHandle() | Closes an open object handle. |
DuplicateHandle() | Duplicates an object handle. |
Table 7: Handle and object functions. |
As an example for information collection, the following Table lists the needed information in order to use the GetHandleInformation() function.
Information | Description |
The function | GetHandleInformation(). |
The use | Retrieves certain properties of an object handle. |
The prototype | BOOL GetHandleInformation(HANDLE hObject, LPDWORD lpdwFlags); |
Example | HANDLE hFile; DWORD lpdwFlags[100];
hFile = CreateFile(...); GetHandleInformation(hFile, lpdwFlags); |
The parameters | hObject - [in] Handle to an object whose information is to be retrieved. You can specify a handle to one of the following types of objects: access token, event, file, file mapping, job, mailslot, mutex, pipe, printer, process, registry key, semaphore, serial communication device, socket, thread, or waitable timer. In Windows Server 2003, Windows XP/2000, this parameter can also be a handle to a console input buffer or a console screen buffer. lpdwFlags- [out] Pointer to a variable that receives a set of bit flags that specify properties of the object handle. The following values are defined:
|
The return value | If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, callGetLastError(). |
The header file | <windows.h> |
Table 8: GetHandleInformation() information. |
From the information in the previous Table, the following program example shows how to obtain an object handle (file) and the use of theGetHandleInformation() function.
#include <windows.h>
#include <stdio.h>
int main()
{
// handle for file
HANDLE hFile;
// file and path
char fname[30] = "c:\\testfile.txt";
DWORD lpdwFlags[100];
hFile = CreateFile(fname, // file to be opened
GENERIC_WRITE, // open for writing
FILE_SHARE_WRITE, // share for writing
NULL, // default security
CREATE_ALWAYS, // create new file only
FILE_ATTRIBUTE_NORMAL |FILE_ATTRIBUTE_ARCHIVE | SECURITY_IMPERSONATION,
// normal file archive and impersonate client
NULL); // no attr. template
if(hFile == INVALID_HANDLE_VALUE)
printf("Could not open %s file, error %d\n", fname, GetLastError());
printf("File's HANDLE is OK!\n");
BOOL test = GetHandleInformation(hFile, lpdwFlags);
printf("The return value is %d, error %d\n", test, GetLastError());
CloseHandle(hFile);
DeleteFile(fname);
return 0;
}
A sample output:
File's HANDLE is OK!
The return value is 1, error 0
Press any key to continue
This Module will try to follow the same steps:
Collecting the required and related information, presented in a Table and
Use the information to build a simple working program.
And another example of the required information in order to use CloseHandle() function.
Information | Description |
The function | CloseHandle(). |
The use | Closes an open object handle. |
The prototype | BOOL CloseHandle(HANDLE hObject); |
Example | hFile = CreateFile(fname, // file to be opened GENERIC_WRITE, // open for writing FILE_SHARE_WRITE, // share for writing NULL, // default security CREATE_ALWAYS, // create new file only FILE_ATTRIBUTE_NORMAL |FILE_ATTRIBUTE_ARCHIVE | SECURITY_IMPERSONATION, // normal file archive and impersonate client NULL); // no attribute template
CloseHandle(hFile); |
The parameters | hObject - [in, out] Handle to an open object. |
The return value | If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, callGetLastError(). |
The header file | <windows.h> |
Table 9: CloseHandle() information. |
The duplicate handle refers to the same object as the original handle. Therefore, any changes to the object are reflected through both handles.
For example, the current file mark for a file handle is always the same for both handles.
Note that DuplicateHandle() should not be used to duplicate handles to I/O completion ports. In this case, no error is returned, but the duplicate handle cannot be used.
In some cases, the new handle can have more access rights than the original handle. However, in other cases, DuplicateHandle() cannot create a handle with more access rights than the original.
For example, a file handle created with the GENERIC_READ access right cannot be duplicated so that it has both the GENERIC_READ and GENERIC_WRITE access right.
DuplicateHandle() can be called by either the source process or the target process (or a process that is both the source and target process).
For example, a process can use DuplicateHandle() to create a non-inheritable duplicate of an inheritable handle, or a handle with different access than the original handle.
The following Table lists the required information in order to use the DuplicateHandle() function.
Information | Description |
The function | DuplicateHandle(). |
The use | Duplicates an object handle. |
The prototype | BOOL DuplicateHandle( HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions ); |
Example | HANDLE hStdinRd, hStdinWrDup; BOOL fSuccess;
fSuccess = DuplicateHandle( GetCurrentProcess(), // process's handle to be duplicated hStdinWr, // standard input handle GetCurrentProcess(), // process to receive the duplicatedhandle &hStdinWrDup, // pointer to variable for duplicated handle process receiver 0, // access for the duplicated/new handle FALSE, // not inherited DUPLICATE_SAME_ACCESS); // same access as the source handle
if(!fSuccess) printf("DuplicateHandle() failed\n"); |
The parameters | hSourceProcessHandle - [in] Handle to the process with the handle to duplicate. The handle must have the PROCESS_DUP_HANDLE access right. hSourceHandle - [in] Handle to duplicate. This is an open object handle that is valid in the context of the source process. hTargetProcessHandle - [in] Handle to the process that is to receive the duplicated handle. The handle must have thePROCESS_DUP_HANDLE access right. lpTargetHandle -[out] Pointer to a variable that receives the duplicate handle. This handle value is valid in the context of the target process. IfhSourceHandle is a pseudo handle returned byGetCurrentProcess() or GetCurrentThread(),DuplicateHandle() converts it to a real handle to a process or thread, respectively. IflpTargetHandle is NULL, the function duplicates the handle, but does not return the duplicate handle value to the caller. This behavior exists only for backward compatibility with previous versions of this function. You should not use this feature, as you will lose system resources until the target process terminates. dwDesiredAccess - [in] Access requested for the new handle. For the flags that can be specified for each object type. This parameter is ignored if the dwOptions parameter specifies theDUPLICATE_SAME_ACCESS flag. Otherwise, the flags that can be specified depend on the type of object whose handle is to be duplicated. bInheritHandle - [in] Indicates whether the handle is inheritable. If TRUE, the duplicate handle can be inherited by new processes created by the target process. If FALSE, the new handle cannot be inherited. dwOptions - [in] Optional actions. This parameter can be zero, or any combination of the following values. DUPLICATE_CLOSE_SOURCE - Closes the source handle. This occurs regardless of any error status returned. DUPLICATE_SAME_ACCESS - Ignores the dwDesiredAccess parameter. The duplicate handle has the same access as the source handle. |
The return value | If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, callGetLastError(). |
The header file | <windows.h> |
Table 10: DuplicateHandle() information. |
Handles returned by GetStdHandle() can be used by applications that need to read from or write to the console.
When a console is created, the standard input handle is a handle to the console's input buffer, and the standard output and standard error handles are handles of the console's active screen buffer.
These handles can be used by the ReadFile() and WriteFile() functions, or by any of the console functions that access the console input buffer or a screen buffer, for example, theReadConsoleInput(), WriteConsole(), or GetConsoleScreenBufferInfo() functions.
The standard handles of a process may be redirected by a call to SetStdHandle(), in which case GetStdHandle() returns the redirected handle.
If the standard handles have been redirected, you can specify the CONIN$ value in a call to the CreateFile() function to get a handle to a console's input buffer. Similarly, you can specify the CONOUT$ value to get a handle to a console's active screen buffer.
The following Table lists the required information in order to use the GetStdHandle() function.
Information | Description |
The function | GetStdHandle(). |
The use | Retrieves a handle for the standard input, standard output, or standard error device. |
The prototype | HANDLE GetStdHandle(DWORD nStdHandle); |
Example | HANDLE hStdout;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE); |
The parameters | nStdHandle - [in] Standard device for which a handle is to be returned. This parameter can be one of the following values:
|
The return value | If the function succeeds, the return value is a handle to the specified device, or a redirected handle set by a previous call toSetStdHandle(). The handle has GENERIC_READ andGENERIC_WRITE access rights, unless the application has usedSetStdHandle() to set a standard handle with lesser access. If the function fails, the return value isINVALID_HANDLE_VALUE. To get extended error information, callGetLastError(). If an application does not have associated standard handles, such as a service running on an interactive desktop, and has not redirected them, the return value is NULL. |
The header file | <windows.h> |
Table 11: GetStdHandle() information. |
The standard handles of a process may have been redirected by a call to SetStdHandle(), in which case GetStdHandle() will return the redirected handle.
If the standard handles have been redirected, you can specify the CONIN$ value in a call to the CreateFile() function to get a handle to a console's input buffer.
Similarly, you can specify the CONOUT$ value to get a handle to the console's active screen buffer.
The following Table lists the required information in order to use the SetStdHandle() function.
Information | Description |
The function | SetStdHandle(). |
The use | Sets the handle for the standard input, standard output, or standard error device. |
The prototype | BOOL SetStdHandle(DWORD nStdHandle, HANDLE hHandle); |
Example | HANDLE hStdout;
BOOL success = SetStdHandle(STD_OUTPUT_HANDLE, hStdout); // if something wrong with handle if(!success) // just exit exit(1); |
The parameters | nStdHandle - [in] Standard device for which the handle to be set. This parameter can be one of the following values:
hHandle - [in] Handle to set to the specified device. |
The return value | If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, callGetLastError(). |
The header file | <windows.h> |
Table 12: SetStdHandle() information. |
The following program example uses GetStdHandle() function for standard input and output handles.
#include <windows.h>
#include <stdio.h>
#define BUFSIZE 2048
int main()
{
char chrBuf[BUFSIZE];
DWORD dwRead, dwWritten;
HANDLE hStdin, hStdout;
BOOL fSuccess;
// standard output handle
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
// standard input handle
hStdin = GetStdHandle(STD_INPUT_HANDLE);
// if something wrong with handle for standard input or output
if((hStdout == INVALID_HANDLE_VALUE) || (hStdin == INVALID_HANDLE_VALUE))
// just exit
exit(1);
printf("Waiting data from standard input:\n");
printf("--EOF to end--\n");
// to stop, press end of file characters
for(;;)
{
// read from standard input, keyboard.
fSuccess = ReadFile(hStdin, chrBuf, BUFSIZE, &dwRead, NULL);
if(!fSuccess || dwRead == 0)
break;
printf("Data to the standard output:\n");
// write to standard output, console.
fSuccess = WriteFile(hStdout, chrBuf, dwRead, &dwWritten, NULL);
if(!fSuccess)
break;
}
return 0;
}
A sample output:
Waiting data from standard input:
--EOF to end--
This line of text is from standard input
Data to the standard output:
This line of text is from standard input
Then redirected to standard output...
Data to the standard output:
Then redirected to standard output...
^Z
Press any key to continue
The following is a sample output run using VC++ Express Edition on Win XP Pro SP2 with Windows SDK.
Check the best selling C, C++ and Windows books at Amazon.com.
Microsoft Visual C++, online MSDN.
For Multibytes, Unicode characters and Localization please refer to Locale, Wide Character & Unicode (Story) and Windows Users & Groups tutorial
Structure, enum, union and typedef story can be found in struct, typedef, union & enum.
Notation used in MSDN is Hungarian Notation instead of CamelCase and is discussedC/C++ Notations.
More for Windows File system, directory and files is Windows File System Supplementary Notes.