이 자료는 정말 마음에 드네요. (아직 다 보지는 못했지만)


Thomas F. Divine님과 James Antognini님이 작성한 문서입니다.
DDK를 깔면 예제로 깔리는 PassThru를 확장해서 설명해 놓으셨습니다.
처음 Intermediate(IM) Driver를 공부하려고 하면 정말... 어떻게 해야 할지 막막했습니다.
DDK 문서와 이 문서를 갖고 계속 공부를 해 나가야겠습니다.
그럼 모두 즐프하세요.


Bloger: moltak.net

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 03) Intermediate Driver 초기화  (0) 2010.05.09
NDIS Driver 02) Intermediate Driver  (0) 2010.05.06
NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18

1. WDK - Windows Vista RTM 을 다운 받아 설치

   

2. http://www.hollistech.com/Resources/ddkbuild/ddkbuild.htm 에서 ddkbuild 를 받아 압축을 풀고 vs .net 이 참조 가능한 패스에 복사한다.( C:\Program Files\Microsoft Visual Studio .NET 2005\Vc7\bin

3. DDKBUILD 에게 사용할 DDK version 을 알려주기 위해 약간의 편집을 해야 한다. ( 설치한 DDK 경로 설정 )

   

4. 프로젝트 생성 -> 메이크 파일을 선택

    

5. 디버그 구성 구성 설정에서 그림과 같이 설정.

   

6. 참고로 드라이버는 일반 어플리케이션과는 달리 debug build/release build 라고 하지 않는다. 
Debug build checked build
Release build free build

    

7. Visual Studio .Net의 intellisense 기능활용하기.

lib\wxp, inc\ddk, inc\api 폴더추가.

'Programming > WinDriver' 카테고리의 다른 글

NDIS Extending The PassThru IM Driver  (0) 2010.05.06
NDIS Driver 01) 시작  (0) 2010.05.02
NDIS/TDI  (0) 2010.03.18
_LIST_ENTRY  (2) 2010.03.18
Lookaside list  (0) 2010.03.18

출처 : http://www.htsns.com


질문1
 NDIS.sys란 계층이 있는데요
 저는 NDIS가 미니포트 IM 프로토콜 드라이버를 감싸고 있는
 그림만 봐서 이그림은 좀 생소하네요
 이그림의 의미가 미니포트에서는 어퍼에지쪽으로 NDIS인터페이스에 맞춰주고 프로토콜 드라이버에서는 로워에지쪽으로 NDIS의 인터페이스에 맞춰준다는 의미인가요?

 네 감싸고 있는 것이 맞습니다. 실제 코드 구현으로 하면, ndis.sys는 하나의 라이브러리라고 생각하시면 됩니다. 즉 표준 인터페이스를 제공함으로써 미니포트 드라이버와 프로토콜 드라이버를 분리시켜서 서로 다른 업체에서 개발할 수 있도록 합니다. 즉 Lower, Upper Edge 함수들은 콜백함수들입니다. 이 부분은 open block이라는 개념으로 미니포트와 프로토콜을 서로 연결 시켜서 미니포트에서는 Lower-Edge 함수들을 ndis 함수들을 통해 호출할 수 있도록 하고 Upper-Edge 함수들도 마찬가지입니다.
 즉 NdisSend 함수를 호출하면 내부적으로 초기화 시에 등록한 미니포트의 Upper-Edge 함수를 호출하게 합니다. 즉 MiniportSend함수를 호출합니다. 이런 구조가 ndis 라는 아키텍처입니다. 

질문2
 그럼 IM드라이버가 들어간다면 그림에서 어떤식으로 연결이 되는건가요?
 
 
프로토콜, 미니포트 드라이버 구조를 이해하고 계시면 im도 이해하는데 큰 어려움은 없을 겁니다. 즉 프로토콜과 연결하는 부분은 im의 미니포트에 해당하고 미니포트와 연결하는 부분은 im의 프로토콜의 해당합니다. 그리고 im 내에서 미니포트와 프로토콜 부분은 내부 바인딩 개념으로 ndis 가 알아서 처리를 해주고 잇습니다. 과거 im 인터페이스가 제공을 하지 않는 ndis 버전에서는 im 드라이버와 같은 역할을 하는 드라이버를 개발할 때, 직접 ndis protocol 드라이버와 가상 nic 드라이버를 만들어서 내부적으로 직접 연결을 시켜서 필터 드라이버를 개발했습니다.

 다시 함수 정리를 한다면, tcpip.sys라는 ndis protocol드라이버와 virtual nic driver와 바인딩 시키고 자체 ndis protocol 드라이버를 개발 미니포트 드라이버와 바인딩 시킵니다. tcpip.sys에서 ndissend함수를 호출하면 virtual nic driver와 바인딩 되었기 때문에 MiniportSend 함수가 호출될 겁니다. 그럼 MiniportSend 함수에서 자체 ndis protocol에서 ndisopenadapter함수를 통해 얻은 바인딩 핸들을 가지고 ndissend 함수를 호출하면 미니포트의 MiniportSend 함수가 호출되는 구조로 개발이 되었습니다. IM 드라이버인 경우 이런 컨텍스트 관리가 ndis 아키텍처에서 관리가 되는데 자체 위 구조로 개발하게 되면 자체적으로 연결 컨텍스트 관리를 해줘야 되는 불편함이 있습니다.

