Some Basic Background Story of The Win32 APIs Win32 API背景故事/背景知识 The Win32 application programming interface (API) provides building blocks used by applications written for the Microsoft Windows operating system family. It defines the 32-bit members of the Windows family from the programmer's point of view and you will find out later, 64-bit members also included. Some members of the Windows family use the entire Win32 API, while others use subsets.
Win32 API提供在微软windows操作系统平台上编制应用程序的函数功能块,Win32 API从应用程序程序员的角度定义32位windows家族平台下应用程序系统接口,在以后的windows版本将将能够看到64位windows平台的WinAPI(注:实际上在XP平台已经有64位版本的WinAPI)。一些windows平台使用全部的Win32 API函数,而一些windows版本则使用Win32 API的子集(注:在工业控制和移动应用中大家熟知的WinCE使用的就是Win32 API的子集,西门子的MP系列触摸屏使用的就是一个子集,在里面编程可以使用VBscript脚本)。
The Microsoft Foundation Class Library (MFC) encapsulates, or "wraps," most of the Win32 API but not all. 微软基础类库封装了Win32 API,但是不是所有的API函数都封装到了MFC.
MFC versions 2.x and earlier encapsulated the 16-bit Windows API. MFC supplies classes representing key Windows objects, such as windows, dialog boxes, brushes, pens, and fonts. 2.x版本或更早版本的MFC封装了部分16位的WinAPI, MFC支持windows面向对象编程的中的对象的概念,例如窗口类、对话框类、画刷类、画笔类和字体类等。
The member functions of these classes wrap most of the important Win32 API functions associated with the encapsulated object. 这些类的成员函数封装了与这些对象相关的大部分重要的Win32 API函数。
The MFC class member function calls the Win32 API function, and might add functionality. MFC类程序员调用Win32 API函数,并且可能自封装一些实现其他功能的成员函数。
The Active Template Library (ATL) is a set of template-based C++ classes that let you create small, fast Component Object Model (COM) objects. ATL wraps Win32 and C run-time library APIs, but does not wrap Win32 to the extent that MFC does. ATL类库是C++模板类库的一个子集,它让你可以创建小而快速的对象组建模型的对象。 ATL封装了Win32和C语言运行时类库函数,但是和MFC不一样的是它没有封装一些给予Win32的MFC扩展。
With Visual C++, you can program for Windows using either: C or C++ and the Win32 API. C++ and MFC or C++ and ATL. 通过Visual C++你能够使用下下列模型来编制应用程序: 1、C语言、C++或者Win32 API。 2、C++或者MFC 3、C++或者 ATL。
For information about Win32 programming we normally refer to Win32 API and the documentation is available in the Platform SDK. 当提及Win32编程时,我们通常描述的是基于Win32 API和平台SDK的相关文档。
In the previous Module we have been introduced to some of the Microsoft implementation of the C using the C Run-time (CRT) libraries. In this Module we will explore the Win32 APIs with C. 在前面的板块我们已经介绍过基于C和C语言运行时库CRT来完成一些微软Windows的应用实现,这里我们将介绍利用Win32和C来的应用实现。
This API is designed for use by C/C++ programmers but in this Module we still drop the Windows graphical user interface and message-driven related things, the MFC and ATL. Don’t worry; C/C++ codes are reusable in the MFC and ATL. API是为使用C/C++的程序员设计的,但是在这里我们讨论windows的图形用户界面接口和事件驱动机制,以及MFC和ATL相关的知识。不必担心,C/C++的代码可以在MFC和ATL中复用(注:这里指的是可以交叉使用)。
Whatever it is, from C/C++ view, these APIs are just functions. As usual, we are going to learn how to use those functions. 然而从C/C++的观点来看,API只是函数,和通常一样我们将学习如何使用这些函数。
We will learn several categories of the available APIs. For others, please refer to the Platform SDK documentations. 接下来我们将学习集中不同种类的API函数,为了更好的使用这些函数,或者需要更多的信息,请参考微软提供的平台SDK文档。
First of all let start with the most basic information required to fully understand how to use the Win32 APIs: the Windows data types, header files issue and handles. 首先,让我们来看看要完全学会使用Win32API的最基本的内容:windows数据类型、windows头文件和句柄。 Other than the standard data types that you have found when doing the C/C++ programming, there is a lot more in Win32 programming. 这些内容不仅仅是标准的C/C++的数据结构类型,而是为Win32编程设计的数据类型。
|
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.
由于windows操作系统的版本不断的更新,当你在不同的windows版本下使用相同的头文件和相同的Win32 API函数名时可能会实现不同的函数功能,这些函数在某些版本上可能会使用宏实现(注:这里在VC++ 里面与库的实现相关,至于在调用过程中是调用宏还是调用函数,请查询库的相关实现文档)
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.
接下来我们将学习Win32 API中关于文件系统管理的相关内容,我们将尝试收集相关的信息,并且尝试建立我们自己的实例应用程序实体。
These functions used to deal with volumes, disks, directories (including paths) and files management. The file system used in the discussion is NTFS.
这些函数实现卷标管理、磁盘管理、目录管理和文件管理,这里我们的讨论都将基于NTFS文件系统。
The not so understandable stories about Windows file system and storage can be found Supplementary for Windows file system.
在整个过程中将不再额外地叙述windows文件系统和存储的相关的基础知识。
There is no new constructs you will find in this Module except functions, arrays, pointers and structures.
这里将不再描述除了函数、数组、指针和结构体外的新的数据类型。
Windows Data Types
Windows数据类型
The data types supported by Microsoft Windows are used to define function return values, function and message parameters, structure members and variables. They define thesize and meaning of these elements.
被微软windows平台支持的数据类型用阿里定义:函数的返回值、函数和消息参数、结构体的结构成员和便面。 Windows数据类型定义这些元素的大小和意义信息。
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.
下表例举了一些数据类型如:字符型、整型、布尔型、指针型和句柄类型。字符、整型和布尔类型被大多数的C/C++编译器支持。这些数据类型中还包括64位的数据类型。
If you have noticed, many types actually are derived from the basic types with new name using the typedef or #define and some are specific for the graphic functions.
也许你会注意到,很多数据类型具有相同的基类型,他们只不过是通过typedef机制定义的数据类型的别名(注:严格来说不能说是数据类型别名,应该就是新的数据类型);或者为图形界面下编程函数使用而用#define定义的宏
Most of the pointer-type names begin with a prefix of P or LP (long pointer) and handle with H.
大部分的指针类型的类型名前面都加了P或者LP(长指针)前缀,而句柄类型则加了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 and winnt.h.
哦哦,在windows环境下面有太多的数据类型, :o).
说明
Keyword 关键字 |
Description 描述 |
ATOM 原子类型 |
Atom. This type is declared in windef.h as follows: typedef WORD ATOM; 原子类型,在windef.h 头文件定义。 定义语法: typedef WORD ATOM; |
BOOL 布尔类型 |
Boolean variable (should be TRUE or FALSE). This type is declared in windef.h as follows: typedef int BOOL; 布尔型变量(变量取值: TRUE和FALSE), 在头文件windef.h里面定义。 定义语法: typedef int BOOL; |
BOOLEAN 布尔类型
|
Boolean variable (should be TRUE or FALSE). This type is declared in winnt.h as follows: typedef BYTE BOOLEAN; 布尔型变量(变量取值: TRUE和FALSE), 在头文件windef.h里面定义。 定义语法: Typedef BYTE BOOLEAN; |
BYTE 字节类型 |
Byte (8 bits). This type is declared in windef.h as follows: typedef unsigned char BYTE; 字节类型,8位数据宽度。 在头文件windef中定义。 定义语法: typedef unsigned char BYTE; |
CALLBACK 回调函数标识 |
Calling convention for callback functions. This type is declared in windef.h as follows: #define CALLBACK __stdcall 回调函数调用规则指示符,知识函数参数的调用规则(这个一般由编译器定义),在头文件windef.h中声明。 声明语法如下: #difine CALLBACK __stdcall |
CHAR 字符类型 |
8-bit Windows (ANSI) character. This type is declared in winnt.h as follows: typedef char CHAR; 8位的ANSI字符类型,在头文件winnt.h中定义。 定义语法: typedef char CHAR; |
COLORREF 颜色数据类型 |
Red, green, blue (RGB) color value (32 bits). This type is declared in windef.h as follows: typedef DWORD COLORREF; 基于红、绿、蓝三原色(RGB)定义的数据结构,32为数据位宽度。在windef.h头文件中定义。 定义语法: 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 表示变量的值在运行期间只读的修饰符,在windef.h头文件中声明。 声明语法: #define CONST const |
DWORD 双字类型 |
32-bit unsigned integer. This type is declared in windef.h as follows: typedef unsigned long DWORD; 32位无符号整型,在头文件windef.h中定义。 定义语法: typedef unsigned long DWORD; |
DWORDLONG 长双字类型 |
64-bit unsigned integer. This type is declared in winnt.h as follows: typedef ULONGLONG DWORDLONG; 64位无符号整型,在winnt.h 头文件中定义。 定义语法: 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;精确指针Unsigned long类型,通常在将一个指针类型转换为长整型数据类型时使用。通常在64位windows里面将32位参数扩展位64位是使用,在头文件basetsd.h中定义。 定义语法: typedef ULONG_PTR DWORD_PTR; |
DWORD32 32位无符号整型。 |
32-bit unsigned integer. This type is declared in basetsd.h as follows: typedef unsigned int DWORD32; 32位无符号整型,在头文件basetsd.h中定义。 定义语法: typedef unsigned int DWORD32; |
DWORD64 64位无符号整型 |
64-bit unsigned integer. This type is declared in basetsd.h as follows: typedef unsigned __int64 DWORD64; 64位无符号整型,在basetsd.h头文件中定义 定义语法: typedef unsigned __int64 DWORD64; |
FLOAT 浮点类型 |
Floating-point variable. This type is declared in windef.h as follows: typedef float FLOAT; 浮点型变量类型,在windef.h中定义。 定义语法: typedef float FLOAT; |
HACCEL 加速器表句柄 |
Handle to an accelerator table. This type is declared in windef.h as follows: accelerator table. 加速器表句柄,在windef头文件中定义。 定义语法: accelerator table. |
HANDLE 句柄 |
Handle to an object. This type is declared in winnt.h as follows: typedef PVOID HANDLE; 对象句柄,在winnt头文件中定义。 定义语法: typedef PVOID HANDLE;
|
HBITMAP 位图对象句柄 |
Handle to a bitmap. This type is declared in windef.h as follows: typedef HANDLE HBITMAP; 位图对象句柄,在windef头文件中定义。 定义语法: typedef HANDLE HBITMAP; |
HBRUSH 画刷句柄 |
Handle to a brush. This type is declared in windef.h as follows: typedef HANDLE HBRUSH; 画刷对象句柄,在windef头文件中定义。 定义语法: typedef HANDLE HBRUSH; |
HCOLORSPACE 颜色空间定义 |
Handle to a color space. This type is declared in windef.h as follows: if(WINVER >= 0x0400) typedef HANDLE HCOLORSPACE; 颜色空间对象句柄,在头文件windef中定义。 定义语法: if(WINVER >= 0x0400) typedef HANDLE HCOLORSPACE; |
HCONV 动态数据交换对象句柄。 |
Handle to a dynamic data exchange (DDE) conversation. This type is declared in ddeml.h as follows: typedef HANDLE HCONV; 动态数据交换对象句柄,在头文件ddeml中定义。 定义语法: typedef HANDLE HCONV; |
HCONVLIST 动态数据交换对象列表句柄 |
Handle to a DDE conversation list. This type is declared in ddeml.h as follows: typedef HANDLE HCONVLIST; 动态数据交换列表句柄;在头文件ddeml中定义。 定义语法: typedef HANDLE HCONVLIST; |
HCURSOR 光标句柄 |
Handle to a cursor. This type is declared in windef.h as follows: typedef HICON HCURSOR; 光标句柄,在头文件windef中定义。 定义语法: typedef HICON HCURSOR; |
HDC 设备内容对象句柄 |
Handle to a device context (DC). This type is declared in windef.h as follows: typedef HANDLE HDC; 设备的内容句柄,在头文件windef中定义。 定义语法: typedef HANDLE HDC; |
HDDEDATA 动态交换数据句柄 |
Handle to DDE data. This type is declared in ddeml.h as follows: typedef HANDLE HDDEDATA; 动态交换数据句柄,在头文件ddeml中定义。 定义语法: typedef HANDLE HDDEDATA; |
HDESK 桌面对象句柄 |
Handle to a desktop. This type is declared in windef.h as follows: typedef HANDLE HDESK; 桌面对象句柄,在头文件windef中定义。 定义语法: 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; 增强型metafile对象句柄,在头文件windef中定义。 定义语法: 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; 通过函数OpenFile打开的文件的句柄,不是CreateFile函数创建的文件句柄。在头文件windef中定义。 定义语法: typedef int HFILE; |
HFONT 字体对象句柄 |
Handle to a font. This type is declared in windef.h as follows: typedef HANDLE HFONT; 字体对象句柄。在头文件windef中定义, 定义语法: typedef HANDLE HFONT; |
HGDIOBJ |
Handle to a GDI object. This type is declared in windef.h as follows: typedef HANDLE HGDIOBJ; 图形设备接口对象句柄,在头文件windef中定义。 定义语法: typedef HANDLE HGDIOBJ; |
HGLOBAL 全局内存块句柄 |
Handle to a global memory block. This type is declared in windef.h as follows: typedef HANDLE HGLOBAL; 全局内存块对象句柄,在头文件windef中定义。 定义语法: typedef HANDLE HGLOBAL; |
HHOOK HOOK钩子句柄 |
Handle to a hook. This type is declared in windef.h as follows: typedef HANDLE HHOOK; Hook钩子对象句柄,在头文件windef中定义。 定义语法: typedef HANDLE HHOOK; |
HICON 图标句柄 |
Handle to an icon. This type is declared in windef.h as follows: typedef HANDLE HICON; 图标句柄,在头文件windef中定义。 定义语法: typedef HANDLE HICON; |
HINSTANCE |
Handle to an instance. This type is declared in windef.h as follows: typedef HANDLE HINSTANCE; 实例句柄,在头文件windef中定义。 定义语法: typedef HANDLE HINSTANCE; |
HKEY |
Handle to a registry key. This type is declared in windef.h as follows: typedef HANDLE HKEY; 注册表项件句柄,在头文件windef中定义。 定义语法: typedef HANDLE HKEY; |
HKL |
Input locale identifier. This type is declared in windef.h as follows: typedef HANDLE HKL; 本地输入标识符句柄,在头文件windef中定义。 定义语法: typedef HANDLE HKL; |
HLOCAL |
Handle to a local memory block. This type is declared in windef.h as follows: typedef HANDLE HLOCAL; 局部内存块对象句柄,在头文件windef中定义。 定义语法: typedef HANDLE HLOCAL; |
HMENU |
Handle to a menu. This type is declared in windef.h as follows: typedef HANDLE HMENU; 菜单句柄,在头文件windef中定义。 定义语法: typedef HANDLE HMENU; |
HMETAFILE |
Handle to a metafile. This type is declared in windef.h as follows: typedef HANDLE HMETAFILE; Metafile对象句柄,在头文件windef中定义。 定义语法: 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 in basetsd.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 a BYTE. This type is declared in windef.h as follows: typedef BYTE *LPBYTE; |
LPCOLORREF |
Pointer to a COLORREF 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 a DWORD. This type is declared in windef.h as follows: typedef DWORD *LPDWORD; |
LPHANDLE |
Pointer to a HANDLE. 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 a LONG. 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 a WORD. 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 a bool. This type is declared in winnt.h as follows: typedef BOOLEAN *PBOOLEAN; |
PBYTE |
Pointer to a BYTE. This type is declared in windef.h as follows: typedef BYTE *PBYTE; |
PCHAR |
Pointer to a CHAR. 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 a DWORD. This type is declared in windef.h as follows: typedef DWORD *PDWORD; |
PDWORDLONG |
Pointer to a DWORDLONG. This type is declared in winnt.h as follows: typedef DWORDLONG *PDWORDLONG; |
PDWORD_PTR |
Pointer to a DWORD_PTR. This type is declared in basetsd.h as follows: typedef DWORD_PTR *PDWORD_PTR; |
PDWORD32 |
Pointer to a DWORD32. This type is declared in basetsd.h as follows: typedef DWORD32 *PDWORD32; |
PDWORD64 |
Pointer to a DWORD64. This type is declared in basetsd.h as follows: typedef DWORD64 *PDWORD64; |
PFLOAT |
Pointer to a FLOAT. This type is declared in windef.h as follows: typedef FLOAT *PFLOAT; |
PHANDLE |
Pointer to a HANDLE. This type is declared in winnt.h as follows: typedef HANDLE *PHANDLE; |
PHKEY |
Pointer to an HKEY. This type is declared in windef.h as follows: typedef HKEY *PHKEY; |
PINT |
Pointer to an int. This type is declared in windef.h as follows: typedef int *PINT; |
PINT_PTR |
Pointer to an INT_PTR. This type is declared in basetsd.h as follows: typedef INT_PTR *PINT_PTR; |
PINT32 |
Pointer to an INT32. This type is declared in basetsd.h as follows: typedef INT32 *PINT32; |
PINT64 |
Pointer to an INT64. This type is declared in basetsd.h as follows: typedef INT64 *PINT64; |
PLCID |
Pointer to an LCID. This type is declared in winnt.h as follows: typedef PDWORD PLCID; |
PLONG |
Pointer to a LONG. This type is declared in winnt.h as follows: typedef LONG *PLONG; |
PLONGLONG |
Pointer to a LONGLONG. This type is declared in winnt.h as follows: typedef LONGLONG *PLONGLONG; |
PLONG_PTR |
Pointer to a LONG_PTR. This type is declared in basetsd.h as follows: typedef LONG_PTR *PLONG_PTR; |
PLONG32 |
Pointer to a LONG32. This type is declared in basetsd.h as follows: typedef LONG32 *PLONG32; |
PLONG64 |
Pointer to a LONG64. 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 a SHORT. This type is declared in winnt.h as follows: typedef SHORT *PSHORT; |
PSIZE_T |
Pointer to a SIZE_T. This type is declared in basetsd.h as follows: typedef SIZE_T *PSIZE_T; |
PSSIZE_T |
Pointer to a SSIZE_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 a TBYTE. This type is declared in winnt.h as follows: typedef TBYTE *PTBYTE; |
PTCHAR |
Pointer to a TCHAR. 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 a UCHAR. This type is declared in windef.h as follows: typedef UCHAR *PUCHAR; |
PUINT |
Pointer to a UINT. This type is declared in windef.h as follows: typedef UINT *PUINT; |
PUINT_PTR |
Pointer to a UINT_PTR. This type is declared in basetsd.h as follows: typedef UINT_PTR *PUINT_PTR; |
PUINT32 |
Pointer to a UINT32. This type is declared in basetsd.h as follows: typedef UINT32 *PUINT32; |
PUINT64 |
Pointer to a UINT64. This type is declared in basetsd.h as follows: typedef UINT64 *PUINT64; |
PULONG |
Pointer to a ULONG. This type is declared in windef.h as follows: typedef ULONG *PULONG; |
PULONGLONG |
Pointer to a ULONGLONG. This type is declared in windef.h as follows: typedef ULONGLONG *PULONGLONG; |
PULONG_PTR |
Pointer to a ULONG_PTR. This type is declared in basetsd.h as follows: typedef ULONG_PTR *PULONG_PTR; |
PULONG32 |
Pointer to a ULONG32. This type is declared in basetsd.h as follows: typedef ULONG32 *PULONG32; |
PULONG64 |
Pointer to a ULONG64. This type is declared in basetsd.h as follows: typedef ULONG64 *PULONG64; |
PUSHORT |
Pointer to a USHORT. 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 a WCHAR. This type is declared in winnt.h as follows: typedef WCHAR *PWCHAR; |
PWORD |
Pointer to a WORD. 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 |
Unsigned CHAR. This type is declared in windef.h as follows: typedef unsigned char UCHAR; |
UINT |
Unsigned int. This type is declared in windef.h as follows: typedef unsigned int UINT; |
UINT_PTR |
Unsigned INT_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 |
Unsigned INT32. This type is declared in basetsd.h as follows: typedef unsigned int UINT32; |
UINT64 |
Unsigned INT64. This type is declared in basetsd.h as follows: typedef unsigned __int 64 UINT64; |
ULONG |
Unsigned LONG. 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 |
Unsigned LONG_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 |
Unsigned LONG32. This type is declared in basetsd.h as follows: typedef unsigned int ULONG32; |
ULONG64 |
Unsigned LONG64. 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. |
Large Integers
大整数
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.
这里讨论32位windows对64位整型数据的支持。应用程序通过使用Int32X32To64()函数或者UInt32X32To64()函数能够将有符号、无符号的32位整型数据相乘得到64位的结果。应用程序同样能够通过使用Int64ShllMod32()函数和Int64ShraMod32()函数和Int64ShrlMod32()函数进行移位操作;这些函数提供逻辑和算术移位操作功能。
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.
应用程序可以使用MulDiv()函数在一次运算过程中实现32位数据的乘法和除法操作。虽然这个函数的返回值是一个32位的值,但是因为在函数内部使用的是64位数据进行计算,因此在计算超过32位长度的数值是不会丢失数据精度。
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.
一些windows 函数使用LARGE_INTEGER结构来支持64位有符号整型,而使用ULARGE_INTEGER结构来支持64位无符号整型。你的C编译器可能内置支持64位的整型数据;例如微软的Visual C++支持__int64位长度的整型。
The New Data Types 新数据类型 There are three classes of new data types: fixed-precision data types, pointer-precision types, and specific-precision pointers. These types were added to the development environment (specifically, to basetsd.h) to allow developers to prepare for 64-bit Microsoft® Windows® well before its introduction. These new types were derived from the basic C-language integer and long types, so they work in existing code. Therefore, use these data types in your code now, test your code on 32-bit Windows, and recompile with the 64-bit compiler when 64-bit Windows is available. 在windows中提供了3种新的数据类型: 定精度数据类型、指针指向型数据结构和指定数据精度指针类型。这些数据类型在开发环境中(有basetsd.h头文件提供定义支持)增加是为了允许开发者开发64位windows应用程序做准备,这些数据类型派生与基本C语言数据类型,这些数据类型已经在使用。因此可以在你windows 32位平台的代码中使用这些数据类型,当你使用64位windows的时候重新编译你的代码。
There is an additional benefit to adopting these new data types now: it will make your code more robust. To use these data types, you must scan your code for potentially unsafe pointer usage, polymorphism, and data definitions. To be safe, use the new types. For example, when a variable is of type ULONG_PTR, it is clear that it will be used for casting pointers for arithmetic operations or polymorphism. It is not possible to indicate such usage directly by using the existing data types. You can do this by using derived type naming or Hungarian notation, but both techniques are prone to errors. 现在使用这些新的数据类型还有一个好处,它可以使你的代码更加健壮。为了使用这些数据类型,你必须排查你代码中潜在的不安全的指针、 polymorphism、和数据定义。为了代码安全,请使用新的数据类型。例如,当定义一个ULONG_PTR类型变量时,很显然他将在用于数据类型转换或者 polymorphism中将指针进行转换成目标数据类型。利用现有的数据结构或者类型就不能这么清楚的指明这一点。你能通过使用内置的数据类型或者 Hungarian notation,但是两种方法都容易产生错误。 |
Fixed Precision
定精度数据
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.
定精度数据在32位或者64位windows中具有相同的数据位宽度。为了便于记忆,这些数据的精度(注:数据宽度)是数据类型的一部分。下表例举了定精度的数据类型:
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 |
Unsigned INT32 |
UINT64 |
Unsigned INT64 |
ULONG32 |
Unsigned LONG32 |
ULONG64 |
Unsigned LONG64 |
Table 2: Fixed precision data types |
Pointer Precision
指针精度/指针长度
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.
当指针精度/指针长度改变,这些数据类型的长度就自动改变(当在32位windows时这些数据类型位32位,在64位windows时是64位长度);因此在将指针转化为这些数据类型后进行数据运算是安全的,当指针精度是64位时,转化后的数据类型也是64位的。计数器类型同样影响一个指针能引用的最大数据宽度。下表例举了一些指针长度类型和计数器类类型。
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 |
Signed SIZE_T. |
UHALF_PTR |
Unsigned HALF_PTR. |
UINT_PTR |
Unsigned INT_PTR. |
ULONG_PTR |
Unsigned LONG_PTR. |
Table 3: Pointer precision |
Specific Pointer-Precision Types
指定长度指针类型
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.
同样存在显示指出数据位宽的新的指针类型。当在64位代码中使用这些数据类型的时候要注意:如果你声明一个32位长度的指针变量,操作系统将自动截取为32位的指针。 记住在64位系统中所有的指针变量都是64位长度/位宽。
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. 32位指针,在32位系统中,是缺省长度指针,而在64位系统,是一个64位指针经系统截取后的指针。 |
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. 64位指针,在64位系统中是指针缺省长度。在32位系统中,是从32位指针扩展的出来的指针。注意:主观假定一个指针的高位状态是一个不安全的行为。 |
Table 4: Another pointer precision types. |
Multiple Versions of Windows Header Files
Windows头文件的版本
Header files for the Windows API enable you to create 32- and 64-bit applications that run on various Microsoft Windows versions.
WindowsAPI相关的头文件允许你创建在不同的windows版本上允许的32位或者64位的应用程序。
They use data types that allow you to build both 32- and 64-bit versions of your application from a single source code base.
这些API使用不同的数据类型,允许你用同一份代码建立可以在32位和64位版本windows下运行的程序。(注:通过数据类型扩展应用程序的应用范围,就是数据类型)
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.
在Visual C++包括它被发布时的windows API相关的头文件。因此当你用一个SDK开发包升级你的Visual C++时,你可能会遇到很多不同版本的windows API相关的头文件。
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.
如果没有确保你在编译时使用的是最新版本的SDK头文件,而在你的代码中使用了Visual C++发布时介绍的新特性,那么在编译代码的过程中你将可能看到如下的错误代码: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.
某些依赖于特定的windows版本的函数使用条件编译代码来进行声明;这样保证你的编译器能检测你的代码中是否了使用了目标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.
为了在一个应用程序中使用这些函数,你必须定义合适的宏。否则你将会看到编译器报C2065错误。下面的表指出了你必须定义的来适合你的操作系统发布的主要版本号通用宏。
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. 表5 不同的windows操作系统和不同版本的系统能够里不同的宏定义 注:从这里可以看出,微软通过宏定义来控制版本信息 |
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.
一些在高版本Windows的特性可以通过SP升级补丁的在低版本的Windows中应用,因此对于一个SP升级包可能需要定义 _WIN32_WINNT 宏来适应下一个发布版的Windows主版本号。
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.
例如,GetDllDirectory函数在Windows Server 2003里面,如果_WIN32_WINNT宏定义代表的值大于等于0X0502,那么它就被定义。 同样这个函数在WinXP SP1中同样可用。 因此如果你已经定义使用于WinXP的_WIN32_WINNT宏,那么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++.
你可以在每一个源文件文件的头部用#define预处理指令来定义这些符号(这里指: 宏),或者通过VC++ IDE环境支持的 /D 的编译器选项来支持这宏扩展功能。
For Visual C++ 7.0: To specify compiler options, go to the Projects menu and click Properties.
对于 VC++ 7.0,为了设置编译器编译选项,那么通过 工程——》属性菜单来进行设置。
For Visual C++ 6.0: To specify compiler options, go to the Projects menu and click Settings, then select the C/C++ tab.
对于VC++ 6.0, 为了设置编译器编译选项,那么通过 工程——》设置 打开设置对话框,然后选择C/C++标签页进行设置。
Windows System Error Codes
Windows系统错误代码
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.
返回错误代码的函数不是WindowsAPI的一部分,并且函数的返回值可能随操作系统的改变或者硬件设备不同而改变。 由于这个原因,这些函数的相关文档并没有罗列这些函数应该返回什么值。
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.
当你的函数调用会返回一个非常重要的值的时候,你应该立即调用GetLastError()函数来获取函数的返回状态,那是因为一些函数在成功执行时会调用SetLastError函数来设定函数错误状态全局存储空间,这样就会覆盖最后调用失败的函数的错误代码。(注: 就是为了防止错误代码在被使用之前改变,最好在调用重要函数之后马上调用一下GetLastError函数获取函数执行情况的信息)
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 call SetLastError() 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.
典型的指示函数执行错误的返回值是例如0、NULL或-1. 一些函数会在成功之后调用SetLastError函数;错误代码是一个32位的返回值(D31 位尤其重要)。D29位是为应用程序自定义错误代码保留的, 系统错误代码不会设置D29这一位。
(注: 也就是说用户可以设置D29这一位来指示用户需要定义的错误类型)
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.
如果你需要自定义应用程序的错误代码,那么你可以设置D29这一位; 这就说明函数返回的错误代码已经被应用程序重定义过,你必须保证应用程序自定义的错误代码不与系统定义的缺省错误代码冲突。
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 theFormatMessage() function.
可以通过Windows Error Codes可以查看完整的关于windows操作系统定义的错误代码。你可以调用FormatMessage函数来将错误代码转换成你需要的关于函数返回错误原因的字符串信息。
Windows Objects and Handles
Windows对象和句柄
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.
在Windows下,对象就是一个结构体,它标示系统资源,例如文件、线程、图像等。因此在Windows下我们处理的是对象。
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.
每一句柄在系统维护的系统资源表中都对应一个入口点。这个入口点信息包含资源的地址(是内存地址吗?)并且它还指示出资源的类型。
Windows Object Categories
Windows对象类型/种类
In Windows, system provides three categories of objects: user, graphics device interface (GDI), and kernel.
在Windows系统中,操作系统提供了3大种类对象:用户对象、GDI对象和内核对象。
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).
系统使用:
1、 用户对象来支持窗口管理。
2、 GDI对象来支持图形。
3、 内核对象来支持内存管理、进程执行和进程间通讯。
The following Tables are the list of the Windows object categories and in this Tutorial we will focus on some of the kernel objects。
下表例举了windows对象的种类,并且在这一节我们将讨论一些关于内核对象的内容。
User object 用户对象 |
Icon, Caret, Cursor, Dynamic Data Exchange (DDE) conversation, Hook, Accelerator table, Menu, Window, Window position. 图标、光标、动态数据交换、钩子、加速器表、菜单、窗口和窗口位置。 |
Graphic Device Interface (GDI) object GDI对象 |
Bitmap, Brush, Device Context (DC), Enhanced metafile, Enhanced-metafile DC, Font, Memory DC, Metafile, Metafile DC, Palette, Region, Pen and extended pen.
位图、画刷、设备内容、增强metafile、增强metafile设备内容、内存映像文件、MeteFile等 |
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. Window是对象类别 |
Handle and Object Functions
句柄和对象函数
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.
下面是一个关于收集句柄信息的示例。 表中罗列了使用GetHandleInformation函数所需要的信息。
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.
hObject-[in]: 需要获取信息的对象的句柄。你可以位这个参数传递下列对象的句柄: 访问信令、事件、文件、文件映像文件、作业、互斥对象、管道、打印机、进程、注册表键、串行通信设备、套接字、线程或 定时器。 在Windows Server 2003、Windows XP/2000,这个参数还可以是控制台输入缓存或者控制台屏幕缓存。 (注: 目前大部分系统的,字符界面输入都是缓冲型的)
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: HANDLE_FLAG_INHERIT - If this flag is set, a child process created with the bInheritHandles parameter ofCreateProcess() set to TRUE will inherit the object handle. HANDLE_FLAG_PROTECT_FROM_CLOSE - If this flag is set, calling the CloseHandle() function will not close the object handle.
lpdwFlagstaff-[out] 变量指针,指针指向的变量是一个位旗标, 通过位旗标来指示句柄对象的属性。下面是一些预定义值:
HANDLE_FLAG_INHERIT: 如果这个设置了这个位旗标,那么表示通过CreateProcess函数创建的子进程对象将继承父进程的对象句柄的特性。
HANDLE_FLAG_PROTECT_FROM_CLOSE: 如果设置了这个位旗标,那么在调用CloseHandle函数的时候将不能正常撤销对象句柄。
|
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, call GetLastError().
如果这个函数成功执行,那么返回值是一个非零值。 如果函数执行失败,那么将返回0. 如果需要获取更多的错误信息,可以调用GetLastError函数。
|
The header file |
<windows.h> 头文件: windows.h |
Table 8: GetHandleInformation() information. GetHandleInformation函数的使用方法 |
From the information in the previous Table, the following program example shows how to obtain an object handle (file) and the use of the GetHandleInformation() function.
基于上面表格描述的信息,下面的代码示例展示了如何使用GetHandleInformation函数和如何获取一个文件对象的句柄。
#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 ", fname, GetLastError());
printf("File's HANDLE is OK! ");
BOOL test = GetHandleInformation(hFile, lpdwFlags);
printf("The return value is %d, error %d ", 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.
一个关于CloseHandle的示例和相关的信息。
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.
hObject参数, 输入/输出参数, 指向一个打开的对象的句柄。 |
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, call GetLastError().
如果函数执行成功,返回值是非零。 如果函数执行失败,那么将返回0. 如果需要获取更多的错误信息,可以调用GetLastError函数。
|
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.
复制对象句柄和原句柄一样可以用来访问对象。因此,可以通过复制对象句柄和原句柄来访问对象。例如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.
注意DuplicateHandle函数不能用来复制完整的I/O端口对象句柄。这种情况下,将不会返回错误,但是复制对象句柄不能使用。
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.
例如,一个具有GENERIC_READ访问控制权限的文件句柄不能被复制,因此它将具有GENERIC_READ和GENERIC_WRITE访问权限。
DuplicateHandle() can be called by either the source process or the target process (or a process that is both the source and target process).
DuplicateHandle函数能够被原进程调用也能被目标进程调用(或者被一个既是原进程,又是目标进程)。
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.
例如,一个进程可以使用DuplicateHandle函数创建一个可继承对象句柄的复制对象句柄,或者创建一个与原句柄对象访问权限不一样的进程。
The following Table lists the required information in order to use the DuplicateHandle() function.
下表描述了DuplicateHandle函数的必要信息和怎样使用DuplicateHandle函数。
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 duplicated handle &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 ");
|
|
The parameters |
hSourceProcessHandle - [in] Handle to the process with the handle to duplicate. The handle must have the PROCESS_DUP_HANDLE access right. hSourceProcessHandle - [in]: 待复制对象句所在进程的句柄。这个进程句柄必须具有PROCESS_DUP_HANDLE的访问权限。
hSourceHandle - [in] Handle to duplicate. This is an open object handle that is valid in the context of the source process. hSourceHandle - [in], 需要复制的句柄,一个在源进程中打开的有效的句柄。
hTargetProcessHandle - [in] Handle to the process that is to receive the duplicated handle. The handle must have the PROCESS_DUP_HANDLE access right. hTargetProcessHandle - [in] 用来存储目标复制句柄的进程对象句柄,这个进程句柄必须具有:PROCESS_DUP_HANDLE 访问权限。
lpTargetHandle - [out] Pointer to a variable that receives the duplicate handle. This handle value is valid in the context of the target process. If hSourceHandle is a pseudo handle returned by GetCurrentProcess() or GetCurrentThread(), DuplicateHandle() converts it to a real handle to a process or thread, respectively. If lpTargetHandle is NULL, the function duplicates the handle, but does not return the duplicate handle value to the caller. This behavior exists only for backward compatibility with previous versions of this function. You should not use this feature, as you will lose system resources until the target process terminates. lpTargetHandle - [out],接收复制对象句柄的句柄指针,这个句柄值在复制句柄所在的进程中是有效的。 如果hSourceHandle句柄是一个通过GetCurrentProcess函数、GetCurrentThread函数返回的虚对象句柄,那么Duplicatehandle函数就将他转换为一个指向进程或者线程的实对象句柄。 如果传递给复制对象句柄指针lpTargetHandle是一个NULL值,那么DuplicateHandle函数依然复制对象句柄,但是不会将对象句柄返回给调用他的函数空间里面。这种现象只在为了向后兼容的情况线存在;你不应该使用这个特性,否则你将会丢失一些系统资源,直到目标进程终止。(注: 这里资源回收需要应用程序和系统共同维护)
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 the DUPLICATE_SAME_ACCESS flag. Otherwise, the flags that can be specified depend on the type of object whose handle is to be duplicated. dwDesiredAccess - [in] :复制对象句柄的访问权限限制,这个参数位旗标可以针对每个对象类型指定。 如果dwOptions参数设置成DUPLICATE_SAME_ACCESS, 那么这个参数的设置将被忽略。 同时这个参数的设置还与要源对象句柄的类型有关。
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. bInheritHandle - [in]: 这个参数设置复制对象句柄的继承特性,如果设置为TRUE,那么复制对象句柄的特性将可以继承。 如果是FALSE,那么复制对象句柄的属性将不可以被继承。(注:就是说新创建的复制对象句柄的属性不可以被它的子对象所继承)
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. dwOptions - [in]: 可选参数。 这个参数可以设置为0,或者是下面预定义宏的组合值(注: 位旗标的 或运算结果) 1、DUPLICATE_CLOSE_SOURCE 指示关闭源对象句柄,表示不管是否发生错误,都不返回值。 2、DUPLICATE_SAME_ACCESS 指示忽略dwDesiredAccess参数的设定,而指定复制对象句柄也源对象句柄具有同样的访问权限。
|
|
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, call GetLastError().
如果函数执行成功,返回值是非零。 如果函数执行失败,那么将返回0. 如果需要获取更多的错误信息,可以调用GetLastError函数。 |
|
The header file |
<windows.h>
需要保护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.
GetStdHandle函数可以在需要读写控制台的时候返回控制台句柄。
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.
这些句柄可以被ReadFile函数和WriteFile函数使用,或者被其他可以访问控制台输入缓存区和控制台窗口缓存区的函数使用, 例如可以被ReadConsoleInput函数、WriteConsole函数、以及GetConsoleScreenBufferInfo函数使用。
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.
一个进程的标准句柄也许会通过调用SetStdHandle句柄来进行重定向, 这种情况下可以通过GetStdHandle函数返回重定向后的指针。如果标准句柄被重定向后,你可以在调用CreateFile函数时传递CONIN$变量来获取控制台输入缓冲区的句柄。 类似的,你可以指定CONOUT$值来获取一个指向活动的控制台窗口缓冲区的句柄。
The following Table lists the required information in order to use the GetStdHandle() function.
下表描述部分GetStdHandle函数的必要信息,以及如何使用它的一些信息。
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: STD_INPUT_HANDLE - Handle to the standard input device. Initially, this is a handle to the console input buffer, CONIN$. STD_OUTPUT_HANDLE - Handle to the standard output device. Initially, this is a handle to the active console screen buffer, CONOUT$. STD_ERROR_HANDLE - Handle to the standard error device. Initially, this is a handle to the active console screen buffer,CONOUT$.
nStdHandle - [in]:指出将要返回那个标准设备的句柄值,这个参数可以取下面几个宏中的一个: 1、STD_INPUT_HANDLE 指出返回标准输入设备的句柄, 通常这个句柄是一个指向控制台输入缓冲区CONIN$ 的句柄。 2、STD_OUTPUT_HANDLE 指出返回的是标准输出设备的句柄,通常这个句柄是一个指向当前激活控制台窗口缓冲区 CONOUT$的句柄。 3、STD_ERROR_HANDLE 指出函数返回的是标准错误输出设备的句柄, 通常这个句柄是一个指向当前激活的控制台窗口缓冲区CONOUT$的句柄。
|
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 and GENERIC_WRITE access rights, unless the application has usedSetStdHandle() to set a standard handle with lesser access. If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError(). 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.
如果这个函数成功执行,那么返回值就是一个指向指定设备的句柄,或者是一个指向通过SetStdHandle函数重定向的设备的句柄值。 返回的句柄具有 GENERIC_READ 和 GENERIC_WRITE的访问权限, 除非应用程序通过SetStdHandle函数设定标准句柄具有其他更低的权限。 如果函数执行失败,返回值是 INVALID_HANDLE_VALUE, 若要获取更多的错误信息,可以调用GetLastError函数。 如果一个应用程序没有标准设备句柄,或者没有重定向标准设备,例如一个内部桌面运行的一个服务,那么函数将返回一个NULL值。
|
The header file |
<windows.h> 需要包含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.
一个进程的标准输入输出设备可能会通过调用SetStdHandle函数进行重定向,这种情况下可以通过GetStdHandle函数来获取进程经过重定向后的标注输入输出设备的句柄。 如果标准输入输出设备被重定向了,那么在应用程序中调用CreateFile函数时可以通过指定CONIN$参数来获取一个指向控制台输入缓冲区的句柄。
Similarly, you can specify the CONOUT$ value to get a handle to the console's active screen buffer.
类似的还可以指定CONNOUT$值来获取指向当前激活的控制台窗口缓冲区的句柄。
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: STD_INPUT_HANDLE - Handle to the standard input device. STD_OUTPUT_HANDLE - Handle to the standard output device. STD_ERROR_HANDLE - Handle to the standard error device.
nStdHandle - [in]:指出要被重新设定的标准设备。可以取下面几个值: 1、STD_INPUT_HANDLE 指出要设定的是标准输入设备。 2、STD_OUTPUT_HANDLE 指出要设定的设备是标准输出设备 3、STD_ERROR_HANDLE 指出要设定的是标准错误输出设备
hHandle - [in] Handle to set to the specified device.
hHandle - [in] 要重定向给标准设备的对象的句柄。
|
|
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, call GetLastError().
如果函数执行成功,返回值是非零。 如果函数执行失败,那么将返回0. 如果需要获取更多的错误信息,可以调用GetLastError函数。 |
|
The header file |
<windows.h> 要包含头文件 window.h |
|
Table 12: SetStdHandle() information. SetStdHandle函数相关信息 |
The following program example uses GetStdHandle() function for standard input and output handles.
下面是一个使用GetStdHandle函数来获取标准输入输出设备句柄的示例。
#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: ");
printf("--EOF to end-- ");
// 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: ");
// 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.