Hi everyone,
I’m working on cleaning up an AHCI Port driver that my team wrote some years ago. (I should also mention I’ve very green when it comes to driver development.) Presently, this driver causes the system to BSOD whenever I enable Driver Verifier on it. The problem appears to be coming from the driver’s AddDevice routine. I’m using this link for reference (http://msdn.microsoft.com/en-us/library/windows/hardware/ff540529(v=vs.85).aspx).
I have 3 main concerns. First, the call to IoCreateDevice is passing in a device name string though the link I referenced earlier says not to do this.
Second, the lack of assignment of the PDO to the device extension. I have a few questions about this. First, the device extension structure for this driver currently hasn’t a field named PDEVICE_OBJECT pPdo. I’ll have to add it. Is it supposed to be in a specific place? Secondly, why is this assignment important? It seems that every function that is called to handle “something” from the user world get’s a pointer to the physical device object anyway.
Third, although several of the steps mentioned in that link from MSDN are missing, I’m very concerned with the fact that IoAttachDeviceToDeviceStack() is commented. It seems as though this should not be.
For reference, here’s how the function looks right now.
NTSTATUS AddDevice(__in struct _DRIVER_OBJECT *DriverObject, __in struct _DEVICE_OBJECT *PhysicalDeviceObject)
{
NTSTATUS ntStatus;
PDEVICE_OBJECT DeviceObject = NULL;
WinIoDevExt* pDevExt = NULL;
LONG tempDriverNum;
DECLARE_UNICODE_STRING_SIZE(DeviceNameUnicodeString, MAX_ID_LEN);
DECLARE_UNICODE_STRING_SIZE(DeviceLinkUnicodeString, MAX_ID_LEN);
UNREFERENCED_PARAMETER(PhysicalDeviceObject);
OutputDebugString (“Entering DriverEntry”);
tempDriverNum = driverNum;
InterlockedIncrement(&driverNum);
ntStatus = RtlUnicodeStringPrintf(&DeviceNameUnicodeString, L"\Device\Port%d",tempDriverNum);
ntStatus = IoCreateDevice (DriverObject,
sizeof(WinIoDevExt),
&DeviceNameUnicodeString,
FILE_DEVICE_WINIO,
FILE_DEVICE_SECURE_OPEN,
TRUE,
&DeviceObject);
if (NT_SUCCESS(ntStatus))
{
// Create dispatch points for device control, create, close.
// Create a symbolic link, e.g. a name that a Win32 app can specify
// to open the device.
ntStatus = RtlUnicodeStringPrintf(&DeviceLinkUnicodeString, L"\DosDevices\Port%d",tempDriverNum);
ntStatus = IoCreateSymbolicLink (&DeviceLinkUnicodeString,
&DeviceNameUnicodeString);
if (!NT_SUCCESS(ntStatus))
{
// Symbolic link creation failed- note this & then delete the
// device object (it’s useless if a Win32 app can’t get at it).
OutputDebugString (“ERROR: IoCreateSymbolicLink failed”);
IoDeleteDevice (DeviceObject);
}
else
{
pDevExt = (WinIoDevExt*) DeviceObject->DeviceExtension;
RtlZeroMemory(pDevExt, sizeof(WinIoDevExt));
pDevExt->emulation = TRUE;
pDevExt->initialized = FALSE;
pDevExt->driverMode = NORMAL;
pDevExt->noReset = FALSE;
//IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
ntStatus = IoInitializeTimer(DeviceObject, (PIO_TIMER_ROUTINE) &TimerRoutine, pDevExt);
if (!NT_SUCCESS(ntStatus))
{
IoDeleteDevice(DeviceObject);
}
}
}
else
{
OutputDebugString (“ERROR: IoCreateDevice failed”);
}
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
OutputDebugString (“Leaving DriverEntry”);
return ntStatus;
}
Please help me in understanding this function.
Thanks,
Andy