スキップしてメイン コンテンツへ

 none
シリアルポートに挿入するフィルタドライバについて RRS feed

  • 質問

  • お世話になります。
    私はWDMの初心者で、WDMの本を参考にしながら簡単なドライバを作成して勉強しています。
    フィルタドライバの作成について教えて下さい。
    やりたい事は、シリアルポートCOM2にフィルタドライバを挿入したいだけです。
    作成したフィルタドライバの名前はserialfil.sysです。
    以下にソースから抜粋してポイントだけ記述しました。

    #define DOS_DEVICE_NAME L"\\DosDevices\\SERIAL_MON" // アプリケーションからのデバイス名

    status = IoCreateDevice(    // デバイスオブジェクトを生成する
                DriverObject,   // DriverEntry関数で渡されたドライバオブジェクトへのポインタ
                sizeof(DEVICE_EXTENSION),   
                NULL,
          FILE_DEVICE_UNKNOWN,
           0,
                FALSE,                  
                &deviceObject    // 作成されたデバイスオブジェクトへのポインタを受け取るポインタ
                );


    RtlCopyMemory(DrvName, L"\\Device\\Serial0", 64);
    RtlInitUnicodeString(&uniNameString, DrvName); // 取り付けのドライバ

              // フィルタドライバをデバイスオブジェクトにアタッチする
    status = IoAttachDevice(deviceObject, // フィルタドライバのデバイスオブジェクトへのポインタ
                            &uniNameString, // アタッチされるデバイス名のUnicode文字列
                           &targetObject); // アタッチされるデバイスオブジェクトへのポインタ


    RtlInitUnicodeString(&DosNameString, DOS_DEVICE_NAME);  // デバイスオブジェクトをWin32 から見えるようにする
      status=IoCreateSymbolicLink(&DosNameString, &uniNameString);


    質問1.
    ・ IoAttachDeviceのアタッチされるデバイス名は"\\Device\\Serial0”にしました。WinObjで確認したところ”COM2”に対応していたので。
       serialfil.sysをインストールして、Device Treeで確認したところ、以下のようになりました。
      -DRV \Driver\Serial
        -DEV \Device\Serial0
         -ATT \Attached(unnamed) -\Driver\serenum
        -ATT \Attached(unnamed) -\Driver\serialfil
    ・ この状態で以下のようにアプリケーション側を実行すると、戻り値がエラーとなり、GetLastErrorで値を確認すると、0x05(アクセスが拒否されました)となります。
      CreateFile("\\\\.\\SERIAL_MON",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);

    ・私はこれでポートがオープン出来ると思ったのですが、駄目みたいです。
     何か根本的に間違っているのでしょうか?。
     なにとぞご教授お願い申しあげます。

    質問2.WDMの本などを参考にすると、アプリケーションからのデバイス名の設定で、以下のような記述でシンボリックを作成していますが、

     #define DOS_DEVICE_NAME L"\\DosDevices\\SERIAL_MON" // アプリケーションからのデバイス名
     RtlInitUnicodeString(&DosNameString, DOS_DEVICE_NAME);  // デバイスオブジェクトをWin32から見えるようにする
      status=IoCreateSymbolicLink(&DosNameString, &uniNameString);//
       
     "\\DosDevices\\SERIAL_MON"の"DosDevices"にはどのような意味があるのでしょうか。

     宜しくお願いします。

    • 移動 Mike Wang (MSCS) 2012年10月2日 12:35 (移動元:Windows デバイスドライバー開発)
    2010年3月25日 6:51

