将u盘量产为CDROM后,刷入ISO后需要重新插拔u盘才能访问新内容。此文展示的代码可以实现模拟这种行为,免插拔使windows重新读取cdrom。

网上参考资料有限,自行试验了很多种方法,终于成功了。

首先调用DeviceIoControl卸载设备。然后用CM_Disable_DevNode禁用设备,最后用CM_Enable_DevNode启用设备。

c# 关键代码:

public const uint GENERIC_READ = 0x80000000;
public const uint GENERIC_WRITE = 0x40000000;
public const int FILE_SHARE_READ = 1;
public const int OPEN_EXISTING = 3;
public const int FILE_ATTRIBUTE_NORMAL = 0x80; public const int FSCTL_IS_VOLUME_MOUNTED = 0x00090028;
public const int FSCTL_DISMOUNT_VOLUME = 0x00090020;
public const int CM_DISABLE_HARDWARE = 0x00000002; public struct DiskExtent
{
public uint DiskNumber;
public long StartingOffset;
public long ExtentLength;
} public struct DiskExtents
{
public int numberOfExtents;
public DiskExtent[] first;
} [StructLayout(LayoutKind.Sequential)]
class SP_DEVINFO_DATA
{
public int cbSize;
public Guid ClassGuid;
public int DevInst;
public ulong Reserved;
} [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern SafeFileHandle CreateFileA(string lpFileName, uint dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile); [DllImport("CfgMgr32.dll", SetLastError = true)]
public static extern int CM_Enable_DevNode(ref SafeFileHandle pdnDevInst, int ulFlags); [DllImport("CfgMgr32.dll", SetLastError = true)]
public static extern int CM_Disable_DevNode(ref SafeFileHandle pdnDevInst, int ulFlags); private SafeFileHandle getHandleByLetter(char letter)
{
string lpFileName;
lpFileName = "\\\\.\\" + letter.ToString() + ":";
SafeFileHandle hDevice = CreateFile(lpFileName, GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
return hDevice;
} SafeFileHandle hDevice = getHandleByLetter(CDROMLetter[i]);
int bytesReturned = 0;
DiskExtents diskExtents = new DiskExtents();
DeviceIoControl(hDevice, FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, ref diskExtents, Marshal.SizeOf(diskExtents), ref bytesReturned, IntPtr.Zero); CM_Disable_DevNode(ref hDevice, CM_DISABLE_HARDWARE);
CM_Enable_DevNode(ref hDevice, 0);
hDevice.Close();

golang参考

package main

import (
"syscall"
) var (
CfgMgr32 = syscall.NewLazyDLL("CfgMgr32.dll")
CM_Disable_DevNode = CfgMgr32.NewProc("CM_Disable_DevNode")
CM_Enable_DevNode = CfgMgr32.NewProc("CM_Enable_DevNode")
) const FSCTL_DISMOUNT_VOLUME = 0x00090020
const CM_DISABLE_HARDWARE = 0x00000002 func main() {
var hDev syscall.Handle
disk := "\\\\.\\G:"
hDev, _ = syscall.Open(disk, syscall.O_RDONLY, 0777)
syscall.DeviceIoControl(hDev, FSCTL_DISMOUNT_VOLUME, nil, 0, nil, 0, nil, nil)
CM_Disable_DevNode.Call(uintptr(hDev), CM_DISABLE_HARDWARE)
CM_Enable_DevNode.Call(uintptr(hDev), uintptr(0))
}

c++参考

#include <Cfgmgr32.h>

#pragma comment(lib, "Cfgmgr32")

...
DeviceIoControl(hDev, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, NULL, NULL);
CM_Disable_DevNode(DEVINST(hDev), CM_DISABLE_HARDWARE);
CM_Enable_DevNode(DEVINST(hDev), NULL);
...

  参考链接:

https://blog.csdn.net/bhw98/article/details/19662?tdsourcetag=s_pctim_aiomsg

https://docs.microsoft.com/en-us/windows/desktop/api/cfgmgr32/nf-cfgmgr32-cm_disable_devnode

https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.win32.safehandles.safefilehandle?view=netframework-4.8

https://stackoverflow.com/questions/37532548/deviceiocontrol-with-ioctl-volume-get-volume-disk-extents-c-sharp

禁用u盘再启用的更多相关文章

  1. 摄像头调用代码 笔记本的话,本身有一个摄像头,由于用的usb摄像头,需要把笔记本的摄像头禁用后,再使用

    摄像头调用代码 笔记本的话,本身有一个摄像头,由于用的usb摄像头,需要把笔记本的摄像头禁用后,再使用 <!DOCTYPE html> <html lang="en&quo ...

  2. was控制台误禁用后的恢复启用办法

    websphere是可以配置禁用控制台的,下面以was6.1.单profile.https控制台为例介绍在(误)禁用控制台后如何恢复启用控制台. 1. 禁用控制台 WCInboundAdmin--控制 ...

  3. 教你如何禁用U盘、屏蔽USB端口的三种方法

    如果想禁止所有U盘的使用,则可以通过修改注册表来实现. 打开”运行“对话框,输入命令“Regedit”进入注册表界面.   依次展开“HKEY_LOCAL_MACHINE”→“SYSTEM”→“ Cu ...

  4. 【转】Internet连接正常但是没有网络,禁用以太网以后再重新启动就可以使用了,原因是什么?

    只是粘贴别人的答案,觉得有理,就放在博客里方便以后再学习~ 这个和网络中hdcp服务有关,网卡要在网路中通讯就必须要网络设备一般是路由器或者交换机分配地址,只有给了你电脑门牌号,信件投递能准确无误.你 ...

  5. window 如何枚举设备并禁用该设备和启用该设备?如何注册设备热拔插消息通知?

    目前实现的功能: 1.设备枚举 2.设置设备禁用和启用 3.注册设备热拔插消息通知 4.获取设备 vid pid 数值 需要链接的库 SetupAPI.lib DeviceManager 类如下: D ...

  6. PLSQL 禁用所有约束,启用约束,索引,触发器等

    --禁用外键和触发器 SET SERVEROUTPUT ON SIZE 50000BEGINfor c in (select 'ALTER TABLE '||TABLE_NAME||' DISABLE ...

  7. 通过域 组策略禁用U盘(只允许部份许可U盘可在客户端读取)

    U盘禁用设置步骤: 1.客户端 注册表修改,USBStor  的start改为4 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UsbSto ...

  8. 禁用U盘的两种方法

    方法一:注册表 计算机\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet003\Services\USBSTOR 更改值为4即可,恢复时同理 ,重启即可 方法二:组策略

  9. Z480联想笔记本突然没有了声音

    这几天笔记本突然没有了声音,重启几次都没有效果. 1.检查了声卡驱动,没有发现问题: 2.检查是否设置了静音,没有问题: 有人说重装驱动,懒得重装,于是下面的一个操作给解决了: 在“设备管理器”中找到 ...

随机推荐

  1. Linux三剑客之awk精讲(基础与进阶)

    第1章 awk基础入门 要弄懂awk程序,必须熟悉了解这个工具的规则.本实战笔记的目的是通过实际案例或面试题带同学们熟练掌握awk在企业中的用法,而不是awk程序的帮助手册. 1.1 awk简介 一种 ...

  2. 手机号----IP api

    /* *手机号码API */ $fPArr = iconv("gbk","utf-8",file_get_contents($fphone)); echo $f ...

  3. Django学习之ORM练习题

    一.表关系 创建表关系,并创建约束 班级表:class 学生表: student cid caption grade_id sid sname gender class_id 1 一年一班 1 1 乔 ...

  4. JavaScript图形实例:图形的平移和对称变换

    1.1  六瓣花平移变换 平移变换是指图形从一个位置到另一个位置所作的直线移动.如果要把一个位于P(x,y)的点移到新位置P’(x’,y’),如图1,则只要在原坐标上加上平移距离Tx和Ty即可. 即  ...

  5. C# FileStream 对象的Seek()方法-----转载

    原创 kevin617 发布于2010-12-08 11:22:00 阅读数 8630 收藏展开 FileStream 可以随机读写文件 使用 Seek 方法 Seek()  ----------有两 ...

  6. Ubuntu 16.04 编译安装&&用dpkg安装--zabbix3.4

    编译安装zabbix3.4,官方有教程,但是遇到一些报错: 总结下来,需要安装这些环境: 更新系统: apt update apt upgrade 先装这些: apt-get install libm ...

  7. 标准模板库中的优先队列(priority_queue)

    //C++数据结构与算法(第4版) Adam Drozdek 著  徐丹  吴伟敏<<清华大学出版社>> #include<queue> priority_queu ...

  8. 第1节 kafka消息队列:11、kafka的数据不丢失机制,以及kafka-manager监控工具的使用;12、课程总结

    12.kafka如何保证数据的不丢失 12.1生产者如何保证数据的不丢失 kafka的ack机制:在kafka发送数据的时候,每次发送消息都会有一个确认反馈机制,确保消息正常的能够被收到 如果是同步模 ...

  9. 对于java多态的总结

    父类引用指向子类对象是Java比较基础的概念.Java作为一门面向对象编程的语言,调用对象是在编程中经常用到的.尚学堂李老师为大家详细说明这一概念. 例如父类Animal,子类Cat,Dog.其中An ...

  10. 《C Primer Plus(第6版)(中文版)》普拉达(作者)epub+mobi+azw3

    内容简介 <C Primer Plus(第6版)中文版>详细讲解了C语言的基本概念和编程技巧. <C Primer Plus(第6版)中文版>共17章.第1.2章介绍了C语言编 ...