Chris Cant - Writing Windows WDM Device Drivers

Здесь есть возможность читать онлайн «Chris Cant - Writing Windows WDM Device Drivers» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Город: Lawrence, Kansas 66046, ISBN: , Издательство: R & D Books, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Writing Windows WDM Device Drivers: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Writing Windows WDM Device Drivers»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Writing Windows WDM Device Drivers — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Writing Windows WDM Device Drivers», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать
Write

Things start to get interesting in the write dispatch routine, Wdm1Write , shown in Listing 7.2. It starts by getting the current stack location pointer and retrieving the current file pointer and the number of bytes to transfer. If the file pointer is less than zero (the kernel should ensure that it never is), it returns STATUS_INVALID_PARAMETER. It is possible to receive a transfer length of zero.

Listing 7.2 Wdm1 write dispatch routine

NTSTATUS Wdm1Write(IN PDEVICE_OBJECT fdo, IN PIRP Irp) {

PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);

NTSTATUS status = STATUS_SUCCESS;

ULONG BytesTxd = 0;

// Get call parameters

LONGLONG FilePointer = IrpStack->Parameters.Write.ByteOffset.QuadPart;

ULONG WriteLen = IrpStack->Parameters.Write.Length;

DebugPrint("Write %d bytes from file pointer %d", (int)WriteLen,(int)FilePointer);

if (FilePointer<0) status = STATUS_INVALID_PARAMETER;

else {

// Get access to the shared buffer

KIRGL irql ;

KeAcquireSpinLock(&BufferLock,&irql);

BytesTxd = WriteLen;

// (Re)allocate buffer if necessary

if ( ((ULONG)FilePointer)+WriteLen>BufferSize) {

ULONG NewBufferSize = ((ULONG)FilePointer)+WriteLen;

PVOID NewBuffer = ExAllocatePool(NonPagedPool.NewBufferSize);

if (NewBuffer==NULL) {

BytesTxd = BufferSize – (ULONG)FilePointer;

if (BytesTxd<0) BytesTxd = 0;

} else {

RtlZeroMemory(NewBuffer,NewBufferSize);

if (Buffer!=NULL) {

RtlCopyMemory(NewBuffer,Buffer,BufferSize);

ExFreePool(Buffer);

}

Buffer = (PUCHAR)NewBuffer;

BufferSize = NewBufferSize;

}

}

// Write to shared memory

if (BytesTxd>0 && Buffer!=NULL) RtlCopyMemory(Buffer+FilePointer, Irp->AssociatedIrp.SystemBuffer, BytesTxd);

// Release shared buffer

KeReleaseSpinLock(&BufferLock,irql);

}

DebugPrint("Write: %d bytes written", (int)BytesTxd);

// Complete IRP

return Completelrp(Irp,status,BytesTxd);

}

The shared memory buffer is implemented using these three global variables.

KSPIN_LOCK BufferLock;

PUCHAR Buffer = NULL;

ULONG BufferSize = 0;

If the buffer size is greater than zero, Buffer points to some nonpaged memory of this size. As mentioned earlier in this chapter, there must be some mechanism to protect access to such global variables in a multiprocessor environment (e.g., to prevent one dispatch routine from changing BufferSize while another, or even the same, routine tries to access or change it simultaneously).

Spin Locks

A kernel spin lock called BufferLock provides this protection. A spin lock can be used where code needs access to a resource of some sort for a short time.

The spin lock is initialized in the Wdm1 DriverEntry routine as follows.

KeInitializeSpinLock(&BufferLock);

Use the KeAcquireSpinLock function to acquire a spin lock and KeReleaseSpinLock to release it. Only one instance of a piece of code can acquire a spin lock at the same time. Other attempts to acquire the spin lock will "spin" until the resource becomes available. "Spinning" means that KeAcquireSpinLock keeps looking continuously. For this reason, make sure that you only hold a spin lock for a short time. The DDK recommends that you never hold a spin lock for more than 25 microseconds.

