您的位置:首页 > 编程语言

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;

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ windows 内核 对象 win32