질문3
 그림에서 1번을 보면 TDI 트랜스포트와 프로토콜이 TCPIP.sys란
 파일로 묶여있는데요.. 두개가 원래 공존하는겁니까?
 
 
네 공존합니다.
즉 프로토콜 드라이버를 개발할 때 소켓단하고 연결을 하려면 tdi transport 계층이 필요합니다.

질문4
 그렇다면 DDK샘플에서 프로토콜드라이버 샘플도 TDI트랜스포트와 프로토콜드라이버로 이루어져 있는겁니까?
 
 
packet이나 ndisuio는 소켓 단과 연결을 하지 않습니다. 그래서 tdi transport 계층이 없습니다. 자체 프로토콜 드라이버기 때문에 바로 어플리케이션과 연결해서 패킷 송/수신을 할 수 있는 하나의 패킷 드라이버라고 할 수 있습니다.

질문5
 우리가 프로토콜 드라이버를 개발하면 기존에 있는 TCPIP.sys를 대체하게 되는겁니까?

 아님 아래쪽이나 위쪽으로 삽입이 되는겁니까?
 
 
병렬 구조입니다. 새로운 프로토콜 드라이버가 생기는 겁니다. 즉 tcpip.sys와는 독립적입니다.

질문6
 그림에서 2번의 TDI.sys는 NDIS.sys처럼 라이브러리(?)를 나타내는겁니까?
 
질문7
 그림 1에서 TDI Transport는 왜 Transport라는 이름이 붙은건가요?
 그림3에서 TDI Client는 왜? Client라는 이름이 붙은건가요?
 Afd.sys에서 Afd는 무슨 약자인가요?
 
 
음 의미상 그런 구조이기 때문에 그런 이름을 붙인것 같습니다. 제 생각입니다만,

transport라는 이름은 osi 7계층에서 전송 계층에 해당하는 부분이라 이런 이름을 사용하지 않았나 생각이 들고 client라는 것은 transport 서비스를 이용하는 부분이기 때문에 client라는 이름을 사용한 것 같습니다.

afd는 모르겠습니다. 추정하는 것은 address family driver 약자가 아닐까.... 생각이 듭니다. 소켓에서 AF_NET이라는 소켓 이름이 사용하는데 AF Address Family 약자라서 ...

질문8
그림3 TDI Client에서요 아래쪽은 TDI인터페이스에 마춰서 동작하는건가요?
그럼 위쪽으로는 유저모드인데 어떤식으로 동작하는지 감이 안잡히네요.. 여기서 IO메니저는 없나요?
 
 
드라이버 통신은 IO 매니저의 의해 이루어집니다. 즉 IRP 통신입니다.
즉 dll <-> sys 사이 통신은 CreateFile, ReadFile, WriteFile, DeviceIoControl, CloseHandle을 통해 이루어집니다. 즉 장치 이름을 ms에서 알고 있기 때문에 이런 인터페이스로 개발이 되었을 겁니다.

 
질문9
 TDI쪽 노란색 계층들도 NDIS의 초록색 계층들이 NDIS인터페이스에 맞춰서 작성되는것처럼
 TDI의 인터페이스가 따로있어서 거기 맞춰서 개발해야하는건가요?
 
네 맞습니다. tdi 문서에 보면 인터페이스 관련 내용들은 자세하게 나와 있습니다.

 
질문10
우리가 NDIS인터페이스에 맞춰서 드라이버를 개발하지만
실제로는 NDIS라이브러리가 윈도우즈의 드라이버 동작방식에
맞춰서 변환해주는건가요?
 
 
ndis 라이브러리의 내부 구조는 wdm 구조일 겁니다.

 
질문11
 이렇게까지 많은 계층들이 필요가 한가요?
 이렇게 여러단계로 나눠논 이유가 무엇인가요??
 
 
