before. This creates the phddo device object and its associated device extension. The
All the appropriate fields are set up in the device extension, including the
Listing 18.1 NT style device creation
PDEVICE_OBJECT phddo = NULL;
#define NT_DEVICE_NAME L'\Device\PHDIo'
#define SYM_LINK_NAME L'\DosDevices\PHDIo'
NTSTATUS PHDIoCreateDevice(IN PDRIVER_OBJECT DriverObject {
NTSTATUS status = STATUS_SUCCESS;
// Initialise NT and Symbolic link names
UNICODE_STRING deviceName, linkName;
RtlInitUnicodeString(&deviceName, NT_DEVICE_NAME);
RtlInitUnicodeString(&linkName, SYM_LINK_NAME);
// Create our device
DebugPrint('Creating device %T',&deviceName);
status = IoCreateDevice(
DriverObject,
sizeof(PHDIO_DEVICE_EXTENSION),
&deviceName,
FILE_DEVICE_UNKNOWN,
0,
TRUE, // Exclusive
&phddo);
if (!NT_SUCCESS(status)) {
DebugPrintMsg('Could not create device');
return status;
}
phddo->Flags |= DO_BUFFEREO_IO;
// Initialise device extension
PPHDIO_DEVICE_EXTENSION dx = (PPHDIO_DEVICE_EXTENSION)phddo->DeviceExtension;
dx->phddo = phddo;
dx->UsageCount = 1;
KeInitializeEvent(&dx->StoppingEvent, NotificationEvent, FALSE);
dx->Stopping = false;
dx->GotPortOrMemory = false;
dx->GotInterrupt = false;
dx->ConnectedToInterrupt = false;
dx->SetTimeout = 10;
dx->Timeout = –1;
dx->StopTimer = false;
dx->WriteCmds = NULL;
dx->ReadCmds = NULL;
dx->StartReadCmds = NULL;
// Initialise timer for this device (but do not start)
status = IoInitializeTimer(phddo, (PIO_TIMER_ROUTINE)Timeout1s, dx);
if (!NT_SUCCESS(status)) {
DebugPrintMsg('Could not initialise timer');
IoDeleteDevice(phddo);
return status;
}
// Create a symbolic link so our device is visible to Win32…
DebugPrint('Creating symbolic link %T', &linkName);
status = IoCreateSymbolicLink(&linkName, &deviceName);
if (!NT_SUCCESS(status)) {
DebugPrintMsg('Could not create symbolic link');
IoDeleteDevice(phddo);
return status;
}
// Initialise our DPC for IRQ completion processing
IoInitializeDpcRequest(phddo, PHDIoDpcForIsr);
return status;
}
When PHDIo is unloaded, its
If a driver makes a variable number of devices, the unload routine could use the following technique to find all the devices to remove. The kernel sets the driver object
Claiming Resources
This section looks at how to allocate resources. The crucial kernel function is
The PHDIo driver only finds out which resources are needed when the user calls
1. Get the resource details from the filename.
2. Check for resource conflicts and reserve the resources.
3. Translate and map the resources.
Getting the resource details is handled by the