本人新手,都说要动用五官才能有效果,写下自己的理解,望提点
1.WinMain hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
参数之一,,HINSTANCE 这个和HMODULE是一样的,这个参数是一个基址地址在win200上>=0x00040000 invoke GetModuleHandle,NULL返回进程地址空间中可执行文件的基地址mov HINSTANCE,eax,
参数之二,汇编里面是NULL,VC里面是HINSTANCE,这个看书说是不让编译器发出"没有引用参数"的警告
参数之3 pszCmdLine 这个参数是用在创建进程时用到CreateProcess的第2个参数LPTSTR lpCommandLine,一个指针型可由GetCommandLine获得一个进程完整命令行指针,如果为空指向进程的名称
参数3为DWORD,一般SW_SHOWDEFAULT
2.CreateProcess
BOOL CreateProcess{
LPCTSTR lpApplicationName, ;进程的名字
LPTSTR lpCommandLine , ;传递给新进程的命令字符串原型为PTSTR
LPSECURITY_ATTRIBUTES lpProcessAttributes,
;进程属性包含nlength(SA结构的长度),lpSecurityDescriptor如果为0默认,bInheritHandle是否可继承,为TRUE新进程可继承
LPSECURITY_ATTRIBUTES lpThreadAttributes, ;是否可被继承,为NULL不能也是一SA结构
BOOL bInheritHandles, ;标记是否继承原来的handle
DWORD dwCreationFlags, ;这个太多了,详见Win32 programmer's reference
LPVOID lpEnvironment, ;环境块,如果为NULL,则和创建些进程的进程一样环境块诚详见进程的环境变量
LPCTSTR lpCurrentDirectory, ;路径,如果为NULL和父进程一样
LPSTARTUPINFO lpStartupInfo, ;指向一个STARTUPINFO结构,对GUI和CUI程序影响各不同为子进程窗口或者控制台进行设置
LPPROCESS_INFORMATION lpProcessInformation ;些结构包含4个参数hProcess,
hThread,dwProcessId,dwThreadId
}
lpEnvironment即环境块是每一个进程都有的,进程地址空间中分配的一个内存块,每个环境块都包含一组字符串,如
VerName1=VerValue1\0
....................................
VerNamen=VerValuen\0
3.内核对象句柄继承性的一个示例分析,先创建进程B,再创建C由B继承来
#include <windows.h>
int WINAPI WinMain(HINSTANCE hinstExe,HINSTANCE, PSTR pszCmdLine,int nCmdShow)
{
STARTINFO si={sizeof(si)}; //为CreateProcess中成员lpStartupInfo定义
SECURITY_ATTRIBUTES sa_Process,sa_Thread; //定义CreateProcess第3,4个参数
PROCESS_INFORMATION piProcessB,piProcessC; //定义了2个新进程信息该结构包含hProcess,hThread,dwProcessId,dwThreadId4个参数
TCHAR szPatch[MAX_PATH];
sa_Process.nLength=sizeof(sa_Process);//sa结构的长度 SECUTIRY_ATTRIBUTE共3个参数nLength,lpSecurityDescripter,bInheritHandles
sa_Process.lpSecurityDescripter=NULL;//设为默认
sa_Process.bInheritHandle=true; //新创建的进程句柄可以补继承
sa_Thread.nLength=sizeof(sa_Thread);//结构和上面一样,这里是线程,因为 一个进程要一个主线程
sa_Thread.lpSecurityDescripter=NULL;
sa_Thread.bInheritHandle=FALSE; //不能继承
//下面为产生线程B,为主线程所以第5个bInheritHandles继承性为FALSE
lstrcpy(szPatch,TEXT("ProcessB"));
CreateProcess(NULL,szPatch,&sa_Process,&sa_Thread,FALSE,0,NULL,NULL,&si,&piProcessB);
//创建进程C由B继承而来
lstrcpy(szPatch,TEXT("ProcessC"));
CreateProcess(NULL,szPatch,NULL,NULL,TRUE,0,NULL,NULL,&si,&piProcessC);
return 0;
}
4.程序错误处理
windows返回值大概分为以下几种:
void 如果返回值为它,该函数运行不会失败
bool 相信大家都知道,如果函数失败则为0,成功为非0
handle 如果函数执行成功返回一个handle句柄,失败返回通常为NULL比如CreateWindow,GetTopWindow,GetWindow等很多
pvoid如果函数运行失败返回为NULL,成功返回pvoid标识数据内存地址我觉得就是个指针
通过DWORD GetLastError可以获得错误信息,该函数返回一个32位的错误代码,Mirsoft在WinError.h这个头文件中定义了21000行,为以下形式,这只是一个例子,具体查看WinError.h中的内容
MessageId:ERROR_SUCCESS //消息ID可以在代码中用些宏
MessageText:
the operation completed successfully //消息文本,对错误的描述
#define ERROR_SUCCESS 0L //一个号码
GetLastError能返回线程产生的最后一个错误,因为这个函数只对32位的有用,对以前的部份16位函数不会返回错误信息,比如MessageBoxEx这个函数,它是通过16位的MessageBox实现的,通过GetLastError不能错得具体的错误信息
可以通过VC自带的error lookup输入ID,查看相应的错误描述信息也可以通过FormatMessage函数
也可以通过自己设定通过SetLastError函数实现,函数参数是一个32位的,其中第29位如果自己设定错误信息必为1,MICROSOFT自己的为0
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!