禁用u盘再启用
将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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架