Trying to understand the AddDevice function

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

xxxxx@micron.com wrote:

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.

Why do you say “appears to be”? From the dump analysis, you ought to be
able to determine exactly which line is causing the BSOD. What bug code
do you get in the BSOD?

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.

That’s just a recommendation; most devices don’t need a name.

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.

AddDevice is the only routine that gets a PDO. The other functions all
get the driver’s own device object (the FDO).

As to whether you need to save it, that all depends on whether you need
the PDO or not. If you never send anything down to the driver below
you, then you don’t need the PDO.

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.

Yes. If this is a PnP device, and it appears that it is, then it needs
to call IoAttachDeviceToDeviceStack.

For reference, here’s how the function looks right now.

NTSTATUS AddDevice(__in struct _DRIVER_OBJECT *DriverObject, __in struct _DEVICE_OBJECT *PhysicalDeviceObject)
{

OutputDebugString (“Entering DriverEntry”);

OutputDebugString is a user-mode API. Do you have a #define that
changes this to DbgPrint?

And this is not DriverEntry, it’s AddDevice.

tempDriverNum = driverNum;
InterlockedIncrement(&driverNum);

That’s not the right way to use InterlockedIncrement. The whole point
of that API is that you do everything in one step. Otherwise, the
interlock does no good. You should use:

tempDriverNum = InterlockedIncrement(&driverNum);

I’m guessing driver verifier doesn’t like the fact that you exit without
attaching to a driver stack, but only the dump analysis can tell you that.

There is another minor problem in this code:

ntStatus = IoCreateDevice (DriverObject,
sizeof(WinIoDevExt),
&DeviceNameUnicodeString,
FILE_DEVICE_WINIO,
FILE_DEVICE_SECURE_OPEN,
TRUE,
&DeviceObject);

if (NT_SUCCESS(ntStatus))
{

}
else
{
OutputDebugString (“ERROR: IoCreateDevice failed”);
}

DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

If IoCreateDevice fails, then DeviceObject will be null, and that last
line will cause a BSOD. It’s probably better to change that first if to
if (!NT_SUCCESS(ntStatus))
{
OutputDebugString(“ERROR: IoCreateDevice failed”);
return ntStatus;
}

OutputDebugString (“Leaving DriverEntry”);
return ntStatus;
}

This is not DriverEntry, this is AddDevice.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim,

Thanks for the quick reply. The bugcheck dump from !analyze -v is lengthy and it doesn’t show me precisely where the problem is (maybe I didn’t check enough things in the list to verify). I checked only “I/O Verification” from the list. When I tried before hand, “Special Pool”, “Force IRQL Tracking” and “Pool Tracking” produced no BSOD: it was only when I checked “I/O Verification”.

The stack trace makes me think that it’s probably the fact that IoAttachDeviceToDeviceStack is commented. The bug check is a NULL_CLASS_PTR_DEREFERENCE (0x7e).

CONTEXT: fffff880037aed80 – (.cxr 0xfffff880037aed80)
rax=0000000000000000 rbx=fffffa8008a13730 rcx=0000000000000000
rdx=0000000000000002 rsi=0000000000000000 rdi=0000000000000005
rip=fffff80003912399 rsp=fffff880037af768 rbp=fffffa8006017960
r8=0000000000000000 r9=fffffa8006017960 r10=fffffa8006017960
r11=fffff880037af438 r12=fffffa8008b65b30 r13=0000000000000005
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010202
nt!IovUtilMarkDeviceObject+0x9:
fffff80003912399 488b8938010000 mov rcx,qword ptr [rcx+138h] ds:002b:0000000000000138=???
Resetting default scope

PROCESS_NAME: System

CURRENT_IRQL: 2

ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

EXCEPTION_PARAMETER1: 0000000000000000

EXCEPTION_PARAMETER2: 0000000000000138

READ_ADDRESS: 0000000000000138

