>VOID XDSPdrvDevice::StartIo(KIrp I) {
> t << "Entering StartIo, " << I << EOL;
> // Здесь надо проверить, отменен этот запрос или нет. Это производится при помощи вызова
> //метода TestAndSetCancelRoutine. Также этот метод устанавливает новую функцию отмены
> //пакетов, если это необходимо. Адрес новой функции передается вторым параметром. Если
> //он равен NULL,то вызывается старая функция. Если пакет должен быть отменен, функция
> //вернет FALSE.
> if (!I.TestAndSetCancelRoutine(LinkTo(CancelQueuedIrp), NULL, CurrentIrp())) {
> //Пакет отменен.
> return;
> }
> // Начать обработку запроса.
> // Выбрать необходимую функцию
> switch (I.MajorFunction()) {
> case IRP_MJ_READ:
> //Чтение
> SerialRead(I);
> break;
> case IRP_MJ_WRITE:
> //Запись
> SerialWrite(I);
> break;
> case IRP_MJ_DEVICE_CONTROL:
> //IOCTL
> switch (I.IoctlCode()) {
> default:
> //Мы обрабатываем пакет, который не должен быть обработан.
> //Поэтому просто выходим.
> ASSERT(FALSE);
> break;
> }
> break;
> default:
> // Драйвер занес в очередь какой-то непонятный пакет,
> //он не должен быть обработан.
> ASSERT(FALSE);
> PnpNextIrp(I);
> break;
> }
>}
Метод Create вызывается, когда пользовательское приложение пытается установить связь с драйвером при помощи вызова API CreateFile(). Обычно этот запрос обрабатывается в нашем объекте устройства и нет смысла пересылать запрос устройству нижнего уровня.
>NTSTATUS XDSPdrvDevice::Create(KIrp I) {
> NTSTATUS status;
> t << "Entering XDSPdrvDevice::Create, " << I << EOL;
> //Здесь можно вставить код пользователя, который должен быть вызван при установлении
> //приложением связи с устройством.
> status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);
> t << "XDSPdrvDevice::Create Status " << (ULONG)status << EOL;
> return status;
>}
Аналогично метод Close вызывается при разрыве связи приложения с драйвером.
>NTSTATUS XDSPdrvDevice::Close(KIrp I) {
> NTSTATUS status;
> t << "Entering XDSPdrvDevice::Close, " << I << EOL;
> //Здесь можно вставить код пользователя, который должен быть вызван при разрыве
> //приложением связи с устройством.
> status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);
> t << "XDSPdrvDevice::Close Status " << (ULONG)status << EOL;
> return status;
>}
В этих методах можно ввести проверки каких-либо условий. Отвлечемся на секунду от нашей PCI-карточки и обратим внимание на другой хороший пример — тот же программатор микроконтроллеров. Предположим, пользователь подключил программатор к компьютеру и начинает записывать в память микроконтроллера разработанную им программу. В принципе, ничто не помешает ему открыть еще одну копию программы и писать в ту же микросхему что-то совсем другое. В результате, в эту несчастную микросхему запишется невообразимая каша. Для того, чтобы избежать такой ситуации, в объекте драйвера надо установить флаг, который будет показывать, свободно ли это устройство, или оно уже кем-то используется. Это может выглядеть так: