zoukankan      html  css  js  c++  java
  • 禁用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

    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

  • 相关阅读:
    Go基础结构与类型06---房贷计算器
    Go基础结构与类型05---程序运算
    Go基础结构与类型04---基本数据类型
    Go基础结构与类型03---标准输入与输出
    Go基础结构与类型02---使用iota定义常量组
    Go基础结构与类型01---常量变量表达式
    java===IO=file
    java===IO=properties
    java===IO基本规律,各大常用IO流介绍练习
    java===IO字节流、字符流
  • 原文地址:https://www.cnblogs.com/sherlock-merlin/p/11066285.html
Copyright © 2011-2022 走看看