Windows内核之进程基本含义以及进程的创建
进程
1 进程的含义:
1.1 一个是操作系统用来管理进程的内核对象。
内核对象也是系统用来存放关于进程的统计信息的地方。
1.2 还有一个是地址空间,它包括全部可运行模块或DL L 模块的代码和数据。它还包括动态内存分配的空间。
如线程堆栈和堆分配空间。
2 操作系统启动应用程序的步骤
2.1 调用C/c++执行时的启动函数
启动函数总共4种,WinMainCRTStartup,wWinMainCRTStartup,mainCRTStartup,wmainCRTStartup。
启动函数完毕例如以下任务:
<1>检索指向新进程的完整命令行的指针
<2>检索指向新进程的环境变量的指针
<3>对C/ C + +执行期的全局变量进行初始化。
假设包括了S t d L i b . h 文件,代码就能訪问这些变量
<4>对C执行期内存单元分配函数(m a l l o c 和c a l l o c )和其它低层输入/输出例程使用的内存栈进行初始化。
<5>为全部全局和静态C+ +类对象调用构造函数。
<6>调用入口点函数
如:int nMainRetVal = wmain(__argc, __wargv, _wenviron);
<7>当进入点函数返回时,启动函数便调用C 执行期的ex i t 函数。将返回值(nMainRetVal )传递给它。
<8>调用由_onexit函数的调用而注冊的不论什么函数
<9>为全部全局的和静态的C++类对象调用析构函数
<10>调用操作系统的ExitProcess函数,将nMainRetVal传递给它。这使得该操作系统可以撤消进程并设置它的e x i t 代码
3 进程的实例句柄
3.1 进程的当前实例句柄
载入到进程地址空间的每一个exe或者dll文件都会被赋予一个独一无二的句柄。
获取载入的模块(exe,dll)的方法:
GetModuleFileName(HMOUDLEhModule,LPTSTR lpFileName,DWROD nSize);
当hModule的值为NULL 的时候,会返回当前调用模块的所有路径名字。
3.2 进程的前一个实例句柄
C++代码总是将NULL赋值给WinMain函数的第二个參数HINSTANCEhPreInstance,这种原因是在16位的程序中对这个參数有保留使用,那么保留它就方便转用16位程序。
4 进程的命令行
LPTSTR GetCommandLine();获取命令行字符串
5 进程的环境变量
每一个进程都有一个与它相关的环境变量块,环境块是进程的地址空间中分配的一个内存块。每一个环境块都包括一组字符串,形式例如以下所看到的:
VarName1=VarValue1\0
VarName2=VarValue2\0
VarName3=VarValue3\0
当中要注意变脸等号前有没有空格,有空格和没空格代表的是全然不同的环境变量。如:
XYZ=xxx;和XYZ =xxx。这就是两个全然不同的环境变量了。
操作华景变量相关的 函数
<1>
LPVOIDGetEnvironmentStrings(VOID);
<2>
BOOL SetEnvironmentVariable(
LPCTSTR lpName, // environment variable name
LPCTSTR lpValue // new value for variable);
<3>
DWORD GetEnvironmentVariable( LPCTSTR lpName, // environment variable name
LPTSTR lpBuffer, // buffer for variable value
DWORD nSize // size ofbuffer);
<4>
BOOL FreeEnvironmentStrings(LPTSTRlpszEnvironmentBlock // environmentstrings);
6 进程的当前文件夹
程序的当前文件夹是能够进行改变的,当前文件夹和进程的启动文件夹是不同的,启动文件夹就是exe或者dll被调用的文件夹,我们能够通过GetModuleFineName函数进行处理。
<1>
DWORD GetCurrentDirectory(
DWORD nBufferLength, //size of directory buffer
LPTSTR lpBuffer //directory buffer);
<2>
BOOL SetCurrentDirectory( LPCTSTR lpPathName // new directory name);
7 系统的版本号信息获得
GetVersion()
可是这个函数有bug,就是程序猿把主版本。次版本放错了高低字节。
BOOL GetVersionEx( LPOSVERSIONINFO lpVersionInfo // versioninformation);
这个是新的修正过来的。
8 创建进程
BOOL WINAPI CreateProcess(
_In_opt_ LPCTSTR lpApplicationName,
_Inout_opt_ LPTSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCTSTR lpCurrentDirectory,
_In_ LPSTARTUPINFO lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation
);
參数解释:
<1> lpApplicationName
被载入模块的名字,必须制定模块的格式,比方exe。由于系统不会默觉得exe,模块的名字能够是部门名字,那么系统就会在当前文件夹去寻找该模块。
通常将其设置为NULL,由于lpCommandLine具有比它更加强大的功能来完毕模块的调用。
<2> lpCommandLine
系统寻找可运行文件exe的顺序是:
应用程序载入的文件夹。
父进程的当前文件夹;
Windows System 文件夹。
Windows文件夹;
环境变量列出的文件夹。
注意:当字符集是Unicode时候,參数类型不能是const类型的。若是就会报错。
<3> lpProcessAttributes
指向 SECURITY_ATTRIBUTES的指针。决定进程创建函数返回的的新进程对象的句柄能否被子进程继承。
当为NULL的时候。获取的是默认安全描写叙述符
<4> lpThreadAttributes
指向SECURITY_ATTRIBUTES 的指针。决定进程创建函数范湖的新线程对象的句柄能否被子进程继承。
当为NULL的时候,获取的是默认安全描写叙述符。
<5> bInheritHandles
假设为True,那么不论什么能够被继承的句柄都会别新创建的进程所继承。
假设为FALSE,那么则不会被新进程继承。
<6>dwCreationFlags
新创建的进程的创建标志位设置,决定是父子进程调试信息的反馈,子进程窗体的产生等行为。
<7> lpEnvironment
新进程中指向的环境块。
假设该值为NULL,那么就表示新进程继承了父进程的环境块。
<8>lpCurrentDirectory
指向新进程的当前文件夹的指针。
假设为NULL,那么则就和调用进程(父进程)具有同样的当前文件夹。
<9> lpStartupInfo
指向 STARTUPINFO or STARTUPINFOEX的指针。主要指定窗体的状态,外观,标准句柄。
当Wi
n d o w s 创建新进程时,它将使用该结构的有关成员。大多数应用程序将要求生成的应用程序只使用默认值。至少应该将该结构中的全部成员初始化为零。然后将cb 成员设置为该结构的大小。
当里面创建的句柄不在是用的使用。要通过CloseHandle来关闭。
<10> lpProcessInformation
指向PROCESS_INFORMATION结构体的指针。
typedef struct _PROCESS_INFORMATION {
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;
里面是用的句柄不在使用的时候,要通过CloseHandle函数来关闭。
当进程内核对象创建后,系统赋予该对象一个独一无二的标识号。系统中的其它不论什么进程内核对象都不能使用这个同样的ID号。线程内核对象的情况也一样。
当一个线程内核对象创建时,该对象被赋予一个独一无二的、系统范围的ID号。进程ID和线程ID共享同样的号码池。这意味着进程和线程不可能拥有同样的ID 。
9 创建进程的实例:
#include <Windows.h>
#include <iostream>
using namespace std; void main()
{
STARTUPINFO si;
PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) ); // Start the child process.
if( !CreateProcess( NULL, // No module name (use command line).
TEXT("Notepad++"), // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
{
cout<<TEXT("CreateProcess failed.");
} // Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE ); // Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
Windows内核之进程基本含义以及进程的创建的更多相关文章
- Windows创建的基本含义和进程的进程的内核
过程 1 这意味着过程: 1.1 一个是在操作系统的内核对象管理处理. 的统计信息的地方. 1.2 还有一个是地址空间.它包括全部可运行模块或DL L 模块的代码和数据.它还包括动态内存分配的 ...
- [5]windows内核情景分析---进程线程
本篇主要讲述进程的启动过程.线程的调度与切换.进程挂靠 进程的启动过程: BOOL CreateProcess ( LPCTSTR lpApplicationName, ...
- Windows系统的四个重要概念——进程、线程、虚拟内存、内核模式和用户模式
引言 本来在写一篇Windows内存管理的文章,写着写着就发现好多基础的概念都要先讲.更可怕的是,这些基础的概念我却不能完全讲清楚.只好再把这本<深入解析Windows操作系统>翻到第一章 ...
- windows内核代码之进程操作
[toc] 一丶简介 整理一下windows内核中.常用的代码.这里只整理下进程的相关代码. 二丶 windows内核之遍历进程 内核中记录进程的结构体是EPROCESS结构.所以只需要遍历这个结构即 ...
- windows 内核下获取进程路径
windows 内核下获取进程路径 思路:1):在EPROCESS结构中获取.此时要用到一个导出函数:PsGetProcessImageFileName,申明如下: NTSYSAPI UCHAR * ...
- Windows内核基础知识-8-监听进程、线程和模块
Windows内核基础知识-8-监听进程.线程和模块 Windows内核有一种强大的机制,可以在重大事件发送时得到通知,比如这里的进程.线程和模块加载通知. 本次采用链表+自动快速互斥体来实现内核的主 ...
- C++windows内核编程笔记day13 进程、线程与信号量
Windows进程 进程是一个容器,包括程序运行须要的代码.数据.资源等信息, windows进程的特点: 每一个进程都有自己的ID号 每一个进程都有自己的地址空间.进程之间无法訪问对方的地址空间. ...
- 【旧文章搬运】Windows内核常见数据结构(进程相关)
原文发表于百度空间,2008-7-24========================================================================== 进程的相关结 ...
- 《windows核心编程系列》四谈谈进程的建立和终止
第二部分:工作机理 第一章:进程 上一章介绍了内核对象,这一节开始就要不断接触各种内核对象了.首先要给大家介绍的是进程内核对象.进程大家都不陌生,它是资源和分配的基本单位,而进程内核对象就是与进程相关 ...
随机推荐
- tap,touch,touchstart,事件与click事件的区别
根据源码所见, 移动端为了将将单击事件更加灵敏,所以现在的JQM,ST...框架都将JS单击事件封装成tap,或者touch或者touchstart事件, 其实现本质是将click触发多次,以打成移动 ...
- vijos1067守望者的逃离
裸的矩阵乘法,我却调了一上午……弱到爆啊…… 不过最终辛苦没有白费,我终于彻底搞懂了 要注意几点: 一.必须构造出前几项 二.用矩阵乘法算法之后还要手工算答案,利用首先算好的前几项 三.想好自己构造的 ...
- [swustoj 183] 种树
种树(0183) 问题描述 Aconly有一块矩形的地,因为这块地里有很多石头,耕作很不方便,所以他打算在这块地上种一些果树.这块地用一个只含‘#’和‘*’的N*M的矩阵来表示,‘#’表示泥土,‘*’ ...
- mysql CMAKE 参数说明
MySQL自5.5版本以后,就开始使用CMake编译工具了,因此,你在安装源文件中找不到configure文件是正常的.很多人下到了新版的MySQL,因为找不到configure文件,不知道该怎么继续 ...
- 【转】google play上传应用
原文网址:https://support.google.com/googleplay/android-developer/answer/113469?hl=zh-Hans 注册 Google Play ...
- mongo客户端mongo VUE增删改查
一.先创建一张mongo表,右击已创建的数据库test,点击addcollection.. 输入Collection Name,点击ok: 二.在创建的表中新增列与数据,右击表选择Insert doc ...
- GC roots 总结
previous content next GC roots The so-called GC (Garbage Collector) roots are objects ...
- 如何理解Stay hungry,stay foolish?
People know about this words because of Steve Jobs.Me too. Hungry,对知识我们一般不会用hungry,我们会用curious,什么时候我 ...
- 50道经典的JAVA编程题(26-30)
50道经典的JAVA编程题(26-30),这么晚了,早点睡了要,明早8点考java祝我好运吧!!!晚安~ [程序26]Ex26.java(跳过了,好没意思的题啊)题目:请输入星期几的第一个字母来判断一 ...
- 沈晓军 / LarvaFrame - 代码托管 - 开源中国社区
沈晓军 / LarvaFrame - 代码托管 - 开源中国社区 统计