《windows核心编程》第一部分

第一部分

(1)windows错误处理

windows大多函数返回值的类型
0_1526713166225_TIM截图20180519145910.png
windows函数运行错误时会返回一个错误代码,此错误代码线程独立,每一个错误代码关联一个详细的错误信息。

DWORD  GetLastError()//返回最近的一次错误代码,要在错误发生后立即调用防止被改写
DWORD FormatMassage()//通过错误代码获取错误的具体信息
VOID SetLastError()//使用此函数可以设定我们自定义函数的错误代码返回值,之后使用GetLastError获取的即是我们设置的值

错误代码设定规则
0_1526715252847_TIM截图20180519153349.png
需要知道的重要域是第29位,Microsoft公司规定,他们建立的所有错误代码的这个信息位均使用0。如果创建自己的错误代码,必须使29位为1。

(2)Unicode字符集

单字节字符集:字符串中每个符号只占一个字节。
ANSI(多字节字符集):字符串中每个符号占一个或两个字节。
Unicode字符集:字符串中的字符都是两个字节。
在日常使用中要尽量使用Unicode字符集
windows 2000是Unicode和ANSI都支持,如果传入了ANSI字符会自动转换成Unicode再进行下面的操作。
Windows 98只支持ANSI。
Windows CE只支持Unicode。
所有的COM接口方法都只能接受Unicode字符串。(COM接口主要是用于不同组件的通信)。
下面是C运行库对Unicode字符集的支持
为了兼容Unicode字符串,C定义了一个wchar_t(w为wide的意思代表宽字节)的数据类型。

wchar_t szBuffer[100];//定义一个Unicode缓冲区。

标准的C运行字符串函数(strcpy,strchr,strcat等)都是ANSI函数。不能处理Unicode字符集。
ANSI C字符函数与Unicode C函数对比

strcat----->wcscat    strchr----->wcschr    strcmp----->wcscmp    strcpy----->wcscmp     strlen----->wcslen 
//所有的Unicode函数都以wcs开头,只需要用str代替wcs即可。

由于所有的C运行库是一样的,所以在Windows 98上也是可以调用Unicode C函数的。

在定义有关字符时,尽量用兼容的TCHAR类型来定义,此类型在UNICODE宏定义是否有不同的编译结果。
定义Unicode字符串:

TCHAR *szError = L"Error";//字符串前面的L告诉编译器要作为Unicode字符串来编译,不过只能在定义了UNICODE的环境下成功运行。
TCHAR *szError=_TEXT("Error");//通用的定义方式,根据判断是否有UNICODE来实现。

Windows下的Unicode数据类型:WCHAR(Unicode字符),PWSTR(指针),PCWSTR(常量指针)。
一些Unicode和ANSI兼容函数大多都是通过宏定义实现的。通过是否具有UNICODE来编译成不同的支持函数。
在使用中最好使用操作系统函数,不使用C运行库字符串函数。
定义在ShlWApi.h头文件中,形式为StrCat,StrChr,StrCmp,StrCpy等
符合ANSI和Unicode的应用程序需要注意的点:
0_1526806984087_TIM截图20180520170151.png
Windows操作Unicode函数:
0_1526807076320_TIM截图20180520170426.png
IsTextUnicode()//判断是否是Unicode字符串
MultiByteToWideChar//ANSI转换为Unicode
WideCharToMultiByte//Unicode转换成ANSI

(3)windows内核对象

内核对象:内核对象是存在于内核,由内核创建,分配内存,之后返回一个句柄,每个内核对象是一个数据结构,多种内核对象之间除了安全描述符和引用计数等部分相同大多都是各个对象独特拥有的属性。程序只能通过句柄使用内核提供的API来调用内核对象。
句柄:每个进程中都有一个句柄表,句柄表中的每个元素是一个数据结构,其中保存了内核对象的地址,继承标识,访问掩码的数据,句柄则是相应内核对象在句柄表中的位置。
安全描述符:安全描述符用以描述内核对象的安全性。它描述了内核对象的拥有者,那组用户可以访问此对象,那组用户无访问权限。安全描述符对应一个数据结构:SECURITY_ATTRIBUTES结构,但是大部分情况下都是传入NULL,表示使用默认的安全性。判断创建的对象是不是内核对象则可以看它的创建函数中是否有安全描述符,内核对象创建都有安全描述符。
SetHandleInformation函数可以修改已经创建了的内核对象的安全描述符。
当进程不再使用某内核对象时应该调用CloseHandle来结束进程对此内核对象的引用。当此内核对象的引用计数变为0则被内核销毁。
进程共享内核对象
(1)使用对象句柄继承
只有进程之间属于父子关系时才可以使用对象句柄继承。
父进程在创建内核对象时需要在传进的安全描述符中指定该内核对象可继承。
相同的内核对象,子进程和父进程句柄在句柄表中的位置相同即句柄相同。
(2)命名对象
只有可命名的内核对象可以使用此方式(大部分内核对象可以继承),如果命名重复则会创建失败。
创建了命名后的内核对象后可以通过调用Open或是Create函数来访问它。
如果对象不存在,Create会创建它,Open将会调用失败。
(3)复制对象句柄
实现该方法使用的是Duplicatehandle函数。

该函数实现一个内核对象从一个进程复制到另一个进程。

本篇博客有对网上资料的总结和自己的理解图片来源与书上

猜你喜欢

转载自blog.csdn.net/hhouxiang/article/details/80653799