[DDK] 파일 시스템 드라이버의 FastIoDispatch 루틴

Filemon과 SFilter를 예로 들어서 설명하자,

일단 Filemon은 동적 필터 드라이버이다.

SFilter와는 다르게 재부팅을 요하는 만큼의 작업은 필요가 없다.

단지 파일의 입출력을 감시할뿐,

이정도의 기능이라면 SDT 후킹을 해서 구현할 수도 있을 것 같다,

하지만 내부적으로 엄청나게 잘짜놨겠지, - _-;

일단 DriverEntry()를 보면 다음과 같은 루틴이 존재한다.

파일 시스템 필터 드라이버를 작성하다보면,

Fast I/O에 대해서 많이 보게 된다,

왜냐하면 파일 시스템 드라이버는 I/O Manager가 생성한

IRP를 사용하여 데이터를 주고 받는 것 이외에 Fast I/O 디스패치 루틴을 통하여

Cache Manager와 직접 데이터를 주고 받는다.

따라서 파일 시스템 필터 드라이버 역시 Cache Manager와 직접 통신하기 위해서는

Fast I/O Dispatch Routine을 등록하여야 한다.


  1.    fastIoDispatch = ExAllocatePoolWithTag( NonPagedPool, sizeof( FAST_IO_DISPATCH ), AMLT_POOL_TAG );  
  2.  
  3. // Non- pageable Pool 할당이 실패하면  
  4.    if ( NULL == fastIoDispatch )   
  5. {  
  6.     // 디바이스를 지우고 자원 부족이라는 반환값으로 리턴한다  
  7.        IoDeleteDevice( g_AuthMonControlDeviceObject );  
  8.        return STATUS_INSUFFICIENT_RESOURCES;  
  9.    }  
  10.  
  11. // 메모리 초기화 Zero-Memory 루틴  
  12.    RtlZeroMemory( fastIoDispatch, sizeof( FAST_IO_DISPATCH ) );  
  13.  
  14. // Fast I/O 자료 구조의 루틴과 값들을 채워넣는다.  
  15. fastIoDispatch->SizeOfFastIoDispatch = sizeof( FAST_IO_DISPATCH );  
  16.  
  17.    fastIoDispatch->FastIoCheckIfPossible = AmFastIoCheckIfPossible;  
  18.    fastIoDispatch->FastIoRead = AmFastIoRead;  
  19.    fastIoDispatch->FastIoWrite = AmFastIoWrite;  
  20.    fastIoDispatch->FastIoQueryBasicInfo = AmFastIoQueryBasicInfo;  
  21.    fastIoDispatch->FastIoQueryStandardInfo = AmFastIoQueryStandardInfo;  
  22.    fastIoDispatch->FastIoLock = AmFastIoLock;  
  23.    fastIoDispatch->FastIoUnlockSingle = AmFastIoUnlockSingle;  
  24.    fastIoDispatch->FastIoUnlockAll = AmFastIoUnlockAll;  
  25.    fastIoDispatch->FastIoUnlockAllByKey = AmFastIoUnlockAllByKey;  
  26.    fastIoDispatch->FastIoDeviceControl = AmFastIoDeviceControl;  
  27.    fastIoDispatch->FastIoDetachDevice = AmFastIoDetachDevice;  
  28.    fastIoDispatch->FastIoQueryNetworkOpenInfo = AmFastIoQueryNetworkOpenInfo;  
  29.  
  30.    fastIoDispatch->MdlRead = AmFastIoMdlRead;  
  31.    fastIoDispatch->MdlReadComplete = AmFastIoMdlReadComplete;  
  32.    fastIoDispatch->PrepareMdlWrite = AmFastIoPrepareMdlWrite;  
  33.    fastIoDispatch->MdlWriteComplete = AmFastIoMdlWriteComplete;  
  34.    fastIoDispatch->FastIoReadCompressed = AmFastIoReadCompressed;  
  35.    fastIoDispatch->FastIoWriteCompressed = AmFastIoWriteCompressed;  
  36.    fastIoDispatch->MdlReadCompleteCompressed = AmFastIoMdlReadCompleteCompressed;  
  37.    fastIoDispatch->MdlWriteCompleteCompressed = AmFastIoMdlWriteCompleteCompressed;  
  38.    fastIoDispatch->FastIoQueryOpen = AmFastIoQueryOpen;  
  39.  
  40. // 드라이버 오브젝트에 FastIoDispatch 함수의 주소에 우리가 정의한 함수의 주소를 넣는다.  
  41.    DriverObject->FastIoDispatch = fastIoDispatch;  
