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

  

U盘自动拷贝的更多相关文章

  1. 树莓派插入U盘自动拷贝系统日志到U盘或通过U盘升级程序

    注意,U盘用Fat32格式,NTFS格式的话,需要在Linux另外安装相应驱动. 可通过udev实现如题的功能. 在/etc/udev/rules.d/目录下新建规则文件98-logcopy.rule ...

  2. 树莓派USB存储设备自动挂载并通过脚本实现自动拷贝,自动播放视频,脚本自动升级等功能

    需求:首先需要树莓派自动挂载USB设备,然后扫描USB指定目录下文件,将相关文件拷贝至树莓派指定目录,然后通过omxplayer循环播放新拷贝文件视频 1. 树莓派实现USB存储设备自动挂载 树莓派U ...

  3. U盘无法拷贝超过4G的大文件

    现在U盘的容量越来越大了,8G闪存满天飞,几乎已成“标配”,市面上再见难觅64M.128M等U盘的踪迹,可是细心的你也许已经发现,即使是8G或更大体积的U盘,仍然不能拷贝存储体积超过4G的大文件,这是 ...

  4. Android PRODUCT_COPY_FILES 自动拷贝文件

    /********************************************************************** * Android PRODUCT_COPY_FILES ...

  5. Archlinux 的U盘自动装载(三)udevil

    U盘的自动装载方法,目前我已经使用过以下几种方法: udev 规则 基于 udev 规则的 Shell script udisks 以及 udisks2 结果,总是存在这样那样的小问题.例如,文件名乱 ...

  6. 33.Linux-实现U盘自动挂载(详解)

    1.当我们每次插入u盘后,都会自动创键U盘的设备节点/dev/sda%d 这是因为里面调用了device_create()实现的, busybox的mdev机制就会根据主次设备号等信息,在/dev下创 ...

  7. 48.Linux-普通U盘以及多分区U盘自动挂载

    在上章学习33.Linux-实现U盘自动挂载(详解)后,只是讲解了普通U盘挂载,并没有涉及到多分区U盘,接下来本章来继续学习 1.多分区U盘和普通U盘区别 1)U盘插上只会创建一个/dev/sda文件 ...

  8. 【360图书馆】插入U盘自动攻击:BadUSB原理与实现

    插入U盘自动攻击:BadUSB原理与实现       漏洞背景 “BadUSB”是今年计算机安全领域的热门话题之一,该漏洞由Karsten Nohl和Jakob Lell共同发现,并在今年的Black ...

  9. Qt程序打包,自动拷贝依赖文件

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt程序打包,自动拷贝依赖文件     本文地址:http://techieliang.com ...

随机推荐

  1. Appium入门(3)__ Appium Server安装

    安装Appium 1.下载并安装:https://bitbucket.org/appium/appium.app/downloads/ 2. 系统变量PATH 增加 C:\Program Files ...

  2. ipv6的校验格式

    ipv6的校验格式: ^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$

  3. 被监测teamviewer被检测出用于商业用途

    一.下载teamviewer的破解程序 下载链接 这个要付几块钱,本人付过,个人下载过,可以免费传给你们,可以留下邮箱,但是不一定及时回复. 二. 解压后将.exe放到对应的软件安装目录,运行,点击f ...

  4. jquery.ajax与axios及定义拦截器

    首先导入jquery和axios包 jquery.ajax function reg(){ var username = $("#username").val(); var pas ...

  5. Python接口自动化【requests处理Token请求】

    首先说一下使用python模拟登录或注册时,对于带token的页面怎么登录注册模拟的思路: 1.对于带token的页面,需要先从最开始的页面获取合法token 2.然后使用获取到的合法token进行后 ...

  6. Java如何循环数组并使用Split

    场景: 当写方法时遇到1个参数有3个值, 该参数类型为数组.    例如:  aaa|bbb|ccc  .  而且需要循环打印,这个时候我们就需要用数组循环输出的方法. 一:feature 示例 Wh ...

  7. c# string 扩展方法

    场景:只显示一字符串的前50个字符,多余的用“...”省略号替代 如果不用扩展方法当然也可以实现,写一个静态方法,如下: public class StringUtil { /// <summa ...

  8. Hibernate的一个小应用

    hibernate 第一步,导入hiberante需要用到的jar包,因为使用hibernate时候,有日志信息输出,hibernate本身没有日志输出的jar包,导入其他日志的jar包 不要忘记还有 ...

  9. Mac本如何卸载MySQL

    Mac本如何卸载MySQL 在Mac上卸载MySQL上一件非常麻烦的事,如果没有卸载干净,就会无法安装新的MySQL 怎样才能完全卸载MySQL呢?(包括所有数据库)    执行以下操作: #打开终端 ...

  10. discuz论坛 模板修改

    门户首页 template/rtj1009_007/portal/index.php 头部二级导航 template/rtj1009_007/common/toubu.php 底部内容文件 templ ...