2010-03-02 33 views
2

我正在嘗試與我的文件系統驅動程序進行通信。我可以用OpenSCManager,CreateService和OpenService啓動驅動程序,但是當我嘗試使用「CreateFile」時,它總是說Errorcode 2(我認爲它沒有找到文件等)。CreateFile在打開fs驅動程序時失敗

這是整個代碼:

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和卸載工作正常(與DebugView中選中)。問題是CreateFile總是說「-1」/「2」。我已經用其他驅動程序測試過,但仍然一樣。當我用CreateFile打開文本文件時,它工作正常,但我想與我的驅動程序(DeviceIOControl)通信,所以我需要打開驅動程序設備...

有人可以幫助我/給我一個暗示? 謝謝!

+0

因此,您正在從creatfile獲取IVALID_HANDLE_VALUE。這也是在Windows 7/Vista或XP中。 – rerun 2010-03-02 21:57:06

+0

它在Windows7中構建,並在WinXP中啓動。驅動程序也針對WinXP環境進行了優化。 – 2010-03-02 22:03:13

回答

1

我想知道司機如何加載失敗,但得到了「卸載」 ......還有,我只需要查詢這個....

 
Win32Driver driver = new Win32Driver(driverName,@"c:\\FsFilter.sys"); 

爲什麼驅動程序的名稱硬編碼,不是一個人,你正在使用的「逐字」字符串,所以沒有必要逃避反斜槓...你嘗試過這種方式:

 
Win32Driver driver = new Win32Driver(driverName, Path.Combine(@"C:\", driverName)); 

另一件事......當調用時通過'CreateFile',你傳遞一個現有的文件名'FsFilter.sys'來閱讀,它已經被加載...?這應該是\\.\FsFilter與擴展下降...這些是我注意到的事情,並有一個關於...的問號?

希望這會有所幫助, 最好的問候, 湯姆。

+0

當我將Win32Driver初始化更改爲您的建議時,程序找不到要加載的sys文件,因爲它需要它的完整路徑。我不認爲有問題,因爲司機的裝卸工作已經完成。 調用系統驅動程序的CreateFile不需要擴展名。只有我認爲的驅動程序名稱(但我也嘗試使用driverName +「。sys」創建文件等)無效。) 謝謝。 – 2010-03-02 23:18:28

+0

@ t0mm13b,出於一些奇怪的原因,我的驅動程序不會在Win2k8上安裝它的ImagePath,它被設置爲\ SystemRoot \ drivers \ ????。sys,因爲錯誤7000(文件未找到)被彈出到日誌中,除非驅動程序被放入路徑。 這是爲什麼?它現在是否需要相對路徑,或者對於ImagePath有「c:\ ... \ ... \ ????。sys」是錯誤的? – 2012-03-12 08:50:53

0

呀, 這並獲得成功:

文件句柄=的CreateFile( 「\ \」 + DRIVERNAME,GENERIC_READ,FILE_SHARE_READ,IntPtr.Zero,OPEN_EXISTING,0,IntPtr.Zero);

感謝湯姆:)

現在我就藍屏,但是這是一個驅動程序問題,我必須去努力。驅動程序現在已正確打開:)

+0

上面的代碼在參數1中丟失了雙斜線。將兩個斜線添加到兩個斜槓。 – 2010-03-03 00:02:01

相關問題