<TEXTAREA class="cpp" style="DISPLAY: none" name=code rows=10 cols=60> fastIoDispatch = ExAllocatePoolWithTag( NonPagedPool, sizeof( FAST_IO_DISPATCH ), AMLT_POOL_TAG ); // Non- pageable Pool 할당이 실패하면 if ( NULL == fastIoDispatch ) { // 디바이스를 지우고 자원 부족이라는 반환값으로 리턴한다 IoDeleteDevice( g_AuthMonControlDeviceObject ); return STATUS_INSUFFICIENT_RESOURCES; } // 메모리 초기화 Zero-Memory 루틴 RtlZeroMemory( fastIoDispatch, sizeof( FAST_IO_DISPATCH ) ); // Fast I/O 자료 구조의 루틴과 값들을 채워넣는다. fastIoDispatch->SizeOfFastIoDispatch = sizeof( FAST_IO_DISPATCH ); fastIoDispatch->FastIoCheckIfPossible = AmFastIoCheckIfPossible; fastIoDispatch->FastIoRead = AmFastIoRead; fastIoDispatch->FastIoWrite = AmFastIoWrite; fastIoDispatch->FastIoQueryBasicInfo = AmFastIoQueryBasicInfo; fastIoDispatch->FastIoQueryStandardInfo = AmFastIoQueryStandardInfo; fastIoDispatch->FastIoLock = AmFastIoLock; fastIoDispatch->FastIoUnlockSingle = AmFastIoUnlockSingle; fastIoDispatch->FastIoUnlockAll = AmFastIoUnlockAll; fastIoDispatch->FastIoUnlockAllByKey = AmFastIoUnlockAllByKey; fastIoDispatch->FastIoDeviceControl = AmFastIoDeviceControl; fastIoDispatch->FastIoDetachDevice = AmFastIoDetachDevice; fastIoDispatch->FastIoQueryNetworkOpenInfo = AmFastIoQueryNetworkOpenInfo; fastIoDispatch->MdlRead = AmFastIoMdlRead; fastIoDispatch->MdlReadComplete = AmFastIoMdlReadComplete; fastIoDispatch->PrepareMdlWrite = AmFastIoPrepareMdlWrite; fastIoDispatch->MdlWriteComplete = AmFastIoMdlWriteComplete; fastIoDispatch->FastIoReadCompressed = AmFastIoReadCompressed; fastIoDispatch->FastIoWriteCompressed = AmFastIoWriteCompressed; fastIoDispatch->MdlReadCompleteCompressed = AmFastIoMdlReadCompleteCompressed; fastIoDispatch->MdlWriteCompleteCompressed = AmFastIoMdlWriteCompleteCompressed; fastIoDispatch->FastIoQueryOpen = AmFastIoQueryOpen; // 드라이버 오브젝트에 FastIoDispatch 함수의 주소에 우리가 정의한 함수의 주소를 넣는다. DriverObject->FastIoDispatch = fastIoDispatch; </TEXTAREA>

왜 이렇게 하는 것일까,

일단 파일 시스템 드라이버는 Cache Manager가 존재한다.

Cache Manager에 대해서는 다음에 확실하게 정리해서 알아보고,

일단 Cache Manager 덕분에 Fast I/O를 처리해줘야한다.

Fast I/O 디스패치 함수를 등록하는 것은

파일 시스템 필터 드라이버가 일단 파일시스템 위에 필터로 붙어있게 된다.

그렇게 되면 파일 시스템 드라이버가 Fast I/O로 통신하는것을 처리할 수있어야

하위 스택으로 자료를 보낼 수 있는 것이다.

그리하여 FSFD는 데이터 전송을 위해 직접 Cache Manager와 통신하기 위해

이를 처리하기 위한 Fast I/O Dispatch Routine을 등록하는 것이다.
 
출처 : http://ssmhz.tistory.com/147
위로 스크롤