回答

  • koridorasu さん、こんにちは。

    - 質問 1 について
    IoCreateDevice の第 4 引数 DeviceType は、デバイスの種類を指定する必要があるため、この場合 FILE_DEVICE_SERIAL_PORT になるかと思われます。また、第 5 引数 DeviceCharacteristics は、少なくとも 1 つ以上のデバイス情報を指定する必要があり、大抵は FILE_DEVICE_SECURE_OPEN を指定することになるかと思われます。勘違いしておりましたらご容赦ください。

      IoCreateDevice より一部抜粋
      http://msdn.microsoft.com/en-us/library/aa490468.aspx
      DeviceType
      Specifies one of the system-defined FILE_DEVICE_XXX constants that indicate the type of device (such as FILE_DEVICE_DISK, FILE_DEVICE_KEYBOARD, etc.) or a vendor-defined value for a new type of device.
      DeviceCharacteristics
      Specifies one or more system-defined constants, ORed together, that provide additional information about the driver's device.

    - 質問 2 について
    MS-DOS Device Name は、主に Win32 プログラム上で該当デバイスを指定するための定義です。ユーザーモードで使用され、カーネルモードでは使用されません。対してカーネルモードで使用されるのは、NT Device Name となります。ドライバは、ユーザーモードでデバイスを特定する必要がある場合、MS-DOS Device Name を提供する必要があります。

      Introduction to MS-DOS Device Names より一部抜粋
      http://msdn.microsoft.com/en-us/library/ms794720.aspx
      Drivers are required to supply an MS-DOS device name only if the device is required to have a specific well-known MS-DOS device name to work with user-mode programs.

      INFO: Understanding Device Names and Symbolic Links より一部抜粋
      http://support.microsoft.com/kb/235128/en-us
      What makes MS-DOS device names different from Windows NT device names is that they are not used by the Windows NT kernel or kernel-mode drivers. Their purpose is to refer to Windows NT device names so that Win32 programs can use the familiar drive letters and device names; for example, COM1:, to access the Windows NT devices.

    参考になりましたら幸いです。

    2010年3月25日 10:30
  • 横から失礼致します。

    ご質問では、「やりたい事は、シリアルポートCOM2にフィルタドライバを挿入したいだけです。」とあります。
    もし、シリアル ポート デバイスのデバイス スタックにフィルタを組み込みたいだけであるならば、
    シンボリック リンクの作成は必要無いと思います。

    ご質問の中に掲載されている部分コードは、おそらく koridorasu さんの作成されているフィルタ ドライバの
    AddDevice ルーチンでの処理だと推測していますが、そもそも "\\Device\\Serial0" のデバイス名は
    serial.sys が作成した Device Object に対して割り当てられたオブジェクト名であり、フィルタ ドライバを
    含め、他のカーネル モード ドライバが自分以外のドライバが作成した Device Object に対して勝手に
    シンボリック リンクを作成すべきではないと思います。

    さらに、"\\Device\\Serial0" のデバイス名に対するシンボリック リンクは serial.sys の中で既に
    作成されているはずなので、あえてフィルタ ドライバが別の名前でシンボリック リンクを作成する必要も
    無いはずです。

    また、IoCreateDevice() の 6th パラメータ Exclusive に FASLE をセットしているようですが、
    シリアル ポートの場合排他制御が必要となるはずなので、TRUE にすべきでは...と思うのです。
    (もしかしたら、CreateFile() で ERROR_ACCESS_DENIED が返されるのは、このフラグが原因かも。)

    なので、フィルタ ドライバ側の AddDevice() ルーチンでの実装例としては、以下のようにすれば動くと思います。

    --------------------------------------------------------------------------

     PDEVICE_OBJECT     TopOfStack;

        :
        :

     status = IoCreateDevice(        // デバイスオブジェクトを生成する
         DriverObject,               // AddDevice() 1st パラメータで渡されたドライバオブジェクトへのポインタ
         sizeof(DEVICE_EXTENSION),   // ベンダー向け構造体deviceExtensionで確保するサイズ
         NULL,                       // デバイスオブジェクトの名前(オプション)
         FILE_DEVICE_SERIAL_PORT,    // デバイスのタイプ !!! あるいは FILE_DEVICE_SERENUM の方が良いかも !!!
         FILE_DEVICE_SECURE_OPEN ,   // デバイスの種類
         TRUE,                       // 排他設定.TRUEにすると複数からのCreateを許可する
         &deviceObject               // 作成されたデバイスオブジェクトへのポインタを受け取るポインタ
                     );

     if ( !NT_SUCCESS( status ) )
     {
        return STATUS_UNSUCCESSFUL;
     }

     TopOfStack = IoAttachDeviceToDeviceStack(
                                                deviceObject,         // フィルタ ドライバのデバイス オブジェクト
                                                PhysicalDeviceObject  // AddDevice() の 2nd パラメータで渡された PDO
                                             );

     if ( !TopOfStack )
     {
        return STATUS_UNSUCCESSFUL;
     }

        :
        :
    --------------------------------------------------------------------------

    一方 User Mode Application 側では、"\\Device\\Serial0" に対するシンボリック リンクは既に serial.sys が
    "COM1", "COM2" という名前で作成しているので、"COM2" をオープンしたいのであれば、以下の様にすればオープン
    出来ると思います。

    --------------------------------------------------------------------------
    hCom = CreateFile(
            "COM2",
            GENERIC_READ | GENERIC_WRITE,
            0,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL
        );
    --------------------------------------------------------------------------

    User Mode Application 側で CreateFile() API をコールすると、そのリクエストは IRP_MJ_CREATE の
    IRP として、I/O マネージャから以下の様に通知されていくはずです。

    ------------------------
       I/O Manager
          ↓
       \Driver\serialfil
          ↓
       \Driver\serenum
          ↓
       \Device\Serial
    ------------------------

    ちなみに serenum.sys はシリアル デバイスを列挙するためのドライバで、serial.sys に対する
    フィルタ ドライバになります。
    シリアル ポートに接続されたデバイスは、serenum.sys が提供する機能のおかげで、自身が接続している
    COM ポート番号を意識する必要が無くなります。

    なお、WDK には serenum.sys や serial.sys の Source Code が提供されているので、その実装を確認すると
    良いと思います。
    (serial.sys に関しては、WDK 7600.116385.1 で WDM から WDF に書き直されているようです。)

    ------------------------
    <WDK 6001.18002 の場合>
    %BaseDir%\src\kernel\serenum
    %BaseDir%\src\kernel\serial
    ------------------------
    <WDK 7600.116385.1 の場合>
    %BaseDir%\src\serial\serenum
    %BaseDir%\src\serial\serial
    ------------------------

    以上、横から失礼致しました。

    2010年3月26日 6:03
  • 再びこんばんわ。

    inf ファイルの記述方法に関しては、どのようにフィルタ ドライバをアタッチさせるかによって変わってくると思いますが、
    とりあえず手っ取り早くアタッチさせたいのであれば、WDK サンプルで提供されている diskperf ドライバの inf が参考に
    なるかもしれません。

    ちょっと興味があったので、先ほど desikper.inf を変更した inf ファイルと Toaster incomplete1 ドライバの組み合わせで、
    ちゃんとシリアル ポートのデバイス スタックにアタッチさせられるか確認してみましたが、一応できました。
    (試したプラットフォームは Vista x86 です。)

    以下は、WinDbg で確認したデバイス スタックの状態です。

    --------------------------------------------------------
    0: kd> !devstack 831a75c8
      !DevObj   !DrvObj            !DevExt   ObjectName
      84ef0628  \Driver\SmpSerFlt  84ef06e0  ; ☆ <=== Toaster incomplete1 ドライバ(名前を変えただけ)
      84ee7978  \Driver\Serenum    84ee7a30 
      84eef040  \Driver\Serial     84eef0f8  Serial0
    > 831a75c8  \Driver\ACPI       8318a808  00000041
    !DevNode 831aa508 :
      DeviceInst is "ACPI\PNP0501\2"
      ServiceName is "Serial"
    --------------------------------------------------------

    私が試した方法が正しいか保証はありませんし、参考になるかどうかわかりませんが(というか、責任は一切負いませんが)、
    一応 inf ファイルの内容も載せておきます。

    --------------------------------------------------------
    <SmpSerFlt.inf>
    =====> ここから...

    [Version]
    Signature = "$Windows NT$"
    Class=Ports
    ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
    Provider  = %msft%
    DriverVer = 03/30/2010, 5.1.2600.0


    ;++++++++++++++++++++++++++++++++++++++++++++++++++
    ;
    ; General installation section
    ;

    [DestinationDirs]
    DefaultDestDir = 12

    ;------------------------------------------------------

    [DefaultInstall.NT]
    CopyFiles = @SmpSerFlt.sys
    Addreg    = SmpSerFlt.AddReg

    [SmpSerFlt.AddReg]
    HKLM, System\CurrentControlSet\Control\Class\{4D36E978-E325-11CE-BFC1-08002BE10318}, UpperFilters, 0x00010008, SmpSerFlt

    ;
    ; Service installation section
    ;
    [DefaultInstall.NT.Services]
    AddService = SmpSerFlt, , SmpSerFlt.Service.Install

    [SmpSerFlt.Service.Install]
    DisplayName    = %service_desc%
    ServiceType    = 1              ; SERVICE_KERNEL_DRIVER
    StartType      = 2              ; SERVICE_AUTO_START
    ErrorControl   = 1              ; SERVICE_ERROR_NORMAL
    ServiceBinary  = %12%\SmpSerFlt.sys
    LoadOrderGroup = "PnP Filter"

    ;------------------------------------------------------

    [DefaultUninstall.NT]
    DelFiles = @SmpSerFlt.sys
    Delreg   = SmpSerFlt.DelReg

    [SmpSerFlt.DelReg]
    HKLM, System\CurrentControlSet\Control\Class\{4D36E978-E325-11CE-BFC1-08002BE10318}, UpperFilters, 0x00018002, SmpSerFlt

    ;
    ; Service uninstallation section
    ;
    [DefaultUninstall.NT.Services]
    DelService = SmpSerFlt,0x200

    ;------------------------------------------------------

    ;++++++++++++++++++++++++++++++++++++++++++++++++++

    [SourceDisksFiles]
    SmpSerFlt.sys=1

    ; Win2000

    [SourceDisksNames]
    1 = %diskid1%,,,\i386

    ; WinXP and later

    [SourceDisksNames.x86]
    1 = %diskid1%,,,\i386

    [SourceDisksNames.ia64]
    1 = %diskid1%,,,\ia64

    [SourceDisksNames.amd64]
    1 = %diskid1%,,,\amd64

    ;
    ; Localizable Strings
    ;

    [Strings]
    msft         = "Nicochan Yorozu-Ya Company"
    service_desc = "Nicochan Serial Port Filter Driver"
    diskid1      = "Nicochan Serial Port Filter Installation Disk #1 (SmpSerFlt)"

     ここまで <===
    --------------------------------------------------------

    使用したドライバは、Toaster incomplete1 ドライバで、名前を "SmpSerFlt.sys" に変えただけです。

    インストール方法は、以下の通りです。

    --------------------------------------------------------
    <インストール方法>

    1. 適当ば場所にフォルダを作って、上記 SmpSerFlt.inf をコピーする。

    2. 上記 1 で作成したフォルダに、下記名前のサブフォルダを作って、
       CPU アーキテクチャに対応したドライバ バイナリ ファイルをコピーする。

        ☆ i386

        ☆ ia64

        ☆ amd64

    3. 管理者権限でコマンド プロンプトをオープンして、上記 1 のフォルダに移動し、
       下記コマンドを実行する。

    rundll32.exe setupapi,InstallHinfSection DefaultInstall 132 .\SmpSerFlt.inf

    4. リブートします。
    --------------------------------------------------------

    ただ、この方法だと、"Ports" クラスに属する全てのデバイス スタックに対して SmpSerFlt ドライバがアタッチされてしまう
    ことになるので、"COM2" だけにアタッチさせたいのであれば、別途ドライバ内の AddDevice ルーチンで判別処理が必要になると
    思います。

    ちなみにアンインストール方法は、上記 3 で示したコマンド ラインの "DefaultInstall" 部分を
    "DefaultUninstall" に変更すれば出来ます。(リブートが必要ですけど。)

    参考になりましたら幸いです。

     

    2010年3月30日 9:49

