[DDK] DRIVER_OBJECT 구조체를 알아보자!!

DRIVER_OBJECT와 DEVICE_OBJECT 구조체는 중요하다.

두개가 헷갈려 하는 경우도 많은데,

일단 DRIVER_OBJECT는 함수포인터로 구성되어 있다.

나머지 필드는 직접 수정을 하면 안되는 부분도 있다.

  1. typedef struct _DRIVER_OBJECT  
  2. {  
  3.    CSHORT Type;  
  4.    CSHORT Size;  
  5.    PDEVICE_OBJECT DeviceObject;  
  6.    ULONG Flags;  
  7.    PVOID DriverStart;  
  8.    ULONG DriverSize;  
  9.    PVOID DriverSection;  
  10.    PDRIVER_EXTENSION DriverExtension;  
  11.    UNICODE_STRING DriverName;  
  12.    PUNICODE_STRING HardwareDatabase;  
  13.    PFAST_IO_DISPATCH FastIoDispatch;  
  14.    PDRIVER_INITIALIZE DriverInit;  
  15.    PDRIVER_STARTIO DriverStartIo;  
  16.    PDRIVER_UNLOAD DriverUnload;  
  17.    PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];  
  18. } DRIVER_OBJECT;  
<TEXTAREA class="cpp" style="DISPLAY: none" name=code rows=10 cols=60>typedef struct _DRIVER_OBJECT { CSHORT Type; CSHORT Size; PDEVICE_OBJECT DeviceObject; ULONG Flags; PVOID DriverStart; ULONG DriverSize; PVOID DriverSection; PDRIVER_EXTENSION DriverExtension; UNICODE_STRING DriverName; PUNICODE_STRING HardwareDatabase; PFAST_IO_DISPATCH FastIoDispatch; PDRIVER_INITIALIZE DriverInit; PDRIVER_STARTIO DriverStartIo; PDRIVER_UNLOAD DriverUnload; PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; } DRIVER_OBJECT; </TEXTAREA>
아래는 흔히 보는 코드이다.
 
  1. NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath )  
  2. {  
  3.     UNICODE_STRING symName, symDevice;  
  4.     PDEVICE_OBJECT pDeviceObject0, pDeviceObject1;  
  5.     PDEVICE_EXTENSION pExt;  
  6.     NTSTATUS status;  
  7.       
  8.     // 드라이버 로드된 것을 DebugView에 뿌려준다.  
  9.     DbgPrint("HzDevice is Loaded\n");  
  10.       
  11.     // UniCode String을 초기화한다.  
  12.     RtlInitUnicodeString(&symDevice, L"\\Device\\System0");  
  13.     RtlInitUnicodeString(&symName, L"\\??\\UserSystem0");  
  14.       
  15.     status = IoCreateDevice( DriverObject, sizeof(DEVICE_EXTENSION),   
  16.                              &symDevice, FILE_DEVICE_HZ, 0, FALSE, &pDeviceObject0 );  
  17.     if( NT_SUCCESS( status ) )  
  18.     {  
  19.         // device Extention으로 변환한다.  
  20.         pExt = (PDEVICE_EXTENSION)pDeviceObject0->DeviceExtension;  
  21.         // Success  
  22.         pExt->Ordinal = 0;  
  23.           
  24.         status = IoCreateSymbolicLink( &symName, &symDevice );  
  25.           
  26.         // IoCreateSymbolicLink() 가 실패 하면  
  27.         if( !NT_SUCCESS( status ) )  
  28.         {  
  29.             IoDeleteDevice( pDeviceObject0 );  
  30.             pExt->Ordinal = -1;  
  31.         }  
  32.     }  
  33.       
  34.     // Dispatch Table을 작성한다.  
  35.     DriverObject->DriverUnload = HzUnload;  
  36.     DriverObject->MajorFunction[ IRP_MJ_CREATE ] = hzIoDispatch;  
  37.     DriverObject->MajorFunction[ IRP_MJ_CLOSE ] = hzIoDispatch;  
  38.       
  39.     return STATUS_SUCCESS;  
  40. }  

<TEXTAREA class="cpp" style="DISPLAY: none" name=code rows=10 cols=60>NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath ) { UNICODE_STRING symName, symDevice; PDEVICE_OBJECT pDeviceObject0, pDeviceObject1; PDEVICE_EXTENSION pExt; NTSTATUS status; // 드라이버 로드된 것을 DebugView에 뿌려준다. DbgPrint("HzDevice is Loaded\n"); // UniCode String을 초기화한다. RtlInitUnicodeString(&symDevice, L"\\Device\\System0"); RtlInitUnicodeString(&symName, L"\\??\\UserSystem0"); status = IoCreateDevice( DriverObject, sizeof(DEVICE_EXTENSION), &symDevice, FILE_DEVICE_HZ, 0, FALSE, &pDeviceObject0 ); if( NT_SUCCESS( status ) ) { // device Extention으로 변환한다. pExt = (PDEVICE_EXTENSION)pDeviceObject0->DeviceExtension; // Success pExt->Ordinal = 0; status = IoCreateSymbolicLink( &symName, &symDevice ); // IoCreateSymbolicLink() 가 실패 하면 if( !NT_SUCCESS( status ) ) { IoDeleteDevice( pDeviceObject0 ); pExt->Ordinal = -1; } } // Dispatch Table을 작성한다. DriverObject->DriverUnload = HzUnload; DriverObject->MajorFunction[ IRP_MJ_CREATE ] = hzIoDispatch; DriverObject->MajorFunction[ IRP_MJ_CLOSE ] = hzIoDispatch; return STATUS_SUCCESS; } </TEXTAREA>

여기서 보면 Driver_Object 구조체에서 MajorFunction에 함수 포인터를 넣어주는 부분이 보인다.

중요 필드의 변수들을 한번 살펴 보자,

 ☞ DeviceObject - 드라이버가 가장 최근에 생성한 DeviceObject를 가르키는 포인터
 ☞ DeviceExtension - 하위 레벨 드라이버에서 하드웨어 장치와 주변 장치들을 관리하기위한 PnP 지원 필드
 ☞ DriverStart - 드라이버가 메모리에 보관된 시작 위치
 ☞ DriverName - 드라이버의 서비스 이름
 ☞ HardwareDatabase - 드라이버가 등록되어 있는 서비스 키
 ☞ DriverInit - DriverEntry 함수 주소
 ☞ MajorFunction - 드라이버가 처리하는 IRP 명령어를 위한 Dispatch Routine들

위의 예제 코드와 위의 설명을 보게 되면, 이해하기 쉬울 것이다.

다음에는 DEVICE_OBJECT 구조체를 알아보자,

 

출처 : 출처 : http://ssmhz.tistory.com

위로 스크롤