如何禁用特定驱动器

时间:2012-03-01 05:04:05

标签: windows-services c#-2.0

我需要使用c#windows服务禁用cdrom和usb海量存储驱动程序。我注意到有一个帖子Disable the use of CD drive (VB.NET)但它不断弹出cdrom托盘。有没有人知道除了使用这种方法之外如何禁用光盘。????

3 个答案:

答案 0 :(得分:0)

在Vista及更高版本上,您可以使用Group Policy设置禁用USB,CD-ROM和其他类型的可移动存储。你甚至不需要服务。如果您无法通过组策略基础结构执行此操作,则可以选择设置组策略控制的注册表项。此Vista forum post中提到了注册表项位置。

答案 1 :(得分:0)

查看下面定义的VolumeManager。它具有锁定卷和禁用CD-ROM弹出的功能

public class VolumeManager
{
    public string DriveLetter { private set; get; }
    public IntPtr hFile { private set; get; }

    public VolumeManager(string driveletter)
    {
        DriveLetter = driveletter;
    }

    public EjectState Eject()
    {
        if (!OpenHandle())
            return EjectState.Failed;

        if (Lock() && Dismount())
        {
            if (PreventRemoval(false) && AutoEject())
            {
                CloseHandle();
                return EjectState.AutoEject;
            }
            else
            {
                CloseHandle();
                return EjectState.RemoveSafely;
            }
        }
        else
        {
            CloseHandle();
            return EjectState.NoLock;
        }
    }

    public bool OpenHandle()
    {
        string filename = "\\\\.\\" + DriveLetter + ":";

        hFile = Win32.CreateFile(filename, Win32.GENERIC_READ | Win32.GENERIC_WRITE,
            Win32.FILE_SHARE_READ | Win32.FILE_SHARE_WRITE, IntPtr.Zero, Win32.OPEN_EXISTING, 0, IntPtr.Zero);

        if (hFile.ToInt32() == Win32.INVALID_HANDLE)
        {
            return false;
        }
        return true;
    }

    public void CloseHandle()
    {
        Win32.CloseHandle(hFile);
    }

    public bool Lock()
    {
        uint bytesReturned = 0;
        int retry = 0;
        while (retry < 20)
        {
            if (Win32.DeviceIoControl(hFile, Win32.FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0,
                ref bytesReturned, IntPtr.Zero))
            {
                return true;
            }
            System.Threading.Thread.Sleep(250);
            retry++;
        }
        return false;
    }


    public bool Dismount()
    {
        uint bytesReturned = 0;
        if (!Win32.DeviceIoControl(hFile, Win32.FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0,
            ref bytesReturned, IntPtr.Zero))
        {
            return false;
        }
        return true;
    }

    public bool PreventRemoval(bool prevent)
    {
        Win32.PREVENT_MEDIA_REMOVAL pmr = new Win32.PREVENT_MEDIA_REMOVAL();
        pmr.PreventMediaRemoval = prevent;
        IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(pmr));
        Marshal.StructureToPtr(pmr, ptr, true);

        uint bytesReturned = 0;
        if (!Win32.DeviceIoControl(hFile, Win32.IOCTL_STORAGE_MEDIA_REMOVAL, ptr, Marshal.SizeOf(pmr), IntPtr.Zero, 0,
            ref bytesReturned, IntPtr.Zero))
        {
            return false;
        }
        return true;

    }

    public bool AutoEject()
    {
        uint bytesReturned = 0;
        if (!Win32.DeviceIoControl(hFile, Win32.IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0,
            ref bytesReturned, IntPtr.Zero))
        {
            return false;
        }
        return true;
    }
}

public enum EjectState
{
    Failed,
    NoVolume,
    NoLock,
    RemoveSafely,
    AutoEject
}