すべての返信

  • koridorasu さん、こんにちは。

    - 質問 1 について
    IoCreateDevice の第 4 引数 DeviceType は、デバイスの種類を指定する必要があるため、この場合 FILE_DEVICE_SERIAL_PORT になるかと思われます。また、第 5 引数 DeviceCharacteristics は、少なくとも 1 つ以上のデバイス情報を指定する必要があり、大抵は FILE_DEVICE_SECURE_OPEN を指定することになるかと思われます。勘違いしておりましたらご容赦ください。

      IoCreateDevice より一部抜粋
      http://msdn.microsoft.com/en-us/library/aa490468.aspx
      DeviceType
      Specifies one of the system-defined FILE_DEVICE_XXX constants that indicate the type of device (such as FILE_DEVICE_DISK, FILE_DEVICE_KEYBOARD, etc.) or a vendor-defined value for a new type of device.
      DeviceCharacteristics
      Specifies one or more system-defined constants, ORed together, that provide additional information about the driver's device.

    - 質問 2 について
    MS-DOS Device Name は、主に Win32 プログラム上で該当デバイスを指定するための定義です。ユーザーモードで使用され、カーネルモードでは使用されません。対してカーネルモードで使用されるのは、NT Device Name となります。ドライバは、ユーザーモードでデバイスを特定する必要がある場合、MS-DOS Device Name を提供する必要があります。

      Introduction to MS-DOS Device Names より一部抜粋
      http://msdn.microsoft.com/en-us/library/ms794720.aspx
      Drivers are required to supply an MS-DOS device name only if the device is required to have a specific well-known MS-DOS device name to work with user-mode programs.

      INFO: Understanding Device Names and Symbolic Links より一部抜粋
      http://support.microsoft.com/kb/235128/en-us
      What makes MS-DOS device names different from Windows NT device names is that they are not used by the Windows NT kernel or kernel-mode drivers. Their purpose is to refer to Windows NT device names so that Win32 programs can use the familiar drive letters and device names; for example, COM1:, to access the Windows NT devices.

    参考になりましたら幸いです。

    2010年3月25日 10:30
  •        peiriさん、こんにちは。

       貴重なご意見ありがとうございます。アプリケーション開発と比べて、ハードルが高いので全てが参考になります。

    しかし、以下のように書き換えて実行しましたが、アプリ側でcreateFileを実行するとエラーとなります。GetLastErrorは0x05(アクセスが拒否されました)になります。

     status = IoCreateDevice(        // デバイスオブジェクトを生成する
         DriverObject,                          // DriverEntry関数で渡されたドライバオブジェクトへのポインタ
         sizeof(DEVICE_EXTENSION),    // ベンダー向け構造体deviceExtensionで確保するサイズ
         NULL,                                     // デバイスオブジェクトの名前(オプション)
         FILE_DEVICE_SERIAL_PORT ,  // デバイスのタイプ
         FILE_DEVICE_SECURE_OPEN , // デバイスの種類
         FALSE,                                   // 排他設定.TRUEにすると複数からのCreateを許可する
         &deviceObject                        // 作成されたデバイスオブジェクトへのポインタを受け取るポインタ
                     );

     

    今回の方法で、キーボードに関してはKeyBoarfClass0にkFilter.sysを取り付けることが出来ましたが、シリアルはこの方法では出来ないのでしょうか。

    serial0についているserenum.sysは何をしているのかなども分らないので、もう少し調べてみたいと思います。

    なにか、参考になるご意見がありましたら又お願いします。

    ありがとうございました。

     

     

     

     

     

    2010年3月26日 2:55
  • 横から失礼致します。

    ご質問では、「やりたい事は、シリアルポートCOM2にフィルタドライバを挿入したいだけです。」とあります。
    もし、シリアル ポート デバイスのデバイス スタックにフィルタを組み込みたいだけであるならば、
    シンボリック リンクの作成は必要無いと思います。

    ご質問の中に掲載されている部分コードは、おそらく koridorasu さんの作成されているフィルタ ドライバの
    AddDevice ルーチンでの処理だと推測していますが、そもそも "\\Device\\Serial0" のデバイス名は
    serial.sys が作成した Device Object に対して割り当てられたオブジェクト名であり、フィルタ ドライバを
    含め、他のカーネル モード ドライバが自分以外のドライバが作成した Device Object に対して勝手に
    シンボリック リンクを作成すべきではないと思います。

    さらに、"\\Device\\Serial0" のデバイス名に対するシンボリック リンクは serial.sys の中で既に
    作成されているはずなので、あえてフィルタ ドライバが別の名前でシンボリック リンクを作成する必要も
    無いはずです。

    また、IoCreateDevice() の 6th パラメータ Exclusive に FASLE をセットしているようですが、
    シリアル ポートの場合排他制御が必要となるはずなので、TRUE にすべきでは...と思うのです。
    (もしかしたら、CreateFile() で ERROR_ACCESS_DENIED が返されるのは、このフラグが原因かも。)

    なので、フィルタ ドライバ側の AddDevice() ルーチンでの実装例としては、以下のようにすれば動くと思います。

    --------------------------------------------------------------------------

     PDEVICE_OBJECT     TopOfStack;

        :
        :

     status = IoCreateDevice(        // デバイスオブジェクトを生成する
         DriverObject,               // AddDevice() 1st パラメータで渡されたドライバオブジェクトへのポインタ
         sizeof(DEVICE_EXTENSION),   // ベンダー向け構造体deviceExtensionで確保するサイズ
         NULL,                       // デバイスオブジェクトの名前(オプション)
         FILE_DEVICE_SERIAL_PORT,    // デバイスのタイプ !!! あるいは FILE_DEVICE_SERENUM の方が良いかも !!!
         FILE_DEVICE_SECURE_OPEN ,   // デバイスの種類
         TRUE,                       // 排他設定.TRUEにすると複数からのCreateを許可する
         &deviceObject               // 作成されたデバイスオブジェクトへのポインタを受け取るポインタ
                     );

     if ( !NT_SUCCESS( status ) )
     {
        return STATUS_UNSUCCESSFUL;
     }

     TopOfStack = IoAttachDeviceToDeviceStack(
                                                deviceObject,         // フィルタ ドライバのデバイス オブジェクト
                                                PhysicalDeviceObject  // AddDevice() の 2nd パラメータで渡された PDO
                                             );

     if ( !TopOfStack )
     {
        return STATUS_UNSUCCESSFUL;
     }

        :
        :
    --------------------------------------------------------------------------

    一方 User Mode Application 側では、"\\Device\\Serial0" に対するシンボリック リンクは既に serial.sys が
    "COM1", "COM2" という名前で作成しているので、"COM2" をオープンしたいのであれば、以下の様にすればオープン
    出来ると思います。

    --------------------------------------------------------------------------
    hCom = CreateFile(
            "COM2",
            GENERIC_READ | GENERIC_WRITE,
            0,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL
        );
    --------------------------------------------------------------------------

    User Mode Application 側で CreateFile() API をコールすると、そのリクエストは IRP_MJ_CREATE の
    IRP として、I/O マネージャから以下の様に通知されていくはずです。

    ------------------------
       I/O Manager
          ↓
       \Driver\serialfil
          ↓
       \Driver\serenum
          ↓
       \Device\Serial
    ------------------------

    ちなみに serenum.sys はシリアル デバイスを列挙するためのドライバで、serial.sys に対する
    フィルタ ドライバになります。
    シリアル ポートに接続されたデバイスは、serenum.sys が提供する機能のおかげで、自身が接続している
    COM ポート番号を意識する必要が無くなります。

    なお、WDK には serenum.sys や serial.sys の Source Code が提供されているので、その実装を確認すると
    良いと思います。
    (serial.sys に関しては、WDK 7600.116385.1 で WDM から WDF に書き直されているようです。)

    ------------------------
    <WDK 6001.18002 の場合>
    %BaseDir%\src\kernel\serenum
    %BaseDir%\src\kernel\serial
    ------------------------
    <WDK 7600.116385.1 の場合>
    %BaseDir%\src\serial\serenum
    %BaseDir%\src\serial\serial
    ------------------------

    以上、横から失礼致しました。

    2010年3月26日 6:03
  • ニコチャン大王さん、ありがとうございます。koridorasuさん、前の回答で "第 5 引数 DeviceCharacteristics は、少なくとも 1 つ以上のデバイス情報を指定する必要があり" と発言しましたが、WDK 6001 サンプルの kbfiltr を確認したところ、IoCreateDevice の第 5 引数は、0 になっており、必須ではなさそうですので訂正させていただきます。失礼いたしました。

    2010年3月26日 12:12
  • ニコチャン大王さん、peiriさん こんにちは。

    ご意見ありがとうございます。

    現状をご報告します。

    ・シンボリックリンクについては理解できました。

    ・私の作成したドライバは、DriverEntryの中でIoCreateDeviceを作成してIoAttachDeviceしており、NT形式のドライバでした。

    ・DriverExtension->AddDeviceとDriverUnloadを記述してWDM形式に書き換えました。また、IoAttachDeviceToDeviceStackを使用するようにしました。

    ・しかし、このドライバをインストールする方法がわかりません。WINDDKにあるAddfilterや、infファイルを作成してインストールするのが一般的であることが分かりました。現在infファイルの記述の仕方を調べています。ClassGuidなどは必須なのでしょうか?、GUIDGENなどで作成するのでしょうか?

    ・DriverExtension->AddDeviceの引数のpdoはinfファイルの内容で決まるのでしょうか?。

    新しい疑問が湧き出てきて本題から外れてきました。

    現状そのような状態ですが、少しずつですが分ってきましたので、継続して進めていきたいと思います。

     

     

     

    2010年3月29日 6:18
  • 再びこんばんわ。

    inf ファイルの記述方法に関しては、どのようにフィルタ ドライバをアタッチさせるかによって変わってくると思いますが、
    とりあえず手っ取り早くアタッチさせたいのであれば、WDK サンプルで提供されている diskperf ドライバの inf が参考に
    なるかもしれません。

    ちょっと興味があったので、先ほど desikper.inf を変更した inf ファイルと Toaster incomplete1 ドライバの組み合わせで、
    ちゃんとシリアル ポートのデバイス スタックにアタッチさせられるか確認してみましたが、一応できました。
    (試したプラットフォームは Vista x86 です。)

    以下は、WinDbg で確認したデバイス スタックの状態です。

    --------------------------------------------------------
    0: kd> !devstack 831a75c8
      !DevObj   !DrvObj            !DevExt   ObjectName
      84ef0628  \Driver\SmpSerFlt  84ef06e0  ; ☆ <=== Toaster incomplete1 ドライバ(名前を変えただけ)
      84ee7978  \Driver\Serenum    84ee7a30 
      84eef040  \Driver\Serial     84eef0f8  Serial0
    > 831a75c8  \Driver\ACPI       8318a808  00000041
    !DevNode 831aa508 :
      DeviceInst is "ACPI\PNP0501\2"
      ServiceName is "Serial"
    --------------------------------------------------------

    私が試した方法が正しいか保証はありませんし、参考になるかどうかわかりませんが(というか、責任は一切負いませんが)、
    一応 inf ファイルの内容も載せておきます。

    --------------------------------------------------------
    <SmpSerFlt.inf>
    =====> ここから...

    [Version]
    Signature = "$Windows NT$"
    Class=Ports
    ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
    Provider  = %msft%
    DriverVer = 03/30/2010, 5.1.2600.0


    ;++++++++++++++++++++++++++++++++++++++++++++++++++
    ;
    ; General installation section
    ;

    [DestinationDirs]
    DefaultDestDir = 12

    ;------------------------------------------------------

    [DefaultInstall.NT]
    CopyFiles = @SmpSerFlt.sys
    Addreg    = SmpSerFlt.AddReg

    [SmpSerFlt.AddReg]
    HKLM, System\CurrentControlSet\Control\Class\{4D36E978-E325-11CE-BFC1-08002BE10318}, UpperFilters, 0x00010008, SmpSerFlt

    ;
    ; Service installation section
    ;
    [DefaultInstall.NT.Services]
    AddService = SmpSerFlt, , SmpSerFlt.Service.Install

    [SmpSerFlt.Service.Install]
    DisplayName    = %service_desc%
    ServiceType    = 1              ; SERVICE_KERNEL_DRIVER
    StartType      = 2              ; SERVICE_AUTO_START
    ErrorControl   = 1              ; SERVICE_ERROR_NORMAL
    ServiceBinary  = %12%\SmpSerFlt.sys
    LoadOrderGroup = "PnP Filter"

    ;------------------------------------------------------

    [DefaultUninstall.NT]
    DelFiles = @SmpSerFlt.sys
    Delreg   = SmpSerFlt.DelReg

    [SmpSerFlt.DelReg]
    HKLM, System\CurrentControlSet\Control\Class\{4D36E978-E325-11CE-BFC1-08002BE10318}, UpperFilters, 0x00018002, SmpSerFlt

    ;
    ; Service uninstallation section
    ;
    [DefaultUninstall.NT.Services]
    DelService = SmpSerFlt,0x200

    ;------------------------------------------------------

    ;++++++++++++++++++++++++++++++++++++++++++++++++++

    [SourceDisksFiles]
    SmpSerFlt.sys=1

    ; Win2000

    [SourceDisksNames]
    1 = %diskid1%,,,\i386

    ; WinXP and later

    [SourceDisksNames.x86]
    1 = %diskid1%,,,\i386

    [SourceDisksNames.ia64]
    1 = %diskid1%,,,\ia64

    [SourceDisksNames.amd64]
    1 = %diskid1%,,,\amd64

    ;
    ; Localizable Strings
    ;

    [Strings]
    msft         = "Nicochan Yorozu-Ya Company"
    service_desc = "Nicochan Serial Port Filter Driver"
    diskid1      = "Nicochan Serial Port Filter Installation Disk #1 (SmpSerFlt)"

     ここまで <===
    --------------------------------------------------------

    使用したドライバは、Toaster incomplete1 ドライバで、名前を "SmpSerFlt.sys" に変えただけです。

    インストール方法は、以下の通りです。

    --------------------------------------------------------
    <インストール方法>

    1. 適当ば場所にフォルダを作って、上記 SmpSerFlt.inf をコピーする。

    2. 上記 1 で作成したフォルダに、下記名前のサブフォルダを作って、
       CPU アーキテクチャに対応したドライバ バイナリ ファイルをコピーする。

        ☆ i386

        ☆ ia64

        ☆ amd64

    3. 管理者権限でコマンド プロンプトをオープンして、上記 1 のフォルダに移動し、
       下記コマンドを実行する。

    rundll32.exe setupapi,InstallHinfSection DefaultInstall 132 .\SmpSerFlt.inf

    4. リブートします。
    --------------------------------------------------------

    ただ、この方法だと、"Ports" クラスに属する全てのデバイス スタックに対して SmpSerFlt ドライバがアタッチされてしまう
    ことになるので、"COM2" だけにアタッチさせたいのであれば、別途ドライバ内の AddDevice ルーチンで判別処理が必要になると
    思います。

    ちなみにアンインストール方法は、上記 3 で示したコマンド ラインの "DefaultInstall" 部分を
    "DefaultUninstall" に変更すれば出来ます。(リブートが必要ですけど。)

    参考になりましたら幸いです。

     

    2010年3月30日 9:49