1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
| #include "Ioctl.h"
#include "Driver.h"
/*##################################################################################*/
/********************Точка добавления нового устройства*************************************************/
/*##################################################################################*/
NTSTATUS AddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo )
{
DbgPrint("AddDevice\n");
/*переменная для хранения статуса ( возвращаемые значния системных функций )*/
NTSTATUS status;
/*здесь будет храниться адрес созданного объекта-устрйоства*/
PDEVICE_OBJECT fdo;
/*переменные для хранения имени объекта-устройства*/
UNICODE_STRING NtDeviceName, DosDeviceName;
/*формирование символьную ссылку ( имя видимое пользователем)*/
RtlInitUnicodeString( &NtDeviceName, L"\\Device\\LedTestD" );
/*формирование символьную ссылку ( имя видимое ядром)*/
RtlInitUnicodeString( &DosDeviceName, L"\\DosDevices\\LEDD");
/*создание объект-устрйоства*/
status = IoCreateDevice( DriverObject, sizeof( DEVICE_EXTENSION ), &NtDeviceName,
FILE_DEVICE_UNKNOWN, 0,FALSE , &fdo );
/*проверяем возвращаемый статус на успех*/
if(!NT_SUCCESS( status ) )
{
/*в случае ошибки при создании устройства удаляем выделенную для него память*/
IoDeleteDevice( fdo );
}
fdo->Flags = fdo->Flags | (DO_BUFFERED_IO | DO_POWER_PAGABLE);
fdo->Flags = fdo->Flags & ~DO_DEVICE_INITIALIZING;
/*присоединяем к стеку устрйоств*/
/*создаём символьную ссылку*/
status = IoCreateSymbolicLink( &DosDeviceName, &NtDeviceName );
/*проверяем возвращаемый статус на успех*/
if(!NT_SUCCESS( status ) )
return status;
/*Получаем указатель на область, предназначенную под
структуру расширение устройства*/
return STATUS_SUCCESS;
}
NTSTATUS DispatchPower( IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
DbgPrint("DispatchPower\n");
return CompleteIrp(Irp,STATUS_SUCCESS,0);
}
NTSTATUS DispatchPnp( IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
DbgPrint("DispatchPnp\n");
return CompleteIrp(Irp,STATUS_SUCCESS,0);
}
/*##################################################################################*/
/********************Точка диспетчерезации(обработка IRP пакетов)************************************/
/*##################################################################################*/
NTSTATUS DispatchWmi( IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
DbgPrint("DispatchWmi\n");
/*Указатель на стековую область*/
PIO_STACK_LOCATION pIrpStack;
/*Сохраним адрес стековой области*/
pIrpStack = IoGetCurrentIrpStackLocation( Irp );
/*выполним требуемые действия*/
switch( pIrpStack -> Parameters.DeviceIoControl.IoControlCode )
{
case IOCTL_LAD_OFF:
__asm{
mov AL,0xED
out 60h,AL
loopK1:
in AL,64h
and AL,2
cmp AL,0
jne loopK1
mov AL,0
out 60h,AL
}
break;
case IOCTL_LAD_ON:
__asm{
mov AL,0xED
out 60h,AL
loopK2:
in AL,64h
and AL,2
cmp AL,0
jne loopK2
mov AL,3
out 60h,AL
}
break;
}
return STATUS_SUCCESS;
}
NTSTATUS DispatchCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
DbgPrint("DispatchCreate\n");
return CompleteIrp(Irp,STATUS_SUCCESS,0);
}
NTSTATUS DispatchClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
DbgPrint("DispatchClose\n");
return CompleteIrp(Irp,STATUS_SUCCESS,0);
}
/*##################################################################################*/
/********************Точка выгрузки объект-драйвера*****************************************************/
/*##################################################################################*/
VOID DriverUnload( IN PDRIVER_OBJECT DriverObject )
{
DbgPrint("DriverUnload\n");
UNICODE_STRING DosDeviceName;
RtlInitUnicodeString(&DosDeviceName, L"\\Device\\LEDD" );
IoDeleteSymbolicLink(&DosDeviceName);
IoDeleteDevice(DriverObject->DeviceObject);
}
//Чтобы не создавать большое количество прототипов , DriverEntry распаложенна в конце
/*##################################################################################*/
/********************функция инициализации драйвера ***************************************************/
/*##################################################################################*/
extern "C"
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject , IN PUNICODE_STRING RegistryPath )
{
/*Фактически здесь мы должны проинициализировать необходимые поля экземпляра ( объекта )
частично документированной структуры PDEVICE_OBJECT выделенной нам Диспетчером I/O */
DbgPrint("DriverEntry\n");
/*регестрируем в объекте-драйвере точку выгрузки*/
DriverObject->DriverUnload = DriverUnload;
/*регестрируем в объекте-драйвере точку для расширения ( добавления ) объекта-устройства*/
DriverObject->DriverExtension->AddDevice = AddDevice;
/*регестрируем в объекте-драйвере точку обработки запроса IRP от PnP*/
DriverObject->MajorFunction[ IRP_MJ_PNP] = DispatchPnp;
/*регестрируем в объекте-драйвере точку обработки запроса IRP от Power I/O*/
DriverObject->MajorFunction[ IRP_MJ_POWER] = DispatchPower;
/*регестрируем в объекте-драйвере точку обработки запроса IRP от Power WMI*/
DriverObject->MajorFunction[ IRP_MJ_SYSTEM_CONTROL] = DispatchWmi;
/*регестрируем в объекте-драйвере точку вызываемую при открытие драйвера*/
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
/*регестрируем в объекте-драйвере точку вызываемую при закрытие драйвера*/
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
/*возвращаем Диспетчеру I/O код о успешной инициализации объекта-драйвера,*/
/*другими словами возвращаем управдение */
return STATUS_SUCCESS;
} |