我正在尝试与我的文件系统驱动程序通信。我可以使用OpenSCManager,CreateService和OpenService启动驱动程序但是当我尝试使用“CreateFile”时,它总是说Errorcode 2(我认为它的文件没找到等等。)。
这是整个代码:
using System;
using System.Diagnostics;
using System.Collections;
using System.Runtime.InteropServices;
using System.Management;
using System.ServiceProcess;
namespace ConsoleApplication2
{
public sealed class Win32Driver : IDisposable
{
string driverName;
string execPath;
IntPtr fileHandle;
public Win32Driver(string driver, string driverExecPath)
{
this.driverName = driver;
this.execPath = driverExecPath;
}
~Win32Driver()
{
// BUG - should never rely on finalizer to clean-up unmanaged resources
Dispose();
}
private void CloseStuff()
{
if (fileHandle != INVALID_HANDLE_VALUE)
{
fileHandle = INVALID_HANDLE_VALUE;
CloseHandle(fileHandle);
}
}
public void Dispose()
{
CloseStuff();
GC.SuppressFinalize(this);
}
private readonly static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
private const int STANDARD_RIGHTS_REQUIRED = 0x000F0000;
private const int SC_MANAGER_CONNECT = 0x0001;
private const int SC_MANAGER_CREATE_SERVICE = 0x0002;
private const int SC_MANAGER_ENUMERATE_SERVICE = 0x0004;
private const int SC_MANAGER_LOCK = 0x0008;
private const int SC_MANAGER_QUERY_LOCK_STATUS = 0x0010;
private const int SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020;
private const int SC_MANAGER_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
SC_MANAGER_CONNECT |
SC_MANAGER_CREATE_SERVICE |
SC_MANAGER_ENUMERATE_SERVICE |
SC_MANAGER_LOCK |
SC_MANAGER_QUERY_LOCK_STATUS |
SC_MANAGER_MODIFY_BOOT_CONFIG;
private const int SERVICE_QUERY_CONFIG = 0x0001;
private const int SERVICE_CHANGE_CONFIG = 0x0002;
private const int SERVICE_QUERY_STATUS = 0x0004;
private const int SERVICE_ENUMERATE_DEPENDENTS = 0x0008;
private const int SERVICE_START = 0x0010;
private const int SERVICE_STOP = 0x0020;
private const int SERVICE_PAUSE_CONTINUE = 0x0040;
private const int SERVICE_INTERROGATE = 0x0080;
private const int SERVICE_USER_DEFINED_CONTROL = 0x0100;
private const int SERVICE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED
|
SERVICE_QUERY_CONFIG |
SERVICE_CHANGE_CONFIG |
SERVICE_QUERY_STATUS |
SERVICE_ENUMERATE_DEPENDENTS |
SERVICE_START |
SERVICE_STOP |
SERVICE_PAUSE_CONTINUE |
SERVICE_INTERROGATE |
SERVICE_USER_DEFINED_CONTROL;
private const int SERVICE_DEMAND_START = 0x00000003;
private const int SERVICE_KERNEL_DRIVER = 0x00000001;
private const int SERVICE_ERROR_NORMAL = 0x00000001;
private const uint GENERIC_READ = 0x80000000;
private const uint FILE_SHARE_READ = 1;
private const uint FILE_SHARE_WRITE = 2;
private const uint OPEN_EXISTING = 3;
private const uint IOCTL_SHOCKMGR_READ_ACCELEROMETER_DATA = 0x733fc;
private const int FACILITY_WIN32 = unchecked((int)0x80070000);
private IntPtr handle = INVALID_HANDLE_VALUE;
[DllImport("advapi32", SetLastError = true)]
internal static extern IntPtr OpenSCManager(string machineName, string
databaseName, uint dwDesiredAccess);
[DllImport("advapi32", SetLastError = true)]
internal static extern IntPtr CreateService(IntPtr hSCManager, string
serviceName, string displayName,
uint dwDesiredAccess, uint serviceType, uint startType, uint
errorControl,
string lpBinaryPathName, string lpLoadOrderGroup, string lpdwTagId,
string lpDependencies,
string lpServiceStartName, string lpPassword);
[DllImport("advapi32")]
internal static extern bool CloseServiceHandle(IntPtr handle);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess);
[DllImport("kernel32", SetLastError = true)]
internal static extern IntPtr CreateFile(string lpFileName, uint
dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint
dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32")]
internal static extern void CloseHandle(IntPtr handle);
[DllImport("kernel32", SetLastError = true)]
private static extern bool DeviceIoControl(IntPtr hDevice, uint
dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, IntPtr lpOutBuffer,
uint nOutBufferSize, ref uint lpBytesReturned, IntPtr lpOverlapped);
internal bool LoadDeviceDriver()
{
IntPtr scHandle = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
Console.WriteLine("OpenSCManager: " + scHandle);
if (scHandle != INVALID_HANDLE_VALUE)
{
IntPtr hService = CreateService(scHandle, this.driverName,
this.driverName, SERVICE_ALL_ACCESS
, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL
,execPath, null, null, null, null, null);
Console.WriteLine("CreateService: " + hService);
hService = OpenService(scHandle, this.driverName,
SERVICE_START | SERVICE_STOP);
Console.WriteLine("OpenService: "+hService);
if (hService != IntPtr.Zero)
{
CloseServiceHandle(hService); // close both handles
CloseServiceHandle(scHandle);
// Start the driver using System.Management (WMI)
if (ExecuteSCMOperationOnDriver(this.driverName, "StartService") == 0)
{
return true;
}
}
else
if (Marshal.GetLastWin32Error()== 1073) // Driver/Service already in DB
{
Console.WriteLine("Marshal=1073");
CloseServiceHandle(scHandle);
// Start the driver using System.Management (WMI)
if (ExecuteSCMOperationOnDriver(this.driverName, "StartService") == 0)
{
return true;
}
}
Marshal.ThrowExceptionForHR(HRESULT_FROM_WIN32(Marshal.GetLastWin32Error()));
}
return false;
}
internal bool UnloadDeviceDriver()
{
int ret = 0;
Console.WriteLine("Unloading now...");
if (fileHandle != IntPtr.Zero && fileHandle != INVALID_HANDLE_VALUE)
{
CloseHandle(fileHandle);
}
if ((ret = ExecuteSCMOperationOnDriver(driverName, "StopService")) == 0)
{
ret = ExecuteSCMOperationOnDriver(driverName, "Delete");
}
if (ret != 0)
{
return false;
}
return true;
}
private static int ExecuteSCMOperationOnDriver(string driverName, string operation)
{
ManagementPath path = new ManagementPath();
path.Server = ".";
path.NamespacePath = @"root\CIMV2";
path.RelativePath = @"Win32_BaseService.Name='" + driverName + "'";
using (ManagementObject o = new ManagementObject(path))
{
ManagementBaseObject outParams = o.InvokeMethod(operation,null, null);
return Convert.ToInt32(outParams.Properties["ReturnValue"].Value);
}
}
internal IntPtr OpenDevice()
{
Console.WriteLine(driverName);
fileHandle = CreateFile("\\\\.\\"+driverName, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
Console.WriteLine("CreateFile: "+fileHandle);
//Console.WriteLine(Marshal.GetLastWin32Error());
if(fileHandle == INVALID_HANDLE_VALUE)
{
Console.WriteLine("Throw exception");
Console.WriteLine((Marshal.GetLastWin32Error()).ToString()+"\n\n\n");
//Marshal.ThrowExceptionForHR(HRESULT_FROM_WIN32(Marshal.GetLastWin32Error()));
}
return fileHandle;
}
internal IntPtr DevControl()
{
Console.WriteLine("DevControl started");
//long DeviceBuffer = 0;
IntPtr dwState = new IntPtr(100);
uint dwRet=0;
bool dc = DeviceIoControl(fileHandle, FSConstants.IO_SET_EVENT, IntPtr.Zero, 0, dwState, (uint)Marshal.SizeOf(dwRet), ref dwRet, IntPtr.Zero);
Console.WriteLine("Operation: "+dc);
Console.WriteLine("Return Value: "+dwRet);
Console.WriteLine("Error: "+(Marshal.GetLastWin32Error()).ToString() + "\n\n\n");
if (fileHandle == INVALID_HANDLE_VALUE)
{
//Console.WriteLine("Throw exception");
//Console.WriteLine((Marshal.GetLastWin32Error()).ToString()+"\n\n\n");
//Marshal.ThrowExceptionForHR(HRESULT_FROM_WIN32(Marshal.GetLastWin32Error()));
}
return fileHandle;
}
private static int HRESULT_FROM_WIN32(int x)
{
return x <= 0 ? x : ((x & 0x0000FFFF) | FACILITY_WIN32);
}
}
internal class FSConstants
{
private const int FILE_DEVICE_COMM_DRIVER = 0x00008810;
const uint METHOD_NEITHER = 3;
const uint METHOD_BUFFERED = 0;
const uint FILE_ANY_ACCESS = 0;
const uint FILE_SPECIAL_ACCESS = FILE_ANY_ACCESS;
public static uint IO_SET_EVENT = CTL_CODE(FILE_DEVICE_COMM_DRIVER, 0x801, METHOD_NEITHER, FILE_ANY_ACCESS);
static uint CTL_CODE(uint DeviceType, uint Function, uint Method, uint Access)
{
return ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method);
}
}
}
和我的主要:
[...]
class Program
{
[DllImport("kernel32.dll")]
static extern int ResumeThread(IntPtr hThread);
[DllImport("kernel32.dll")]
static extern int SuspendThread(IntPtr hThread);
[DllImport("kernel32.dll")]
static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess,
bool bInheritHandle,
uint dwThreadId
);
[Flags]
public enum ThreadAccess : int
{
TERMINATE = (0x0001),
SUSPEND_RESUME = (0x0002),
GET_CONTEXT = (0x0008),
SET_CONTEXT = (0x0010),
SET_INFORMATION = (0x0020),
QUERY_INFORMATION = (0x0040),
SET_THREAD_TOKEN = (0x0080),
IMPERSONATE = (0x0100),
DIRECT_IMPERSONATION = (0x0200)
}
[DllImport("kernel32", SetLastError = true)]
internal static extern IntPtr CreateFile(string lpFileName, uint
dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint
dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
private const uint GENERIC_READ = 0x80000000;
private const uint OPEN_EXISTING = 3;
static void Main(string[] args)
{
bool check=true;
string driverName = "FsFilter";
//load systemdriver
Win32Driver driver = new Win32Driver(driverName,@"c:\\FsFilter.sys");
if (driver.LoadDeviceDriver()){
Console.WriteLine(driverName + " loaded");
IntPtr handle = driver.OpenDevice();
Console.WriteLine(handle);
Console.WriteLine("Device opened");
// use device using ....DeviceIoControl(handle,....) see class code for signature
driver.DevControl();
}
//unload when done
Console.Read();
driver.DevControl();
driver.UnloadDeviceDriver();
Console.WriteLine(driverName + " unloaded");
Console.Read();
}
[...]
输出是:
OpenSCManager: 1576104
CreateService: 1576624
OpenService: 1576704
FsFilter loaded
FsFilter
CreateFile: -1
Throw exception
2
-1
Device opened
DevControl started
Operation: False
Return Value: 0
Error: 6
Unloading now...
FsFilter unloaded
DriverLoading和Unloading工作正常(使用DebugView检查)。问题是CreateFile总是说“-1”/“2”。我已经和其他驱动程序一起测试过,但仍然是相同的。当我用CreateFile打开文本文件时,它工作正常,但我想与我的驱动程序(DeviceIOControl)通信,所以我需要打开驱动程序设备......
有人可以帮我/给我一个暗示吗? 谢谢!
答案 0 :(得分:1)
我想知道驱动程序是如何加载但却“卸载”的......而且,我只需要查询这个....
Win32Driver driver = new Win32Driver(driverName,@"c:\\FsFilter.sys");
为什么驱动程序的名称是硬编码的,而不是单独使用'verbatim'字符串,因此无需转义反斜杠...你是否尝试过这种方式:
Win32Driver driver = new Win32Driver(driverName, Path.Combine(@"C:\", driverName));
另一件事......当通过'CreateFile'进行调用时,你传入一个现有的文件名'FsFilter.sys'进行读取,它已经被加载了......?如果\\.\FsFilter
已经删除了扩展名......这些是我注意到的并且有关于......的问号吗?
希望这有帮助, 最好的祝福, 汤姆。
答案 1 :(得分:0)
对, 这就是诀窍:
fileHandle = CreateFile(“\。\”+ driverName,GENERIC_READ,FILE_SHARE_READ,IntPtr.Zero,OPEN_EXISTING,0,IntPtr.Zero);
感谢Tom:)
现在我得到了蓝屏,但这是我必须要解决的驱动问题。驱动程序现在已正确打开:)