DRIVER_OBJECT와 DEVICE_OBJECT 구조체는 중요하다.
두개가 헷갈려 하는 경우도 많은데,
일단
DRIVER_OBJECT는 함수포인터로 구성되어 있다.
나머지 필드는 직접 수정을 하면 안되는 부분도 있다.
- 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;
아래는 흔히 보는 코드이다.
- 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 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