third party 개발을 위한 구조입니다. 그리고 os 의 아키텍처입니다. os 개발을 잘하기 위한 구조입니다.

 
한 반년동안 제대로 이해안되던 질문들입니다 ㅠㅠ
정확한 동작을 이해하기가 엄청 어렵네요
항상 답변해주시는 운영자님 감사합니다^^
수고하세요^^
 
 
운영자님 답변 정말 감사합니다^^
 많은 걸 이해하게 됐습니다^^
 
근데 또 질문이 있어요 하하~
프로토콜 드라이버를 보면 TCPIP.sys 란 파일있잖아요
여기는 IP기반 패킷만 이 드라이버로 가는건가요?
IPX라든가 IP기반이 아닌 패킷들은 다른 프로토콜 드라이버로 올라가잖아요


질문 1
 그렇다면 미니포트에서 이더넷 프레임을 검사해서 적절한 프로토콜 드라이버로 올리는 건가요?

미니포트에서는 바인딩된 모든 프로토콜 드라이버에 패킷들을 인디케이트합니다. 프로토콜 드라이버에서 자기 패킷이 아니면 드랍을 하는 방법입니다.

질문 2
 이더넷 헤더는 어디서 붙이고 버리나요?(?)
 TDI에서는 이더넷 헤더를 얻을 수 없다고 알고 있거든요

tdi에서 다루는 구조는 이더넷 프레임을 다루는 게 아니고 연결 관리를 핸들로 처리하기 때문에 즉 연결을 캡슐화해서 처리합니다. 즉 소켓 단위라고 생각하시면 될 겁니다. 그래서 이더넷 헤더를 파악할 수 없습니다.

질문 3
 TDI 클라이언트를 개발한다면
 이것두 병렬구조로 붙게 되나요?

네 그렇게 되겠죠.. 

질문 4
 Hook Driver라는건
 네트워크 계층에서 어떤 드라이버에도 붙일 수 있는건가요?

hook 방법을 이해하시면 좀 더 이해가 쉬울 겁니다. 훅은 함수 포인터를 훅하는 것이기 때문에 원본 함수 포인터를 알면 모든 함수들이 훅이 가능합니다. 네트워크 계층에 상관이 없습니다.

질문 5
 Ip Filter Hook Driver는 어떤 드라이버에 붙은 필터드라이번가요?

tcpip.sys에서 export한 필터 함수입니다. 그래서 기능이 제한되었습니다. 즉 제공된 함수이외의 기능은 불가능합니다.

질문 6
 TDI 계층에서도 어퍼에지 로워에지라는 개념이 있나요?

다른 이름으로 사용합니다. transport와 client 개념입니다. 통신 방법도 차이가 있습니다.

질문 7
 TDI를 개발하지 않고도(IM이나 HookDriver에서)
 소켓의 생성을 감지하고 차단할 수 있을까요?

소켓의 생성이라는 말의 의미에 따라 다릅니다. 소켓의 생성이 인터넷 차단인지 아니면 실제 소켓 함수의 차단인지에 따라 차이가 있습니다. 원하는 기능이나 구조에 따라 훅 방법과 접근 레이어가 달라집니다.

질문 8
 LSP계층에 대한 어떤 문서나 사이트는 없나요?
 이쪽은 자료가 전혀 없는거 같던데 ㅠㅠ

sdk에 샘플 코드가 있고 msdn 도움말과 과거 한국전산원에서 프로젝트로 한 문서가 있습니다.
그리고 lsp를 사용한 스팸 메일 차단 공개 프로젝트가 있습니다.

질문 9
 paathru예제를 보면 모든 callback(?)함수들을 다 구현해 주던데요
 보통 필터 드라이버에서 보면
 자신이 필요한 동작만 프록시함수를 만들어서 연결시켜주잖아요
 IM에서는 모든 동작을 다 정의해줘야 하나요?

훅 드라이버와 차이점입니다. 훅방법은 자신의 훅할 위치만 훅하면 되지만 im은 ndis 아키텍처입니다. 이 구조에 맞춰 개발을 해줘야 합니다.

질문 10
 윈도우 방화벽은 무슨 드라이버로 제작된건가요?

분석을 안해봐서 어떻게 개발되었는지는 모르겠습니다.
분석을 하실 때는 일단 사용된 바이너리를 검색하시고 바이너리를 역어샘블이나 바이너리 십육진 덤프등등의 리버스 엔지니어링 툴들을 사용해서 분석해 보세요.

질문 11
 미니포트 드라이버는 왜 미니포트라고 부르는건가요?
 
또 질문 많이 하게 되네요^^

