将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 centosVMware MySQL常用操作设置更改root密码、连接mysql、mysql常用命令

    一.设置更改root密码 启动mysql /usr/local/mysql/bin/mysql -uroot 更改环境变量PATH,增加mysql绝对路径 使mysql -uroot永久生效需要编辑, ...

  2. 什么是Device ID?

    Android ID用于唯一识别一部设备的一次刷机行为,虽然不能完全确定该设备的唯一性(真的唯一性是用IMEI号的),但是可以很大程度上过滤重复设备.这是移动互联网广告行业的基础,尤其是CPI广告,设 ...

  3. git 常用命令记录 -- 快捷&备忘

    1.安装 略2.git拉取远程分支 git config user.name git config user.email git config --global user.name xxxx git ...

  4. windows服务使用和控制启停

    https://www.cnblogs.com/mq0036/p/7875864.html

  5. 获取navigationController中的控制器

    @implementation UIViewController (UIViewControllerExt) - (void)popViewController:(NSString *)control ...

  6. etc/passwd 和 /etc/shadow 文件内容及其解释

    /etc/passwd 和 /etc/shadow 文件内容及其解释 默认情况下,/etc/passwd 存储有关本地用户的信息 /etc/passwd 采用以下格式: 1)username      ...

  7. mysql5.6源码安装(转)

    mysql5.6源码安装 转自 jabbok博客园 https://www.cnblogs.com/jabbok/p/9418344.html 1 编译安装 1 2 3 4 5 6 groupadd ...

  8. SpringCloud实战——(3)通过RESTful方式调用模块的方法

    在项目中创建一个类,编写如下内容: package com.f*iservice.controller; import org.springframework.web.bind.annotation. ...

  9. day17-Python运维开发基础(类的封装 / 对象和类的相关操作、构造方法)

    1. 类的封装及相关操作 # ### oop 面向对象程序开发 """ #用几大特征表达一类事物称为一个类,类更像是一张图纸,表达的是一个抽象概念 "" ...

  10. Python 绘图

    python绘图库有很多,底层的就是matplotlib,另外还有基于matplotlib的更方便,代码可读性更强的库,比如seaborn.plotnine等.各个库之间的对比: https://ww ...