描述:启动该程序后,自动检测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. Python3+Selenium环境配置

    一.所需工具 1.Python3.6安装包 2.Selenium安装包(selenium-server-standalone-3.8),如果是Python3的话可以不用下载selenium压缩包,Py ...

  2. python作用域问题

    今天出了个低级的错误,最后确定是作用域问题,特回顾知识点如下: 在Python程序中创建.改变.查找变量名时,都是在一个保存变量名的空间中进行,我们称之为命名空间,也被称之为作用域. Python的作 ...

  3. falsk 与 django cookie和session存、取、删的区别

    falsk cookie的存取删需导入from flask import Flask,make_response,request# 存COOKIE的方法@app.route('/setcookie') ...

  4. InnoDB启用大内存页

    在 Linux 操作系统上运行内存需求量较大的应用程序时,由于其采用的默认页面大小为 4KB,因而将会产生较多 TLB Miss 和缺页中断,从而大大影响应用程序的性能.当操作系统以 2MB 甚至更大 ...

  5. PropTypes使用

    PropTypes防止后期代码传参数错误,所以加一个校验, 代码: import React, {Component,PropTypes} from 'react'; import {View, Te ...

  6. what's the python之面向对象

    编程分为面向过程和面向对象,首先我们要了解什么是面向对象. 面向对象 面向过程就是我们之前学的内容,主要是函数式,其核心是过程,过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全 ...

  7. perfmon——使用windows系统自带的性能监视器监控进程信息

    第一次使用perfmon监控应用进程的信息,步骤总结如下: 第一部分 性能监视器 1.快捷键Win+R打开运行界面,输入“perfmon”命令后回车即可打开windows的性能监视器 2.点击“性能监 ...

  8. 004-js-md5

    参看地址:https://www.bootcdn.cn/blueimp-md5/

  9. 20165236 2017-2018-2 《Java程序设计》第八周学习总结

    20165236 2017-2018-2 <Java程序设计>第八周学习总结 一.第十二章教材内容总结: 1.Java的多线程机制: 多线程是指一个应用程序中同时存在几个执行体,按几条不同 ...

  10. strlen函数细节

    strlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止,然后返回计数器值. 原型: ...