과거 랜카드 드라이버는 풀 닉드라이버라고 했습니다. 말 그대로 입니다. 포트는 하드웨어와 통신을 하는 최단부분입니다. 버스 포트 등등... 미니는 최소 업체 스펙만 구현을 하면 되도록 os에서 전체 구조를 제공해주었기 때문에 미니 부분만 개발을 하면 되는게 아닌가 생각이 듭니다. 정확히 모르겠네요.. 정의에 대해서는 



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


sfilter.dll은 



NTDDK\src\network\config\filter를 build하면 sfilter.dll이 생성된다고 합니다.



저의 경우에는 ddk sample설치시 골라서 설치해서 이 폴더가 없었던것 같습니다.



이 파일의 기능은 hantech에 netcoder님이 잘 설명 해주셨더군요.



설치 관련 dll입니다.

notify object으로써 동적으로 설치 관련 부분을 담당합니다.

즉 프로토콜을 등록하면서 가상 미니포트를 등록하려하면 이 dll 안에서 설치 관련 연산을 하면 됩니다.

2003 dotnet ddk에서는 passthru의 notify object은 사용을 안해서 제거를 했습니다. mux에서는 이 부분을 사용해서 (프로토콜 + 가상 미니포트) 먼저 네트워크 등록 정보에서 muxp 프로토콜을 등록을 하면 네트워크 구성 서브시스템(네트워크 설치 관련 모듈:운영체제)에서 notify object(CoM)을 호출을 하면 이 내에서 가상 미니포트를 등록을 합니다.



즉 프로그램 상으로 설치 과정을 변경하려면(네트워크 등록 정보에서 새로운 프로퍼티 sheet 추가 등등) 이 dll을 등록을 해야 합니다.(inf 파일 내에 component dll 부분에)



보다 자세한 내용은 ddk의 네트워크 부분에서 install 부분을 참조하세요.

자세하게 나와 있습니다.

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
_LIST_ENTRY  (2) 2010.03.18
Lookaside list  (0) 2010.03.18
Fast I/O  (0) 2010.03.18

WDK에서는 드라이버에서 사용하기 위한 리스트를 제공한다. 리스트 뿐만아니라

KQUEUE, KDVICE_QUEUE, IO_REMOVE_LOCK, MDL 을 제공하고 있다.

아래는 LIST_ENTRY의 사용 예이다.

Snap2.bmp


참고 사이트: http://groups.google.co.kr/group/endless-creation/web/드라이버에서+링크드+리스트+구현시+참고사항

http://www.pyrasis.com/blog/17

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18
Lookaside list  (0) 2010.03.18
Fast I/O  (0) 2010.03.18

Heap 관리자는 메모리 블럭의 크기가 무작위로 결정되기 때문에 인접한 free 블럭을 합치기 위해 많은 CPU 시간을 요구하게 됩니다.


항상 고정된 크기의 메모리 블럭만을 사용한다면 heap을 관리하는데 있어 훨씬 효율적인 방식으로 사용이 가능한데 예를 들면

큰 메모리 블럭을 미리 할당하여, 이를 주어진 크기로 조각냅니다. 블럭이 heap에 리턴되면 실제로 해제하는 것이 아니라 사용이

끝남으로 표시하면서 사용하게 되는데, 이에 대한 몇가지 문제점이 있습니다.


너무 많은 메모리를 할당할 경우는 메모리 낭비를 가져올 수 있고, 너무 적게 할당할 경우는 알고리즘이 동작하지 않거나 더 많은 블럭을 얻으려고 heap 관리자를 너무 자주 사용하게 되는 것입니다.


Microsoft에서는 이러한 단점을 극복하기 위해 lookaside list 객체를 제공합니다.


lookaside list

  1. lookaside list 객체 초기화시 시스템에게 작업할 단위 메모리 블럭의 크기를 알립니다. ( 용량은 운영체제가 탄력적으로 감지합니다. )
  2. 메모리 블럭을 할당하기 위해서 시스템은 일단 하나의 블럭의 제거를 시도합니다.
    1. 더 이상 남은 블럭이 없다면 메모리 pool에서 빼옵니다.
  3. 메모리 블럭을 반환하려면, 시스템은 리스트에 되돌리기를 시도하게 되며, 리스트가 꽉 차면 일반 heap 관리 루틴을 사용해서 pool에 블럭을 되돌립니다.

시스템은 실제 사용에 따라 모든 lookaside list의 depth를 정기적으로 조작합니다.

  • 시스템에 최근 접근하지 않았거나, 총 시간에서 5% 이상 액세스 하지 않은 lookaside list에 대해 depth를 감소 시킵니다.
  • 처음의 새 리스트 값인 4 이하로는 줄어들지 않습니다.
  • driver verifier 실행시는 모든 lookaside list의 depth는 모두 0으로 바뀝니다. ( 메모리 오류와 관련된 드라이버 문제를 발견하기 쉽게 하기 위해서 입니다. )

