Hello,
Firstly please excuse me if my question may seem a little stupid, that is because I’m new to driver development.
I am trying to build a virtual sound driver starting from MSVAD sample from DDK and now I’m confronted with the following problem: How do I get a user mode application to talk to my miniport driver.
I see that MSVAD does not have any IRP dispatching functions and I read somewhere that is because portclass.sys handles most of the IRPs.
However I found after some “googleing” that you can actually create your own device object in addDevice from MSVAD and use it to receive IRPs that you pass it from user mode.
So here is how it looks the modified addDevice:
NTSTATUS AddDevice
(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
{
PAGED_CODE();
NTSTATUS ntStatus;
NTSTATUS addAdDeviceStatus = STATUS_UNSUCCESSFUL;
PDEVICE_OBJECT deviceObject;
UNICODE_STRING usDeviceName;
UNICODE_STRING usDosDeviceName;
DPF(D_TERSE, (“[AddDevice]”));
// Tell the class driver to add the device.
//
ntStatus =
PcAddAdapterDevice
(
DriverObject,
PhysicalDeviceObject,
PCPFNSTARTDEVICE(StartDevice),
MAX_MINIPORTS,
0
);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
addAdDeviceStatus = ntStatus;
DPF(D_TERSE, (“[Added Adapter driver]”));
RtlInitUnicodeString(&usDeviceName, MY_DEVICE_NAME);
RtlInitUnicodeString(&usDosDeviceName, MY_DOSDEVICE_NAME);
// Create the device
ntStatus = IoCreateDevice
(
DriverObject,
0,
&usDeviceName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&deviceObject
);
if(!NT_SUCCESS(ntStatus))
{
DPF(D_TERSE, (“[Failed IoCreateDevice…]”));
return addAdDeviceStatus;
}
deviceObject->Flags |= DO_BUFFERED_IO;
DPF(D_TERSE, (“[Device Created]”));
// Create the symbolic link
ntStatus = IoCreateSymbolicLink
(
&usDosDeviceName,
&usDeviceName
);
if (!NT_SUCCESS(ntStatus)) //try to delete the symbolic link first
{
DPF(D_TERSE,(“[Failed IoCreateSymbolicLink…]”));
IoDeleteDevice(DriverObject->DeviceObject);
return addAdDeviceStatus;
}
DPF(D_TERSE, (“[SymbolicLink Created]”));
// Initialize device object flags
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
return ntStatus;
} // AddDevice
I also added:
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=HMIDIDispatchDeviceControl;
in driver entry. I understand that I can use the device object address above to see if the irp is for me so in the future I should probably add a device extension to my device object but I’m not there yet. One question I have is if I see that the IRP is not mine (MSVAD’s) how do I send it back to PORTCLS?
Ok, I built the driver in this form and saw that MY_DEVICE_NAME was created and I built a simple user mode application(called testdevioctrl) which should connect to the driver and send some IRP. The application causses portcls to crash the code causing the crash is:
HANDLE hDevice; // handle to the drive to be examined
hDevice = CreateFile(_T(“\\.\hmidi”), // drive to open
0, // no access to the drive
FILE_SHARE_READ | // share mode
FILE_SHARE_WRITE,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
_tprintf(_T(“Invalid handle\n”));
return (FALSE);
}
Windbg says:
Access violation - code c0000005 (!!! second chance !!!)
nt!__InterlockedIncrement+0x5:
80541ac1 0fc101 xadd dword ptr [ecx],eax
kd> !analyze -v
Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
…
Loading User Symbols
…
Loading unloaded module list
…
*** WARNING: Unable to verify checksum for testdevioctrl.exe
*** ERROR: Module load completed but symbols could not be loaded for vmx_fb.dll
*** ERROR: Module load completed but symbols could not be loaded for hgfs.sys
*** ERROR: Symbol file could not be found. Defaulted to export symbols for drmk.sys -
*** ERROR: Module load completed but symbols could not be loaded for Afc.sys
*** ERROR: Symbol file could not be found. Defaulted to export symbols for vmxnet.sys -
*** ERROR: Module load completed but symbols could not be loaded for vmscsi.sys
*** ERROR: Module load completed but symbols could not be loaded for vmx_svga.sys
*** ERROR: Module load completed but symbols could not be loaded for vmmouse.sys
ERROR: FindPlugIns 8007007b
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
Unknown bugcheck code (0)
Unknown bugcheck description
Arguments:
Arg1: 00000000
Arg2: 00000000
Arg3: 00000000
Arg4: 00000000
Debugging Details:
PROCESS_NAME: testdevioctrl.e
FAULTING_IP:
nt!__InterlockedIncrement+5
80541ac1 0fc101 xadd dword ptr [ecx],eax
EXCEPTION_RECORD: ffffffff – (.exr ffffffffffffffff)
ExceptionAddress: 80541ac1 (nt!__InterlockedIncrement+0x00000005)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000001
Parameter[1]: 00000080
Attempt to write to address 00000080
ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at “0x%08lx” referenced memory at “0x%08lx”. The memory could not be “%s”.
WRITE_ADDRESS: 00000080
BUGCHECK_STR: ACCESS_VIOLATION
DEFAULT_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE
LAST_CONTROL_TRANSFER: from bac8c455 to 80541ac1
STACK_TEXT:
f7988a0c bac8c455 f7988a28 bac9d02a 00000000 nt!__InterlockedIncrement+0x5
f7988a14 bac9d02a 00000000 81e50f38 81e2dc00 portcls!IncrementPendingIrpCount+0x14
f7988a28 804edfe3 81e50bf8 82838f68 806d02e8 portcls!DispatchCreate+0x13
f7988a38 8064b8a8 82838f78 82838f68 81e2dcf8 nt!IopfCallDriver+0x31
f7988a5c 80577672 81e50be0 81e3639c f7988c04 nt!IovCallDriver+0xa0
f7988b3c 805b390a 81e50bf8 00000000 81e362f8 nt!IopParseDevice+0xa12
f7988bc4 805afdeb 00000000 f7988c04 00000040 nt!ObpLookupObjectName+0x56a
f7988c18 8056a3b1 00000000 00000000 00046001 nt!ObOpenObjectByName+0xeb
f7988c94 8056ad28 0012fe28 00100080 0012fdc8 nt!IopCreateFile+0x407
f7988cf0 8056d3fa 0012fe28 00100080 0012fdc8 nt!IoCreateFile+0x8e
f7988d30 8053ca28 0012fe28 00100080 0012fdc8 nt!NtCreateFile+0x30
f7988d30 7c90eb94 0012fe28 00100080 0012fdc8 nt!KiFastCallEntry+0xf8
0012fd84 7c90d68e 7c810916 0012fe28 00100080 ntdll!KiFastSystemCallRet
0012fd88 7c810916 0012fe28 00100080 0012fdc8 ntdll!NtCreateFile+0xc
0012fe20 004307a7 00000000 00000000 00000003 kernel32!CreateFileW+0x35f
0012ff54 00430fe2 00000001 00332f68 00333018 testdevioctrl!wmain+0x37 [d:\test\minidriver\testdevioctrl\testdevioctrl\testdevioctrl.cpp @ 21]
0012ffb8 00430d9d 0012fff0 7c816fd7 0007da50 testdevioctrl!__tmainCRTStartup+0x232 [f:\sp\vctools\crt_bld\self_x86\crt\src\crt0.c @ 327]
0012ffc0 7c816fd7 0007da50 7c90e1fe 7ffd6000 testdevioctrl!wmainCRTStartup+0xd [f:\sp\vctools\crt_bld\self_x86\crt\src\crt0.c @ 196]
0012fff0 00000000 0042e5a0 00000000 78746341 kernel32!BaseProcessStart+0x23
STACK_COMMAND: kb
FOLLOWUP_IP:
portcls!IncrementPendingIrpCount+14
bac8c455 5d pop ebp
SYMBOL_STACK_INDEX: 1
SYMBOL_NAME: portcls!IncrementPendingIrpCount+14
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: portcls
IMAGE_NAME: portcls.sys
DEBUG_FLR_IMAGE_TIMESTAMP: 41107f13
FAILURE_BUCKET_ID: ACCESS_VIOLATION_W_VRF_portcls!IncrementPendingIrpCount+14
BUCKET_ID: ACCESS_VIOLATION_W_VRF_portcls!IncrementPendingIrpCount+14
Followup: MachineOwner
Now I have a few more questions, the obvious would be why does it crash? Another is if there is another possibility to access MSVAD directly without going through the entire driver stack?
Best regards,
Cristi