2017-03-23 17 views
2

ファイルシステムフィルタドライバを作成しました。ファイルシステムフィルタドライバ - 拒否ファイルの作成

マイドライバはIRP_MJ_CREATEをフィルタリングし、ファイル名を出力します。

NTSTATUS DispatchCreate(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) 
{ 
    PFILE_OBJECT FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject; 

    DbgPrint("DispatchCreate() : %wZ\n", &FileObject->FileName;) 

    return DispatchPassThrough(DeviceObject, Irp); 
} 

これは問題なく動作します。

これで、新しいファイルを作成するたびにアクセス拒否を取得したいと考えています。

(可能ならば、 'あなたは権限がありません。')

だから私はいくつかのことを試してみました。

まず、以下のことを行いました。

NTSTATUS DispatchCreate(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) 
{ 
    PFILE_OBJECT FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject; 
    PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); 

    ULONG Option = Stack->Parameters.Create.Options; 

    if ((Option >> 24) == FILE_CREATE) 
    { 
     DbgPrint("DispatchCreate() : File Create Denied, %wZ, %x \n", &FileObject->FileName, Option); 

     return STATUS_ACCESS_VIOLATION; // or any error code 
    } 

    return DispatchPassThrough(DeviceObject, Irp); 
} 

これはうまくいきましたが、ちょっと変わったものでした。

たとえば、管理者権限を持っていない場合は、「C:\」で何かを作成しようとするとちょっとしたことがあります。

現時点では、FileObjectが正常に削除される可能性があります。

私は以下の変更を行いました。

NTSTATUS DispatchCreate(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) 
{ 
    PFILE_OBJECT FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject; 
    PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); 

    ULONG Option = Stack->Parameters.Create.Options; 

    if ((Option >> 24) == FILE_CREATE) 
    { 
     DbgPrint("DispatchCreate() : File Create Denied, %wZ, %x \n", &FileObject->FileName, Option); 

     Irp->IoStatus.Status = STATUS_ACCESS_VIOLATION; 
     return Irp->IoStatus.Status; 
    } 

    return DispatchPassThrough(DeviceObject, Irp); 
} 

ただし、少し異なるエラーメッセージが表示されます。

通常の権限がないため、「アクセスが拒否されました」と同じように動作します。



、別の質問があります。

他のディスパッチルーチンとは異なり、IRP_MJ_CREATEIRP_MJ_CLOSEIoCompleteRequest()を必要としません。

私は次の部分だけを持っていてもハンドルが正常に返されたことを確認しました。 (ユーザーモードで。)

return STATUS_SUCCESS; 



お読みいただきありがとうございました。

私の質問についてお答えください。

答えて

3

あなたがフィルターにいくつかの要求を拒否する必要がある場合 - 接続されたデバイスに渡す必要はありません - あなた自身のセットエラーステータスと完全IRP他のディスパッチルーチンとは異なり

Irp->IoStatus.Status = STATUS_ACCESS_DENIED; 
IofCompleteRequest(Irp);// !!! 
return STATUS_ACCESS_DENIED; // ! not Irp->IoStatus.Status - you can not access Irp after call IofCompleteRequest 

を必要とし、IRP_MJ_CREATEとIRP_MJ_CLOSEがない を行いますIoCompleteRequest()が必要です。

もちろんこれは絶対的な誤りです。すべてのIrpは電話で完了する必要がありますIofCompleteRequest

+0

ありがとうございます。 私はこの問題を解決しました。 しかし、私は最初に練習用の簡単なドライバを作成したとき、CreateDispatch()とCloseDispatch()ルーチンは、ユーザーモードプログラムが通常は 'return STATUS_SUCCESS';を返してもハンドルを取得することを確認しました。 理由を説明できますか? – SlayerBae

+0

@SlayerBae - あなたはドライバーからコントロールを返します。作成/閉じるには出力パラメータはありません(ステータスブロックを作成しますが、ユーザーはそれを確認できません)。 irpはまだ破壊されません。これはメモリの割り当てと同様です。メモリを割り当ててから解放しないでください(それ以上使用しないでください)。メモリリークを除いて、okのように動作します。 – RbMm

+0

あなたは別のirpを完了しない場合、より深刻になります。バッファリングされたioの読み込み - データはユーザのバッファにコピーされません。非同期io - apcまたはiocpパケットがキューに入れられない場合スレッド終了システムチェック時 - スレッドに関連するirpが存在する - まだ存在していれば(終了/完了していないなど)スレッドは終了時にハングアップすることがあります。システムはシャットダウン/再起動しません。完全ではないirp - 非常に重大なエラー、メモリリーク以上。これは長い時間が表示された後にのみ – RbMm

関連する問題