public class Win32
{
    public const uint FILE_DEVICE_FILE_SYSTEM = 0x00000009;
    public const uint IOCTL_STORAGE_BASE = 0x0000002d;
    public const uint FILE_ANY_ACCESS = 0;
    public const uint FILE_READ_ACCESS = 1;
    public const uint METHOD_BUFFERED = 0;
    public const uint FSCTL_LOCK_VOLUME = ((FILE_DEVICE_FILE_SYSTEM << 16) | (FILE_ANY_ACCESS << 14) | (6 << 2) | (METHOD_BUFFERED));
    public const uint FSCTL_DISMOUNT_VOLUME = ((FILE_DEVICE_FILE_SYSTEM << 16) | (FILE_ANY_ACCESS << 14) | (8 << 2) | (METHOD_BUFFERED));
    public const uint IOCTL_STORAGE_MEDIA_REMOVAL = ((IOCTL_STORAGE_BASE << 16) | (FILE_READ_ACCESS << 14) | (0x0201 << 2) | (METHOD_BUFFERED));
    public const uint IOCTL_STORAGE_EJECT_MEDIA = ((IOCTL_STORAGE_BASE << 16) | (FILE_READ_ACCESS << 14) | (0x0202 << 2) | (METHOD_BUFFERED));

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, IntPtr lpInBuffer, int nInBufferSize,
        IntPtr lpOutBuffer, uint nOutBufferSize, ref uint lpBytesReturned, IntPtr lpOverlapped);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool CloseHandle(IntPtr hObject);

    public const uint GENERIC_READ = 0x80000000;
    public const uint GENERIC_WRITE = 0x40000000;
    public const uint FILE_SHARE_READ = 0x00000001;
    public const uint FILE_SHARE_WRITE = 0x00000002;
    public const uint OPEN_EXISTING = 3;
    public const int INVALID_HANDLE = -1;

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess,
        uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
        uint dwFlagsAndAttributes, IntPtr hTemplateFile);

    public struct PREVENT_MEDIA_REMOVAL
    {
        [MarshalAs(UnmanagedType.Bool)]
        public bool PreventMediaRemoval;
    }
}

禁用CD-ROM弹出:

string DriveLetter = "G"; // Or whatever letter you have assigned for your CD-ROM
var VolumeManager = new VolumeManager(DriveLetter);
if (VolumeManager.OpenHandle())
{
    if (!VolumeManager.PreventRemoval(true))
    {
        // Failed to disable CD-ROM eject
        VolumeManager.CloseHandle();
    }
}
else
{
    // Failed to access volume
}

答案 2 :(得分:0)

我资助了一个解决方案

#region EjectMedia
        const uint GENERICREAD = 0x80000000;
        const uint OPENEXISTING = 3;
        const uint IOCTL_STORAGE_EJECT_MEDIA = 2967560;
        const int INVALID_HANDLE = -1;

        private static IntPtr fileHandle;
        private static uint returnedBytes;

        [DllImport("kernel32", SetLastError = true)]
        static extern IntPtr CreateFile(string fileName,
        uint desiredAccess,
        uint shareMode,
        IntPtr attributes,
        uint creationDisposition,
        uint flagsAndAttributes,
        IntPtr templateFile);
        [DllImport("kernel32", SetLastError = true)]
        static extern int CloseHandle(IntPtr driveHandle);
        [DllImport("kernel32", SetLastError = true)]
        static extern bool DeviceIoControl(IntPtr driveHandle,
        uint IoControlCode,
        IntPtr lpInBuffer,
        uint inBufferSize,
        IntPtr lpOutBuffer,
        uint outBufferSize,
        ref uint lpBytesReturned,
                 IntPtr lpOverlapped);
        #endregion

private void loop(object sender, EventArgs e)
{
 DriveInfo[] allDrives = DriveInfo.GetDrives();
            foreach (DriveInfo d in allDrives)
            {
                if (d.IsReady)
                {
                    if (d.DriveType == DriveType.Removable || d.DriveType == DriveType.Ram || d.DriveType == DriveType.Unknown) 
                        Eject(@"\\.\" + d.Name.Substring(0, 1) + ":");
                }
            }
}

 public void Eject(string driveLetter)
        {
            try
            {
                fileHandle = CreateFile(driveLetter, GENERICREAD, 0, IntPtr.Zero, OPENEXISTING, 0, IntPtr.Zero);
                if ((int)fileHandle != INVALID_HANDLE)
                    DeviceIoControl(fileHandle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, ref returnedBytes, IntPtr.Zero);
            }

            catch
            {
                EventLog.WriteEntry(Marshal.GetLastWin32Error().ToString());
            }

            finally
            {
                CloseHandle(fileHandle);
                fileHandle = IntPtr.Zero;
            }
        }