Windows核心编程学习笔记之二(进程)

Windows核心编程学习笔记之二(进程)

5.进程:

1)在Win32系统中每一个进程都拥有4GB的地址空间。Win32进程什么也不执行,它只是拥有4GB的地址空间来存放应用程序EXE文件所需要的代码和数据。除地址空间外,进程还拥有文件、动态内存、线程等资源。由线程负责执行包含在进程地址空间里的代码。每一个线程有它自己的CPU寄存器组和自己的栈。每一个进程至少有一个线程来执行包含在地址空间中的代码。如果地址空间中没有线程在执行代码,那么系统就会释放进程和它的地址空间。


(2)加载器:Win32支持两类应用程序,控制台应用程序CUI和图形用户界面应用程序GUIExe文件中的一个子系统值指出这个应用程序是控制台应用程序还是图形用户界面应用程序。

(3)VC编写的Win32控制台应用程序都有一个main函数,而图形界面应用程序都有一个WinMain函数。

(4)C/C++的启动函数:_WinMainCRTStartup函数。它负责执行:

1.得到一个新进程的全部命令行指针。

2.得到一个新进程的环境变量指针。

3.通过包含Stdlib.h来初始化能被应用程序访问的C运行时全局变量。

4.初始化由C运行时内存分配函数使用的堆和其它的低级输入输出例程。

5调用WinMain函数。

6.WinMain返回后,启动代码调用C运行时的exit函数,传给它WinMain的返回值。Exit函数执行一些清理工作,然后调用Win32ExitProcess函数,传给它WinMain函数的返回值。

(5)实例句柄:每一个加载到进程地址空间的ExeDLL文件都有一个唯一的实例句柄。WinMain的第一个参数hinstExeExe文件的实例。在加载资源时所使用的函数要使用这个实例句柄。

(6)基本内存地址:WinMain的参数hinstExe的实际值就是一个基本内存地址。它指出系统是在什么地方把EXE文件的映象装入进程的地址空间的。基本内存地址由链接器决定。

(7)HANDLE GetModuleHandle(LPCTSTR lpszModule)函数:返回的句柄是EXEDLL文件在地址空间里的基本地址。参数是ExeDLL文件的名字。该函数的两个需要注意的地方:一、该函数只查看调用进程的地址空间。二、参数为NULL时返回的是EXE文件的基本内存地址。

(8)Win32hinstExehmodExe是一个值。WinMain的参数hinstExePrev对于Win32无意义,它的值总为NULL。在Win32下,应用程序的每一个实例都必须注册它自己窗口类,这是因为窗口类不能被同一应用程序中的所有实例共享。只有hinstExePrev值为NULL时,在Win32下应用程序的每一个实例才会注册它自己的窗口类。

(9)进程的环境变量函数:BOOL SetEnviromentVariable(LPCTSTR lpszName,LPCTSTR lpszValue);该函数把由lpszName标识的值设置为由lpszValue标识的值。如果指定的变量名已经存在,就修改它的值。如果不存在,就增加该变量。如果lpszValue的值为NULL,变量就被从环境变量中删除。

(10)进程的命令行

(11)进程的错误模式:当进程出现错误时, 它用来告诉系统应当以何种模式去处理该错误。使用的函数是:UINT SetErrorMode(UINT fuErrorMode);其中参数fuErrorMode是以下四个值的任意组合,它们是:SEM_FAILCRITICALERRORS(系统不显示严重错误处理消息框,把错误返回调用的进程)SEM_NOGPFAULTERRORBOX(系统不显示普通保护错误消息框。该标识只能被调试应用程序设置来用异常句柄自己处理普通保护错误GP)SEM_NOOPENFILEERRORBOX(系统在找不到文件时不显示消息框)SEM_NOALIGNMENTFAULTEXCEPT(系统自动修复内在排列错误,使它们对应用不可见。该标识对x86Alpha处理器无用)

注:缺省情况下子进程会继承父进程的错误模式。但是父进程可以通过在调用CreateProcess时设置CREATE_DEFAULT_ERROR_MODE标识来防止子进程继承。

 

(12)进程的当前驱动器和目录:可以使用下列函数来得到和设置进程的当前驱动器和目录:DWORD GetCurrentDirectory(DWORD cchCurDir,LPCTSTR lpszCurDir);

BOOL SetCurrentDirectory(LPCTSTR lpszCurDir);

(13)系统版本号:一般使用 BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInformation);来得到系统版本号,其中参数lpVersionInformation是一个LPOSVERSIONINFO结构,该结构的定义如下:

typedef struct{

DWORD dwOSVersionInfoSize;//在调用GetVersionEx函数前必须被设置为:SizeOf(OSVERSIONINFO);

DWORD dwMajorVersion;//系统主版本号

DWORD dwMinorVersion;//系统次版本号

DWORD dwBuildNumber;

DWORD dwPlatformID;//标识当前系统支持的平台

TCHAR szCSDVersion[128];

}OSVERSIONINFO,*LPOSVERSIONINFO;

(14)CreateProcess函数:应用程序调用CreateProcess函数来创建一个进程。

BOOL CreateProcess(

LPCTSTR lpszApplicationName,

LPCTSTR lpszCommandLine,

LPSECURITY_ATTRIBUTES lpsaProcess,

LPSECURITY_ATTRIBUTES lpsaThread,

BOOL fInheritHandles,

DWORD fdwCreate,

LPVOID lpvEnvironment,

LPTSTR lpszCurDir,

LPSTARTUPINFO lpsiStartInfo,

LPPROCESS_INFORMATION lppiProcInfo

);

当应用程序中某个线程调用这个函数时,系统创建了一个引用计数为1的进程内核对象。该内核对象不是进程,而是操作系统用来管理进程的一小块数据结构。系统然后为新进程创建一个4GB的虚拟地址空间,把可执行文件和DLL及数据都装入该地址空间。系统之后为新进程的主线程创建一个使用计数为1的线程内核对象,之后主线程开始执行C运行时的启动代码,最终会调用WinMain函数。如果系统成功地创建了新进程和主线程,CreateProcess函数返回True

各个参数说明:

lpszCommandLine:该参数可以用来指定CreateProcess用来创建新进程的完整命令行,这个命令行里可以包含“可执行文件名”(如果这个可执行文件没有指定扩展名的话,系统会认为其扩展名为exe)注:可以包含可执行文件名+这个可执行文件的完整路径,如果未指定完整路径,那么CreateProcess会以下面的顺序查找可执行文件:1.含有调用进程的Exe文件目录2调用进程的当前目录3 Windows系统目录4Windows目录5列在PATH环境变量中的目录。如果系统找到了可执行文件,就创建一个进程,把可执行文件的代码和DLL及数据装入新进程的地址空间。系统然后调用C运行时的启动例程。之后C运行时的启动例程会查看进程的命令行,把可执行文件名后的第一个参数地址传递为WinMainlpszCmdLine参数。上面讲述的情况是在参数lpszApplicationNameNULL时。

lpszApplicationName:可执行文件的名称及其扩展名。如果不指定扩展名那么系统将不会认为其扩展名为exe。如果不指定可执行文件的路径,那么CreateProcess只在当前目录下查找可执行文件,如果找不到它将返回失败。

下面列举一例说明上面讲的两个参数,CreateProcess(“C:WINNTSYSTEM32NOTEPAD.EXE”,”WORDPAD README.TXT”…..);

系统将启动NotePad,但是NotePad的命令行是WORDPAD README.TXT这样写主要是为了支持Windows NTPOSIX子系统。

你可能感兴趣的:(Windows核心编程学习笔记之二(进程))