为x64驱动程序创建服务位置

时间:2014-07-17 14:34:44

标签: c# service installation

我有一个同时具有x86和x64位驱动程序的驱动程序。安装程序会检查Is64BitOS && Is64BitProcess。如果它是真的那么它会抓住我的x64驱动程序并对我做一些有点奇怪的事情。它将禁用DisableWow64FSRedirection,将x64驱动程序复制到c:\ windows \ system32 \ drivers,然后RevertWow64FSRedirection

这对我来说似乎不对。哦,在完成复制所述文件后,它会创建一个内核服务。我不确定为什么安装程序会这样做,或者即使应该这样做。当我在HKLM\System\CurrentControlSet\Services\driver64查看我的注册表(出于好奇心,我在我的x64机器上安装了它们)时,图像路径为\??\C:\Windows\System32\drivers\driver64.sys

但是当我查看HKLM\System\CurrentControlSet\Services\driver86时,ImagePath只是driver86而不是sys扩展......虽然我确实看到了另一个没有的WOW64标志..有趣的。

长话短说。我不喜欢那样。如果Microsoft决定进行重定向,那么我也确定当我为所述驱动程序创建一个SafeFileHandle时它会重定向到正确的驱动程序。我疯了吗?

我在C#中安装了安装程序。以下是代码的安装位

    private static void InstallDriver()
    {
        string name = GetCorrectDriverName();
        byte[] driver = is64Bit ? Properties.Resources.inpoutx64 : Properties.Resources.inpout32;
        string path = Kernel32.CopyDriverToSystem32(is64Bit, name, driver);
        ServiceInstaller.InstallAndStart(name, name, path);
    }

Kernel32.cs

    /// <summary>
    /// Copies a driver with a specific name to the System32\Driver folder
    /// </summary>
    /// <param name="is64Bit">Value to determine if system is 32 or 64 bit. SYSTEM not program</param>
    /// <param name="driverName">the name of the driver. file extension and path will be added to this, so just the name</param>
    /// <param name="driver">the driver itself. In this case it is an embedded resource.</param>
    /// <returns>the full path name of the driver that was intalled.</returns>
    public static string CopyDriverToSystem32(bool is64Bit, string driverName, byte[] driver)
    {
        bool oldValue = false;
        if (is64Bit) DisableWow64FSRedirection(out oldValue);
        string path = Path.Combine(Environment.SystemDirectory, "drivers");
        path = Path.Combine(path,  driverName + ".sys");
        File.WriteAllBytes(path, driver);
        if (is64Bit) RevertWow64FSRedirection(oldValue);
        return path;
    } 

ServiceInstaller.cs

    public static void InstallAndStart(string serviceName, string displayName, string fileName)
    {
        IntPtr scm = OpenSCManager(ScmAccessRights.AllAccess);

        try
        {
            IntPtr service = OpenService(scm, serviceName, ServiceAccessRights.AllAccess);

            if (service == IntPtr.Zero)
            {
                service = CreateService(scm, serviceName, displayName, ServiceAccessRights.AllAccess, SERVICE_KERNEL_DRIVER, ServiceBootFlag.AutoStart, ServiceError.Normal, fileName, null, IntPtr.Zero, null, null, null);
            }
            if (service == IntPtr.Zero)
                throw new ApplicationException("Failed to install service.");

            try
            {
                StartService(service);
            }
            finally
            {
                CloseServiceHandle(service);
            }
        }
        finally
        {
            CloseServiceHandle(scm);
        }
    }
    private static IntPtr OpenSCManager(ScmAccessRights rights)
    {
        IntPtr scm = OpenSCManager(null, null, rights);
        if (scm == IntPtr.Zero)
            throw new ApplicationException("Could not connect to service control manager.");

        return scm;
    }

完成安装后使用它非常简单,这就是我希望保留的内容。

        string driverName = GetCorrectDriverName();
        try
        {
            var driverHandle = Kernel32.CreateExclusiveRWFile(driverName);
        }
        catch (System.IO.FileNotFoundException)
        {
            InstallDriver();
        }

0 个答案:

没有答案