You’re still supposed to wait if you get STATUS_PENDING. Did you even bother
searching the WDK for examples?
I searched for IoBuildDeviceIoControlRequest and found 25 files containing
in in the WDK \src folder. This is one example from
src\filesys\cdfs\Win7\deviosup.c:
NTSTATUS
CdPerformDevIoCtrlEx (
__in PIRP_CONTEXT IrpContext,
__in ULONG IoControlCode,
__in PDEVICE_OBJECT Device,
__in_bcount_opt(InputBufferLength) PVOID InputBuffer,
__in ULONG InputBufferLength,
__out_bcount_opt(OutputBufferLength) PVOID OutputBuffer,
__in ULONG OutputBufferLength,
__in BOOLEAN InternalDeviceIoControl,
__in BOOLEAN OverrideVerify,
__out_opt PIO_STATUS_BLOCK Iosb
)
/*++
Routine Description:
This routine is called to perform DevIoCtrl functions internally within
the filesystem. We take the status from the driver and return it to our
caller.
Arguments:
IoControlCode - Code to send to driver.
Device - This is the device to send the request to.
OutPutBuffer - Pointer to output buffer.
OutputBufferLength - Length of output buffer above.
InternalDeviceIoControl - Indicates if this is an internal or external
Io control code.
OverrideVerify - Indicates if we should tell the driver not to return
STATUS_VERIFY_REQUIRED for mount and verify.
Iosb - If specified, we return the results of the operation here.
Return Value:
NTSTATUS - Status returned by next lower driver.
–*/
{
NTSTATUS Status;
PIRP Irp;
KEVENT Event;
IO_STATUS_BLOCK LocalIosb;
PIO_STATUS_BLOCK IosbToUse = &LocalIosb;
PAGED_CODE();
UNREFERENCED_PARAMETER( IrpContext );
//
// Check if the user gave us an Iosb.
//
if (ARGUMENT_PRESENT( Iosb )) {
IosbToUse = Iosb;
}
IosbToUse->Status = 0;
IosbToUse->Information = 0;
KeInitializeEvent( &Event, NotificationEvent, FALSE );
Irp = IoBuildDeviceIoControlRequest( IoControlCode,
Device,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength,
InternalDeviceIoControl,
&Event,
IosbToUse );
if (Irp == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
if (OverrideVerify) {
SetFlag( IoGetNextIrpStackLocation( Irp )->Flags,
SL_OVERRIDE_VERIFY_VOLUME );
}
Status = IoCallDriver( Device, Irp );
//
// We check for device not ready by first checking Status
// and then if status pending was returned, the Iosb status
// value.
//
if (Status == STATUS_PENDING) {
(VOID) KeWaitForSingleObject( &Event,
Executive,
KernelMode,
FALSE,
(PLARGE_INTEGER)NULL );
Status = IosbToUse->Status;
}
ASSERT( !(OverrideVerify && (STATUS_VERIFY_REQUIRED == Status)));
return Status;
}
And here is another one from src\storage\class\disk\diskwmi.c.
//
// FP Ioctl specific routines
//
NTSTATUS
DiskSendFailurePredictIoctl(
PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
PSTORAGE_PREDICT_FAILURE checkFailure
)
{
KEVENT event;
PDEVICE_OBJECT deviceObject;
IO_STATUS_BLOCK ioStatus = { 0 };
PIRP irp;
NTSTATUS status;
PAGED_CODE();
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
deviceObject = IoGetAttachedDeviceReference(FdoExtension->DeviceObject);
irp = IoBuildDeviceIoControlRequest(
IOCTL_STORAGE_PREDICT_FAILURE,
deviceObject,
NULL,
0,
checkFailure,
sizeof(STORAGE_PREDICT_FAILURE),
FALSE,
&event,
&ioStatus);
if (irp != NULL)
{
status = IoCallDriver(deviceObject, irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE,
NULL);
status = ioStatus.Status;
}
} else {
status = STATUS_INSUFFICIENT_RESOURCES;
}
ObDereferenceObject(deviceObject);
return status;
}
You can even find calls for the IOCTL you want (IOCTL_STORAGE_QUERY_PROPERTY
IOCTL), though it doesn’t call IoBuildDeviceIoControlRequest. See the code
in classpnp.c:
…
ClassSendDeviceIoControlSynchronous(
IOCTL_STORAGE_QUERY_PROPERTY,
DeviceObject,
&query,
sizeof(STORAGE_PROPERTY_QUERY),
sizeof(ULONG) * 2,
FALSE,
&ioStatus
);
…
Where ClassSendDeviceIoControlSynchronous is:
…
VOID
ClassSendDeviceIoControlSynchronous(
__in ULONG IoControlCode,
__in PDEVICE_OBJECT TargetDeviceObject,
__inout_xcount_opt(max(InputBufferLength,OutputBufferLength)) PVOID
Buffer,
__in ULONG InputBufferLength,
__in ULONG OutputBufferLength,
__in BOOLEAN InternalDeviceIoControl,
__out PIO_STATUS_BLOCK IoStatus
)
{
PIRP irp;
PIO_STACK_LOCATION irpSp;
ULONG method;
PAGED_CODE();
irp = NULL;
method = IoControlCode & 3;
#if DBG // Begin Argument Checking (nop in fre version)
ASSERT(ARGUMENT_PRESENT(IoStatus));
if ((InputBufferLength != 0) || (OutputBufferLength != 0)) {
ASSERT(ARGUMENT_PRESENT(Buffer));
}
else {
ASSERT(!ARGUMENT_PRESENT(Buffer));
}
#endif
//
// Begin by allocating the IRP for this request. Do not charge quota to
// the current process for this IRP.
//
irp = IoAllocateIrp(TargetDeviceObject->StackSize, FALSE);
if (!irp) {
IoStatus->Information = 0;
IoStatus->Status = STATUS_INSUFFICIENT_RESOURCES;
return;
}
//
// Get a pointer to the stack location of the first driver which will be
// invoked. This is where the function codes and the parameters are
set.
//
irpSp = IoGetNextIrpStackLocation(irp);
//
// Set the major function code based on the type of device I/O control
// function the caller has specified.
//
if (InternalDeviceIoControl) {
irpSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
} else {
irpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
}
//
// Copy the caller’s parameters to the service-specific portion of the
// IRP for those parameters that are the same for all four methods.
//
irpSp->Parameters.DeviceIoControl.OutputBufferLength =
OutputBufferLength;
irpSp->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
irpSp->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
//
// Get the method bits from the I/O control code to determine how the
// buffers are to be passed to the driver.
//
switch (method)
{
//
// case 0
//
case METHOD_BUFFERED:
{
if ((InputBufferLength != 0) || (OutputBufferLength != 0))
{
irp->AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(NonPagedPoolCacheAligned,
max(InputBufferLength, OutputBufferLength),
CLASS_TAG_DEVICE_CONTROL);
if (irp->AssociatedIrp.SystemBuffer == NULL)
{
IoFreeIrp(irp);
IoStatus->Information = 0;
IoStatus->Status = STATUS_INSUFFICIENT_RESOURCES;
return;
}
if (InputBufferLength != 0)
{
RtlCopyMemory(irp->AssociatedIrp.SystemBuffer, Buffer,
InputBufferLength);
}
}
irp->UserBuffer = Buffer;
break;
}
//
// case 1, case 2
//
case METHOD_IN_DIRECT:
case METHOD_OUT_DIRECT:
{
if (InputBufferLength != 0)
{
irp->AssociatedIrp.SystemBuffer = Buffer;
}
if (OutputBufferLength != 0)
{
irp->MdlAddress = IoAllocateMdl(Buffer,
OutputBufferLength,
FALSE,
FALSE,
(PIRP) NULL);
if (irp->MdlAddress == NULL)
{
IoFreeIrp(irp);
IoStatus->Information = 0;
IoStatus->Status = STATUS_INSUFFICIENT_RESOURCES;
return;
}
try
{
MmProbeAndLockPages(irp->MdlAddress,
KernelMode,
(method == METHOD_IN_DIRECT) ?
IoReadAccess : IoWriteAccess);
}
except(EXCEPTION_EXECUTE_HANDLER)
{
IoFreeMdl(irp->MdlAddress);
IoFreeIrp(irp);
IoStatus->Information = 0;
IoStatus->Status = GetExceptionCode();
return;
}
}
break;
}
//
// case 3
//
case METHOD_NEITHER:
{
ASSERT(!“ClassSendDeviceIoControlSynchronous does not support
METHOD_NEITHER Ioctls”);
IoFreeIrp(irp);
IoStatus->Information = 0;
IoStatus->Status = STATUS_NOT_SUPPORTED;
return;
}
}
irp->Tail.Overlay.Thread = PsGetCurrentThread();
//
// send the irp synchronously
//
ClassSendIrpSynchronous(TargetDeviceObject, irp);
//
// copy the iostatus block for the caller
//
*IoStatus = irp->IoStatus;
//
// free any allocated resources
//
switch (method) {
case METHOD_BUFFERED: {
ASSERT(irp->UserBuffer == Buffer);
//
// first copy the buffered result, if any
// Note that there are no security implications in
// not checking for success since only drivers can
// call into this routine anyways…
//
if (OutputBufferLength != 0) {
RtlCopyMemory(Buffer, // irp->UserBuffer
irp->AssociatedIrp.SystemBuffer,
OutputBufferLength
);
}
//
// then free the memory allocated to buffer the io
//
if ((InputBufferLength !=0) || (OutputBufferLength != 0)) {
FREE_POOL(irp->AssociatedIrp.SystemBuffer);
}
break;
}
case METHOD_IN_DIRECT:
case METHOD_OUT_DIRECT: {
//
// we alloc a mdl if there is an output buffer specified
// free it here after unlocking the pages
//
if (OutputBufferLength != 0) {
ASSERT(irp->MdlAddress != NULL);
MmUnlockPages(irp->MdlAddress);
IoFreeMdl(irp->MdlAddress);
irp->MdlAddress = (PMDL) NULL;
}
break;
}
case METHOD_NEITHER: {
ASSERT(!“Code is out of date”);
break;
}
}
//
// we always have allocated an irp. free it here.
//
IoFreeIrp(irp);
irp = (PIRP) NULL;
//
// return the io status block’s status to the caller
//
return;
} // end ClassSendDeviceIoControlSynchronous()
Thanks,
Alex.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Monday, September 05, 2011 3:01 AM
To: Windows File Systems Devs Interest List
Subject: RE:[ntfsd] 64 bit sfilter - to retrieve vendor name hang xp 64
hi Alex ,
i tried this but this also hang in Xp 64
while calling the below function from SfPassThrough routine.
NTSTATUS GetDeviceTypeAndUniqueID(IN PDEVICE_OBJECT
StorageStackDeviceObject) {
STORAGE_PROPERTY_QUERY Query;
STORAGE_DEVICE_DESCRIPTOR Buffer[4];
NTSTATUS Status = STATUS_SUCCESS;
ULONG uBusType=BusTypeUnknown;
PSTORAGE_DEVICE_DESCRIPTOR Descriptor=NULL;
PIRP NewIrp2;
IO_STATUS_BLOCK IoStatus;
Query.PropertyId = StorageDeviceProperty;// first set the query
properties
Query.QueryType = PropertyStandardQuery;
if (KeGetCurrentIrql() > PASSIVE_LEVEL)
return STATUS_SUCCESS;
if(StorageStackDeviceObject == NULL)
{
return STATUS_SUCCESS;
}
if(StorageStackDeviceObject->DeviceType != FILE_DEVICE_DISK)
{
return STATUS_SUCCESS;
}
KeInitializeEvent(&WaitEvent_newIrp, NotificationEvent, TRUE);//
initialize the waitable event
__try {
NewIrp2 =
IoBuildDeviceIoControlRequest(IOCTL_STORAGE_QUERY_PROPERTY,
StorageStackDeviceObject,
(PVOID)&Query,
sizeof(STORAGE_PROPERTY_QUERY),
(PVOID)&Buffer,
sizeof(STORAGE_DEVICE_DESCRIPTOR)*4,
FALSE,
&WaitEvent_newIrp,
&IoStatus);
Status = IoCallDriver(StorageStackDeviceObject, NewIrp2);// send
this irp to the storage device
NewIrp2 =NULL;
}
__finally
{
DbgPrint(“in Test finaly”);
//IoCompleteRequest(NewIrp2, IO_NO_INCREMENT);
if (NT_SUCCESS(Status))
{
if(Buffer!=NULL)
{
Descriptor =
(PSTORAGE_DEVICE_DESCRIPTOR)Buffer;
uBusType = Descriptor->BusType;
//Get the bus type.
DbgPrint(“test one BusType
=%d”,uBusType);
//if(Descriptor->VendorIdOffset!=0)
//Is Valid VendorIDOffset, append it to the ID
//{
//
pszStart=(char*)(UINT_PTR)Descriptor+(DWORD32)Descriptor->VendorIdOffset;
//}
}
}
return Status;
}
Sorry for the delay , I am in the midst of onam celebrations here.
Thanks,
Dileep S
NTFSD is sponsored by OSR
For our schedule of debugging and file system 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