سؤال

أحاول التواصل مع برنامج تشغيل نظام الملفات الخاص بي. يمكنني بدء تشغيل برنامج التشغيل باستخدام OpenScManager ، وإنشاء خدمة و 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

يعمل التحميل والتفريغ بشكل جيد (تم فحصه مع DebugView). المشكلة هي أن CreateFile يقول دائمًا "-1" / "2". لقد اختبرته مع برامج تشغيل أخرى ولكن لا يزال كما هو. عندما أفتح textfile مع CreateFile ، يعمل بشكل جيد ، لكنني أريد التواصل مع برنامج التشغيل الخاص بي (DeviceIocontrol) ، لذلك أحتاج إلى فتح جهاز التشغيل ...

هل يمكن لأحد أن يساعدني / يعطيني تلميحًا؟ شكرًا!

هل كانت مفيدة؟

المحلول

أنا أتساءل كيف فشل السائق في التحميل وحتى الآن "تم تفريغه" ... أيضًا ، لا بد لي من الاستعلام عن هذا ....

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

لماذا هو اسم السائق المتشددين ، ليس وحدك ، أنت تستخدم سلسلة "حرفي" لذلك ليست هناك حاجة للهروب من الزلاجة الخلفية ... هل جربتها بهذه الطريقة:

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

شيء آخر ... عندما يتم إجراء مكالمة عبر "CreateFile" ، فأنت تمر في اسم ملف موجود "fsfilter.sys" للقراءة حتى الآن ، تم تحميله بالفعل ...؟ كان ينبغي أن يكون ذلك \\.\FsFilter مع انخفاض التمديد ... هذه هي الأشياء التي لاحظتها ولديها علامة استفهام حول ...؟

أتمنى أن يساعد هذا ، مع أطيب التحيات ، توم.

نصائح أخرى

نعم ، هذا فعل الخدعة:

fileHandle = createFile (".

شكرا لتوم :)

الآن أحصل على شاشة Bluescreen ، لكن هذه مشكلات سائق يجب أن أعمل عليها. تم فتح السائق الآن بشكل صحيح :)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top