#include "CopyFileThread.h"
#include <shlwapi.h>
#include <shlobj.h>
RecycleBin g_RecycleBin; // 回收池
MemPool g_MemPool; // 内存池
//ParamIndex g_ParamIndex;
vector<HANDLE> g_WorkPool; // 工作池
vector<CopyFileThread*> g_ThreadObjs;
HANDLE hIOCompPort;
HANDLE hSemaphore;
DWORD pageSize = 0;
LPHANDLE lpHandle = NULL;
DWORD WINAPI ThreadProc(LPVOID lpParameter);
void Initialize()
{
// 获取系统页面大小
SYSTEM_INFO sysInfo;
ZeroMemory(&sysInfo,sizeof(SYSTEM_INFO));
GetSystemInfo(&sysInfo);
pageSize = sysInfo.dwPageSize;
hIOCompPort = NULL;
hSemaphore = CreateSemaphore(NULL,500,500,NULL);
}
void CopyTotalDir(string strSour,string strDesc)
{
WIN32_FIND_DATA dataFind;
bool bMoreFiles = true;
string strSearchPath = strSour + "\\*.*";
HANDLE hFind = FindFirstFile(strSearchPath.c_str(),&dataFind);
while(hFind != INVALID_HANDLE_VALUE && bMoreFiles == true)
{
string strSourPath,strDesPath;
strSourPath = strSour+ "\\" + dataFind.cFileName;
strDesPath = strDesc + "\\" + dataFind.cFileName;
if(dataFind.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
{
if (dataFind.nFileSizeHigh != 0 || dataFind.nFileSizeLow > 0x7FFFFFFF)
{
cout << "文件 "<< strSourPath << "超过2G,暂不支持复制!" << endl;
bMoreFiles = FindNextFile(hFind,&dataFind);
continue;
}
CopyFileThread* pThread = new CopyFileThread(strSourPath,strDesPath,ThreadProc);
pThread->StartThread();
//g_WorkPool.push_back(*pThread);
g_ThreadObjs.push_back(pThread);
WaitForSingleObject(*pThread,INFINITE);
}
else if (dataFind.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY && strcmp(dataFind.cFileName,".") && strcmp(dataFind.cFileName,".."))
{
if (!CreateDirectory(strDesPath.c_str(),NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
{
cout << "创建目的目录失败!" << endl;
return;
}
CopyTotalDir(strSourPath,strDesPath);
}
bMoreFiles = FindNextFile(hFind,&dataFind);
}
}
int main(int argc, char ** argv)
{
Initialize();
if (argc != 2)
{
cout << "参数错误!按任意键退出...." << endl;
system("pause");
return 1;
}
//char strSour[MAX_PATH] = {0};
char strDes[MAX_PATH] = {0};
cout << "请输入目的目录地址(绝对路径,可以不存在):\n";
//cin >> strSour;
cin >> strDes;
if (!PathFileExists(argv[1]))
{
cout << "指定的源目录不存在!" << endl;
system("pause");
return 1;
}
if (!PathFileExists(strDes) && SHCreateDirectoryEx(NULL,strDes,NULL) != ERROR_SUCCESS )
{
cout << "创建目的目录失败!" << endl;
system("pause");
return 1;
}
time_t begin = time(NULL);
CopyTotalDir(argv[1],strDes);
/*if (g_WorkPool.empty())
{
cout << "没有工作可做!" << endl;
CloseHandle(hIOCompPort);
return 1;
}
WaitForMultipleObjects(g_WorkPool.size(),&g_WorkPool[0],true,INFINITE);*/
time_t end = time(NULL);
cout << "耗时 " << end - begin << "秒!";
CloseHandle(hIOCompPort);
system("pause");
return 0;
}
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
pParam param = (pParam)lpParameter;
BOOL bSuccess;
DWORD bytesTransferred;
DWORD key;
LPOVERLAPPED overlappedComp;
PBUFFER_DATA pBufferData;
bSuccess = GetQueuedCompletionStatus(hIOCompPort, &bytesTransferred,&key, &overlappedComp,(DWORD)-1);
if( !bSuccess && (overlappedComp == NULL))
{
cout<<"::GetQueuedCompletionStatus Failed::"<<endl;
ExitThread(-1);
}
pBufferData = (PBUFFER_DATA)overlappedComp;
if (bytesTransferred == 0)
{
//free(pBufferData->lpData);
cout<<"::GetQueuedCompletionStatus Failed:: 严重错误!!"<<endl;
return 1;
}
DWORD dwTemp = (bytesTransferred + pageSize - 1) & ~(pageSize-1);
if (dwTemp > bytesTransferred)
{
memset(((char*)(pBufferData->lpData)) + bytesTransferred ,' ',dwTemp - bytesTransferred);
}
::ResetEvent(pBufferData->overLapped.hEvent);
bSuccess = WriteFile(param->hDestination, pBufferData->lpData,dwTemp,&dwTemp,&pBufferData->overLapped);
if (!bSuccess)
{
if (GetLastError() == ERROR_IO_PENDING)
{
WaitForSingleObject(pBufferData->overLapped.hEvent,INFINITE);
}
else
{
cout<<"::Error While Writing File::"<<endl;
}
}
/*pParam pThisParam = g_ParamIndex.FindParam(key);
if (pThisParam == NULL)
{
cout << "严重错误,在全局参数表中找不到指定参数!" << endl;
Beep(1,232);
return 0;
}
ReleaseSemaphore(hSemaphore,1,NULL);*/
g_RecycleBin.AddRecyclerIndex(pBufferData->iIndex);
param->CheckOver(bytesTransferred);
return 0;
}