windows核心编程第三章学习事件内核对象代码
2014-06-04 20:58
393 查看
本文是看书时调试时的代码。主要用于调试事件内核对象的继承性。但是有一个问题始终无法解决,程序中父进程已经修改了事件内核对象的继承性为FALSE,但第二个子进程依然能够访问,要按值传递事件内核对象,需要在父子进程中传递内核对象时用注释的代码。都是win32工程。源码如下:
// HandInherit.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
#include "../ComWnd/CommonWnd.h"
int _tmain(int argc, _TCHAR* argv[])
{
printf( "父进程运行...\n");
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd,TRUE,NULL,FALSE);
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE; // 句柄可被子进程继承
sa.lpSecurityDescriptor = &sd;
TCHAR szEventName[] = "zsEvent";
HANDLE hEvent = ::CreateEvent( &sa, TRUE, TRUE, szEventName );
if( NULL == hEvent )
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf("创建事件内核对象失败:%s\n", cMsg );
system("PAUSE");
return 0;
}
printf( "事件:0x%x\n", hEvent );
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
TCHAR cmdLine[100] = {0};
TCHAR szPath[MAX_PATH] = {0};
ZeroMemory( szPath, MAX_PATH );
int iLen = GetCurrentPath( szPath );
TCHAR cAppName[MAX_PATH];
ZeroMemory( cAppName, MAX_PATH );
sprintf( cAppName, "%sChildProcess.exe", szPath );
char cHandle[MAX_PATH] = {0};
// sprintf( cHandle, "%x", hEvent ); // 按值传递
sprintf( cHandle, "%s", szEventName );
sprintf( cmdLine, "%s %s", cAppName, cHandle );
printf( "创建子进程1\n" );
BOOL bOk = CreateProcess(
cAppName,
cmdLine,
NULL,
NULL,
TRUE,
CREATE_FORCEDOS | CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi );
if( !bOk )
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf("创建子进程1失败:%s\n", cMsg );
system("PAUSE");
return 0;
}
HANDLE hChildPros = pi.hProcess;
printf( "子进程1句柄值:%x\n", hChildPros );
DWORD dwRt = WaitForSingleObject( pi.hProcess, INFINITE ); // WaitForInputIdle
if( dwRt == WAIT_OBJECT_0 )
{
printf( "成功等待子进程结束\n" );
// printf( "成功等待子进程1初始化\n" );
}
else if( WAIT_FAILED == dwRt )
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf( "等待子进程1结束失败:%s\n", cMsg );
// printf( "等待子进程1初始化失败:%s\n", cMsg );
}
BOOL bInherit = TRUE;
DWORD dwFlags;
GetHandleInformation(hEvent, &dwFlags);
bInherit = (0 != ( dwFlags & HANDLE_FLAG_INHERIT ) );
BOOL bSet = SetHandleInformation( hEvent, HANDLE_FLAG_INHERIT, 0 ); // 设置为不可继承状态
BOOL bSet2 = ResetEvent(hEvent);
if( !bSet )
{
DWORD dwError = GetLastError();
char cMsg[1024]={0};
ZeroMemory( cMsg, 1024 );
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf( "关闭事件对象(或者重置)继承性失败:%s\n", cMsg );
}
GetHandleInformation(hEvent, &dwFlags);
bInherit = (0 != ( dwFlags & HANDLE_FLAG_INHERIT ) );
Sleep(100);
printf( "创建子进程2\n" );
STARTUPINFO si2 = { sizeof(si2) };
PROCESS_INFORMATION pi2;
bOk = CreateProcess(
cAppName,
cmdLine,
NULL,
NULL,
TRUE,
CREATE_FORCEDOS | CREATE_NEW_CONSOLE,
NULL,
NULL,
&si2,
&pi2 );
if( !bOk )
{
printf("创建子进程2失败%d\n",GetLastError() );
system("PAUSE");
return 0;
}
HANDLE hChildPros2 = pi2.hProcess;
printf( "子进程2句柄值:%x\n", hChildPros2 );
dwRt = WaitForSingleObject( pi2.hProcess, INFINITE ); //WaitForInputIdle
if( dwRt == WAIT_OBJECT_0 )
{
printf( "成功等待子进程2结束\n" );
// printf( "成功等待子进程2初始化\n" );
}
else if( WAIT_FAILED == dwRt )
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf( "等待子进程2结束失败:%s\n", cMsg );
// printf( "等待子进程2初始化失败:%s\n", cMsg );
}
CloseHandle(hEvent);
system("PAUSE");
return 0;
}
// ChildProcess.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include "../ComWnd/CommonWnd.h"
int _tmain(int argc, _TCHAR* argv[])
{
printf( "子进程运行...\n");
if( argc < 2 )
{
printf( "没有传递命令行参数\n" );
char* p = argv[0];
printf( "%s\n", p );
system( "PAUSE" );
return 0;
}
LPSTR lpCmdLine = GetCommandLine();
printf( "命令行:%s\n", lpCmdLine );
HANDLE hEvent = NULL;
char cPath[MAX_PATH] = {0};
char cHand[MAX_PATH] = {0};;
sscanf( lpCmdLine, "%s %s", cPath, cHand );
// hEvent = (HANDLE)atoi( cHand ); // 按值传递
// hEvent = CreateEvent( NULL, TRUE, TRUE , cHand );
hEvent = OpenEvent( EVENT_ALL_ACCESS, TRUE, cHand );
printf( "事件解析为:%s\n", cHand );
if( NULL == hEvent )
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf( "打开事件内核对象失败:%s\n", cMsg );
system("PAUSE");
return 0;
}
DWORD dwRt = WaitForSingleObject( hEvent, INFINITE );
if( dwRt == WAIT_TIMEOUT )
{
printf( "等待超时\n");
}
else if( WAIT_OBJECT_0 == dwRt )
{
printf( "成功等待父进程重置事件\n" );
char szPath[MAX_PATH];
ZeroMemory( szPath, MAX_PATH );
int iLen = GetCurrentPath( szPath );
strcpy( &szPath[iLen], _T("abc.txt") );
HANDLE hFile = CreateFile(
szPath,
GENERIC_WRITE|GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL,
CREATE_ALWAYS, // OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if( INVALID_HANDLE_VALUE != hFile )
{
DWORD iSize = 0;
char cTmp[100];
sprintf( cTmp, "事件内核对象的名称是:%x", hEvent );
BOOL bWrite = WriteFile(hFile, cTmp, strlen(cTmp), &iSize, NULL );
if( !bWrite )
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf( "创建文件成功,写文件失败:%s", cMsg );
}
else
{
printf( "创建文件成功,写入文件%d个字符\n", iSize);
}
CloseHandle(hFile);
}
else
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf( "创建文件失败:%s\n", cMsg );
}
}
else if( WAIT_ABANDONED == dwRt )
{
printf( "解析事件有误\n" );
}
else if( WAIT_FAILED == dwRt )
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf( "等待事件失败:%s\n", cMsg );
}
printf( "等待事件内核对象返回%d\n", dwRt );
CloseHandle(hEvent);
system( "PAUSE" );
return 0;
}
// CommonWnd.h 头文件
// 公共代码
#pragma once
#include <Windows.h>
BOOL GetLastErrorMsg( char* pBuf, DWORD dwError );
int GetCurrentPath( char* szPath );
// CommonWnd.cpp 文件
#include "StdAfx.h"
#include "CommonWnd.h"
int GetCurrentPath( char* szPath )
{
TCHAR szLibFile[MAX_PATH];
GetModuleFileName( NULL, szLibFile, MAX_PATH );
TCHAR szTmp[MAX_PATH] = {0};
strcpy( szTmp, szLibFile );
char seps[] = "\\";
char* pTmpTok = NULL;
char* token = strtok( szLibFile, seps );
while( token != NULL )
{
pTmpTok = token;
token = strtok( NULL, seps );
}
int iPathLen = pTmpTok - szLibFile;
strncpy( szPath, szTmp, iPathLen );
szPath[iPathLen] = 0;
return iPathLen;
}
BOOL GetLastErrorMsg( char* pBuf, DWORD dwError )
{
BOOL bGet = FALSE;
HLOCAL hlocal = NULL; // Buffer that gets the error message string
// Use the default system locale since we look for Windows messages.
// Note: this MAKELANGID combination has 0 as value
DWORD systemLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
// Get the error code's textual description
BOOL fOk = FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, dwError, systemLocale,
(PTSTR) &hlocal, 0, NULL);
if (!fOk)
{
// Is it a network-related error?
HMODULE hDll = LoadLibraryEx(TEXT("netmsg.dll"), NULL,
DONT_RESOLVE_DLL_REFERENCES);
if (hDll != NULL)
{
fOk = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
hDll, dwError, systemLocale,
(PTSTR) &hlocal, 0, NULL);
FreeLibrary(hDll);
}
}
if ( fOk && (hlocal != NULL) )
{
strcpy( pBuf, (PCTSTR)LocalLock(hlocal) );
LocalFree(hlocal);
bGet = TRUE;
}
else
{
strcpy( pBuf, "No text found for this error number" );
bGet = TRUE;
}
return bGet;
}
// HandInherit.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
#include "../ComWnd/CommonWnd.h"
int _tmain(int argc, _TCHAR* argv[])
{
printf( "父进程运行...\n");
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd,TRUE,NULL,FALSE);
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE; // 句柄可被子进程继承
sa.lpSecurityDescriptor = &sd;
TCHAR szEventName[] = "zsEvent";
HANDLE hEvent = ::CreateEvent( &sa, TRUE, TRUE, szEventName );
if( NULL == hEvent )
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf("创建事件内核对象失败:%s\n", cMsg );
system("PAUSE");
return 0;
}
printf( "事件:0x%x\n", hEvent );
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
TCHAR cmdLine[100] = {0};
TCHAR szPath[MAX_PATH] = {0};
ZeroMemory( szPath, MAX_PATH );
int iLen = GetCurrentPath( szPath );
TCHAR cAppName[MAX_PATH];
ZeroMemory( cAppName, MAX_PATH );
sprintf( cAppName, "%sChildProcess.exe", szPath );
char cHandle[MAX_PATH] = {0};
// sprintf( cHandle, "%x", hEvent ); // 按值传递
sprintf( cHandle, "%s", szEventName );
sprintf( cmdLine, "%s %s", cAppName, cHandle );
printf( "创建子进程1\n" );
BOOL bOk = CreateProcess(
cAppName,
cmdLine,
NULL,
NULL,
TRUE,
CREATE_FORCEDOS | CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi );
if( !bOk )
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf("创建子进程1失败:%s\n", cMsg );
system("PAUSE");
return 0;
}
HANDLE hChildPros = pi.hProcess;
printf( "子进程1句柄值:%x\n", hChildPros );
DWORD dwRt = WaitForSingleObject( pi.hProcess, INFINITE ); // WaitForInputIdle
if( dwRt == WAIT_OBJECT_0 )
{
printf( "成功等待子进程结束\n" );
// printf( "成功等待子进程1初始化\n" );
}
else if( WAIT_FAILED == dwRt )
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf( "等待子进程1结束失败:%s\n", cMsg );
// printf( "等待子进程1初始化失败:%s\n", cMsg );
}
BOOL bInherit = TRUE;
DWORD dwFlags;
GetHandleInformation(hEvent, &dwFlags);
bInherit = (0 != ( dwFlags & HANDLE_FLAG_INHERIT ) );
BOOL bSet = SetHandleInformation( hEvent, HANDLE_FLAG_INHERIT, 0 ); // 设置为不可继承状态
BOOL bSet2 = ResetEvent(hEvent);
if( !bSet )
{
DWORD dwError = GetLastError();
char cMsg[1024]={0};
ZeroMemory( cMsg, 1024 );
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf( "关闭事件对象(或者重置)继承性失败:%s\n", cMsg );
}
GetHandleInformation(hEvent, &dwFlags);
bInherit = (0 != ( dwFlags & HANDLE_FLAG_INHERIT ) );
Sleep(100);
printf( "创建子进程2\n" );
STARTUPINFO si2 = { sizeof(si2) };
PROCESS_INFORMATION pi2;
bOk = CreateProcess(
cAppName,
cmdLine,
NULL,
NULL,
TRUE,
CREATE_FORCEDOS | CREATE_NEW_CONSOLE,
NULL,
NULL,
&si2,
&pi2 );
if( !bOk )
{
printf("创建子进程2失败%d\n",GetLastError() );
system("PAUSE");
return 0;
}
HANDLE hChildPros2 = pi2.hProcess;
printf( "子进程2句柄值:%x\n", hChildPros2 );
dwRt = WaitForSingleObject( pi2.hProcess, INFINITE ); //WaitForInputIdle
if( dwRt == WAIT_OBJECT_0 )
{
printf( "成功等待子进程2结束\n" );
// printf( "成功等待子进程2初始化\n" );
}
else if( WAIT_FAILED == dwRt )
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf( "等待子进程2结束失败:%s\n", cMsg );
// printf( "等待子进程2初始化失败:%s\n", cMsg );
}
CloseHandle(hEvent);
system("PAUSE");
return 0;
}
// ChildProcess.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include "../ComWnd/CommonWnd.h"
int _tmain(int argc, _TCHAR* argv[])
{
printf( "子进程运行...\n");
if( argc < 2 )
{
printf( "没有传递命令行参数\n" );
char* p = argv[0];
printf( "%s\n", p );
system( "PAUSE" );
return 0;
}
LPSTR lpCmdLine = GetCommandLine();
printf( "命令行:%s\n", lpCmdLine );
HANDLE hEvent = NULL;
char cPath[MAX_PATH] = {0};
char cHand[MAX_PATH] = {0};;
sscanf( lpCmdLine, "%s %s", cPath, cHand );
// hEvent = (HANDLE)atoi( cHand ); // 按值传递
// hEvent = CreateEvent( NULL, TRUE, TRUE , cHand );
hEvent = OpenEvent( EVENT_ALL_ACCESS, TRUE, cHand );
printf( "事件解析为:%s\n", cHand );
if( NULL == hEvent )
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf( "打开事件内核对象失败:%s\n", cMsg );
system("PAUSE");
return 0;
}
DWORD dwRt = WaitForSingleObject( hEvent, INFINITE );
if( dwRt == WAIT_TIMEOUT )
{
printf( "等待超时\n");
}
else if( WAIT_OBJECT_0 == dwRt )
{
printf( "成功等待父进程重置事件\n" );
char szPath[MAX_PATH];
ZeroMemory( szPath, MAX_PATH );
int iLen = GetCurrentPath( szPath );
strcpy( &szPath[iLen], _T("abc.txt") );
HANDLE hFile = CreateFile(
szPath,
GENERIC_WRITE|GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL,
CREATE_ALWAYS, // OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if( INVALID_HANDLE_VALUE != hFile )
{
DWORD iSize = 0;
char cTmp[100];
sprintf( cTmp, "事件内核对象的名称是:%x", hEvent );
BOOL bWrite = WriteFile(hFile, cTmp, strlen(cTmp), &iSize, NULL );
if( !bWrite )
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf( "创建文件成功,写文件失败:%s", cMsg );
}
else
{
printf( "创建文件成功,写入文件%d个字符\n", iSize);
}
CloseHandle(hFile);
}
else
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf( "创建文件失败:%s\n", cMsg );
}
}
else if( WAIT_ABANDONED == dwRt )
{
printf( "解析事件有误\n" );
}
else if( WAIT_FAILED == dwRt )
{
DWORD dwError = GetLastError();
char cMsg[1024];
BOOL bGet = GetLastErrorMsg( cMsg, dwError );
printf( "等待事件失败:%s\n", cMsg );
}
printf( "等待事件内核对象返回%d\n", dwRt );
CloseHandle(hEvent);
system( "PAUSE" );
return 0;
}
// CommonWnd.h 头文件
// 公共代码
#pragma once
#include <Windows.h>
BOOL GetLastErrorMsg( char* pBuf, DWORD dwError );
int GetCurrentPath( char* szPath );
// CommonWnd.cpp 文件
#include "StdAfx.h"
#include "CommonWnd.h"
int GetCurrentPath( char* szPath )
{
TCHAR szLibFile[MAX_PATH];
GetModuleFileName( NULL, szLibFile, MAX_PATH );
TCHAR szTmp[MAX_PATH] = {0};
strcpy( szTmp, szLibFile );
char seps[] = "\\";
char* pTmpTok = NULL;
char* token = strtok( szLibFile, seps );
while( token != NULL )
{
pTmpTok = token;
token = strtok( NULL, seps );
}
int iPathLen = pTmpTok - szLibFile;
strncpy( szPath, szTmp, iPathLen );
szPath[iPathLen] = 0;
return iPathLen;
}
BOOL GetLastErrorMsg( char* pBuf, DWORD dwError )
{
BOOL bGet = FALSE;
HLOCAL hlocal = NULL; // Buffer that gets the error message string
// Use the default system locale since we look for Windows messages.
// Note: this MAKELANGID combination has 0 as value
DWORD systemLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
// Get the error code's textual description
BOOL fOk = FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, dwError, systemLocale,
(PTSTR) &hlocal, 0, NULL);
if (!fOk)
{
// Is it a network-related error?
HMODULE hDll = LoadLibraryEx(TEXT("netmsg.dll"), NULL,
DONT_RESOLVE_DLL_REFERENCES);
if (hDll != NULL)
{
fOk = FormatMessage(
FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
hDll, dwError, systemLocale,
(PTSTR) &hlocal, 0, NULL);
FreeLibrary(hDll);
}
}
if ( fOk && (hlocal != NULL) )
{
strcpy( pBuf, (PCTSTR)LocalLock(hlocal) );
LocalFree(hlocal);
bGet = TRUE;
}
else
{
strcpy( pBuf, "No text found for this error number" );
bGet = TRUE;
}
return bGet;
}
相关文章推荐
- windows核心编程第三章阅读 内核对象
- <<Windows核心编程(第五版)>>第九章用内核对象进行线程同步:9.3事件内核对象
- 《Windows核心编程》学习——内核对象
- Windows核心编程 第三章 内核对象
- 读书笔记----《windows核心编程》第三章 内核对象1(句柄与安全性)
- WINDOWS核心编程第三章内核对象的一点细节
- Windows核心编程学习八:事件内核对象
- Windows核心编程--事件内核对象
- Windows核心编程 第三章 内核对象
- 线程与内核对象的同步——Windows核心编程学习手札之九
- 【windows核心编程】 第三章 内核对象
- WINDOWS核心编程--读书笔记:第三章 内核对象
- windows核心编程第三章--内核对象
- 【windows核心编程】 第三章 内核对象
- WINDOWS核心编程--第二章内核对象
- BT源代码学习心得(七):跟踪服务器(Tracker)的代码分析(HTTP协议处理对象) -- 转贴自 wolfenstein (NeverSayNever)
- 开始从代码入手学习内核
- Silverlight 2学习教程(六): Silverlight托管代码调用Javascript中的JSON对象
- javascript高级程序设计学习笔记--第三章对象基础
- 从零开始学习jQuery (五) 事件与事件对象