Windwos 进程

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

1 操作系统用来管理进程的内核对象 。 内核对象也是系统用来存放关于进程的统计信息的地方

2 另一个是地址空间 , 它包含所有可执行模块 或 DLL 模块的代码和数据 。 它还包含动态内存分配的空间 。 如 线程堆栈 和 堆分配的空间

进程可能包含若干个线程 , 每个线程都有它自己的一组 CPU寄存器 和 它自己的堆栈 .


CUI 应用程序的连接程序开关是 /SUBSYSTEM : CONDOLE
GUI 应用程序的连接程序开关是 /SUBSYSTEM : WINDOWS

操作系统实际上并不调用用户编写的进入点函数 , 它调用的是 C/C++ 运行期启动函数 。 该函数负责对 C/C++ 运行期库进行初始化 , 这样就可以调用 malloc 和 free 之类的函数 。 它还能够确保已经声明的任何全局精通对象 和 精通 C++ 对象能够在代码执行前正确的创建 。


应用程序的进入点 :
----------------------------------------------------------------------------------------------------------
应用程序类型     进入点   嵌入可执行文件的启动函数
----------------------------------------------------------------------------------------------------------
需要 ANSI 字符和字符串的 GUI 应用程序   WinMain   WinMainCRTStartup

需要 Unicode 字符和字符串的 GUI 应用程序 wWinMain wWinMainCRTStartup

需要 ANSI 字符和字符串的 CUI 应用程序   main   mainCRTStartup

需要 Unicode 字符和字符串的 CUI 应用程序 wmain   wmainCRTStartup

连接程序负责在它连接可执行文件时选择相应的 C/C++ 运行期启动函数 。如果设定了 /SUBSYSTEM:WINDOWS 连接程序开关 , 那么该连接程序期望找到一个 WinMain 或 wWinmain 函数 。 如果这两个函数都不存在 , 连接程序便返回一个 "为转换的外部符号" 的错误信息 . 否则它可以分别选择 WinMainCRTStartup 函数 或 wWinMainCRTStartup 函数 。

同样,如果设定了/SUBSYSTEM:CONSOLE 链接程序开关,那么该链接程序便期望找到 main 或 wmain函数,并且可以分别选择mainCRTStartup 函数或 wmainCRTStartup 函数。同样,如果 main 或 wmain 都不存在,那么链接程序返回一条“未转换外部符号”的消息。


VC++ 配有 C 运行库的源代码 。 可以在 CR t0.c 文件中找到这 4 个启动函数的代码 。现在将启动函数的功能归纳如下

1 检索指向新进程的完整命令行的指针

2 检索指向新进场的环境变量的指针

3 对 C/C++ 运行期的全局变量进行初始化 。如果包含了 StdLib.h 文件 , 代码就能访问这些变量 。

4 对 C 运行期内存单元分配函数(malloc 和 calloc) 和 其他底层 输入/输出 例程使用的内存栈进行初始化

5 为所有全局和镜态 C++ 类对象调用构造函数

当所有这些初始化操作完成后 , C/C++ 启动函数就调用应用程序的进入点函数 。

当进入点函数返回时 , 启动函数便调用 C 运行期的 exit 函数 , 将返回值 (nMainRetVal) 传递给它 . Exit 函数负责的操作 :

1 调用由 _onexit 函数的调用而注册的任何函数 。

2 为所有全局的和镜头的 C++ 类对象调用析构函数 。

3 调用操作系统的 ExitProcess 函数 , 将 nMainRetVal 传递给它 。 这使得该操作系统能够撤销进程并设置它的 exit 代码

 

 

进程的实例句柄 :

若要从可执行文件的映像来加载图标资源 , 需要调用函数 HICON LoadIcon(HINSTANCE hInst,PCTSTR pszIcon);

VC++ 连接程序使用的默认基址是 0x00400000 。 因为这使在运行 windows 98 时可执行文件的映像可以加载到的最低地址

HMODULE GetModuleHandle(PCTSTR pszModule); //返回可执行文件或DLL问津加载到进程的地址空间时所使用的句柄/基地址
如果传递的参数 pszModule 是 NULL , 返回调用的可执行文件的基地址 。

 

 


进程的命令行 :

当一个新的进程创建时 , 它要传递一个命令行 。 该命令行几乎永远不会为空的 , 创建新进程的可执行文的名字命令行上的第一个标记。


PTSTR GetCommandLine() 函数 :

返回一个指向包含完整命令行的缓存的指针 , 该命令行包括执行文件的完整路径名


PWSTR CommandLineToArgvW(PWSTR pszCmdLine,int* pNumArgs); 函数 :

将命令行的 Unicode 字符串分隔成它的各个标记

pszCmdLine 参数是 GetCommandLine() 函数的返回值

pNumArgs    参数是个整数地址 , 该整数被设置为命令行中的参数个数


CommandLineToArgvW() 函数负责在内部分配内存 , 大多数的应用程序不释放该内存 , 它们在进程运行终止时依靠操作系统来释放内存 。


HeapFree() 函数 : 手动的释放内存

PWSTR *ppArgv = CommandLineToArgvW(GetCommandLineW(),&nNumArgs);

HeapFree(GetProcessHeap(),0,ppArgv);

 

 

进程的环境变量 :

每个进程都有一个与它相关的环境块 。 环境块是进程的地址空间中分配的一个内存块 。 每个环境块都包含一组字符串 。
环境变量中的空格是很严谨的 。环境变量的结尾处必须是一个 0 字符 , 表示环境变量块的结束

子进程可以继承一组与父进程相同的环境变量 。 父进程能够控制子进程继承什么环境变量 。

       //环境变量名    //指向存放变量值的缓存    //缓存的大小    
