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