수정 이력(5건, 최종 수정 2026년 09월 03일)
이 글에 적용한 변경 사항의 기록입니다. 보관해 둔 수정 전 버전은 DOI가 부여된 고정 URL에서 읽을 수 있습니다.
- Codex 리뷰에 따라 상담·문의 링크에 /ko/ 로케일 접두를 붙였습니다. 본문의 기술적인 주장은 바꾸지 않았습니다.
- permalink·저자 표기·지식 맵 래퍼·깨진 내부 링크 등 CI가 지적한 표시용 수정을 반영했습니다. 본문의 기술적인 주장은 바꾸지 않았습니다.
- 이 기사의 지식 맵에 포함된 관계를 재검토했습니다. 본문보다 넓은 주장이 되어 있던 것(조건부일 때만 성립하는 관계, 「막는다」가 아니라 「완화한다」에 해당하는 관계, 전제가 아니라 권장에 해당하는 관계)을 조건부로 고치거나 더 정확한 서술로 바꿨습니다. 본문의 주장은 바꾸지 않았습니다.
- 기사 앞에 「이 기사의 지식 맵」을 추가했습니다. 본문에서 다루는 개념 사이의 관계를 한 장의 그림으로 볼 수 있습니다. 관계의 전체 목록(근거 URL·확신도·확인일 포함)과 주요 개념의 정의는 지식 맵 상세 페이지에 모았고, 기계 가독 데이터를 JSON-LD와 Turtle로 공개합니다.
- `fltmc` 출력의 열 구성과 읽는 법을 추가했습니다(게재한 값은 Microsoft가 공개한 altitude 할당 목록의 것이며, 실제 기기 출력이 아닙니다). altitude 신청 절차와 신청처, Process Monitor에서 처음 할 3단계, 연재 링크 레이블 정리를 추가했습니다.
- 최초 공개
이 글을 인용하기(DOI(등록된 아카이브): 10.5281/zenodo.22175400)
아래 DOI는 이전에 등록된 아카이브를 가리키며 현재 본문과 다를 수 있습니다. 현재 본문을 참조할 때는 이 페이지의 URL을 사용하세요.
Go Komura (2026). 「Windows I/O의 심층(제6회·최종회) ── 필터 드라이버와 minifilter: Procmon과 바이러스 검사가 I/O에 끼어들 수 있는 이유」. 합동회사 코무라소프트. https://comcomponent.com/ko/blog/windows-minifilter-filter-drivers/
- DOI(등록된 아카이브)
- 10.5281/zenodo.22175400
- DOI(마지막 등록 버전)
- 10.5281/zenodo.22175401
연재 「Windows I/O의 심층」, 최종회입니다.
제1회의 device stack 그림에 「파일 시스템 필터(바이러스 백신·암호화·Procmon 등)」라는 상자를 그린 뒤, 이 연재에는 사이에 끼는 존재들이 여러 번 등장했습니다. Procmon이 모든 I/O를 기록할 수 있는 이유(제1회). 「그 환경에서만 파일 접근이 느리다」(제2회). 열린 순간에 OneDrive가 다운로드를 시작하는 reparse point(제5회). 이번에는 그 끼어드는 구조 자체──파일 시스템 필터 드라이버와 minifilter──를 정면에서 다루고, 연재의 복선을 모두 회수합니다.
1. 먼저 결론
- 「I/O에 끼어든다」는 OS가 공인한 확장 지점입니다. 파일 시스템 필터는 파일 시스템에 대한 요청을 보고, 다시 쓰고, 거부하고, 대신 처리할 수 있습니다(2장).1
- 현재 표준은 minifilter입니다. device stack에 직접 끼어드는 legacy 방식의 문제(순서 불확정·unload 불가)를 해결하기 위해, Windows에 포함된 Filter Manager(FltMgr)에 callback을 등록하는 방식으로 세대가 바뀌었습니다(2장).23
- 동작은 pre/post callback입니다. 각 작업의 전과 후에, 등록 순서=altitude 순서로 호출됩니다. 통과·완료·거부·재작성──제1회에서 본 「드라이버의 선택지」가 그대로 쓰입니다(3장).2
- altitude(고도)가 순서를 정합니다. 용도별 그룹에 번호 대역이 할당되고(Activity Monitor 360000〜389999, Anti-Virus 320000〜329999 등), 볼륨에 attach되는 instance마다 고유 번호가 붙습니다(4장).45
- 사용 중인 PC의 구성원은
fltmc로 볼 수 있습니다. Procmon(실행 중일 때만), 바이러스 백신, OneDrive의 클라우드 필터──모두 여기에 줄 섭니다(5장). - 바이러스 백신의 제외 설정은 「그 제품 자신의 스캔 생략」이며, 다른 minifilter에는 영향을 주지 않습니다. 제외는 보호를 약화하는 트레이드오프이고, 개발 볼륨에는 Dev Drive(비동기 스캔)라는 더 안전한 선택지가 있습니다(6장).67
- 「그 환경에서만 느린」 조사는 Procmon의 Duration 열과
fltmc의 구성 비교에서 시작합니다(7장).
그림의 실선은 항상 성립하는 관계, 점선은 조건이 붙는 관계입니다(성립 조건은 상세 페이지의 관계별 설명에 적혀 있습니다). 관계 전체 목록(총 34건, 근거와 확신도 포함)과 주요 개념의 정의는 지식 맵 상세 페이지에 정리되어 있습니다(일본어). 데이터: JSON-LD / Turtle
2. 사이에 끼는 존재들의 역사 ── legacy filter에서 FltMgr로
파일 시스템 필터 드라이버는 파일 시스템(또는 그 아래 볼륨)으로 향하는 요청을 가로챌 수 있는 드라이버입니다. 요청을 기록하고, 감시하고, 내용을 바꾸며, 거부나 대체 처리까지 할 수 있습니다──바이러스 백신, 암호화, 백업, hierarchical storage 같은 소프트웨어의 기반입니다.1
오래된 구현 방식(legacy filter)은 제1회에서 본 device stack에 자신의 device object를 직접 쌓는 방식이었습니다. 구조로는 단순하지만, 실무에서는 문제가 많았습니다──쌓이는 순서는 로드 순서에 의존해 보장하기 어렵고, 한 번 쌓으면 안전하게 빠질 수 없으며(unload 불가), 필터 간 호환 버그의 온상이 됩니다.
그래서 Windows는 Filter Manager(FltMgr)를 도입했습니다. FltMgr 자신이 OS에 포함된 필터로서 stack에 서고, 개별 필터 기능은 minifilter로서 FltMgr에 callback을 등록하는 방식입니다.2
flowchart TB
subgraph OLD["legacy 방식"]
L1["legacy filter A"]
L2["legacy filter B"]
LFS1["파일 시스템"]
L1 --> L2
L2 --> LFS1
NOTE1["순서는 로드 순서에 맡김<br/>안전한 unload 불가"]
end
subgraph NEW["minifilter 방식(현재 표준)"]
FM["Filter Manager(FltMgr)<br/>OS 포함. stack에 서는 것은 이것뿐"]
M1["minifilter A(altitude 높음)"]
M2["minifilter B(altitude 낮음)"]
LFS2["파일 시스템"]
FM -. "callback 등록" .- M1
FM -. "callback 등록" .- M2
FM --> LFS2
NOTE2["순서는 altitude로 결정적<br/>임의의 시점에 로드 가능<br/>(대응하는 필터는 unload도 가능)"]
end
그림 1: 세대 교체. stack에 「쌓는」 방식이 아니라 FltMgr에 「등록하는」 방식으로
minifilter 방식의 이점은 공식으로 열거되어 있습니다──언제든 로드할 수 있고, 순서를 제어할 수 있으며, unload callback을 구현한 필터라면 가동 중 unload도 가능합니다(구현하지 않거나 거부하는 필터는 분리할 수 없습니다).3 legacy filter와의 공존을 위해 FltMgr는 여러 「frame」으로 stack의 여러 지점에 설 수 있고, minifilter는 unload 후 다시 로드해도 같은 위치(같은 altitude)로 돌아가는 것이 보장됩니다.2 현대의 바이러스 백신·감시·동기화 소프트웨어는 거의 모두 이 minifilter입니다.
3. minifilter의 동작 ── pre/post callback
minifilter는 「어느 작업에 관심이 있는지」를 FltMgr에 선언합니다. 예를 들어 IRP_MJ_CREATE(열기)와 IRP_MJ_WRITE(쓰기)에만 관심이 있다는 식입니다. 그러면 그 작업이 흐를 때마다 작업 전(pre callback)과 작업 후(post callback)가 호출됩니다.
sequenceDiagram
participant IOM as I/O Manager
participant FM as FltMgr
participant A as minifilter A<br/>(altitude 높음)
participant B as minifilter B<br/>(altitude 낮음)
participant FS as NTFS
IOM->>FM: 요청(IRP_MJ_CREATE 등. 제1회의 세계)
FM->>A: pre callback
FM->>B: pre callback
FM->>FS: 파일 시스템으로
FS-->>FM: 처리 결과
FM-->>B: post callback
FM-->>A: post callback
FM-->>IOM: 완료(제1회의 완료 흐름으로)
그림 2: pre/post callback. 갈 때는 altitude가 높은 순, 돌아올 때는 역순으로 호출됩니다
각 callback에서 무엇을 할 수 있는가. 제1회 4.3절의 「드라이버의 세 가지 선택지」와 같은 구도가, 더 안전한 API로 제공됩니다.
flowchart TB
PRE["pre callback이 호출됨"]
Q{"이 작업을 어떻게 할 것인가"}
PASS["통과시킨다<br/>(post도 필요 없으면 그것도 선언)"]
DENY["거부한다<br/>액세스 거부 등을 즉시 반환<br/>예: 바이러스 검출, 쓰기 금지"]
DONE["스스로 완료한다<br/>예: 클라우드 필터가<br/>실체를 가져와 내놓는다"]
MOD["매개변수나 내용에 손을 댄 뒤 흘린다<br/>예: 암호화 필터"]
PRE --> Q
Q --> PASS
Q --> DENY
Q --> DONE
Q --> MOD
그림 3: pre callback의 선택지. 「보기·멈추기·대신하기·다시 쓰기」가 모두 공식적으로 가능합니다
그리고 제4회의 숙제가 여기서 회수됩니다──minifilter는 fast I/O(IRP를 만들지 않는 지름길)에도 함께할 수 있습니다. FltMgr가 fast I/O 경로에도 callback 구조를 통과시키기 때문이며, legacy 시대처럼 「지름길을 타면 보이지 않는」 일이 없습니다. Procmon 로그에 FASTIO_ 행까지 늘어서는 것은 이 위치 덕분입니다.
4. altitude ── 「고도」가 순서를 정한다
여러 필터가 같은 작업에 관심을 가질 때 누가 먼저 보는가는 중대한 문제입니다. 암호화보다 먼저 바이러스 백신이 보지 않으면 암호문을 스캔하게 되고, 감시 도구는 모두보다 위에 있지 않으면 전체를 관찰할 수 없습니다.
이 순서를 정하는 것이 altitude(고도)입니다. 필터 종류마다 load order group과 번호 대역이 정의되어 있습니다. 정확히 말하면 altitude가 붙는 단위는 드라이버 전체가 아니라, 볼륨에 attach되는 minifilter의 「instance」입니다. 번호는 고유하고, 숫자가 클수록 stack의 위(앱 쪽)에 위치합니다.4 하나의 드라이버가 여러 instance 정의를 갖고 서로 다른 고도에 나타나는 구성도 가능하며, fltmc instances 목록이 instance 단위인 것은 이 때문입니다.
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: altitude 대역(발췌). 용도마다 「서야 할 고도」가 정해져 있습니다
중요한 점은 이 번호가 Microsoft가 할당·관리한다는 것입니다.5 벤더가 마음대로 자칭하는 것이 아니라 신청해서 받습니다──그래서 어느 PC에서든 「감시는 바이러스 백신보다 위, 바이러스 백신은 암호화보다 위」라는 질서가 유지됩니다. legacy 시대의 「로드 순서가 운에 맡겨지던 문제」에 대한 답이 이것이었습니다.
자사에서 minifilter를 만들 때의 신청처. 개발자를 위해 다음 단계만 적어 둡니다. altitude는 Request a Filter Altitude Identifier의 절차를 따라, 제목을 「Filter altitude request」로 하고 fsfcomm@microsoft.com에 영문 메일로 신청합니다. 회사명·연락처(개인이 아니라 장기 사용할 수 있는 회사 alias)·제품명·제품 URL·필터 설명·드라이버 파일명·필터 종류·시작 종류·희망 load order group과 희망 altitude를 모두 기입해야 합니다. 처리에는 30영업일을 잡을 것, 긴급 취급 창구는 없다는 것, 할당되는 번호가 희망과 다를 수 있다는 것도 명시되어 있습니다.8 같은 load order group에 이미 정수 altitude를 가진 회사라면, 그 번호에 소수를 붙인 값(예: 325000.3)을 스스로 정해도 되며, 그 경우는 사후에 메일로 알리면 됩니다.8
5. 구성원 소개 ── fltmc로 보는 사용 중인 PC
이론은 여기까지 하고, 실물을 봅시다. 관리자 권한 명령 프롬프트에서:
:: 등록된 minifilter 목록(altitude 포함)
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
위는 설명을 위한 발췌입니다. 늘어선 구성원과 instance 수는 환경마다 다르지만, altitude 수치는 Microsoft가 할당한 고정값이므로 4장에서 다룬 공개 목록과 대조할 수 있습니다.
열의 의미는 다음과 같습니다.
| 열 | 의미 |
|---|---|
| Filter Name | 필터(드라이버) 이름 |
| Num Instances | 몇 개의 볼륨에 attach되어 있는지(4장의 instance 수) |
| Altitude | altitude. 클수록 앱 쪽 |
| Frame | FltMgr의 frame 번호. 여기가 <Legacy>이면 FltMgr를 쓰지 않는 legacy filter가 살아 있는 표시입니다.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으로 시작하는 행이 하나 늘어납니다.
환경에 따라 구성원은 다르지만, 전형적인 구성원은 이 연재의 단골뿐입니다.
WdFilter── Microsoft Defender의 minifilter. Anti-Virus 대역에 있습니다. 많은 PC에서 모든 파일 I/O가 반드시 통과하는 관문입니다.cldflt── 클라우드 파일 필터. OneDrive 파일 온디맨드의 실행 부대로, 제5회에서 본 reparse point(placeholder)가 열릴 때 실체를 준비합니다.10PROCMON24(등) ── Process Monitor를 실행하는 동안에만 나타나는, Activity Monitor 대역의 일시적 minifilter. Procmon이 모든 I/O를 볼 수 있는 정체는 이것입니다.11 시작 전후에fltmc를 실행해 비교해 보십시오.- 그 밖에 백업 소프트웨어, 암호화(정보 유출 대책) 제품, EDR, 가상화 스토리지 등──업무 PC일수록 구성원은 늘어납니다.
제1회부터 써 온 Procmon이라는 도구를 최종회에서 도구 상자 밖에서 다시 보면, 「관찰자 또한 관찰 대상과 같은 구조의 구성원이었다」는 깔끔한 순환이 됩니다.
6. 바이러스 백신은 어디에서 시간을 쓰는가
필터의 실무 영향으로 가장 큰 것이 바이러스 백신의 스캔 비용입니다. 어디에서 시간이 생기는지를 그림으로 그립니다(제품에 따라 세부는 다릅니다. 아래는 전형입니다).
sequenceDiagram
participant App as 앱
participant AV as AV minifilter
participant FS as NTFS
App->>AV: 파일을 연다
Note over AV: pre-create: 경로나 정책의 사전 판정
AV->>FS: 통과(open 실행)
FS-->>AV: open 성립(post-create)
Note over AV: 미검사 파일이면<br/>여기서 내용을 스캔하고<br/>문제가 있으면 open을 취소한다<br/>── 열기가 느려지는 주된 원인
AV-->>App: 문제가 없으면 handle이 돌아온다
App->>AV: 쓰기·닫기
Note over AV: 변경된 파일은<br/>close 시 등에 재스캔 대상이 된다
Note over App,FS: 대량의 작은 파일(빌드 중간 생성물 등)에서는<br/>이 왕복이 파일 수만큼 쌓인다
그림 5: 스캔 비용이 생기는 지점. 파일 하나당은 작아도 수만 파일이면 지배적이 됩니다
이를 바탕으로 두 실무 주제를 정확히 이해할 수 있습니다.
제외 설정의 기술적 의미. 제외 목록과 일치하는 경로의 I/O에서는 필터의 스캔 처리가 생략됩니다. 필터가 stack에서 사라지는 것이 아니라, 「검사하지 않는다」는 판단이 빨리 이루어지게 되는 것이 실태입니다. 그리고 또 하나 중요한 한정이 있습니다──제외가 효력을 갖는 것은 그 설정을 가진 제품 자신의 필터뿐입니다. Microsoft Defender의 제외 설정이 바꾸는 것은 WdFilter의 스캔이며, 함께 있는 다른 minifilter(타사 바이러스 백신·EDR·백업·암호화 등)의 동작에는 아무 영향도 없습니다. 「제외를 넣었는데도 여전히 느리다」는 때는 다른 구성원이 시간을 쓰고 있을 가능성을 의심하십시오(7장의 fltmc 비교). 효과는 큰 한편, 제외는 그 장소의 보호를 확실히 약화합니다. Microsoft 문서도 제외는 방어를 줄이므로 위험 평가 위에서 최소한으로 하라고 반복해서 경고합니다.6 오탐 대응과 성능 영향의 실무는 「자체 개발 Windows 앱이 바이러스로 취급되면」에서 다루었습니다.
Dev Drive라는 새로운 답. 개발 워크로드(대량의 작은 파일)를 위해 설계된 전용 볼륨으로, Microsoft Defender가 성능 모드(비동기 스캔)로 동작합니다. 폴더 제외의 더 안전한 대안으로 자리매김되어 있으며, 기본값에서는 추가 필터가 attach되지 않는 한편, 필터를 전부 빼고 운용하는 것에 대한 강한 경고도 명시되어 있습니다.7 「빌드를 빠르게 하고 싶지만 제외는 두렵다」에 대한 현재 Microsoft가 권장하는 해법입니다.
7. 「그 환경에서만 느린」 조사 절차
연재에서 쌓아 온 도구를 마지막으로 하나의 절차로 정리합니다.
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: 필터 기인 느림의 원인 분리. 열쇠는 「작업 단위 소요 시간」과 「환경 간 필터 구성 차이」입니다
포인트는 두 가지입니다. 첫째, 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회에 그린 지도의 모든 상자를 열었습니다. 전체를 한 장으로 합니다.
flowchart TB
APP["애플리케이션<br/>ReadFile / WriteFile / async-await"]
API["제2회: 동기·비동기 I/O<br/>handle 모드와 OVERLAPPED"]
IOCP["제3회: IOCP와 .NET thread pool<br/>완료 수신과 계속 실행"]
IOM["제1회: I/O Manager와 IRP<br/>이름 해석·세 객체·device stack"]
FLT["제6회: 필터와 minifilter<br/>FltMgr·altitude·pre/post"]
CACHE["제4회: Cache Manager<br/>256KB view·lazy writer·fast I/O<br/>(NTFS와 협력해 동작)"]
NTFS["제5회: NTFS<br/>MFT·stream·링크·두 저널"]
HW["스토리지 stack과 디바이스"]
APP --> API
API --> IOM
IOCP -. "완료는 여기로 돌아온다" .-> APP
IOM --> FLT
FLT --> NTFS
NTFS -. "캐시 유효 I/O는 협력<br/>(파일 시스템이 캐시 기능을 호출)" .- CACHE
NTFS --> HW
HW -. "인터럽트→완료(제1회)" .-> IOCP
그림 7: 연재 전체 지도. Cache Manager는 「통과하는 층」이 아니라 파일 시스템과 협력하는 짝이며, 캐시 미스 때 NTFS에서 스토리지로 요청이 나갑니다
- 제1회: 전체 모습 ── 모든 읽기/쓰기는 IRP가 된다
- 제2회: 동기/비동기 ── OVERLAPPED의 진짜 의미
- 제3회: IOCP ── async/await의 지하실
- 제4회: 캐시 ── WriteFile은 언제 디스크에 닿는가
- 제5회: NTFS ── MFT에서 이해하는 파일 시스템
- 제6회: 필터와 minifilter(본 기사) ── Procmon과 바이러스 검사가 I/O에 끼어들 수 있는 이유
9. 정리 ── 연재의 맺음
최종회의 정리입니다.
- I/O에 대한 끼어들기는 OS가 공인한 확장 지점이며, 현재 표준은 FltMgr에 callback을 등록하는 방식(minifilter)입니다. 순서는 altitude로 결정적으로 정해지고, Microsoft가 번호를 할당·관리합니다.245
- 동작은 pre/post callback. 통과·거부·대신 처리·재작성을 할 수 있고, fast I/O에도 함께합니다. Procmon도 Defender도 OneDrive도 이 같은 구조의 구성원입니다.11110
- 제외 설정=스캔 생략이며, 보호와의 트레이드오프입니다. 개발 볼륨에는 Dev Drive(비동기 스캔)라는 더 안전한 선택지가 있습니다.67
- 「그 환경에서만 느린」 것은 Procmon의 Duration과
fltmc의 구성 차이로 원인을 가릅니다──연재의 도구가 그대로 조사 절차가 됩니다.
그리고 연재 전체의 결론을 한 줄로 말하면 이렇게 됩니다──Windows의 I/O는 이름 공간에서 대상을 정하고, 요청을 패킷(IRP)으로 만들어 층 사이를 흐르게 하며, 각 층이 「보기·맡아 두기·대신하기」를 고를 수 있게 만든, 일관된 설계이다. File.ReadAllText 한 줄 아래에서 이 6회분의 구조가 매번 움직입니다. API 동작을 암기하는 대신 이 지도에서 「그렇게 되어야 한다」고 이끌어 내는 것──그것이 이 연재에서 손에 넣기를 바란 힘입니다. 긴 여정에 함께해 주셔서 감사합니다.
관련 기사
- Windows I/O의 심층(제1회) ── 모든 읽기/쓰기는 IRP가 된다: I/O 시스템의 전체 모습
- Windows I/O의 심층(제4회) ── Cache Manager: WriteFile은 언제 디스크에 닿는가
- Windows I/O의 심층(제5회) ── NTFS의 내부 구조: MFT에서 이해하는 파일 시스템
- Process Monitor(ProcMon) 실전 가이드 ── 「설정이 읽히지 않는다」「ACCESS DENIED」를 10분에 특정한다
- 자체 개발 Windows 앱이 바이러스로 취급되면 ── Microsoft Defender 오탐 대응과 성능 영향과의 관계
- Process Explorer / Handle / VMMap 실전 ── hang·leak·「파일이 사용 중」을 지금 이 순간의 상태에서 추적한다
- Windows 앱 보안 최소 체크리스트
관련 상담 영역
合同会社小村ソフト에서는 「특정 환경에서만 느리다」「보안 소프트웨어와 자체 앱이 간섭한다」와 같이 필터 드라이버가 얽힌 Windows 업무 앱의 성능 문제·장애 조사를 다룹니다.
참고 링크
-
Microsoft Learn, About file system filter drivers. 파일 시스템 필터 드라이버가 파일 시스템 또는 다른 필터 드라이버로 향하는 요청을 가로챌(intercept) 수 있는 선택적 드라이버라는 점, 요청을 가로채 원래 대상에 전달되기 전에 기능을 확장·치환할 수 있고 요청 기록·감시·데이터 변경·동작 방지를 할 수 있다는 점, 바이러스 백신 유틸리티·암호화 프로그램·hierarchical storage 관리 시스템 등이 필터 드라이버의 예라는 점에 대해. ↩ ↩2 ↩3
-
Microsoft Learn, Filter Manager Concepts. Filter Manager(FltMgr)가 Windows에 포함된 kernel-mode 드라이버이며 minifilter 드라이버 개발을 단순화하는 기능을 공개한다는 점, minifilter가 I/O 작업의 전후(pre/post callback)에 처리를 등록할 수 있다는 점, legacy filter와의 공존을 위해 FltMgr가 frame으로서 I/O stack의 여러 지점에 attach할 수 있다는 점, minifilter가 unload·재로드되어도 같은 frame의 같은 altitude로 돌아간다는 점에 대해. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Advantages of the Filter Manager Model. minifilter 모델이 legacy filter 모델에 대해 갖는 이점으로, 필터 로드 순서를 더 잘 제어할 수 있다는 점, legacy filter와 달리 minifilter는 임의의 시점에 로드할 수 있다는 점, unload가 가능하다는 점, DAX 볼륨 연결 등이 거론된다는 점에 대해. ↩ ↩2
-
Microsoft Learn, Load order groups and altitudes for minifilter drivers. 파일 시스템 필터용으로 용도별 load order group이 정의되고 각 그룹에 altitude 범위가 할당되어 있다는 점, 모든 필터 드라이버가 고유한 altitude 식별자를 가지며 그것이 I/O stack 안에서 다른 필터에 대한 상대 위치를 정한다는 점, 그룹 예로 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. minifilter의 altitude가 Microsoft에 의해 할당·관리되며 공개된 할당 완료 altitude 목록이 유지된다는 점, 그 목록에 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에 attach되지 않는다는 점, 바이러스 백신 필터를 뺀 운용은 중대한 보안 위험이라고 경고된다는 점에 대해. ↩ ↩2 ↩3
-
Microsoft Learn, Request a Filter Altitude Identifier. 새 필터 altitude 신청이 제목 「Filter altitude request」의 ASCII 텍스트 메일을 fsfcomm@microsoft.com으로 보내는 방법으로 이루어진다는 점, 회사명·연락처 메일(개인이 아니라 장기의 회사 alias)·제품명·제품 URL·필터 설명·필터 파일명·필터 종류·시작 종류·희망 load order group·희망 altitude의 모든 항목을 기입해야 한다는 점, 처리에 30영업일을 잡아야 하고 이 절차 외에 신청 창구가 없다는 점, Microsoft가 희망과 다른 altitude를 할당할 수 있다는 점, 이미 정수 altitude를 가진 경우 같은 load order group 안에서 소수를 붙인 독자 altitude를 만들 수 있고 사후 연락으로 충분하다는 점에 대해. ↩ ↩2
-
Microsoft Learn, Blocking legacy file system filter drivers. 관리자 권한 명령 프롬프트에서
fltmc filters를 실행하면 「Filter Name / Num Instances / Altitude / Frame」 4열로 필터가 목록화된다는 점, Frame 열이<Legacy>인 것은 FltMgr를 거치지 않는 legacy 파일 시스템 필터 드라이버이며 minifilter에서는 Frame에 수치(0 등)가 들어간다는 점에 대해. ↩ ↩2 -
Microsoft Learn, Cloud Files API. Cloud Files API(클라우드 필터)가 클라우드상의 파일을 placeholder로 로컬에 보이게 하고 접근 시 실체를 가져오는 동기 엔진(OneDrive Files On-Demand 등)의 기반이라는 점에 대해. ↩ ↩2
-
Microsoft Learn, Process Monitor - Sysinternals. Process Monitor가 파일 시스템·레지스트리·프로세스/스레드 활동을 실시간으로 표시하는 고급 감시 도구라는 점에 대해(본문과 같이, 동작 중에는 fltmc 목록에 minifilter로 나타나는 것을 관찰할 수 있음). ↩ ↩2
관련 기사
같은 태그를 공유하는 최신 기사입니다. 더 가까운 주제로 지식을 넓힐 수 있습니다.
Windows I/O의 심층(제4회) ── 캐시 관리자: WriteFile은 언제 디스크에 도달하는가
Windows의 캐시 관리자를 그림으로 설명하는 연재 제4회입니다. 파일 매핑으로 구현된 캐시, read-ahead와 lazy write, FlushFileBuffers와 FILE_FLAG_NO_BUFFERING의 용도 구분, 전원 차단으로 데이...
Windows I/O의 심층(제3회) ── I/O 완료 포트(IOCP)와 .NET 스레드 풀: async/await의 지하실
I/O 완료 포트(IOCP)를 그림으로 설명하는 연재의 제3회입니다. 완료 큐와 스레드 수 제어를 하나로 묶은 설계, 동시성 값과 LIFO 해제, .NET 스레드 풀과 async/await 계속(continuation)의 실행 스레드까지 정리합니다.
Windows I/O의 심층(제2회) ── 동기 I/O와 비동기 I/O: OVERLAPPED의 진짜 의미
Windows의 동기 I/O와 비동기 I/O(overlapped I/O)를 그림으로 설명하는 연재의 제2회입니다. FILE_FLAG_OVERLAPPED의 의미, 완료 통지의 네 가지 방식, 비동기인데도 동기 완료되는 조건, 취소 절차, .NET과...
Windows I/O 내부 구조(제1회) ── 모든 읽기·쓰기는 IRP가 된다: I/O 시스템의 전체 그림
Windows I/O 시스템을 밑바닥부터 설명하는 연재의 제1회입니다. Object Manager namespace, driver·device·file 세 가지 object, IRP 수명 주기, CloseHandle 뒤에서 일어나는 일까지를 그림...
Windows는 왜 지금의 모습이 되었나: 개발자가 보는 역대 Windows의 진화
Windows 95부터 Windows 11까지의 변화를, 겉모습의 연표가 아니라 호환성, 안정성, 권한 관리, 드라이버, Win32, .NET, 보안 등 Windows 앱 개발자의 시점에서 정리합니다.
관련 토픽
이 기사와 가까운 토픽 페이지입니다. 기사를 출발점 삼아 관련 서비스와 다른 기사로 이어집니다.
Windows 기술 토픽
Windows 개발, 장애 조사, 기존 자산 활용에 관한 KomuraSoft LLC 기사를 모은 토픽 허브입니다.
이 주제와 연결되는 서비스
이 기사는 다음 서비스 페이지로 이어집니다. 가까운 입구부터 확인해 주세요.
Windows 앱 개발
상주 처리, 장비 연동, 운영 로그, 유지 보수 가능한 구조가 필요한 Windows 데스크톱 애플리케이션을 지원합니다.
자주 묻는 질문
이 기사 주제에 대해 상담 시 자주 나오는 질문을 모았습니다.
- 파일 시스템 필터 드라이버와 minifilter는 무엇이 다릅니까?
- 둘 다 「파일 시스템에 대한 I/O 요청에 끼어드는 드라이버」이지만, 끼어드는 방식의 세대가 다릅니다. 오래된 legacy filter는 파일 시스템의 device stack에 자신의 device object를 직접 쌓는 방식이라, 로드 순서로 위치가 정해져 순서를 보장하기 어렵고, 한 번 로드하면 안전하게 unload할 수 없는 등의 문제가 있었습니다. 현재 표준인 minifilter는 Windows에 포함된 Filter Manager(FltMgr)에 「이 작업의 전후에 호출해 달라」고 callback을 등록하는 방식입니다. 위치는 altitude라는 번호로 결정적으로 정해지고, 임의의 시점에 로드할 수 있으며, unload callback을 구현한 필터라면 가동 중에 분리할 수도 있습니다. 바이러스 백신·암호화·감시 도구·클라우드 동기화 등 현대의 필터는 거의 모두 minifilter로 구현되어 있습니다.
- 왜 바이러스 백신은 모든 파일 접근을 검사할 수 있습니까?
- OS가 공식적으로 그 확장 지점을 마련해 두었기 때문입니다. minifilter는 파일을 열기·읽기·쓰기와 같은 작업의 전(pre callback)과 후(post callback)에 호출되는 코드를 Filter Manager에 등록할 수 있습니다. 바이러스 백신 필터는 안티바이러스용 altitude 대역(320000〜329999)에 위치하며, 예를 들어 파일 open이 성립한 직후(post-create)에 내용을 스캔하고, 문제가 있으면 그 open을 취소해 접근을 실패시킬 수 있습니다. 연재 제1회에서 본 것처럼 모든 파일 I/O는 device stack을 흐르므로, 그 경로의 정해진 위치에 서면 모든 접근을 검사할 수 있다는 이치입니다. 편법이 아니라 OS 설계에 들어 있는 구조입니다.
- 바이러스 백신의 제외 설정(폴더 제외)은 기술적으로 무엇을 합니까?
- 제외 목록과 일치하는 경로로의 I/O에 대해, 그 제품의 필터가 수행하는 스캔 처리를 생략시킵니다. 필터 자체가 stack에서 사라지는 것이 아니라, 「이 경로는 검사하지 않는다」는 판단이 이르게 이루어지는 것에 가깝습니다. 중요한 한정은, 제외가 효력을 갖는 것은 그 설정을 가진 제품 자신뿐입니다. 예를 들어 Microsoft Defender의 제외 설정이 바꾸는 것은 Defender의 필터(WdFilter) 스캔이며, 함께 있는 타사 바이러스 백신·EDR·백업 등 다른 minifilter의 동작에는 영향을 주지 않습니다. 제품마다 개별 제외 설정이 필요하며, 「제외했는데도 여전히 느리다」면 다른 필터가 원인인 경우가 있습니다. 또한 Microsoft 문서가 반복해서 경고하듯, 제외는 그 장소의 보호를 약화하므로 위험 평가와 함께 최소한으로 해야 합니다. 개발 용도에서는 폴더 제외의 안전한 대안으로 설계된 Dev Drive(성능 모드=비동기 스캔)를 검토할 가치도 있습니다.
- Process Monitor는 어떻게 모든 I/O를 기록합니까?
- Procmon 자신이 시작 시 Activity Monitor(활동 감시)용 altitude 대역의 minifilter로 자신을 Filter Manager에 등록하기 때문입니다. Procmon을 실행한 상태에서 관리자 권한 명령 프롬프트에서 fltmc를 실행하면, PROCMON으로 시작하는 이름의 필터가 목록에 나타나는 것을 확인할 수 있습니다. minifilter로서 모든 볼륨의 I/O 작업 pre/post에 함께할 수 있으므로, 어느 프로세스가 어느 파일에 어떤 작업을 했는지를 빠짐없이 기록할 수 있습니다. 연재에서 본 IRP와 fast I/O 용어가 Procmon 표시에 그대로 나오는 것은, 바로 I/O 경로 그 자체에 서서 관찰하기 때문입니다.
- 개발 머신의 빌드가 느릴 때 필터 드라이버를 의심해야 합니까?
- 의심할 가치는 충분히 있습니다. 빌드는 대량의 작은 파일 생성·읽기/쓰기·삭제의 덩어리이고, 하나하나가 필터 군(특히 바이러스 백신 스캔)의 검사 대상이 되므로, 필터 비용이 가장 잘 드러나는 워크로드입니다. 조사는 Procmon에서 Duration 열을 보고 시간이 어느 작업에서 사라지는지 확인하고, fltmc instances로 환경별 필터 구성 차이를 비교하는 것이 기본 절차입니다. 대책으로는 위험을 평가한 뒤의 제외 설정 외에, 개발 볼륨 전용으로 설계된 Dev Drive 이용이 있습니다. Dev Drive에서는 바이러스 백신이 성능 모드(비동기 스캔)로 동작하며, 제외 설정보다 안전한 대안으로 Microsoft가 자리매김합니다.