读《windows核心编程》笔记1

来源:互联网 发布:自动开关机的软件 编辑:程序博客网 时间:2024/05/21 18:38

1,错误处理没什么:GetLastError 而已。

2,字符和字符串处理:

      1.   P代表指针,W代表Unicode宽字符,C代表const,T代表可以为宽字符,也可以不是。

      2.  一些定义:     L"abc"(L代表宽字符)         TEXT("This is a const string.");

           _T("Hello")               TCHAR* szBuf = _T("Hello");   

      3.    C运行库中 _tcslen       

      4.    Windows中的Unicode和Ansi函数: 有两个版本如: CreateWindowsExW, CreateWindowsExA。后者在内部调用前者。CreateWindowsEx则受控与宏定义。

      5.   C运行库中的安全字符串函数。传统的有安全问题,如:(_tcslen)

            wchar_t *wcscpy( wchar_t *strDestination, const wchar_t *strSource );

            这个函数也许会破坏内存。

           安全字符加上_s,numberOfElements告诉程序destination string的长度。如:

          errno_t strcpy_s( char *strDestination, size_tnumberOfElements, const char *strSource );     //Zero if successful; an error otherwise.

      6.   Unicode与Ansi的转换。

3,内核对象

      1. 定义:由内核维护的一个数据结构。所以内核对象的所有者是内核。应用程序通过Windows提供的一组函数,传递内核对象。这组函数会以恰当的方式来操纵这些数据结构。

      2.使用计数:这个是所有内核对象中都的一个数据成员,和进程相关。使操作系统知道有多少个进程在使用这个内核对象。

      3.内核对象的安全性。  create系列的创建内核的函数独有一个参数PSECURITY_ATTRIBUTES。用于标志内核对象的权限。

      4.内核对象句柄。进程中有一个句柄表,句柄表是一个数据结构的表。每个结构独有一个内核对象指针,一个访问掩码,和一些标志。create函数会返回句柄表,其他使用内核句柄的函数通过句柄找到句柄表中对应的结构。 CloseHandle可以关闭句柄,并销毁句柄表中的对应的结构。

      5.跨进程边界共享内核对象。三种方法:对象句柄继承,为对象命名,复制对象句柄。第二种较为方便。共享的理由如下:

• 文件映射对象使你能够在同一台机器上运行的两个进程之间共享数据块。
• 邮箱和指定的管道使得应用程序能够在连网的不同机器上运行的进程之间发送数据块。
• 互斥对象、信标和事件使得不同进程中的线程能够同步它们的连续运行,这与一个应用
程序在完成某项任务时需要将情况通知另一个应用程序的情况相同

 4,进程

      1.进程通常被定义为一个正在运行的程序的实例,它由两个部分组成:


• 一个是操作系统用来管理进程的内核对象。内核对象也是系统用来存放关于进程的统计
信息的地方。
• 另一个是地址空间,它包含所有可执行模块或D L L模块的代码和数据。它还包含动态内
存分配的空间。如线程堆栈和堆分配空间。

      2.Wi n d o w s支持两种类型的应用程序。一种是基于图形用户界面( G U I)的应用程序,另一种是基于控制台用户界面(C U I)的应用程序。用于C U I应用程序的链接程序开关是/ S U B S Y S T E M : C O N D O L E,而用于G U I 应用程序的链接程序开关是/S U B S Y S T E M : W I N D O W S。

      3.如果该值指明这是个G U I 应用程序,那么加载程序不创建控制台窗口,而只是加载应用程序。一旦应用程序启动运行,操作系统就不再考虑应用程 序拥有什么类型的用户界面。Wi n d o w s 应用程序必须拥有一个在应用程序启动运行时调用的进入点函数。可以使用的进入点函数有4 个:

