更新履歴(3件・最終更新 2026年08月02日)
この記事に加えた変更の記録です。アーカイブした更新前のバージョンは、DOI付きの固定URLから読めます。
- この記事の知識マップに含まれる関係を見直しました。本文より広い主張になっていたもの(条件付きでしか成り立たない関係、「防ぐ」ではなく「軽減する」にあたる関係、前提ではなく推奨にあたる関係)を、条件付きに改めるか、より正確な述語に置き換えています。本文の主張は変えていません。
- 記事の冒頭に「この記事の知識マップ」を追加しました。本文で扱う概念どうしの関係を一枚の図で見渡せます。関係の全一覧(根拠のURL・確度・確認日つき)と主要概念の定義は知識マップ詳細ページにまとめ、機械可読データをJSON-LDとTurtleで公開しています。
- `fltmc`の出力の列構成と読み方を追加しました(掲載した値はMicrosoftが公開しているアルティチュード割り当て一覧のもので、実機の出力ではありません)。アルティチュードの申請手順と申請先、Process Monitorで最初に行う3手、連載リンクのラベルの整理を追加しました。
- 初版公開
この記事を引用する(DOI: 10.5281/zenodo.21739478)
この記事はZenodoにアーカイブされています。常に最新版へ解決されるDOIと、いま表示している版に固定されたDOIの両方を下に示します。
小村 豪(2026)「Windows I/Oの深層(第6回・最終回) ── フィルタードライバーとミニフィルター:ProcmonとウイルススキャンがI/Oに割り込める理由」合同会社小村ソフト. https://doi.org/10.5281/zenodo.21739478 https://staging.comcomponent.com/blog/windows-minifilter-filter-drivers/
- DOI(最新版)
- 10.5281/zenodo.21739478
- DOI(この版)
- 10.5281/zenodo.21739479
連載「Windows I/Oの深層」、最終回です。
第1回のデバイススタックの図に「ファイルシステムフィルター(ウイルス対策・暗号化・Procmonなど)」という箱を描いてから、この連載には間に挟まる者たちが何度も顔を出してきました。Procmonが全I/Oを記録できる理由(第1回)。「あの環境でだけファイルアクセスが遅い」(第2回)。開かれた瞬間にOneDriveがダウンロードを始めるリパースポイント(第5回)。今回はいよいよ、その挟まる仕組みそのもの──ファイルシステムフィルタードライバーとミニフィルター──を正面から扱い、連載の伏線をすべて回収します。
1. まず結論
- 「I/Oに割り込む」はOS公認の拡張点です。ファイルシステムフィルターは、ファイルシステムへの要求を見て、書き換え、拒否し、代わりに処理できます(2章)。1
- 現在の標準はミニフィルターです。デバイススタックに直接割り込むレガシー方式の問題(順序不定・アンロード不可)を解決するため、Windows付属のフィルターマネージャー(FltMgr)にコールバックを登録する方式に世代交代しました(2章)。23
- 動きはpre/postコールバックです。各操作の前と後に、登録順=アルティチュード順で呼ばれます。素通し・完了・拒否・書き換え──第1回で見た「ドライバーの選択肢」がそのまま使えます(3章)。2
- アルティチュード(標高)が順序を決めます。用途別のグループに番号帯が割り当てられ(Activity Monitor 360000〜389999、Anti-Virus 320000〜329999など)、ボリュームにアタッチされるインスタンスごとに一意の番号が付きます(4章)。45
- あなたのPCの住人は
fltmcで見られます。Procmon(起動中のみ)、ウイルス対策、OneDriveのクラウドフィルター──全員ここに並びます(5章)。 - ウイルス対策の除外設定とは「その製品自身のスキャンの省略」であり、他のミニフィルターには影響しません。除外は保護を弱めるトレードオフで、開発ボリュームにはDev Drive(非同期スキャン)というより安全な選択肢があります(6章)。67
- 「あの環境だけ遅い」の調査は、ProcmonのDuration列と
fltmcの構成比較からです(7章)。
この記事の知識マップ
現在のファイルシステムフィルターの標準はミニフィルターで、デバイススタックに直接デバイスオブジェクトを積むレガシーフィルターと違い、Windows付属のフィルターマネージャー(FltMgr)へpre/postコールバックを登録する方式です。呼ばれる順序はMicrosoftが割り当て管理するアルティチュードで決定的に決まり、fltmcコマンドで実際の構成を観察できます。ウイルス対策・Procmon・OneDriveのクラウド同期はいずれもこの同じ仕組みの住人で、除外設定は該当製品自身のスキャンを省略するだけで保護を弱めるトレードオフを伴い、開発ボリューム向けにはDev Driveというより安全な代替があります。
flowchart LR
accTitle: フィルタードライバーとミニフィルターの知識マップ
accDescr: ファイルシステムフィルタードライバー、レガシーフィルターからミニフィルターへの世代交代、フィルターマネージャー(FltMgr)、pre/postコールバック、アルティチュードとロード順グループ、fltmcによる観察、ウイルス対策ミニフィルターと除外設定・Dev Drive、Procmonがミニフィルターとして全I/Oを記録する仕組みの関係を示す図
minifilter["ミニフィルター"]
filter_manager["フィルターマネージャー(FltMgr)"]
legacy_filter_driver["レガシーフィルター"]
filesystem_filter_driver["ファイルシステムフィルタードライバー"]
device_stack["デバイススタック"]
load_order_instability["ロード順序の不安定さ"]
minifilter_callback["pre/postコールバック"]
altitude["アルティチュード"]
load_order_group["ロード順グループ"]
fltmc["fltmc"]
altitude_request["アルティチュードの申請"]
procmon["Process Monitor(procmon.exe)"]
antivirus_minifilter["ウイルス対策ミニフィルター"]
cloud_filter["クラウドファイルフィルター(cldflt)"]
onedrive_files_on_demand["OneDriveのファイルオンデマンド"]
fast_io["ファストI/O"]
scan_performance_cost["スキャンによる性能コスト"]
exclusion_setting["除外設定(フォルダー除外)"]
reduced_protection["保護レベルの低下"]
dev_drive["Dev Drive"]
frame["FltMgrフレーム"]
driver_object["ドライバーオブジェクト"]
legacy_filter_driver -->|"実装を担う"| filesystem_filter_driver
minifilter -->|"実装を担う"| filesystem_filter_driver
minifilter -->|"の後継"| legacy_filter_driver
legacy_filter_driver -->|"前提とする"| device_stack
legacy_filter_driver -->|"原因になり得る"| load_order_instability
minifilter -.->|"防止する"| load_order_instability
minifilter -->|"前提とする"| filter_manager
filter_manager -->|"利用する"| minifilter_callback
minifilter -->|"利用する"| minifilter_callback
minifilter -->|"で構成できる"| altitude
altitude -->|"で構成できる"| load_order_group
altitude -->|"で確認できる"| fltmc
altitude -.->|"前提とする"| altitude_request
altitude_request -->|"より先に行うべき"| minifilter
minifilter -->|"で確認できる"| fltmc
legacy_filter_driver -->|"で確認できる"| fltmc
procmon -->|"利用する"| minifilter
procmon -->|"利用する"| minifilter_callback
antivirus_minifilter -->|"利用する"| minifilter_callback
antivirus_minifilter -->|"で構成できる"| altitude
cloud_filter -->|"自動化する"| onedrive_files_on_demand
minifilter -.->|"利用する"| fast_io
antivirus_minifilter -.->|"原因になり得る"| scan_performance_cost
exclusion_setting -->|"軽減する"| scan_performance_cost
exclusion_setting -->|"原因になり得る"| reduced_protection
antivirus_minifilter -->|"で構成できる"| exclusion_setting
dev_drive -->|"軽減する"| scan_performance_cost
dev_drive -->|"軽減する"| reduced_protection
antivirus_minifilter -->|"推奨される対応"| dev_drive
filter_manager -->|"利用する"| frame
frame -->|"で確認できる"| fltmc
legacy_filter_driver -->|"利用する"| driver_object
minifilter -->|"利用する"| driver_object
filter_manager -->|"前提とする"| device_stack
filter_manager -->|"利用する"| driver_object
図の実線は常に成り立つ関係、破線は条件付きの関係です(成立条件は詳細ページの各関係の説明に記載)。関係すべての一覧(全35件、根拠・確度つき)と主要概念の定義は知識マップ詳細ページにまとめています。データ: JSON-LD / Turtle
2. 挟まる者たちの歴史 ── レガシーフィルターからFltMgrへ
ファイルシステムフィルタードライバーは、ファイルシステム(またはその下のボリューム)に向かう要求を横取りできるドライバーです。要求を記録し、監視し、内容を変更し、さらには拒否や代替処理までできる──ウイルス対策、暗号化、バックアップ、階層記憶といったソフトの土台です。1
古い実装方式(レガシーフィルター)は、第1回で見たデバイススタックに自分のデバイスオブジェクトを直接積む方式でした。仕組みとしては素直ですが、実務では問題だらけでした──積まれる順序はロード順に依存して保証しにくく、一度積んだら安全に抜けない(アンロードできない)、フィルター同士の相性バグの温床になる。
そこでWindowsはフィルターマネージャー(FltMgr)を導入しました。FltMgr自身がOS付属のフィルターとしてスタックに立ち、個々のフィルター機能はミニフィルターとしてFltMgrにコールバックを登録する方式です。2
flowchart TB
subgraph OLD["レガシー方式"]
L1["レガシーフィルターA"]
L2["レガシーフィルターB"]
LFS1["ファイルシステム"]
L1 --> L2
L2 --> LFS1
NOTE1["順序はロード順まかせ<br/>安全なアンロード不可"]
end
subgraph NEW["ミニフィルター方式(現在の標準)"]
FM["フィルターマネージャー(FltMgr)<br/>OS付属。スタックに立つのはこれだけ"]
M1["ミニフィルターA(アルティチュード高)"]
M2["ミニフィルターB(アルティチュード低)"]
LFS2["ファイルシステム"]
FM -. "コールバック登録" .- M1
FM -. "コールバック登録" .- M2
FM --> LFS2
NOTE2["順序はアルティチュードで決定的<br/>任意のタイミングでロード可<br/>(対応フィルターはアンロードも可)"]
end
図1: 世代交代。スタックに「積む」のではなく、FltMgrに「登録する」方式へ
ミニフィルター方式の利点は公式に列挙されています──いつでもロードでき、順序を制御でき、アンロードコールバックを実装したフィルターなら稼働中のアンロードもできる(実装していない・拒否するフィルターは外せません)。3 レガシーフィルターとの共存のためにFltMgrは複数の「フレーム」としてスタックの複数箇所に立つことができ、ミニフィルターはアンロード後の再ロードでも同じ位置(同じアルティチュード)に戻ることが保証されます。2 現代のウイルス対策・監視・同期ソフトは、ほぼすべてこのミニフィルターです。
3. ミニフィルターの動き ── pre/postコールバック
ミニフィルターは「どの操作に興味があるか」をFltMgrに宣言します。たとえば IRP_MJ_CREATE(開く)と IRP_MJ_WRITE(書く)にだけ興味がある、という具合です。すると、その操作が流れるたびに、操作の前(preコールバック)と操作の後(postコールバック)が呼ばれます。
sequenceDiagram
participant IOM as I/Oマネージャー
participant FM as FltMgr
participant A as ミニフィルターA<br/>(アルティチュード高)
participant B as ミニフィルターB<br/>(アルティチュード低)
participant FS as NTFS
IOM->>FM: 要求(IRP_MJ_CREATEなど。第1回の世界)
FM->>A: preコールバック
FM->>B: preコールバック
FM->>FS: ファイルシステムへ
FS-->>FM: 処理結果
FM-->>B: postコールバック
FM-->>A: postコールバック
FM-->>IOM: 完了(第1回の完了の流れへ)
図2: pre/postコールバック。行きはアルティチュードの高い順、帰りは逆順で呼ばれる
各コールバックで何ができるか。第1回4.3節の「ドライバーの3つの選択肢」と同じ構図が、より安全なAPIで提供されます。
flowchart TB
PRE["preコールバックが呼ばれた"]
Q{"この操作をどうするか"}
PASS["素通しする<br/>(postも要らなければそれも宣言)"]
DENY["拒否する<br/>アクセス拒否などを即座に返す<br/>例: ウイルス検出、書き込み禁止"]
DONE["自分で完了する<br/>例: クラウドフィルターが<br/>実体を取得して差し出す"]
MOD["パラメーターや内容に手を入れて流す<br/>例: 暗号化フィルター"]
PRE --> Q
Q --> PASS
Q --> DENY
Q --> DONE
Q --> MOD
図3: preコールバックの選択肢。「見る・止める・肩代わりする・書き換える」がすべて公式にできる
そして第4回の宿題がここで回収されます──ミニフィルターはファストI/O(IRPを作らない近道)にも立ち会えます。FltMgrがファストI/O経路にもコールバック機構を通しているためで、レガシー時代のように「近道を通られると見えない」ことがありません。Procmonのログに FASTIO_ の行まで並ぶのは、この立ち位置のおかげです。
4. アルティチュード ── 「標高」が順序を決める
複数のフィルターが同じ操作に興味を持つとき、誰が先に見るかは重大な問題です。暗号化より先にウイルス対策が見なければ暗号文をスキャンする羽目になり、監視ツールは全員より上にいなければ全体を観察できません。
この順序を決めるのがアルティチュード(altitude:標高)です。フィルターの種類ごとにロード順グループと番号帯が定義されています。正確に言うと、アルティチュードが付く単位はドライバー全体ではなく、ボリュームにアタッチされるミニフィルターの「インスタンス」です。番号は一意で、数字が大きいほどスタックの上(アプリ寄り)に位置します。4 1つのドライバーが複数のインスタンス定義を持ち、異なる標高に現れる構成も可能で、fltmc instances の一覧がインスタンス単位なのはこのためです。
flowchart TB
APP["アプリ寄り(数字が大きい)"]
G1["FSFilter Activity Monitor: 360000〜389999<br/>I/Oの観察・記録(Procmonはここ)"]
G2["FSFilter Undelete: 340000〜349999<br/>削除ファイルの復元"]
G3["FSFilter Anti-Virus: 320000〜329999<br/>ウイルスの検出・駆除"]
G4["FSFilter Replication: 300000〜309999<br/>リモートへの複製"]
G5["FSFilter Continuous Backup: 280000〜289999<br/>継続バックアップ"]
G6["さらに下へ: Content Screener /<br/>Quota Management / System Recovery /<br/>暗号化・圧縮などの帯が続く"]
FS["ファイルシステム寄り(数字が小さい)"]
APP --> G1 --> G2 --> G3 --> G4 --> G5 --> G6 --> FS
図4: アルティチュード帯(抜粋)。用途ごとに「立つべき標高」が決まっている
重要なのは、この番号がMicrosoftによって割り当て管理されていることです。5 ベンダーが勝手に名乗るのではなく申請して受け取る──だからどのPCでも「監視はウイルス対策より上、ウイルス対策は暗号化より上」という秩序が保たれます。レガシー時代の「ロード順ガチャ」への、これが答えでした。
自社でミニフィルターを作る場合の申請先。開発者向けに、次の一手だけ書いておきます。アルティチュードは Request a Filter Altitude Identifier の手順に従い、件名を「Filter altitude request」にして fsfcomm@microsoft.com へ英文メールを送って申請します。会社名・連絡先(個人ではなく長期利用できる会社のエイリアス)・製品名・製品URL・フィルターの説明・ドライバーのファイル名・フィルター種別・スタート種別・希望するロード順グループと希望アルティチュードを、すべて記入する必要があります。処理には30営業日を見込むこと、緊急扱いの窓口は無いこと、割り当てられる番号が希望と異なる場合があることも明記されています。8 なお、同じロード順グループにすでに整数のアルティチュードを持っている会社なら、その番号に小数を付けた値(例: 325000.3)を自分で決めてよく、その場合は事後にメールで連絡すれば足ります。8
5. 住人紹介 ── fltmcで見るあなたのPC
理屈はここまでにして、実物を見ましょう。管理者権限のコマンドプロンプトで:
:: 登録されているミニフィルターの一覧(アルティチュード付き)
fltmc
:: どのボリュームにどのフィルターが付いているか
fltmc instances
:: ボリューム側から見る
fltmc volumes
引数なしの fltmc は fltmc filters と同じ一覧を出します。出力は4列で、Microsoftのドキュメントにも同じ形式の例が載っています。9
C:\Windows\system32>fltmc
Filter Name Num Instances Altitude Frame
------------------------------ ------------- ------------ -----
bindflt 1 409800 0
cldflt 1 409500 0
WdFilter 4 328010 0
luafv 1 135000 0
FileInfo 4 45000 0
上は説明のための抜粋です。並ぶ顔ぶれとインスタンス数は環境ごとに違いますが、アルティチュードの数値はMicrosoftが割り当てた固定値なので、4章で触れた公開一覧と突き合わせられます。
列の意味はこうです。
| 列 | 意味 |
|---|---|
| Filter Name | フィルター(ドライバー)の名前 |
| Num Instances | いくつのボリュームにアタッチされているか(4章のインスタンスの数) |
| Altitude | アルティチュード。大きいほどアプリ寄り |
| Frame | FltMgrのフレーム番号。ここが <Legacy> なら、FltMgrを使わないレガシーフィルターが生きている印です。9 |
この5行だけでも、bindflt と cldflt が最上位のFSFilter Top帯(400000〜409999)、WdFilter がAnti-Virus帯(320000〜329999)、FileInfo が最下層のFSFilter Bottom帯(40000〜49999)にいることが読み取れます。4章で見た「用途ごとに立つべき標高が決まっている」構図が、そのまま数字で確認できるわけです。そして Procmonを起動してからもう一度 fltmc を実行すると、Activity Monitor帯(360000〜389999)に PROCMON で始まる行が1つ増えます。
環境によって顔ぶれは違いますが、典型的な住人はこの連載の常連ばかりです。
WdFilter── Microsoft Defenderのミニフィルター。Anti-Virus帯にいます。多くのPCで、すべてのファイルI/Oが必ず通る関所です。cldflt── クラウドファイルのフィルター。OneDriveのファイルオンデマンドの実行部隊で、第5回で見たリパースポイント(プレースホルダー)が開かれたときに実体を用意します。10PROCMON24(など) ── Process Monitorを起動している間だけ現れる、Activity Monitor帯の一時的なミニフィルター。Procmonが全I/Oを見られる種明かしはこれです。11 起動前後でfltmcを実行して比べてみてください。- そのほか、バックアップソフト、暗号化(情報漏えい対策)製品、EDR、仮想化ストレージなど──業務PCほど住人は増えます。
第1回から使ってきたProcmonという道具を、最終回で道具箱の外から眺め直すと、「観察者もまた、観察対象と同じ仕組みの住人だった」というきれいな循環になっています。
6. ウイルス対策はどこで時間を使うのか
フィルターの実務影響として最大のものが、ウイルス対策のスキャンコストです。どこで時間が発生するのかを図にします(製品により詳細は異なります。以下は典型形です)。
sequenceDiagram
participant App as アプリ
participant AV as AVミニフィルター
participant FS as NTFS
App->>AV: ファイルを開く
Note over AV: pre-create: パスやポリシーの事前判定
AV->>FS: 通す(オープンの実行)
FS-->>AV: オープン成立(post-create)
Note over AV: 未スキャンのファイルなら<br/>ここで中身をスキャンし<br/>問題があればオープンを取り消す<br/>── 開くのが遅くなる主因
AV-->>App: 問題なければハンドルが返る
App->>AV: 書き込み・閉じる
Note over AV: 変更されたファイルは<br/>クローズ時などに再スキャン対象へ
Note over App,FS: 大量の小ファイル(ビルドの中間生成物など)では<br/>この往復がファイル数ぶん積み重なる
図5: スキャンコストの発生地点。1ファイルあたりは僅かでも、数万ファイルなら支配的になる
これを踏まえると、2つの実務トピックが正確に理解できます。
除外設定の技術的意味。除外リストに一致するパスのI/Oでは、フィルターのスキャン処理が省略されます。フィルターがスタックから消えるわけではなく、「検査しない」という判断が早く行われるようになる、というのが実態です。そしてもうひとつ大事な限定があります──除外が効くのは、その設定を持つ製品自身のフィルターだけです。Microsoft Defenderの除外設定が変えるのは WdFilter のスキャンであって、同居している他のミニフィルター(他社ウイルス対策・EDR・バックアップ・暗号化など)の動作には何の影響もありません。「除外を入れたのに遅いままだ」というときは、別の住人が時間を使っている可能性を疑ってください(7章の fltmc 比較)。効果は大きい一方、除外はその場所の保護を確実に弱めます。Microsoftのドキュメントも、除外は防御を減らすためリスク評価の上で最小限に、と繰り返し警告しています。6 誤検知対応と性能影響の実務は「自社開発のWindowsアプリがウイルス扱いされたら」で扱いました。
Dev Driveという新しい答え。開発ワークロード(大量小ファイル)のために設計された専用ボリュームで、Microsoft Defenderがパフォーマンスモード(非同期スキャン)で動作します。フォルダー除外のより安全な代替と位置付けられており、既定では追加のフィルターがアタッチされない一方、フィルターを全部外して運用することへの強い警告も明記されています。7 「ビルドを速くしたいが除外は怖い」への、現在のMicrosoftの推奨解です。
7. 「あの環境だけ遅い」の調査手順
連載で積み上げた道具を、最後に1本の手順にまとめます。
flowchart TB
S["症状: 同じアプリなのに特定環境だけ<br/>ファイルアクセスが遅い"]
P1["ProcmonでDuration列を見る<br/>どの操作(IRP_MJ_CREATE? WRITE?)に<br/>時間が消えているか"]
Q1{"特定の操作が一様に遅い?"}
F1["fltmc instances を速い環境と比較<br/>フィルター構成の差分を見る"]
Q2{"差分のフィルターが原因?"}
A1["除外設定(リスク評価つき)や<br/>Dev Driveの検討・ベンダーへの相談"]
A2["フィルター以外を疑う:<br/>キャッシュ(第4回)・断片化やMFT(第5回)・<br/>ネットワーク先(UNC)・デバイス自体"]
S --> P1 --> Q1
Q1 -->|"はい"| F1 --> Q2
Q2 -->|"はい"| A1
Q2 -->|"いいえ"| A2
Q1 -->|"いいえ(散発的)"| A2
図6: フィルター起因の遅さの切り分け。鍵は「操作単位の所要時間」と「環境間のフィルター構成差分」
ポイントは2つです。第一に、Procmonは操作ごとの所要時間(Duration)を持っています。「遅い」を「どの操作が遅い」に分解できれば、犯人探しは半分終わりです。第二に、環境差はフィルター構成の差であることが多い。開発機と本番機、自社PCと客先PC──fltmc の出力を並べるだけで、疑うべき候補が見えてきます。
Procmonを触ったことがない場合の最初の3手。Duration列は既定では表示されていないので、ここで止まらないように操作だけ書いておきます。
- 管理者として
Procmon.exeを起動する。 - Options メニュー > Select Columns… を開き、列の一覧から Duration にチェックを入れる。
- Filter メニュー > Filter…(Ctrl+L) で
Process Name/is/ 対象のexe名 /Includeを入力し、Add ボタンを押してから OK する(Addを押さないと条件が入りません)。
そのうえで Duration 列をクリックしてソートすれば、時間を食っている操作が上に集まります。プロセス単位・ファイル単位の集計なら Tools メニュー > File Summary も使えます。ProcMonの操作全般は「Process Monitor(ProcMon)実践ガイド」にまとめています。
8. 連載の総仕上げ ── 6回の地図
これで、第1回に描いた地図のすべての箱を開けました。全体を1枚にします。
flowchart TB
APP["アプリケーション<br/>ReadFile / WriteFile / async-await"]
API["第2回: 同期・非同期I/O<br/>ハンドルのモードとOVERLAPPED"]
IOCP["第3回: IOCPと.NETスレッドプール<br/>完了の受け取りと継続の実行"]
IOM["第1回: I/OマネージャーとIRP<br/>名前解決・3つのオブジェクト・デバイススタック"]
FLT["第6回: フィルターとミニフィルター<br/>FltMgr・アルティチュード・pre/post"]
CACHE["第4回: キャッシュマネージャー<br/>256KBビュー・lazy writer・ファストI/O<br/>(NTFSと協調して働く)"]
NTFS["第5回: NTFS<br/>MFT・ストリーム・リンク・2つのジャーナル"]
HW["ストレージスタックとデバイス"]
APP --> API
API --> IOM
IOCP -. "完了はここへ戻る" .-> APP
IOM --> FLT
FLT --> NTFS
NTFS -. "キャッシュ有効I/Oは協調<br/>(ファイルシステムがキャッシュ機能を呼ぶ)" .- CACHE
NTFS --> HW
HW -. "割り込み→完了(第1回)" .-> IOCP
図7: 連載全体の地図。キャッシュマネージャーは「通過する層」ではなくファイルシステムと協調する相棒で、キャッシュミス時にNTFSからストレージへの要求が出る
- 第1回: 全体像 ── すべての読み書きはIRPになる
- 第2回: 同期/非同期 ── OVERLAPPEDの本当の意味
- 第3回: IOCP ── async/awaitの地下室
- 第4回: キャッシュ ── あなたのWriteFileはいつディスクに届くのか
- 第5回: NTFS ── MFTから理解するファイルシステム
- 第6回: フィルターとミニフィルター(本記事) ── ProcmonとウイルススキャンがI/Oに割り込める理由
9. まとめ ── 連載の結びに
最終回のまとめです。
- I/Oへの割り込みはOS公認の拡張点で、現在の標準はFltMgrへのコールバック登録(ミニフィルター)です。順序はアルティチュードで決定的に決まり、Microsoftが番号を割り当て管理しています。245
- 動きはpre/postコールバック。素通し・拒否・肩代わり・書き換えができ、ファストI/Oにも立ち会えます。ProcmonもDefenderもOneDriveも、この同じ仕組みの住人です。11110
- 除外設定=スキャンの省略であり、保護とのトレードオフです。開発ボリュームにはDev Drive(非同期スキャン)というより安全な選択肢があります。67
- 「あの環境だけ遅い」は、ProcmonのDurationと
fltmcの構成差分から切り分ける──連載の道具がそのまま調査手順になります。
そして連載全体の結論を一行で言うなら、こうなります──WindowsのI/Oは、名前空間で宛先を決め、要求をパケット(IRP)にして層の間を流し、各層が「見る・預かる・肩代わりする」を選べるように作られた、一貫した設計である。File.ReadAllText の1行の下に、この6回ぶんの構造が毎回動いています。APIの挙動を暗記する代わりに、この地図から「そうなるはずだ」と導ける──それがこの連載で手に入れてほしかった力です。長い旅にお付き合いいただき、ありがとうございました。
関連記事
- Windows I/Oの深層(第1回) ── すべての読み書きはIRPになる:I/Oシステムの全体像
- Windows I/Oの深層(第4回) ── キャッシュマネージャー:あなたのWriteFileはいつディスクに届くのか
- Windows I/Oの深層(第5回) ── NTFSの内部構造:MFTから理解するファイルシステム
- Process Monitor(ProcMon)実践ガイド ── 「設定が読まれない」「ACCESS DENIED」を10分で特定する
- 自社開発のWindowsアプリがウイルス扱いされたら ── Microsoft Defenderの誤検知対応と、性能影響との付き合い方
- Process Explorer / Handle / VMMap実践 ── ハング・リーク・「ファイルが使用中」を今この瞬間の状態から追う
- Windowsアプリのセキュリティ最小チェックリスト
関連する相談領域
合同会社小村ソフトでは、「特定の環境でだけ遅い」「セキュリティソフトと自社アプリが干渉する」といった、フィルタードライバーが絡むWindows業務アプリの性能問題・不具合の調査を扱っています。
参考リンク
-
Microsoft Learn, About file system filter drivers. ファイルシステムフィルタードライバーが、ファイルシステムまたは他のフィルタードライバーに向かう要求を横取り(インターセプト)できるオプションのドライバーであること、要求を横取りすることで元の宛先に渡る前に機能を拡張・置換でき、要求の記録・監視・データの変更・動作の防止ができること、ウイルス対策ユーティリティ・暗号化プログラム・階層記憶管理システムなどがフィルタードライバーの例であることについて。 ↩ ↩2 ↩3
-
Microsoft Learn, Filter Manager Concepts. フィルターマネージャー(FltMgr)がWindowsに付属するカーネルモードドライバーであり、ミニフィルタードライバーの開発を簡素化する機能を公開すること、ミニフィルターがI/O操作の前後(pre/postコールバック)に処理を登録できること、レガシーフィルターとの共存のためにFltMgrがフレームとしてI/Oスタックの複数箇所にアタッチできること、ミニフィルターがアンロード・再ロードされても同じフレームの同じアルティチュードに戻ることについて。 ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Advantages of the Filter Manager Model. ミニフィルターモデルがレガシーフィルターモデルに対して持つ利点として、フィルターのロード順のより良い制御ができること、レガシーフィルターと異なりミニフィルターは任意の時点でロードできること、アンロードが可能なこと、DAXボリュームへの接続などが挙げられていることについて。 ↩ ↩2
-
Microsoft Learn, Load order groups and altitudes for minifilter drivers. ファイルシステムフィルター用に用途別のロード順グループが定義され、各グループにアルティチュードの範囲が割り当てられていること、すべてのフィルタードライバーが一意のアルティチュード識別子を持ち、それがI/Oスタック内での他のフィルターに対する相対位置を定めること、グループの例としてFSFilter Activity Monitor(360000〜389999、I/Oの観察と報告)、FSFilter Undelete(340000〜349999)、FSFilter Anti-Virus(320000〜329999、ファイルI/O中のウイルス検出と駆除)、FSFilter Replication(300000〜309999)、FSFilter Continuous Backup(280000〜289999)などがあることについて。 ↩ ↩2 ↩3
-
Microsoft Learn, Allocated altitudes. ミニフィルターのアルティチュードがMicrosoftによって割り当て・管理されており、公開されている割り当て済みアルティチュードの一覧が維持されていること、その一覧にWdFilter.sysがFSFilter Anti-Virusグループの328010、cldflt.sysがFSFilter Topグループの409500として掲載されていることについて。 ↩ ↩2 ↩3
-
Microsoft Learn, Configure and validate exclusions for Microsoft Defender Antivirus. Microsoft Defenderの除外設定により、除外対象のファイル・フォルダー・プロセスがスキャンの対象から外れること、除外は保護レベルを下げるため、必要性を評価した上で慎重に定義すべきであると繰り返し注意されていることについて。 ↩ ↩2 ↩3
-
Microsoft Learn, Set up a Dev Drive on Windows 11. Dev Driveが開発ワークロード向けに設計されたボリュームであり、Microsoft Defenderがパフォーマンスモード(非同期スキャン)で動作すること、これが速度と性能を考慮しつつフォルダー除外の安全な代替(secure alternative to folder exclusions)として位置付けられていること、追加のフィルターは既定でDev Driveにアタッチされないこと、ウイルス対策フィルターを外した運用は重大なセキュリティリスクであると警告されていることについて。 ↩ ↩2 ↩3
-
Microsoft Learn, Request a Filter Altitude Identifier. 新しいフィルターアルティチュードの申請が、件名「Filter altitude request」のASCIIテキストメールをfsfcomm@microsoft.comへ送る方法で行われること、会社名・連絡先メール(個人ではなく長期の会社エイリアス)・製品名・製品URL・フィルターの説明・フィルターのファイル名・フィルター種別・スタート種別・希望するロード順グループ・希望アルティチュードのすべての項目を記入する必要があること、処理に30営業日を見込むべきでこの手順以外に申請の窓口がないこと、Microsoftが希望と異なるアルティチュードを割り当てる場合があること、すでに整数アルティチュードを持つ場合は同じロード順グループ内で小数を付けた独自のアルティチュードを作成でき事後連絡でよいことについて。 ↩ ↩2
-
Microsoft Learn, Blocking legacy file system filter drivers. 管理者権限のコマンドプロンプトで
fltmc filtersを実行すると「Filter Name / Num Instances / Altitude / Frame」の4列でフィルターが一覧されること、Frame列が<Legacy>になっているものがFltMgrを介さないレガシーファイルシステムフィルタードライバーであり、ミニフィルターではFrameに数値(0など)が入ることについて。 ↩ ↩2 -
Microsoft Learn, Cloud Files API. クラウドファイルAPI(クラウドフィルター)が、クラウド上のファイルをプレースホルダーとしてローカルに見せ、アクセス時に実体を取得する同期エンジン(OneDriveのファイルオンデマンド等)の土台であることについて。 ↩ ↩2
-
Microsoft Learn, Process Monitor - Sysinternals. Process Monitorがファイルシステム・レジストリ・プロセス/スレッドの活動をリアルタイムに表示する高度な監視ツールであることについて(本文のとおり、動作中はfltmcの一覧にミニフィルターとして現れることが観察できる)。 ↩ ↩2
関連する記事
同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。
Windows I/Oの深層(第1回) ── すべての読み書きはIRPになる:I/Oシステムの全体像
WindowsのI/Oシステムを底から解説する連載の第1回です。オブジェクトマネージャーの名前空間、ドライバー・デバイス・ファイルの3つのオブジェクト、IRPのライフサイクル、CloseHandleの裏側までを図解で整理します。
Windows I/Oの深層(第5回) ── NTFSの内部構造:MFTから理解するファイルシステム
NTFSの内部構造を図解で解説する連載の第5回です。MFTとファイルレコード、複数データストリーム(Zone.Identifier)、ハードリンクと8.3名、リパースポイント、2つのジャーナル、スパースと圧縮までを開発者視点で整理します。
Windows I/Oの深層(第4回) ── キャッシュマネージャー:あなたのWriteFileはいつディスクに届くのか
Windowsのキャッシュマネージャーを図解で解説する連載の第4回です。ファイルマッピングとして実装されたキャッシュ、先読みと遅延書き込み、FlushFileBuffersやFILE_FLAG_NO_BUFFERINGの使い分け、電源断でデータが消える条件までを整理します。
Windows I/Oの深層(第2回) ── 同期I/Oと非同期I/O:OVERLAPPEDの本当の意味
Windowsの同期I/Oと非同期I/O(オーバーラップI/O)を図解で解説する連載の第2回です。FILE_FLAG_OVERLAPPEDの意味、完了通知の4方式、非同期のはずが同期完了する条件、キャンセルの作法、.NETとの対応までを整理します。
Windows I/Oの深層(第3回) ── I/O完了ポート(IOCP)と.NETスレッドプール:async/awaitの地下室
I/O完了ポート(IOCP)を図解で解説する連載の第3回です。完了キューとスレッド数制御を一体化した設計、コンカレンシー値とLIFO解放、.NETスレッドプールとasync/await継続の実行スレッドまでを整理します。
関連トピック
このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。
Windows技術トピック
Windows 開発、不具合調査、既存資産活用の技術トピックをまとめた入口です。
不具合調査 / 長期稼働テーマ
再現しにくい不具合、通信停止、長期稼働障害、失敗パス検証を整理するトピックです。
このテーマがつながるサービス
この記事は次のサービスページにつながります。近い入口からご覧ください。
Windowsアプリ開発
業務アプリ、装置連携、通信ツールなどの Windows ソフト開発を支援します。
不具合調査・原因解析
再現しにくい障害、長期稼働後の不具合、通信停止などの調査を支援します。
よくある質問
この記事のテーマについて、相談時によくある質問をまとめています。
- ファイルシステムフィルタードライバーとミニフィルターは何が違いますか?
- どちらも「ファイルシステムへのI/O要求に割り込むドライバー」ですが、割り込み方の世代が違います。古いレガシーフィルターは、ファイルシステムのデバイススタックに自分のデバイスオブジェクトを直接積み重ねる方式で、読み込み順で位置が決まるため順序が保証しにくく、一度ロードしたら安全にアンロードできないなどの問題がありました。現在の標準であるミニフィルターは、Windows付属のフィルターマネージャー(FltMgr)に「この操作の前後で呼んでほしい」とコールバックを登録する方式です。位置はアルティチュードという番号で決定的に決まり、任意のタイミングでロードでき、アンロードコールバックを実装したフィルターなら稼働中に取り外すこともできます。ウイルス対策・暗号化・監視ツール・クラウド同期など現代のフィルターはほぼすべてミニフィルターとして実装されています。
- なぜウイルス対策ソフトはすべてのファイルアクセスを検査できるのですか?
- OSが公式にそのための拡張点を用意しているからです。ミニフィルターは、ファイルを開く・読む・書くといった操作の前(preコールバック)と後(postコールバック)に呼び出されるコードをフィルターマネージャーに登録できます。ウイルス対策のフィルターはアンチウイルス用のアルティチュード帯(320000〜329999)に位置し、たとえばファイルのオープンが成立した直後(post-create)に中身をスキャンし、問題があればそのオープンを取り消してアクセスを失敗させることができます。連載第1回で見たとおり、すべてのファイルI/Oはデバイススタックを流れるので、その通り道の決まった位置に立てば全アクセスを検査できる、という理屈です。ハックではなく、OSの設計に組み込まれた仕組みです。
- ウイルス対策ソフトの除外設定(フォルダー除外)は技術的に何をしているのですか?
- 除外リストに一致するパスへのI/Oについて、その製品のフィルターが行うスキャン処理を省略させています。フィルター自体がスタックから消えるわけではなく、「このパスは検査しない」という判断が早期に行われるようになる、というのが実態に近い理解です。重要な限定として、除外が効くのはその設定を持つ製品自身だけです。たとえばMicrosoft Defenderの除外設定が変えるのはDefenderのフィルター(WdFilter)のスキャンであって、同居する他社ウイルス対策・EDR・バックアップなど他のミニフィルターの動作には影響しません。製品ごとに個別の除外設定が必要で、「除外したのに遅いまま」の場合は別のフィルターが原因のことがあります。またMicrosoftのドキュメントが繰り返し警告するとおり、除外はその場所の保護を弱めるため、リスク評価とセットで最小限にすべきです。開発用途では、フォルダー除外の安全な代替として設計されたDev Drive(パフォーマンスモード=非同期スキャン)の検討も価値があります。
- Process Monitorはどうやって全部のI/Oを記録しているのですか?
- Procmon自身が、起動時にActivity Monitor(活動監視)用のアルティチュード帯のミニフィルターとして自分をフィルターマネージャーに登録するからです。Procmonを起動した状態で管理者権限のコマンドプロンプトからfltmcを実行すると、PROCMONで始まる名前のフィルターが一覧に現れるのが確認できます。ミニフィルターとして全ボリュームのI/O操作のpre/postに立ち会えるため、どのプロセスがどのファイルにどんな操作をしたかを漏れなく記録できます。連載で見てきたIRPやファストI/Oの用語がProcmonの表示にそのまま出てくるのは、まさにI/Oの通り道そのものに立って観察しているからです。
- 開発マシンのビルドが遅いとき、フィルタードライバーを疑うべきですか?
- 疑う価値は大いにあります。ビルドは大量の小ファイルの作成・読み書き・削除の塊で、その1つ1つがフィルター群(特にウイルス対策のスキャン)の検査対象になるため、フィルターのコストが最も表面化しやすいワークロードです。調査はProcmonでDuration列を見て時間がどの操作に消えているかを確認し、fltmc instancesで環境ごとのフィルター構成の差を比較するのが基本手順です。対策としては、リスクを評価した上での除外設定のほか、開発ボリューム専用に設計されたDev Driveの利用が挙げられます。Dev Driveではウイルス対策がパフォーマンスモード(非同期スキャン)で動作し、除外設定より安全な代替になるとMicrosoftが位置付けています。