As shown in the code example, you must provide a pointer to a KIRQL variable in the call to KeAcquireSpinLock . This stores the original IRQL level before it is raised (if necessary) to DISPATCH_LEVEL The call to KeReleaseSpinLock lowers the IRQL if necessary. If you are certain that your code is working at DISPATCH_LEVEL, you can use the KeAcquireSpinLockAtDpcLevel and KeReleaseSpinLockFromDpcLevel routines for better performance.

The Wdm1 driver acquires the BufferLock spin lock for the duration of any accesses to the Buffer and BufferSize variables. Do not access paged code or data while holding a spin lock, as the system will almost certainly crash. Definitely do not exit a main dispatch routine while holding a spin lock.

Write Algorithm

The write dispatch stores the write data in the shared memory buffer, starting from the given file pointer. It extends the buffer, if necessary.

If there is no buffer at all, or the buffer needs to be extended, ExAllocatePool is called to allocate some nonpaged memory. Notice that the algorithm checks for a NULL return value and copes as best as it can.

A new memory buffer is zeroed using RtlZeroMemory . If an old shorter buffer exists, it is copied to the start of the new buffer using RtlCopyMemory . RtlMoveMemory can be used if the source and destination pointers overlap. The old buffer is removed with ExFreePool .

Finally, Wdm1Write copies the data from the user buffer using RtlCopyMemory . As Wdm1 uses Buffered I/O, it can simply copy the data from Irp->AssociatedIrp.SystemBuffer.

This algorithm is fairly crude, because the buffer may have to be reallocated often. A much-enhanced version of Wdm1 could implement a RAM disk.

The driver unload routine frees any shared memory buffer.

if (Buffer!=NULL) ExFreePool(Buffer);

Read

The read dispatch routine for Wdm1, Wdm1Read , is simpler than the write handler. It acquires the spin lock while it accesses the global variables. The required number of bytes are copied to the user's buffer at Irp->AssociatedIrp.SystemBuffer. If the user requests more data than is in the buffer, the request is truncated.

IOCTL

The Wdm1DeviceControl dispatch routine handles the four IOCTLs defined for Wdm1 devices: Zero the buffer, Remove the Buffer, Get the buffer size, and Get the buffer.

All these IOCTLs use Buffered I/O, so any input and output data is found at Irp->Associ-atedIrp.SystemBuffer. As usual, the routine acquires the shared buffer spin lock for the duration of the call. The actual implementation of each IOCTL is straightforward. The Get buffer size and Get buffer handlers check that the output buffer is large enough; if not, they return STATUS INVALID_PARAMETER.

Defining IOCTLs

An IOCTL code is a 32-bit value formed using the CTL_CODE macro shown in Table 7.4. The Wdm1 example defines its IOCTL codes in Ioctl.h, as shown in this example.

//define IOCTL_WDM1_ZERO_BUFFER CTL_CODE( \

FILE_DEVICE_UNKNOWN, \

0x801, \

METHOD_BUFFERED, \

FILE_ANY_ACCESS)

Table 7.4 CTL_CODE macro parameters

Parameter Description
DeviceType FILE_DEVICE_XXX value given to IoCreateDevice.
Control Code IOCTL Function Code 0x000–0x7FFReserved for Microsoft 0x800-0xFFFPrivate codes
TransferType METHOD_BUFFERED METHOD_IN_DIRECT METHOD_OUT_DIRECT METHOD_NEITHER
RequiredAccess FILE_ANY_ACCESS FILE READ_DATA FILE_WRITE_DATA FILE READ_DATA|FILE_WRITE_DATA

Ioctl.h is also included in the Wdm1Test project. It includes the standard winioctl.h header file first to get the definition of CTL_CODE.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Writing Windows WDM Device Drivers»

Представляем Вашему вниманию похожие книги на «Writing Windows WDM Device Drivers» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Writing Windows WDM Device Drivers»

Обсуждение, отзывы о книге «Writing Windows WDM Device Drivers» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x