描述:启动该程序后,自动检测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; }