Lookaside list 지원 함수

Lookaside list를 지원하는 함수는 paged / non-paged 두 분류로 나뉘게 됩니다.

  • ExInitializeNPagedLookasideList  / ExInitializePagedLookasideList : Lookaside list를 초기화 한다.
  • ExAllocateFromNPagedLookasideList / ExAllocateFromPagedLookasideList : 고정된 크기의 블럭을 할당한다.  
  • ExFreeToNPagedLookasideList / ExFreeToPagedLookasideList : 해제해서 lookaside list로 다시 돌려준다.
  • ExDeleteNPagedLookasideList / ExDeletePagedLookasideList : Lookaside list를 삭제한다.


lookaside list 객체를 위해 메모리를 확보하고 나서 적절한 초기화 루틴을 호출합니다.


각 함수에서 첫 번째 인수는 이미 공간을 확보해둔 (N)PAGED_LOOKASIDE_LIST 객체에 대한 포인터입니다. Allocate와 Free는 heap에서 메모리를 할당하거나 해제할 수 있는 루틴들에 대한 포인터 입니다. ExAllocatePoolWithTag와 ExFreePool을 쓸 시에는 이 인수들을 NULL로 하면 됩니다. blocksize 인수는 리스트에서 할당하는 메모리 블럭의 크기를 나타냅니다. tag는 이러한 각 블럭의 앞에 붙은 32비트 태그 값입니다.


리스트에서 메모리 블럭을 할당하려면 적절한 AllocateFrom 함수를 호출한다.

PVOID p = ExAllocateFromPagedLookasideList(pagelist);

PVOID p = ExAllocateFromNPagedLookasideList(nonpagedlist);

블럭을 리스트로 다시 돌리려면 적절한 FreeTo 함수를 호출하면 됩니다.

ExFreeToPagedLookasideList(pagedlist, p);

ExFreeToNPagedLookasideList(nonpagedlist, p);

마지막으로 리스트를 제거하려면 적절한 Delete 함수를 호출하면 됩니다.

ExDeletePagedLookasideList(pagedlist);

ExDeleteNPagedLookasideList(nonpagedlist);

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18
_LIST_ENTRY  (2) 2010.03.18
Fast I/O  (0) 2010.03.18

2006/10/31 19:10


복사http://blog.naver.com/dbtalk/110010329621


Fast I/O는 Cached file을 read/write함에 있어서 IRP를 만들지 않고 가능하게 해줍니다.
 
ReadFile를 예로 들어 Fast I/O의 흐름을 설명하면 다음과 같습니다.


순서1. NtReadFile에서 요청된 data가 Cached data인지 또는 Synchronous I/O인지를 판단하여

         Yes이면 File system driver를 호출합니다.
 
순서2. File system Driver에서는 Fast I/O가 가능한지를 판단하여 가능하면 Cache manager로

          제어를 넘긴다.


순서3. Cache Manager가 실제 Data를 I/O를 요청한 Process buffer로 복사한다.
 
순서4. 만약 순서1 또는 순서2에서 조건이 만족하지 않으면 IRP를 만들어서 I/O를 수행한다.


-- 부가 설명 --


일반적으로 File system에서의 I/O 요청은 
(1) File system driver(FSD)
(2) Cache Manager
(3) Memory Manager
(4) File system driver 재 진입
(5) DISK I/O 순으로 IRP 가 처리됩니다.
 
이 과정에서 Synchronous, buffered I/O 인 경우 I/O 요청은 결국 Cache Manager가 처리하게 된다. FSD는 단지 IRP를 Cache Manger에게 전달하는 역할 뿐이다.
따라서 Fast I/O는 IRP를 생성하고 FSD를 호출하는 부담을 줄이고 막바로 Cache Manger의 service를 호출 하는 방식이다.
fast의 원래 목적인 Synchronous, Buffered I/O read/write를 지원하면서 좀 더 확장되어 여러가지 FSD 함수들도 Fast I/O로 서비스 되고 있다.

'Programming > WinDriver' 카테고리의 다른 글

NDIS Driver 01) 시작  (0) 2010.05.02
DDK 개발 환경 구축  (0) 2010.04.18
NDIS/TDI  (0) 2010.03.18
_LIST_ENTRY  (2) 2010.03.18
Lookaside list  (0) 2010.03.18

+ Recent posts