Выкладываю СЫРОЙ код - на причесывание нет времени (и это - то делалось урывками)
Найдете ошибки - буду признателен
Что может предоставлять интерес (или ключевые слова):
CreateWaitableTimer
CreateFileMapping
OpenFileMapping
MapViewOfFile
CreateProcess
CreateRemoteThread
TerminateProcess
Источники:
MSDN
http://www.windevnet.com/documents/s=7285/wdj9907c/9907c.htmAdvanced Windows, Jeffrey Richter
Файл main.cpp
#define _WIN32_WINNT 0x0400
#include <windows.h>
//#include <winbase.h>
#include "task.h"
/*
Логика:
1. Создать таймер
2. Запустить исследуемый процесс
3. Создать общую область через Mapping
4. Периодически по таймеру проверять Жив/Мертв исследуемый процесс
5. If (dead)
5.1 Внедрить в исследуемый процесс запрос на останов
5.2 Если через н сек не завершится - TerminateProcess
5.3 go to 2
*/
#define INTERVAL -10000000 /* 1 sec */
HANDLE hTimer;
bool inline IsEnd();
void StartTask();
void MakeConnect();
Task tsk1("test.exe");
//_______________________________________________________________________
WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
LARGE_INTEGER li;
hTimer = CreateWaitableTimer(NULL,FALSE,NULL);
if (!hTimer)
{
throw "can't create timer";
}
li.QuadPart=INTERVAL;
if (!tsk1.Start()) throw "can't start";
tsk1.WaitForProcess(1000);
MakeConnect();
// MemSharePtr=tsk1.MakeShare(10);
do
{
if (!SetWaitableTimer(hTimer,&li,0,NULL,NULL,0))
{
throw "can't set timer";
}
WaitForSingleObject(hTimer,INFINITE);
// MessageBox(0,"!","",0);
} while(!IsEnd());
if (!tsk1.WaitForProcess(1000))
{
int res;
res=tsk1.End(FALSE);
}
tsk1.CloseHandle();
CloseHandle(hTimer);
return 0;
}
//---------------------------------------------------------------------------
static void * MemSharePtr;
unsigned int MyCounter;
void MakeConnect()
{ // Создадим общую область и прочтем начальные значения счетчика
MemSharePtr=tsk1.MakeShare(10);
if (MemSharePtr!=NULL)
{
MyCounter=*((unsigned int*)MemSharePtr);
}
else MyCounter=-1;
}
bool IsEnd()
{
// Проверка процесса - жив - мертв?
// Через общую память проверяем счетчик, периодически записываемый туда
// // счетчик обновляется 1 раз в сек, сл. отл
unsigned int cnt;
int l;
if (MyCounter!=-1)
{
MyCounter++;
cnt=*((unsigned int*)MemSharePtr);
if (MyCounter<cnt)MyCounter=cnt;
l=MyCounter-cnt;
if (MyCounter-cnt>5)
{
return true; // разница в 5 единиц срабатывания таймера
}
}
return false;
}
Файл task.cpp
#include <windows.h>
#include "task.h"
void * GetFileMapping(char *FName,char *MapName,int size,bool New);
void CloseMapping(void * fldat);
Task::Task()
{
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
}
Task::Task(const string fName):FName(fName)
{
ZeroMemory( &si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
}
int Task::Start()
{ // Step 1: Start the main programm
return CreateProcess( NULL,const_cast<char *>(FName.c_str()),
NULL,NULL,FALSE,0,NULL,NULL,&si,&pi );
}
int Task::WaitForProcess()
{ // Wait until process exits.
return (WaitForSingleObject( pi.hProcess,INFINITE)==WAIT_OBJECT_0)?1:0;
}
int Task::WaitForProcess(unsigned int time)
{ // Wait until process exits.
int res;
res=WaitForSingleObject( pi.hProcess,time);
return (res==WAIT_OBJECT_0)?1:0;
// return (WaitForSingleObject( pi.hProcess,time)==WAIT_OBJECT_0)?1:0;
}
int Task::End(bool NoWait)
{
DWORD thrID;
HANDLE ht;
// Kill it Now!
if (NoWait) return TerminateProcess(pi.hProcess,-99);
// Let himself to close
LPTHREAD_START_ROUTINE MR; // get adress of ExitProcess
HMODULE hUSRdll=LoadLibrary("Kernel32.dll");
MR=(LPTHREAD_START_ROUTINE)GetProcAddress(hUSRdll,"ExitProcess1");
if (MR==NULL) return TerminateProcess(pi.hProcess,-99);
ht=CreateRemoteThread(pi.hProcess,NULL,0,MR,NULL,0,&thrID);
::CloseHandle(ht);
// wait for successful finishing
if (ht!=NULL || !WaitForProcess(500)) return TerminateProcess(pi.hProcess,-99);
return 1; // All are ok
?
}
void Task::CloseHandle()
{
// Close process and thread handles.
::CloseHandle( pi.hProcess );
::CloseHandle( pi.hThread );
}
void * Task::MakeShare(int size)
{
// Получить указатель на расSharенную память
MemSharePtr=(char *)GetFileMapping(NULL,"MIG_SH_MEM",size,false);
return MemSharePtr;
}
void Task::CloseShare()
{
CloseMapping(MemSharePtr);
}
Файл Share.cpp
#include <windows.h>
#include <stdio.h>
#pragma hdrstop
//---------------------------------------------------------------------------
void * GetFileMapping(char *FName,char *MapName,int size,bool New);
void CloseMapping(void * fldat);
void * GetFileMapping(char *FName,char *MapName,int size,bool New)
{
HANDLE hfile=INVALID_HANDLE_VALUE;
if (FName!=NULL)
{
hfile=CreateFile(FName,GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ| FILE_SHARE_WRITE, NULL, OPEN_EXISTING,//CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,NULL);
if (hfile==INVALID_HANDLE_VALUE)
{
throw "Error create file";
return NULL;
}
}
HANDLE hfmap;
if (New) hfmap=CreateFileMapping(/*(HANDLE)0xFFFFFFFF*/hfile,NULL,
PAGE_READWRITE,0,size,MapName);
else hfmap=OpenFileMapping(FILE_MAP_READ|FILE_MAP_WRITE,FALSE,MapName);
if (hfmap==NULL)
{
throw "Error create File Mapping";
return NULL;
}
if (hfile!=INVALID_HANDLE_VALUE) CloseHandle(hfile);
char * fldat=(char*)MapViewOfFile(hfmap,FILE_MAP_WRITE,0,0,0);
// CloseHandle(hfmap); !!!! нельзя закрывать этот handle!!!!
if (fldat==NULL) throw "error map";
return (void *)fldat;
}
void CloseMapping(void * fldat)
{
UnmapViewOfFile(fldat);
}
//---------------------------------------------------------------------------