一、本人建的空间里,很少写,也不善于写的原因吧。但是此网站我找到很多好资料,所以,也想有点奉献。最近本人写了一个小程序,主要是学习用的,因为在自学win32编程。主要的功能就是来启动你需要的其他进程,比如,你不想某进程退出后,就不启动了。程序可以帮你完成这个任务。哦!还有程序的知识重点是动态载入动态链接库,接着调用里面的方法。
好了:直接上代码吧:
#ifndef _ORIONSCORPION_PROCESSGUARD_H_
#define _ORIONSCORPION_PROCESSGUARD_H_
#pragma once
#include <windows.h>
#define MAX_UNICODE_PATH 1024
typedef LONG NTSTATUS;
typedef ULONG* ULONG_PTR;
typedef ULONG PPS_POST_PROCESS_INIT_ROUTINE;
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWCHAR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef enum _PROCESSINFOCLASS
{
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers,
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup ,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
ProcessDeviceMap,
ProcessSessionInformation,
ProcessForegroundInformation,
ProcessWow64Information,
ProcessImageFileName,
ProcessLUIDDeviceMapsEnabled,
ProcessBreakOnTermination,
ProcessDebugObjectHandle,
ProcessDebugFlags,
ProcessHandleTracing,
ProcessUnknown33,
ProcessUnknown34,
ProcessUnknown35,
ProcessCookie,
MaxProcessInfoClass
} PROCESSINFOCLASS;
typedef struct _RTL_USER_PROCESS_PARAMETERS
{
BYTE Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB_LDR_DATA
{
BYTE Reserved1[8];
PVOID Reserved2[3];
LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _PEB
{
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[1];
PVOID Reserved3[2];
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
BYTE Reserved4[104];
PVOID Reserved5[52];
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
BYTE Reserved6[128];
PVOID Reserved7[1];
ULONG SessionId;
} PEB, *PPEB;
typedef struct _PROCESS_BASIC_INFORMATION
{
LONG ExitStatus;
PPEB PebBaseAddress;
ULONG_PTR AffinityMask;
LONG BasePriority;
ULONG_PTR UniqueProcessId;
ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
typedef struct _smPROCESSINFO
{
DWORD dwPID;
DWORD dwParentPID;
DWORD dwSessionID;
DWORD dwAffinityMask;
DWORD dwPEBBaseAddress;
LONG dwBasePriority;
LONG dwExitStatus;
BYTE cBeingDebugged;
TCHAR szImgPath[MAX_UNICODE_PATH];
TCHAR szCmdLine[MAX_UNICODE_PATH];
} smPROCESSINFO, *PsmPROCESSINFO;
typedef enum _PROCESSSTATUS
{
Intital,
Running,
Stopped
} PROCESSSTATUS;
typedef struct _PROCESSCONF
{
int procStatus ;
TCHAR szCmdLine[MAX_UNICODE_PATH];
} PROCESSCONF, *PPROCESSCONF;
typedef struct _LINK_PROCESSCONF
{
PROCESSCONF processConf;
_LINK_PROCESSCONF* nextLinkProconf;
} LINK_PROCESSCONF, *PLINK_PROCESSCONF;
// NtQueryInformationProcess in NTDLL.DLL
typedef NTSTATUS (WINAPI *NTQUERYINFORMATIONPROCESS)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength
);
#endif //_ORIONSCORPION_PROCESSGUARD_H_
以上是头文件大家一看想必都明白了啊 ):,这些结构主要是跟Ntdll.dll相关的一些数据结构,本人也是网上捞的。哦!大部分在msdn上多有E文说明的。
二、当然,下面就 .cpp文件了:
#pragma comment(lib,"shlwapi.lib")
#include "ProcessGuard.h"
#include <stdio.h>
#include <tchar.h>
#include <TLHELP32.H>
#include <Shlwapi.h>
#define RE_SUCCESS 1
#define RE_FAILED 0
#define CONF_FILE_NAME "proconf.conf"
#define LOG_FILE_NAME "pro.log"
#define NEW_LINE_SEPARATE "/r/n"
#define SLEEP_TIME 5000
HANDLE m_hLogFile;
FILE* m_hConfFile;
HMODULE m_hNtdll;
LINK_PROCESSCONF* m_linkProConf = NULL;
int Initial();
void WriteLog(const char * str);
BOOL ParseConfig();
int DeleteLink();
BOOL GetNtProcessInfo(const DWORD dwPID, smPROCESSINFO* ppi);
BOOL CompareCmdLine(const char * confstr, const char * procstr);
void StartupProcess();
BOOL MngProcessStatus();
void Finish();
//Manage windows services function
void ServiceMain(int argc, char** argv);
void ControlHandler(DWORD request);
int InitService();
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
NTQUERYINFORMATIONPROCESS NtQueryInformationProcess;
int main(int argc, char* argv[])
{
/***
* control service command
* sc create ProcessGuard binpath=c://path//ProcessGuard.exe start= auto
*/
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = "ProcessGuard";
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
// Start the control dispatcher thread for our service
StartServiceCtrlDispatcher(ServiceTable);
//*/
/*
if(!Initial())
{
return 0;
}
MngProcessStatus();
Finish();
//*/
return 1;
}
//Service initialization
int InitService()
{
return Initial();
}
void ServiceMain(int argc, char** argv)
{
BOOL rebool = TRUE;
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted =SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandler("ProcessGuard",(LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
{
// Registering Control Handler failed
return;
}
if (!InitService())
{
// Initialization failed
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
// We report the running status to SCM.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hStatus, &ServiceStatus);
// The worker loop of a service
while (ServiceStatus.dwCurrentState==SERVICE_RUNNING)
{
rebool= MngProcessStatus();
if(!rebool)
{
WriteLog("MngProcessStatus is fail!");
}
else
{
WriteLog("MngProcessStatus is success!");
}
Sleep(SLEEP_TIME);
}
//Release resources and memorys;
Finish();
return;
}
// Control Handler
void ControlHandler(DWORD request)
{
switch(request)
{
case SERVICE_CONTROL_STOP:
WriteLog("Monitoring stopped.");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
case SERVICE_CONTROL_SHUTDOWN:
WriteLog("Monitoring shutdown.");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
default:
break;
}
}
void StartupProcess()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
LINK_PROCESSCONF* templinkProConf = NULL;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
templinkProConf = m_linkProConf;
while(templinkProConf != NULL)
{
switch(templinkProConf->processConf.procStatus)
{
case Stopped:
WriteLog(templinkProConf->processConf.szCmdLine);
WriteLog("The previous process is Stopped!");
if(!CreateProcess(NULL, templinkProConf->processConf.szCmdLine,NULL,
NULL, NULL, CREATE_NEW_CONSOLE|CREATE_NEW_PROCESS_GROUP,
NULL, NULL, &si, &pi))
{
WriteLog("The previous process was starting fail!");
}
else
{
WriteLog("The previous process was starting success!");
}
break;
case Running:
WriteLog(templinkProConf->processConf.szCmdLine);
WriteLog("The previous process is Running!");
break;
default:
WriteLog(templinkProConf->processConf.szCmdLine);
WriteLog("The previous process status Unkown!");
}
templinkProConf = templinkProConf->nextLinkProconf;
}
}
BOOL CompareCmdLine(const char * confstr, const char * procstr)
{
//char tempprocstr[MAX_UNICODE_PATH],tempconfstr[MAX_UNICODE_PATH];
BOOL rebool = TRUE;
char *tempprocstr, *tempconfstr, *backconfstr,*tempconfTok;
char* procTok, *confTok;
tempprocstr = (char*)LocalAlloc(LPTR, strlen(procstr)+1);
tempconfstr = (char*)LocalAlloc(LPTR, strlen(confstr)+1);
backconfstr = (char*)LocalAlloc(LPTR, strlen(confstr)+1);
ZeroMemory(tempprocstr, strlen(procstr)+1);
ZeroMemory(tempconfstr, strlen(confstr)+1);
ZeroMemory(backconfstr, strlen(confstr)+1);
strncpy(tempprocstr, procstr, strlen(procstr)+1);
strncpy(backconfstr, confstr, strlen(confstr)+1);
StrTrim(tempprocstr, " /t/"");
StrTrim(tempconfstr, " /t/"");
procTok = strtok(tempprocstr, " /t");
confTok = strchr(backconfstr, ' ');
if(confTok != NULL)
strncpy(tempconfstr, confstr, confTok-backconfstr);
else
strncpy(tempconfstr, confstr, strlen(backconfstr)+1);
//confTok = strtok(tempconfstr, " /t");
while(procTok!=NULL && tempconfstr!=NULL)
{
StrTrim(tempconfstr, " /t/"");
StrTrim(procTok, " /t/"");
if(strcmp(tempconfstr, procTok)!=0)
{
rebool = FALSE;
break;
}
procTok = strtok(NULL, " /t");
ZeroMemory(tempconfstr, strlen(tempconfstr)+1);
if(confTok == NULL)
break;
StrTrim(confTok, " /t/"");
tempconfTok = confTok;
//Find string by white space
confTok = strchr(tempconfTok, ' ');
if(confTok != NULL)
strncpy(tempconfstr, tempconfTok, confTok-tempconfTok);
else
strncpy(tempconfstr, tempconfTok, strlen(tempconfTok)+1);
//procTok = strtok(NULL, " /t");
}
if(rebool &&(procTok!=NULL || strlen(tempconfstr)>0))
{
rebool= FALSE;
}
LocalFree(tempprocstr);
LocalFree(tempconfstr);
LocalFree(backconfstr);
return rebool;
}
int Initial()
{
DWORD rePointer;
m_hConfFile = fopen(CONF_FILE_NAME, "a+");
// m_hConfFile = CreateFile(CONF_FILE_NAME, GENERIC_READ, FILE_SHARE_READ,
// NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
m_hLogFile = CreateFile(LOG_FILE_NAME, GENERIC_WRITE, FILE_SHARE_READ,
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(!m_hLogFile)
{
return RE_FAILED;
}
if(!m_hConfFile)
{
WriteLog("Config file initelize is fail!");
return RE_FAILED;
}
rePointer = SetFilePointer(m_hLogFile, 0, NULL, FILE_END);
if( rePointer == -1)
{
WriteLog("Config file moved pointer is fail!");
return RE_FAILED;
}
//Parse Config for protected process
if(!ParseConfig())
{
WriteLog("Parse config file is fail!");
return RE_FAILED;
}
//WriteLog("Starting Success!");
//Load ntdll.dll library
m_hNtdll = LoadLibrary("ntdll.dll");
if(m_hNtdll == NULL)
{
WriteLog("Load library with ntdll.dll is fail!");
return RE_FAILED;
}
NtQueryInformationProcess = (NTQUERYINFORMATIONPROCESS)GetProcAddress(m_hNtdll,
"NtQueryInformationProcess");
if(NtQueryInformationProcess == NULL)
{
WriteLog("Get function with NtQueryInformationProcess is fail!");
return RE_FAILED;
}
return RE_SUCCESS;
}
void Finish()
{
if(m_linkProConf)
{
DeleteLink();
}
if(m_hConfFile)
{
fclose(m_hConfFile);
}
//The last close
if(m_hLogFile)
{
CloseHandle(m_hLogFile);
}
if(m_hNtdll)
{
BOOL refreelib = FreeLibrary(m_hNtdll);
}
}
// Gets information on process with NtQueryInformationProcess
BOOL GetNtProcessInfo(const DWORD dwPID, smPROCESSINFO *ppi)
{
BOOL bReturnStatus = TRUE;
DWORD dwSize = 0;
DWORD dwSizeNeeded = 0;
DWORD dwBytesRead = 0;
DWORD dwBufferSize = 0;
HANDLE hHeap = 0;
WCHAR* pwszBuffer = NULL;
HANDLE hProcess = NULL;
smPROCESSINFO spi = {0};
PPROCESS_BASIC_INFORMATION pbi = NULL;
PEB peb = {0};
PEB_LDR_DATA peb_ldr = {0};
RTL_USER_PROCESS_PARAMETERS peb_upp = {0};
ZeroMemory(&spi, sizeof(spi));
ZeroMemory(&peb, sizeof(peb));
ZeroMemory(&peb_ldr, sizeof(peb_ldr));
ZeroMemory(&peb_upp, sizeof(peb_upp));
spi.dwPID = dwPID;
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, dwPID);
if(hProcess == NULL)
{
DWORD errorCode = GetLastError();
char errorstr[64];
sprintf(errorstr, "GetNtProcessInfo open process error code: %d", errorCode);
WriteLog(errorstr);
return FALSE;
}
hHeap = GetProcessHeap();
dwSize = sizeof(PROCESS_BASIC_INFORMATION);
pbi = (PPROCESS_BASIC_INFORMATION)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize);
if(!pbi)
{
WriteLog("Alloc heap for PEB error!");
return FALSE;
}
NTSTATUS dwStatus = NtQueryInformationProcess(hProcess, ProcessBasicInformation, pbi, dwSize, &dwSizeNeeded);
if(dwStatus >= 0 && dwSize < dwSizeNeeded)
{
if(pbi)
{
HeapFree(hHeap, 0, pbi);
}
pbi = (PPROCESS_BASIC_INFORMATION)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSizeNeeded);
if(!pbi)
{
WriteLog("Alloc heap for PEB error!");
CloseHandle(hProcess);
return FALSE;
}
dwStatus = NtQueryInformationProcess(hProcess, ProcessBasicInformation, pbi,
dwSizeNeeded, &dwSizeNeeded);
}
if(dwStatus >= 0)
{
spi.dwParentPID = (DWORD)pbi->InheritedFromUniqueProcessId;
spi.dwBasePriority = (LONG)pbi->BasePriority;
spi.dwExitStatus = (NTSTATUS)pbi->ExitStatus;
spi.dwPEBBaseAddress = (DWORD)pbi->PebBaseAddress;
spi.dwAffinityMask = (DWORD)pbi->AffinityMask;
if(pbi->PebBaseAddress)
{
if(ReadProcessMemory(hProcess, pbi->PebBaseAddress, &peb, sizeof(peb), &dwBytesRead))
{
spi.dwSessionID = (DWORD)peb.SessionId;
spi.cBeingDebugged = (BYTE)peb.BeingDebugged;
//if PEB read, try to read Process Parameters
dwBytesRead = 0;
if(ReadProcessMemory(hProcess, peb.ProcessParameters,&peb_upp,
sizeof(RTL_USER_PROCESS_PARAMETERS), &dwBytesRead))
{
//Wo got Process Parameters, is CommandLine filled in
if(peb_upp.CommandLine.Length > 0){
pwszBuffer = (WCHAR *)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, peb_upp.CommandLine.Length);
if(pwszBuffer)
{
if(ReadProcessMemory(hProcess, peb_upp.CommandLine.Buffer, pwszBuffer,
peb_upp.CommandLine.Length, &dwBytesRead))
{
//if commandline is larger than our variable, truncate
if(peb_upp.CommandLine.Length >= sizeof(spi.szCmdLine))
{
WriteLog("CommandLine is larger than our variable!");
dwBufferSize = sizeof(spi.szCmdLine) - sizeof(TCHAR);
}
else
{
dwBufferSize = peb_upp.CommandLine.Length;
}
#if defined(UNICODE)||(_UNICODE)
strncpy(spi.szCmdLine, sizeof(spi.szCmdLine),pwszBuffer, dwBufferSize);
#else
WideCharToMultiByte(CP_ACP, 0, pwszBuffer, (int)(dwBufferSize/sizeof(WCHAR)),
spi.szCmdLine, sizeof(spi.szCmdLine), NULL, NULL);
#endif
if(!HeapFree(hHeap, 0, pwszBuffer))
{
bReturnStatus = FALSE;
goto gnpiFreeMemFailed;
}
}
}
}
//We got Process Parameters, is ImagePath filled in
if(peb_upp.ImagePathName.Length > 0)
{
dwBytesRead = 0;
pwszBuffer = (WCHAR*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY,
peb_upp.ImagePathName.Length);
if(pwszBuffer)
{
if(ReadProcessMemory(hProcess, peb_upp.ImagePathName.Buffer,
pwszBuffer, peb_upp.ImagePathName.Length,&dwBytesRead))
{
if(peb_upp.ImagePathName.Length >= sizeof(spi.szImgPath))
{
WriteLog("ImagePath is larger than our variable!");
dwBufferSize = sizeof(spi.szImgPath) - sizeof(TCHAR);
}
else
{
dwBufferSize = peb_upp.ImagePathName.Length;
}
#if defined(UNICODE)||(_UNICODE)
strncpy(spi.szImgPath, sizeof(spi.szImgPath),pwszBuffer, dwBufferSize);
#else
WideCharToMultiByte(CP_ACP, 0, pwszBuffer, (int)(dwBufferSize/sizeof(WCHAR)),
spi.szImgPath, sizeof(spi.szImgPath), NULL, NULL);
#endif
if(!HeapFree(hHeap, 0, pwszBuffer))
{
// failed to free memory
bReturnStatus = FALSE;
goto gnpiFreeMemFailed;
}
}
}
}
}
}
}
// System process for WinXP and later is PID 4 and we cannot access
// PEB, but we know it is aka ntoskrnl.exe so we will manually define it.
// ntkrnlpa.exe if Physical Address Extension (PAE)
// ntkrnlmp.exe if Symmetric MultiProcessing (SMP)
// Actual filename is ntoskrnl.exe, but other name will be in
// Original Filename field of version block.
if(spi.dwPID == 4)
{
ExpandEnvironmentStrings(_T("%SystemRoot%//System32//ntoskrnl.exe"),
spi.szImgPath, sizeof(spi.szImgPath));
}
}
gnpiFreeMemFailed:
if(pbi != NULL)
if(!HeapFree(hHeap, 0, pbi))
{
WriteLog("pbi HeapFree is error!");
}
CloseHandle(hProcess);
*ppi = spi;
return bReturnStatus;
}
//Manage Process status with LINK_PROCESSCONF
BOOL MngProcessStatus()
{
HANDLE hProcessSnap = NULL;
PROCESSENTRY32 pe32;
smPROCESSINFO procinfo;
LINK_PROCESSCONF* itemLinkProcessConf;
if(m_linkProConf == NULL)
{
WriteLog("No process is manage!");
return TRUE;
}
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == NULL)
{
WriteLog("Create process snapshot is fail!");
return FALSE;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if(Process32First(hProcessSnap, &pe32))
{
do
{
BOOL reProcinfo = GetNtProcessInfo(pe32.th32ProcessID, &procinfo);
if(!reProcinfo)
{
WriteLog("GetNtProcessInfo is fail!");
continue;
}
itemLinkProcessConf = m_linkProConf;
do
{
BOOL recmd = CompareCmdLine(itemLinkProcessConf->processConf.szCmdLine, procinfo.szCmdLine);
if(recmd)
{
itemLinkProcessConf->processConf.procStatus = Running;
break;
}
itemLinkProcessConf = itemLinkProcessConf->nextLinkProconf;
} while (itemLinkProcessConf != NULL);
}while(Process32Next(hProcessSnap, &pe32));
StartupProcess();
}
else
{
WriteLog("Don't get process snap!");
return FALSE;
}
return TRUE;
}
int DeleteLink()
{
if(m_linkProConf == NULL)
{
return RE_SUCCESS;
}
LINK_PROCESSCONF* tempLinkProConf = NULL;
while(m_linkProConf != NULL)
{
tempLinkProConf = m_linkProConf;
m_linkProConf = tempLinkProConf->nextLinkProconf;
tempLinkProConf->nextLinkProconf = NULL;
if(LocalFree(tempLinkProConf) != NULL)
{
DWORD errorCode = GetLastError();
char errorstr[64];
sprintf(errorstr,"DeleteLink free memory error code: %d", errorCode);
WriteLog(errorstr);
//return RE_FAILED;
}
}
return RE_SUCCESS;
}
BOOL ParseConfig()
{
char line[MAX_UNICODE_PATH];
int readcount = 0;
LINK_PROCESSCONF* tempLinkProConf = NULL;
LINK_PROCESSCONF* beforeLinkProConf = NULL;
while(!feof(m_hConfFile))
{
if(fgets(line, MAX_UNICODE_PATH, m_hConfFile)==NULL)
{
if(feof(m_hConfFile))break;
WriteLog("ParseConfig readed new line is error!");
return FALSE;
}
long posetion = ftell(m_hConfFile);
//printf("position: %d/n" , fgetc(m_hConfFile));
StrTrim(line, " /t/n");
if(strlen(line) <= 0)
{
continue;
}
if(beforeLinkProConf == NULL)
{
tempLinkProConf = (LINK_PROCESSCONF*)LocalAlloc(LPTR, sizeof(LINK_PROCESSCONF));
strcpy(tempLinkProConf->processConf.szCmdLine, line);
tempLinkProConf->processConf.procStatus = Stopped;
tempLinkProConf->nextLinkProconf = NULL;
m_linkProConf = tempLinkProConf;
beforeLinkProConf = tempLinkProConf;
}
else
{
tempLinkProConf = (LINK_PROCESSCONF*)LocalAlloc(LPTR, sizeof(LINK_PROCESSCONF));
strcpy(tempLinkProConf->processConf.szCmdLine, line);
tempLinkProConf->processConf.procStatus = Stopped;
beforeLinkProConf->nextLinkProconf = tempLinkProConf;
beforeLinkProConf = tempLinkProConf;
}
}
return TRUE;
}
void WriteLog(const char * str)
{
char timestr[100];
DWORD reWriteByte;
SYSTEMTIME systemTime;
GetLocalTime(&systemTime);
sprintf(timestr, "%d-%d-%d %d:%d:%d.%d",
systemTime.wYear,
systemTime.wMonth,
systemTime.wDay,
systemTime.wHour,
systemTime.wMinute,
systemTime.wSecond,
systemTime.wMilliseconds);
//add separate string for datetime and log string
strcat(timestr, " ");
WriteFile(m_hLogFile, timestr, strlen(timestr),&reWriteByte,NULL);
WriteFile(m_hLogFile, str, strlen(str),&reWriteByte,NULL);
WriteFile(m_hLogFile, NEW_LINE_SEPARATE, strlen(NEW_LINE_SEPARATE),&reWriteByte,NULL);
printf("%s %s%s", timestr, str, NEW_LINE_SEPARATE);
}
好了,有兴趣的朋友拷贝到vc 6.0上就可以了,就可以跑了。还有就是默认当成windows的服务程序来实现的,作为普通的应用程序可以把
SERVICE_TABLE_ENTRY 这段代码隐藏掉,下面的就可以了阿。
三、还有一点就是要一个配置文件proconf.conf的格式要说明一下,一行就是一个进程的启动命令。所以,可以监管多个进程。其他不清楚地,就跟我谈论吧。互相学习,天天向上。哈哈......,有可以优化的,程序有缺陷的,欢迎各位同仁请指出。
真的写累了阿,哈哈......,看人家上千字的敲,不容易啊!