FOLLOWUP_IP:
nt!IovUtilMarkDeviceObject+9
fffff800`03912399 488b8938010000 mov rcx,qword ptr [rcx+138h]

BUGCHECK_STR: 0x7E

DEFAULT_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE

LOCK_ADDRESS: fffff80003a8cbe0 – (!locks fffff80003a8cbe0)

Resource @ nt!PiEngineLock (0xfffff80003a8cbe0) Exclusively owned
Contention Count = 2
NumberOfExclusiveWaiters = 1
Threads: fffffa8005536040-01<*>
Threads Waiting On Exclusive Access:
fffffa8005536b50

1 total locks, 1 locks currently held

PNP_TRIAGE:
Lock address : 0xfffff80003a8cbe0
Thread Count : 1
Thread address: 0xfffffa8005536040
Thread wait : 0x356

LAST_CONTROL_TRANSFER: from fffff80003979a12 to fffff800038809f0

STACK_TEXT:
fffff880037af768 fffff80003940a57 : 0000000000000000 0000000000000000 0000000000000005 0000000000000002 : nt!IovUtilMarkDeviceObject+0x9
fffff880037af770 fffff80003c769fd : fffffa8006017960 0000000000000000 fffff8a005266b80 fffff8a005266b80 : nt!IovUtilMarkStack+0x67
fffff880037af7a0 fffff80003c77ed2 : fffffa8008a13730 fffffa8008a13730 0000000000000000 fffffa8008b65b30 : nt!PipCallDriverAddDevice+0x71d
fffff880037af950 fffff80003c7836c : fffff80003a8a560 0000000000000000 0000000000000001 fffff80003af3e08 : nt!PipProcessDevNodeTree+0x2b2
fffff880037afbc0 fffff8000398b802 : 0000000100000003 fffff80003a2e2d8 0000000000000001 0000000000000000 : nt!PiProcessStartSystemDevices+0x7c
fffff880037afc10 fffff80003892261 : fffff8000398b500 fffff8a00084bc01 fffff80003a2e200 0000000000000000 : nt!PnpDeviceActionWorker+0x302
fffff880037afcb0 fffff80003b252ea : 0000000000000000 fffffa8005536040 0000000000000080 fffffa80054a3b30 : nt!ExpWorkerThread+0x111
fffff880037afd40 fffff800038798e6 : fffff8800356a180 fffffa8005536040 fffff880035750c0 0000000000000000 : nt!PspSystemThreadStartup+0x5a
fffff880037afd80 0000000000000000 : fffff880037b0000 fffff880037aa000 fffff880037aeb10 0000000000000000 : nt!KiStartSystemThread+0x16

You have the code for AddDevice, I think the only place that a null device reference would come from is the lack of that function being called.

Andy

xxxxx@micron.com wrote:

Thanks for the quick reply. The bugcheck dump from !analyze -v is lengthy and it doesn’t show me precisely where the problem is (maybe I didn’t check enough things in the list to verify). I checked only “I/O Verification” from the list. When I tried before hand, “Special Pool”, “Force IRQL Tracking” and “Pool Tracking” produced no BSOD: it was only when I checked “I/O Verification”.

The stack trace makes me think that it’s probably the fact that IoAttachDeviceToDeviceStack is commented. The bug check is a NULL_CLASS_PTR_DEREFERENCE (0x7e).

Looks like it. So, add in the IoAttachDeviceToDeviceStack call and
let’s see what happens.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

So, now I’m getting somewhere. I uncommented the line as it was written. I added a check to verify the returned pointer from IoAttachDeviceToDeviceStack isn’t NULL and to exit with a code if it is.

I verified that the system still boots with this change in place. I then started driver verifier on it and I’m finally getting a verifier error in the debugger. It’s IOMANAGER_VIOLATION (c9). It’s taken quite a bit of digging (I’m so very new to this) but I’ve finally narrowed it down to the fact that the driver doesn’t arrange for a handler for the IRP_MJ_PNP IRP.

The verifier bugcheck showed me enough right off that I knew the driver wasn’t assigning a handler for a major IRP. The code from this bugcheck was 0x21f which states that this is a non-fatal problem. What took the most time was deciphering the output of !irp to make sure I was looking at the correct IRP number. I got this:

4: kd> !irp fffffa8008a63430
Irp is active with 5 stacks 5 is current (= 0xfffffa8008a63620)
No Mdl: No System Buffer: Thread fffffa8005536040: Irp stack trace.
cmd flg cl Device File Completion-Context
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[1b,18] 0 e0 fffffa8008a636b0 00000000 fffff80003d15eb0-fffffa8008a63620 Success Error Cancel
\DRIVER\VERIFIER_FILTER nt!IovpInternalCompletionTrap
Args: 00000000 00000000 00000000 00000000

[1b,18] 0 0 fffffa8008a636b0 00000000 00000000-00000000
\DRIVER\VERIFIER_FILTER
Args: 00000000 00000000 00000000 00000000

I interpret all of that to mean it’s IRP 0x1b which is IRP_MJ_PNP. Although this is classified as a non-fatal issue, it seems that it’s still reasonable that something must be provided for these functions. Where can I look for some examples on how to handle the minor PNP IRPs associated with this major IRP?

Andy

Adding PnP support to a WDM driver such as you have is no small (or even medium sized) task. This task is made even more complex by the need to coordinate what you’re doing with you power mgmt code.

It’s hard to know what to advise youth yo do in this situation. Really, the extent of the work begs the question: what are you hoping to DO with thus driver once it’s “done”?

Peter
OSR
@OSRDrivers

> 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.

There were some security issues with this, namely: what DO in the devnode stack is used for an ACL check in Create path.

PnP suggests to ONLY PDO have name, which is usually auto-generated by the kernel, so only the PDO’s ACL will be used for checks.

This mean that any other names you need should NOT be created by providing name to IoCreateDevice of the FDO/FiDO. Instead, ObQueryNameString the PDO and then IoCreateSymbolicLink the your alternative name (same name as above).

Some stacks like CD/DVD drive letters IIRC still violate this (at least in Win7), though.

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?

No.

Secondly, why is this assignment important?

To call IoGetDeviceProperty and some other PnP functions later.

IRPs are sent to the DoBelowYou, not to the Pdo. But IoGetDeviceProperty requires a PDO.

Surely attach must be done in AddDevice.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

The effort is lowered by skipping WDM and moving to WDF.

Mark Roddy

On Mon, Mar 17, 2014 at 8:47 PM, wrote:

> Adding PnP support to a WDM driver such as you have is no small (or even
> medium sized) task. This task is made even more complex by the need to
> coordinate what you’re doing with you power mgmt code.
>
> It’s hard to know what to advise youth yo do in this situation. Really,
> the extent of the work begs the question: what are you hoping to DO with
> thus driver once it’s “done”?
>
> Peter
> OSR
> @OSRDrivers
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

You have stumbled on yet another of my zillion or so hot-buttons.

With all due respect, this is pure nonsense propagated before people fully understood (or perhaps, fully fleshed-out) how naming works in a device stack.

If done incorrectly, there CAN be a security issue. Of course, this is true with almost anything (especially when it comes to WDM which the OP is using).

If you name your FDO correctly, there’s no security issue at all. None. Absolutely zero.

See:
http://www.osronline.com/article.cfm?article=507
and
http://www.osronline.com/article.cfm?article=508

While I recognize the wondrous advantages that created a device interface provides (let’s not enumerate them here, but the ability to be informed when an interface is enabled/disabled is so useful you practically can’t do without it), device names are just plain handy and aren’t going anywhere soon.

Go ahead: Name your FDOs. Just do it correctly, please.

Peter
OSR
@OSRDrivers

I don’t quite see use for FDO name in a custom driver of custom class. You have to maintain a counter, format it, and then there is NO association between the name and the device instance. No persistence. There is NO good way to enumerate custom link names (if you use them) from user mode. Interfaces solve ALL these problems.

If you make a custom driver for standard class, you don’t want to give your devices a standard name anyway, because it will collide with the inbox drivers.

It’s not quite a security issue, it’s just pointless hassle with no benefits.

Naming your device object only makes sense if it’s outside of a PNP stack.

xxxxx@micron.com wrote:

So, now I’m getting somewhere. I uncommented the line as it was written. I added a check to verify the returned pointer from IoAttachDeviceToDeviceStack isn’t NULL and to exit with a code if it is.

I verified that the system still boots with this change in place. I then started driver verifier on it and I’m finally getting a verifier error in the debugger. It’s IOMANAGER_VIOLATION (c9). It’s taken quite a bit of digging (I’m so very new to this) but I’ve finally narrowed it down to the fact that the driver doesn’t arrange for a handler for the IRP_MJ_PNP IRP.

This is a fatal flaw. You are a PnP driver (because you have an
AddDevice handler). You are required to handle PnP requests.

So, you have two choices. One, plug your ears and say “la la la” to
ignore the issue, and hope none of your customers ever runs the
operating system with driver verifier enabled. Two, add PnP support.
That’s hard. Three, rewrite the driver in KMDF. That is by far the
best solution.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> With all due respect, this is pure nonsense propagated before people fully understood (or perhaps,

fully fleshed-out) how naming works in a device stack.

And where exactly I’m wrong?

The “what DO is used for ACL checks”? issue is really here, at least with CD/DVD drives if you open them as a) \.\D: or as b) a PnP name.

Some IOCTL_CDROM_ calls depend on this (I think something related to lock/unlock media).

SPTI is fine in both cases (which is good).

Go ahead: Name your FDOs. Just do it correctly, please.

What is “correctly”? using an incrementing counter?


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

I guess I should use the e-mail interface instead of the web interface to make replies easier to read. Tim, rewriting in KMDF sounds intriguing (mostly because you say it is the best solution). I am very new to driver work. How are KMDF drivers written? I can probably look at some examples in the WDK. I also have a book, “Developing Drivers with the Windows Driver Foundation” from Microsoft Press. Is that a good resource?

xxxxx@micron.com wrote:

I guess I should use the e-mail interface instead of the web interface to make replies easier to read. Tim, rewriting in KMDF sounds intriguing (mostly because you say it is the best solution). I am very new to driver work. How are KMDF drivers written?

Virtually every Windows driver ever written began life as one of the WDK
samples.

I can probably look at some examples in the WDK.

Yep, that’s a good start. You should try to find a sample that is
somewhat similar to the driver you need.

Start out thinking about what your driver really has to do. Besides
overhead functions like power and PnP, do you have to respond to
interrupts? Are you offering services to user mode? Are you offering
services to other drivers? Are you intercepting requests destined for
another driver? What I/O requests will you receive?

Once you can answer questions like that, it will become more clear what
parts of KMDF you’ll need to bone up on.

If your deadline is too short, there are people on this list who could
do the basic conversion on contract, and return something to you that
you could build on for later. Email me privately if that’s an option
you are considering.

I also have a book, “Developing Drivers with the Windows Driver Foundation” from Microsoft Press. Is that a good resource?

Yes, I have that on my shelf as well. Personally, I learn better from
examples, but the book has the background you will need.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

I took the time to explain the answers to your questions in the articles I wrote, to which I provided links above.

Read those, and if you have specific questions, please come back and ask.

No, not at all… because the protection on all the DEVICE_OBJECTs will be the same.

Peter
OSR

I figured out why IoAttachDeviceToDeviceStack was commented. When present in the driver, as shown in this thread earlier, the driver reports that it doesn’t have enough resources to function and so doesn’t really start. Device Manager shows that the driver has issues.

When I comment the call to IoAttachDeviceToDeviceStack, the driver starts and “works” as it should (we already know the driver is missing many key elements).

So, the big question is, how should this driver (or device) be plugged into the device stack? This driver is designed such that no other drivers/devices should be above or below it. Should I call IoGetDeviceObjectPointer for the bus and use that pointer for the target parameter of IoAttachDeviceToDeviceStack? I tried using NULL which ended disastrously. On the bright side, it was neat to actually see windbg show me precisely where in my driver code there was a problem.

xxxxx@micron.com wrote:

I figured out why IoAttachDeviceToDeviceStack was commented. When present in the driver, as shown in this thread earlier, the driver reports that it doesn’t have enough resources to function and so doesn’t really start. Device Manager shows that the driver has issues.

That’s probably because you are ignoring and/or failing every PnP
request, including those that allocate resources.

So, the big question is, how should this driver (or device) be plugged into the device stack? This driver is designed such that no other drivers/devices should be above or below it.

That’s not true. You are a PnP driver, and the only way a PnP driver
comes alive is when a driver below you creates a PDO for you to drive.

Don’t you ever have to send any requests down to hardware? I don’t see
how your driver could do anything without doing so, but without being
attached, I don’t know how you would do that. However, you’re in the
disk stack, and I admit there are mysteries in the disk driver stack of
which I am not cognizant.

Should I call IoGetDeviceObjectPointer for the bus and use that pointer for the target parameter of IoAttachDeviceToDeviceStack?

No. The PDO from the bus is in the PhysicalDeviceObject parameter to
AddDevice. That’s always the value you pass to IoAttachDeviceToDeviceStack.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim,

Ok, some things are starting to make some sense. The driver that I’m debugging is a driver which is attached to a PDO that is made by a driver that is “below” me in the stack. The way this was designed, another driver (also written by someone on my team) is attached to an AHCI HBA. It then determines the number of ports that this HBA implements and makes a PDO for each of these ports. The driver that I’m debugging is then attached to these port objects.

These port objects were defined by our team. I know that much. The guy who wrote these generated our own GUID for them and everything.

It sounds like I should call IoGetDeviceObjectPointer for the device object of the HBA driver “below” these port drivers. I know that the HBA driver isn’t designed to talk directly with the hardware. It’s all done with these port drivers. The port drivers take care of all IRPs and IOCTLs. The HBA driver’s sole purpose in life is to make PDOs for each port implemented on the HBA to which it is attached.

I’m leaning quite heavily toward this should really be redone. The existing driver seems to have too many issues.

xxxxx@micron.com wrote:

Ok, some things are starting to make some sense. The driver that I’m debugging is a driver which is attached to a PDO that is made by a driver that is “below” me in the stack. The way this was designed, another driver (also written by someone on my team) is attached to an AHCI HBA. It then determines the number of ports that this HBA implements and makes a PDO for each of these ports. The driver that I’m debugging is then attached to these port objects.

These port objects were defined by our team. I know that much. The guy who wrote these generated our own GUID for them and everything.

It sounds like I should call IoGetDeviceObjectPointer for the device object of the HBA driver “below” these port drivers.

That is just piling a hack on top of a hack.

You have a bus driver that creates PDOs, and your driver is an FDO for
that PDO. Bus drivers and FDOs are plug-and-play concepts, but you are
not following any of the plug-and-play rules, because you ignore
IRP_MJ_PNP. I’m frankly surprised that it works as well as it does.

So, I’m not sure what to advise you.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Let me repeat what I said earlier: What you are trying to do is no small task. This is true even for somebody who is an experienced WDM driver developer. It’s a complex undertaking.

Writing Windows drivers, especially WDM drivers, is not something you can just sort of “whack out”. You really *must* understand how the Windows I/O Subsystem works, how PnP works, and the basics of general Windows architecture. WDM driver development isn’t like trying to add some functionality to a C# app… you can’t Google around, find some examples, cut and paste some code, and ask people on a forum for further assistance. WDM was designed “back in the day” and has its roots in the old, initial, Windows NT driver architecture. There’s more than 20 years of architectural stuff piled onto stuff that’s piled onto fixed that’s heaped onto evolutionary changes that you need to understand to make ANY sense out of the job.

Soooo… what are your options:

a) Learn WDM – Take a class, if you can find one. Then spend months re-writing your driver to add PnP and power support.

b) Re-write the driver using WDF – WDF is the new Windows driver architecture, introduced about 7 years ago now. It updates, corrects, and modernizes Windows driver development. As somebody who writes Windows drivers for a living I hope to never write a WDM driver again… I always want to use WDF. It is almost certain that you could re-write your WDM driver using WDF faster than you could add PnP support correctly to your existing WDM driver.

If you go this route I’d strongly suggest you: TAKE A CLASS… spend a week, and skip the painful learning curve.

c) Give up on this project.

That’s my best advice. I’ve been doing this Windows driver thing a lot of years, and I’ve taught thousands of people how to write Windows drivers. Trust me. Your only three reasonable options are a, b, and c above.

Peter
OSR
@OSRDrivers