int WINAPI WinMain(HINSTANCE hinstExe, HINSTANCE,   PSTR pszCmdLine, int nCmdShow);int WINAPT wWinMain(HINSTANCE hinstExe,HINSTANCE,   PWSTR pszCmdLine,int nCmdShow);int __cdecl main(int argc,char *argv[],char *envp[]);int _cdecl wmain(int argc, wchar_t *argv[],   wchar_t *envp[]);

 

       4.操作系统实际上并不调用你编写的进入点函数。它调用的是C / C + +运行期启动函数。该函数负责对C / C + +运行期库进行初始化,这样,就可以调用m a l l o c和f r e e之类的函数。它还能够确保已经声明的任何全局对象和静态C + +对象能够在代码执行以前正确地创建。

      5.加载到进程地址空间的每个可执行文件或D L L文件均被赋予一个独一无二的实例句柄。可执行文件的实例作为( w ) Wi n M a i n的第一个参数h i n s t E x e来传递。对于加载资源的函数调用来说,通常都需要该句柄的值。例如,若要从可执行文件的映象来加载图标资源,需要调用下面这个函数:

HICON LoadIcon( HINSTANCE hinst, PCTSTR pszIcon);

       有些函数需要H M O D U L E类型的一个参数。如:G e t M o d u l e F i l e N a m e函。实际情况说明:H M O D U L E与H I N S TA N C E是完全相同的对象

      6.可以用C r e a t e P r o c e s s函数创建一个进程

      7..Wi n d o w s提供了若干种方法,以便在不同的进程中间传送数据,比如动态数据交换( D D E)、O L E、管道和邮箱等。共享数据最方便的方法之一是,使用内存映射文件(关于内存映射文件的详细说明请参见第1 7章

 5,作业

        通常,必须将一组进程当作单个实体来处理。例如,当让Microsoft Developer Studio为你创建一个应用程序项目时,它会生成C l . e x e,C l . e x e则必须生成其他的进程(比如编译器的各个函数传递)。如果用户想要永远停止该应用程序的创建,那么Developer Studio必须能够终止C l . e x e和它的所有子进程的运行。在Wi n d o w s中解决这个简单(和常见的)的问题是极其困难的,因为Wi n d o w s并不维护进程之间的父/子关系。即使父进程已经终止运行,子进程仍然会继续运行。

       Microsoft Windoss 2000提供了一个新的作业内核对象,使你能够将进程组合在一起,并且创建一个“沙框”,以便限制进程能够进行的操作。最好将作业对象视为一个进程的容器。但是,创建包含单个进程的作业是有用的,因为这样一来,就可以对该进程加上通常情况下不能加的限制。

6,线程的基础知识

      1.线程也是由两个部分组成的:
                • 一个是线程的内核对象,操作系统用它来对线程实施管理。内核对象也是系统用来存放线程统计信息的地方。
                • 另一个是线程堆栈,它用于维护线程在执行代码时需要的所有函数参数和局部变量。

      2.C r e a t e T h r e a d  调用C r e a t e T h r e a d可使系统创建一个线程内核对象。该对象的初始使用计数是2(在线程停止运行和从C r e a t e T h r e a d返回的句柄关闭之前,线程内核对象不会被撤消)。线程的内核对象的其他属性也被初始化,暂停计数被设置为1,退出代码始终为S T I L L _ A C T I V E(0 x 1 0 3),该对象设置为未通知状态(未通知状态?)。

      3._ b e g i n t h r e a d e x

      4.GetCurrentProcess,GetCurrentThread 返回伪句柄。如果调用C l o s e H a n d l e,将伪句柄作为参数来传递,那么C l o s e H a n d l e就会忽略该函数的调用并返回FA L S E。当调用一个需要进程句柄或线程句柄的Wi n d o w s函数时,可以传递一个伪句柄,使该函数执行它对调用进程或线程的操作。有时可能需要获得线程的实句柄而不是它的伪句柄。所谓“实句柄”,我是指用来明确标识一个独一无二的线程的句柄, u p l i c a t e H a n d l e函数能够执行这一转换。