DWORD GetEnvironmentVariable(PCTSTR pszName,PTSTR pszValue,DWORD cchValue) 函数 :

能够确定某个环境变量是否存在以及它的值 。返回值是拷贝到缓存的字符数 , 如果在环境中找不到该变量名 , 返回 0

 

     
DWORD ExpandEnvironmentString(PCSTR pszSrc,PSTR pszDst,DWORD nSize) 函数 :   替换字符串变量

BOOL SetEnvironmentVariable(PCTSTR pszName , PCTSTR pszValue) 函数 : 添加 ,删除 环境变量或者修改环境变量的值

 


进程的错误模式 :

UINT SetErrorMode(UINT fuErrorMode)   函数 : 进程用来告诉系统如何处理每一种错误 。

fuErrorMode 参数的标志 :
-------------------------------------------------------------------------------------------------
SEM_FAILCRITICALERRORS    系统不显示关键错误句柄消息框 , 并将错误返回给调用进程

SEM_NOGOFAULTERRORBOX    系统不显示一般保护故障消息框 。本标志只应该由采用异常情况处理程序来处理一般保护(GP) 故障的调试应用程序来设定

SEM_NOOPENFILEERROEBOX    当系统找不到文件时 , 它不显示消息框 。

SEM_NOALIGNMENTFAULTEXCEPT   系统自动排除内存没有对其的故障 ,并使应用程序看不到这些故障 。本标志对x86处理器不起作用

 

 

进程的当前驱动器和目录 :

DWORD GetCurrentDirectory(DWORD cchCurDir , PTSTR pszCurDir) 函数 : 获取当前进程的当前驱动器和目录

BOOL SetCurrentDirectory(PCTSTR pszCurDir) 函数 : 设置当前进程的当前驱动器和目录

可以使用C运行期函数 _chdir,而不是使用 Windows 的 SetCurrentDirectory 函数来变更当前目录。_chdir 函数从内部调用 SetCurrentDirectory,但是 _chdir 也能够添加或修改该环境变量,这样,不同驱动器的当前目录就可以保留。


DWORD GetFullPathName(PCTSTR pszFile,DWORD cchPath,PTSTR pszPath,PTSTR *ppszilePart) 函数 : 父进程可以获得它的当前目录

 

 

系统版本 :

DWORD GetVersion() 函数 : 获得系统版本

BOOL GetVersionEx(POSVERSIONINFO pVersionInformation) 函数 :

typedef struct{

DWORD dwOSVersionInfoSize;

DWORD dwMajorVersion;

DWORD dwMinorVersion;

DWORD dwBuildNumber;

DWORD dwPlatformId;

TCHAR szCSDVersion[128];

WORD wServicePackMajor;

WORD wServicePackMinor;

WORD wSuiteMask;

BYTE wProductType;

BYTE wReserved;

}OSVERSIONINFOEX *posversioninfoex;

 


CreateProcess 函数 : 用于创建一个进程

BOOL CreateProcess(

PCTSTR pszApplicationName ,
  
PTSTR pszCommandLine ,

PSECURITY_ATTRIBUTES pszProcess ,

PSECURITY_ATTRIBUTES pszThread ,

BOOL bInheritHandles ,

DWORD fdwCreate ,

PVOID pvEnvironment ,

PCTSTR pszCurDir ,

PSTARTUPINFO psiStartInfo ,

PPROCESS_INFORMATION ppiProcInfo);

注意 : pszCommandLine 参数的原型是 PTSTR 。这意味着 CreateProcess 期望你将传递一个非常量字符串的地址 。

可以使用 pszCommandLine 参数设定一个完整的命令行 , 以便 CreateProcess 用来创建新进程 。 当 CreateProcess 分析 pszCommandLine 字符串时 , 它将查看字符串中的第一个标记 , 并假设该标记是想运行的可执行文件的名字 。 如果可执行文件没有扩展名 , 便假设它的扩展名为 .exe


CreateProcess 函数按以下的顺序搜索该可执行文件 :

1 包含调用进程的 .exe 文件的目录

2 调用进程的当前目录

3 Windows 的系统目录

4 Windows 目录

5 PATH 环境变量中列出的目录

 

pszProcess pszThread 和 binheritHandles 参数 :

psaProcess 和 psaThread 参数分别设定进程对象和线程对象需要的安全性 。如果传递 NULL 则赋予默认的安全性描述符 , 也可以指定

SECURITY_ATTRIBUTES 结构 , 并对它们进行初始化 , 以便创建自己的安全性权限 , 并将它们赋予进程对象和线程对象 。

 


fdwCreate 参数 :

用于标识标志 , 以便用于规定如何来创建新进程 。 如果将标志逐位用 OR 操作符组合起来的话 , 就可以设定多个标志 。

 

pvEnvironment 参数 :

指向包含新进程将要使用的环境字符串的内存块 。


PVOID GetEnvironmentString() 函数 :

该函数用于获得调用进程正在使用的环境字符串数据块的地址 。可以使用该函数的返回地址 , 作为 CreateProcess 的 pvEnvironment 参数 。

BOOL FreeEnvironmentStrings(PTSTR pszEnvironmentBlock) 函数 : 释放内存块。


pszCurDir   参数 :

允许父进程设置子进程的当前驱动器和目录 。 如果本参数是 NULL , 则新进程的工作目录将与生产新进程的应用程序的目录相同 。 如果本参数不是 NULL , 那么 pszCurDir 必须指向包含需要的工作驱动器 和 工作目录的以 0 结尾的字符串 。

注意 : 必须设定路径中的驱动器名 。

posted on 2012-02-20 10:47  多个马甲  阅读(221)  评论(0编辑  收藏  举报