2010-03-02 9 views
2

J'essaie de communiquer avec mon pilote de système de fichiers. Je peux démarrer le pilote avec OpenSCManager, CreateService et OpenService mais quand j'essaie d'utiliser "CreateFile", ça dit toujours Errorcode 2 (je pense que c'est un fichier non trouvé etc.).CreateFile échoue à l'ouverture du pilote fs

C'est tout le code:

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); 
     } 
    } 


} 

et mon principal:

[...] 
    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(); 
} 
[...] 

sortie est:

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 et Déchargement fonctionne très bien (vérifié avec DebugView). Le problème est que CreateFile dit toujours "-1"/"2". Je l'ai testé avec d'autres pilotes mais toujours pareil. Lorsque j'ouvre un fichier texte avec CreateFile, cela fonctionne très bien, mais je veux communiquer avec mon pilote (DeviceIOControl), donc j'ai besoin d'ouvrir le pilote-périphérique ...

Quelqu'un peut-il m'aider/me donner un allusion? Merci!

+0

Donc, vous obtenez IVALID_HANDLE_VALUE de creatfile. Aussi est-ce dans Windows 7/Vista ou XP. – rerun

+0

Il est construit dans Windows7 et a commencé dans WinXP. Le pilote est également optimisé pour l'environnement WinXP. –

Répondre

1

Je me demande comment le pilote n'a pas réussi à charger et encore se « déchargé » ... aussi, je viens d'interroger ce ....

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

Pourquoi le nom du pilote hardcoded, pas seul, vous utilisez la chaîne « verbatim » il n'y a donc pas besoin d'échapper à la barre oblique inverse ... avez-vous essayé cette façon:

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

une autre chose ... quand un appel est fait via 'CreateFile', vous passez un nom de fichier existant 'FsFilter.sys' pour le lire, il a déjà été chargé ...? Si cela avait été \\.\FsFilter avec l'extension abandonnée ... ce sont les choses que je remarque et ont un point d'interrogation sur ...?

Espérons que cela aide, Cordialement, Tom.

+0

Lorsque je modifie l'initialisation Win32Driver à votre suggestion, le programme ne trouve pas le fichier sys à charger, car il a besoin du chemin d'accès complet. Je ne pense pas qu'il y ait un problème, car le chargement et le déchargement du pilote fonctionnent déjà. L'extension n'est pas nécessaire pour CreateFile appelant un pilote système. Seul le nom du pilote je pense (mais j'ai aussi essayé de créer un fichier avec driverName + ". Sys" etc. ne fonctionnait pas.) Merci. –

+0

@ t0mm13b, pour une raison étrange, mon pilote n'a pas Win2k8 à moins que son ImagePath ait été défini sur \ SystemRoot \ drivers \ ????. Sys, car l'erreur 7000 (fichier introuvable) apparaissait dans les journaux à moins que le pilote ne soit mis dans chemin. Pourquoi est-ce?Avait-il besoin maintenant d'être dans un chemin relatif, ou d'avoir "c: \ ... \ ... \ ???? sys" est faux pour ImagePath? –

0

Ouais, ce a fait l'affaire:

fileHandle = CreateFile ("\ \" + driverName, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

Merci à Tom :)

Maintenant, je reçois un écran bleu, mais cela est un pilote problème que je dois travailler. Le pilote est maintenant correctement ouvert :)

+0

Le code ci-dessus a perdu la double barre oblique dans l'argument 1. Ajoutez un \ aux deux barres obliques. –