将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. 使用 CocoaPods 遇到的问题记录

    1. 在 Terminal 输入 Cocoapods 命令时,有时会一直等待,出现“Performing a deep fetch of the `master` specs repo to impr ...

  2. Dubbo 18 问

    dubbo是什么 dubbo是一个分布式框架,远程服务调用的分布式框架,其核心部分包含: 集群容错:提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集 ...

  3. c-指针的理解

    c-指针的理解 最近在学习MFC,其中的代码有点看的不是很深刻,究其原因还是对c语言中的指针理解的不是很好,下面详细的给大家介绍一下指针,如有不当之处,欢迎各位读者指正. 一.指针的概念 C语言里,变 ...

  4. 子组件props接受父组件传递的值 能修改吗?

    vue2.0 子组件props接受父组件传递的值,能不能修改的问题整理 父组件代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...

  5. SqlCommand的ExecuteReader方法----转载

    SqlCommand的ExecuteReader方法 原创 小道  2018-08-28 17:32:01  阅读 1353 次 评论 0 条 摘要: 用于执行查询语句,并返回一个DataReader ...

  6. 今日份学习: Spring - 事实标准

    笔记 Spring IOC Inverse of Control:控制反转 DI:Dependancy Injections:依赖注入 没有IOC的时候,各种依赖需要逐个按顺序创建. 有了IOC的之后 ...

  7. 无法通过128在表空间temp中扩展temp字段

    truncate 表后在执行,这个原因是数据太大了

  8. Eclipse - 常见问题 - Refresh

    有时候项目代码正确但运行后出现异常,是因为eclipse没有刷新 (如jar包添加了但没用),比较脑慢. 解决方法: clean缓存,或者要多点几次Refresh,或者重启 eclipse.

  9. IOS switch-case知多少

    1. switch参数类型 switch参数类型要求是integer type,准确来讲,是可以转换成integer的类型, 这包括所有的C基本数据类型((signed/unsigned)char, ...

  10. IOS UIPanGestureRecognizer手势使用及识别状态UIGestureRecognizerState

    UIGestureRecognizerState -- 手势识别器状态 1.先来看官方文档 定义UIGestureRecognizer.h 英文: typedef NS_ENUM(NSInteger, ...