64 bit sfilter - to retrieve vendor name hang xp 64

I had builded Sfilter & namelookup.lib (C:\WinDDK\6000\src\filesys\filter) using WDK 7600.16385.1 win 7 x64 free build

it working in Xp 64
But
in SfCreate imodified like this

PAGED_CODE();

if (devExt==NULL)
goto NORMAL_ROUTINE;

if(devExt->NLExtHeader.StorageStackDeviceObject==NULL)
goto NORMAL_ROUTINE;

if (devExt->NLExtHeader.StorageStackDeviceObject->Vpb==NULL)
goto NORMAL_ROUTINE;

//ulSerialNo=devExt->NLExtHeader.StorageStackDeviceObject->Vpb->SerialNumber;
if (irpSp->MajorFunction == IRP_MJ_POWER)
goto NORMAL_ROUTINE;

GetDeviceTypeAndUniqueID(devExt->NLExtHeader.StorageStackDeviceObject->Vpb->RealDevice);

//
// If this is for our control device object, don’t allow it to be opened.
//
NORMAL_ROUTINE:
if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))

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;
PIO_STACK_LOCATION irpSp =NULL;

PIRP NewIrp2;
IO_STATUS_BLOCK IoStatus;

char szSptr[2]={‘_’,‘\0’};

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, FALSE);// initialize the waitable event

NewIrp2 = IoBuildDeviceIoControlRequest(IOCTL_STORAGE_QUERY_PROPERTY,
StorageStackDeviceObject,
(PVOID)&Query,
sizeof(STORAGE_PROPERTY_QUERY),
(PVOID)Buffer,
sizeof(STORAGE_DEVICE_DESCRIPTOR)*4,
FALSE,
&WaitEvent_newIrp,
&IoStatus);

if (NewIrp2==NULL) //can’t create new irp.
{

goto ERROR_HANDLER;
}

if (NewIrp2->AssociatedIrp.SystemBuffer ==NULL)
{
DbgPrint(“AssociatedIrp.SystemBuffer isnull”);
IoCancelIrp(NewIrp2);
goto ERROR_HANDLER;
}

irpSp = IoGetNextIrpStackLocation ( NewIrp2 );
IoSetCompletionRoutine(NewIrp2, MyOnIrpComplete, (PVOID)&WaitEvent_newIrp, TRUE, TRUE, TRUE);

DbgPrint(“outbufferlength =%u” ,irpSp->Parameters.DeviceIoControl.OutputBufferLength);

if(irpSp->Parameters.DeviceIoControl.OutputBufferLength == 0)
{
goto ERROR_HANDLER;
}

if(irpSp->Parameters.DeviceIoControl.IoControlCode != IOCTL_STORAGE_QUERY_PROPERTY)
{
DbgPrint(“IOCTL is incorrect”);
goto ERROR_HANDLER;

}
DbgPrint(“\n irpSp->MajorFunction =%d”,irpSp->MajorFunction );
if(irpSp->MajorFunction != IRP_MJ_DEVICE_CONTROL)
{
goto ERROR_HANDLER;
}

if(irpSp->FileObject == NULL)
{
DbgPrint(“FileObject is null”);
//goto ERROR_HANDLER;
}
else
DbgPrint(“FileObject is not null”);

Status = IoCallDriver(StorageStackDeviceObject, NewIrp2);// send this irp to the storage device

if (Status == STATUS_PENDING)
{
LARGE_INTEGER TimeOut;

TimeOut.QuadPart=-50000000;//5 Seconds
Status = KeWaitForSingleObject(&WaitEvent_newIrp, Executive, KernelMode, FALSE, &TimeOut);

if(Status==STATUS_TIMEOUT)
{
IoCancelIrp(NewIrp2);
KeWaitForSingleObject(&WaitEvent_newIrp, Executive, KernelMode, FALSE, NULL);
}
}

KeClearEvent(&WaitEvent_newIrp);
IoCompleteRequest(NewIrp2, IO_NO_INCREMENT);

//cwStrCat(pszUniqueID,szSptr);
//IoCancelIrp(NewIrp2);
if (NT_SUCCESS(Status))
{
if(Buffer!=NULL)
{
/*char vendorId [1000];
char szUID[128]=“”;
char szUID1[128]=“”;*/

Descriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Buffer;
uBusType = Descriptor->BusType; //Get the bus type.
DbgPrint(“Bus Type =%u”, uBusType);
}
}

EXIT_ROUTINE:
return Status;

ERROR_HANDLER:
Status=STATUS_SEVERITY_ERROR;
goto EXIT_ROUTINE;
}

After build ing the modified code in 7600.16385.1 win 7 x64 free build

it is hanging in windows Xp 64 sp2 after restart

I am not yet tried remote debugging to get callstack
No dumps were found.

Regards,
Dileep S

Well, a hang doesn’t generate a crash dump. You can use OSR’s tool for that

At a quick glance I don’t understand this part:

Status = IoCallDriver(StorageStackDeviceObject, NewIrp2);// send
this irp to the storage device

if (Status == STATUS_PENDING)
{

}

KeClearEvent(&WaitEvent_newIrp);
IoCompleteRequest(NewIrp2, IO_NO_INCREMENT);

So you complete the request again just to make sure ?

I think you are confused about this line:

“IRPs that are created by IoBuildDeviceIoControlRequest must be completed by
a driver’s call to IoCompleteRequest. A driver that calls
IoBuildDeviceIoControlRequest must not call IoFreeIrp, because the I/O
manager frees these synchronous IRPs after IoCompleteRequest has been
called.”

The point MSDN is trying to make is that if you get an IRP from
IoBuildDeviceIoControlRequest() and something goes wrong and you decide not
to send it (you’re not calling IoCallDriver() with it) then you can’t simply
call IoFreeIrp() to get rid of it since the IOMGR needs to reclaim it. Some
pseudocode here:

__try {
myIrp = IoBuildDeviceIoControlRequest(…);
if (myIrp == NULL) {
__leave;
}



// issue the IRP:
status = IoCallDriver( DeviceObject, myIrp);
myIrp = NULL;

if (status == STATUS_PENDING) {
status = KeWaitForSingleObject( …);
}

} __finally {

If (myIrp != NULL) {
// this means we’ve allocated it but never sent it
IoCompleteRequest( myIrp, IO_NO_INCREMENT );
}
}

Basically, if you call IoCallDriver on an IRP allocated by
IoBuildDeviceIoControlRequest() then you can’t touch it anymore.

Hope this helps.

Thanks,
Alex.

Ah, forgot to post the tool… it’s called BANG!
http://www.osronline.com/article.cfm?article=153

This should help generate a memory dump even when the machine is frozen (in
some cases).

Thanks,
Alex.

Dear Alex,

It works fine.

Hearty Thanks,

Dileep S.

But When I call same in SfPassThrough

before IoSkipCurrentIrpStackLocation( Irp );

It again make hang in XP 64 …

Thanks & regards,
Dileep s

Code please ?

Thanks,
Alex.

Dear Alex ,

Code is As below,

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;
PIO_STACK_LOCATION irpSp =NULL;
PIRP NewIrp2;
IO_STATUS_BLOCK IoStatus;

char szSptr[2]={‘_’,‘\0’};

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);

if (NewIrp2==NULL) //can’t create new irp.
{
__leave;
}

IoSetCompletionRoutine(NewIrp2, MyOnIrpComplete, (PVOID)&WaitEvent_newIrp, TRUE, TRUE, TRUE);
Status = IoCallDriver(StorageStackDeviceObject, NewIrp2);// send this irp to the storage device
if (Status == STATUS_PENDING)
{
LARGE_INTEGER TimeOut;

TimeOut.QuadPart=-50000000;//5 Seconds
Status = KeWaitForSingleObject(&WaitEvent_newIrp, Executive, KernelMode, FALSE, &TimeOut);

if(Status==STATUS_TIMEOUT)
{
//IoCancelIrp(NewIrp2);
KeWaitForSingleObject(&WaitEvent_newIrp, Executive, KernelMode, FALSE, NULL);
}
}
}
__finally
{

if (NewIrp2!=NULL)
{
IoCompleteRequest(NewIrp2, IO_NO_INCREMENT);

if (NT_SUCCESS(Status))
{
if(Buffer!=NULL)
{

}
}
}

}
}

and called in the function sfPassThrough of sfilter as like

NTSTATUS
SfPassThrough (
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp
)

{
int checkUsb =0;
PIO_STACK_LOCATION pIrp = IoGetCurrentIrpStackLocation( Irp );

//
// Sfilter doesn’t allow handles to its control device object to be
// created, therefore, no other operation should be able to come through.
//

ASSERT(!IS_MY_CONTROL_DEVICE_OBJECT( DeviceObject ));

ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));

//
// File systems should NEVER receive a power IRP
//

ASSERT(pIrp->MajorFunction != IRP_MJ_POWER);

//
// Get this driver out of the driver stack and get to the next driver as
// quickly as possible.
//

if (pIrp->MajorFunction==IRP_MJ_WRITE || pIrp->MajorFunction==IRP_MJ_SET_INFORMATION ||
pIrp->MajorFunction==IRP_MJ_SET_VOLUME_INFORMATION || pIrp->MajorFunction==IRP_MJ_SET_SECURITY ||
pIrp->MajorFunction==IRP_MJ_SET_QUOTA)
{
PSFILTER_DEVICE_EXTENSION devExt = (PSFILTER_DEVICE_EXTENSION)(DeviceObject->DeviceExtension);

if (devExt==NULL)
goto NORMAL_ROUTINE;

if(devExt->NLExtHeader.StorageStackDeviceObject==NULL)
goto NORMAL_ROUTINE;

if (devExt->NLExtHeader.StorageStackDeviceObject->Vpb==NULL)
goto NORMAL_ROUTINE;

//ulSerialNo=devExt->NLExtHeader.StorageStackDeviceObject->Vpb->SerialNumber;
{
if(!IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
{
if(IS_MY_DEVICE_OBJECT( DeviceObject ))
{

GetDeviceTypeAndUniqueID(devExt->NLExtHeader.StorageStackDeviceObject->Vpb->RealDevice);

}
}

}
}
NORMAL_ROUTINE:

IoSkipCurrentIrpStackLocation( Irp );
//
// Call the appropriate file system driver with the request. //

return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->NLExtHeader.AttachedToDeviceObject,
Irp );
}

Thanks & Regards,
Dileep S

Hi Dileep,

Can you please also post MyOnIrpComplete ? Also, where does WaitEvent_newIrp
come from ? I can’t see it defined anywhere.

If your MyOnIrpComplete routine does nothing more than to set the event
WaitEvent_newIrp, then you don’t need it. As per the documentation for
IoBuildDeviceIoControlRequest, “Most drivers do not need to set an
IoCompletion routine for the IRP.”… However if you remove the call to
IoSetCompletionRoutine then please make sure to make NewIrp2 NULL
immediately after calling IoCallDriver on it.

Thanks,
Alex.

Hi Alex,

I had declared KEVENT WaitEvent_newIrp; globally just before Function Prototypes.

NTSTATUS MyOnIrpComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
UNREFERENCED_PARAMETER(DeviceObject);
UNREFERENCED_PARAMETER(Irp);

if(Irp->PendingReturned)
KeSetEvent((PKEVENT) Context, IO_NO_INCREMENT, FALSE);
//IoCancelIrp(NewIrp2);

return STATUS_MORE_PROCESSING_REQUIRED;
}

Hi Alex,
Whether to Set Environment variable WINDDK as C:\WinDDK\7600.16385.1 before build is made?

Thanks,
Dileep S.

Um… I’m not sure what the question is but if you go through the start menu
-> Windows Driver Kits -> WDK 7600.16385.1 -> Build Environments -> Windows
7 or whatever and run one of the batch files it will take care of setting up
WINDDK and everything else for you so you don’t normally need to do it
manually…

Thanks,
Alex.

Hi Alex,

I normaly built the driver as you said (start menu
-> Windows Driver Kits -> WDK 7600.16385.1 -> Build Environments -> Windows
7 ) . But just to ensure the above thing .

I had declared KEVENT WaitEvent_newIrp; globally just before Function
Prototypes.
The code for MyOnIrpComplete:-

NTSTATUS MyOnIrpComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
UNREFERENCED_PARAMETER(DeviceObject);
UNREFERENCED_PARAMETER(Irp);

if(Irp->PendingReturned)
KeSetEvent((PKEVENT) Context, IO_NO_INCREMENT, FALSE);
//IoCancelIrp(NewIrp2);

return STATUS_MORE_PROCESSING_REQUIRED;
}

i will try as you said

if you remove the call to
IoSetCompletionRoutine then please make sure to make NewIrp2 NULL
immediately after calling IoCallDriver on it.

Thanks,
Dileep S

Hi Dileep,

Actually, could you please also remove your completion notification callback
? You don’t need it and IO manager does all of that for you.

Thanks,
Alex.

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

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

Hi Alex,

I included wait if you get STATUS_PENDING.

but I find it works in passthrough also if I use

STORAGE_DEVICE_DESCRIPTOR Buffer[1];

NewIrp2 = IoBuildDeviceIoControlRequest(IOCTL_STORAGE_QUERY_PROPERTY,
StorageStackDeviceObject,
(PVOID)&Query,
sizeof(STORAGE_PROPERTY_QUERY),
(PVOID)&Buffer,
sizeof(STORAGE_DEVICE_DESCRIPTOR)*1,
FALSE,
&WaitEvent_newIrp,
&IoStatus);


instead of

STORAGE_DEVICE_DESCRIPTOR Buffer[4];

NewIrp2 = IoBuildDeviceIoControlRequest(IOCTL_STORAGE_QUERY_PROPERTY,
StorageStackDeviceObject,
(PVOID)&Query,
sizeof(STORAGE_PROPERTY_QUERY),
(PVOID)&Buffer,
sizeof(STORAGE_DEVICE_DESCRIPTOR)*4,
FALSE,
&WaitEvent_newIrp,
&IoStatus);

is it due size of OutputBufferLength =sizeof(STORAGE_DEVICE_DESCRIPTOR)*4 ?

When checked the below code
if(StorageStackDeviceObject->StackSize <= sizeof(STORAGE_DEVICE_DESCRIPTOR) * 4)
{
DbgPrint("Stack size is small ");
return STATUS_SUCCESS;
}

it always return in sfpassthrough

let me know about it ,
I will try with ClassSendDeviceIoControlSynchronous.

Thanks & Regards,
Dileep S

Dear Alex,

I bulded classpnp.lib and modified sources

TARGETLIBS=$(OBJ_PATH)..\lib$(O)\namelookup.lib \
$(DDK_LIB_PATH)\ntstrsafe.lib \
$(OBJ_PATH)\classpnp.lib
and called

ClassSendDeviceIoControlSynchronous(IOCTL_STORAGE_QUERY_PROPERTY,
StorageStackDeviceObject, (PVOID)Buffer, sizeof(STORAGE_PROPERTY_QUERY),sizeof(STORAGE_DEVICE_DESCRIPTOR)*1, FALSE, &IoStatus);

from sfpassthrough it works fine

but when I called

ClassSendDeviceIoControlSynchronous(IOCTL_STORAGE_QUERY_PROPERTY, StorageStackDeviceObject, (PVOID)Buffer,sizeof(STORAGE_PROPERTY_QUERY),
156, FALSE, &IoStatus);

I found that Descrptor->Size is 156 so that I called so to get vendor ID …
it hangs in xp 64.

The code Itried is :-
NTSTATUS TestOne(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=NULL;
PIO_STACK_LOCATION NextIrpStack=NULL;
IO_STATUS_BLOCK IoStatus;
char szSptr[2]={‘_’,‘\0’};
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;
}

/*if(StorageStackDeviceObject->StackSize <= sizeof(STORAGE_DEVICE_DESCRIPTOR) * 2)
{
DbgPrint("Stack size is small ");
return STATUS_SUCCESS;
}*/

KeInitializeEvent(&WaitEvent_newIrp, NotificationEvent, TRUE);// initialize the waitable event

__try {
RtlCopyMemory(Buffer, &Query, sizeof(STORAGE_PROPERTY_QUERY) );

ClassSendDeviceIoControlSynchronous(IOCTL_STORAGE_QUERY_PROPERTY,
StorageStackDeviceObject, (PVOID)Buffer,sizeof(STORAGE_PROPERTY_QUERY), 156, FALSE, &IoStatus);

/*NewIrp2=IoBuildDeviceIoControlRequest(IOCTL_STORAGE_QUERY_PROPERTY, StorageStackDeviceObject,
(PVOID)&Query,sizeof(STORAGE_PROPERTY_QUERY),
(PVOID)Buffer, 156,
FALSE,&WaitEvent_newIrp,&IoStatus);*/

}

__finally
{
//if(NewIrp2 != NULL)
{
//NextIrpStack =IoGetNextIrpStackLocation ( NewIrp2 );
//if(NextIrpStack->Parameters.DeviceIoControl.OutputBufferLength>=156)
//{
// Status = IoCallDriver(StorageStackDeviceObject, NewIrp2);
// if (Status == STATUS_PENDING)
// {
// LARGE_INTEGER TimeOut;
// TimeOut.QuadPart=-50000000;//5 Seconds

// Status = KeWaitForSingleObject(&WaitEvent_newIrp, Executive, KernelMode, FALSE, &TimeOut);
//
// if(Status==STATUS_TIMEOUT)
// {
// NewIrp2=NULL;
// DbgPrint(“STATUS_TIMEOUT”);
// //KeWaitForSingleObject(&WaitEvent_newIrp, Executive, KernelMode, FALSE, NULL);
// }
// if(NewIrp2 != NULL)
// {
// Descriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Buffer;
// uBusType = Descriptor->BusType; //Get the bus type.
// DbgPrint(“test one BusType =%d”,uBusType);
// DbgPrint(“Descriptor->Size =%u,Descriptor->VendorIdOffset =%u”,Descriptor->Size, Descriptor->VendorIdOffset);

// }

// }
//}

}

}

return Status;
}

Thanks & Regards,
Dileep S.

So you’re saying that calling it with sizeof(STORAGE_DEVICE_DESCRIPTOR)
works, but calling it with 156 hangs ? Make sure that you have the size
right… Use a C_ASSERT to make sure. But anyway, why even use 156 if
sizeof(STORAGE_DEVICE_DESCRIPTOR) works? Just use it that way… In general
you should not use hardcoded numbers for sizes and should rely on compiler
calls since the compiler knows what the data output will look like.

Since you have the source to ClassSendDeviceIoControlSynchronous, where does
it hang ?

Thanks,
Alex.

Dear Alex,

At first I had used sizeof(STORAGE_DEVICE_DESCRIPTOR)*4 instead of 156

this works in SfCreate but hang in SfPassThrough for Xp 64 machine.

I tried sizeof(STORAGE_DEVICE_DESCRIPTOR) instead of sizeof(STORAGE_DEVICE_DESCRIPTOR)*4
then both SfCreate & SfPassThrough works but not able to get
Descriptor->VendorIdOffset
Descriptor->ProductIdOffset
Descriptor->ProductRevisionOffset (All are getting zero if sizeof(STORAGE_DEVICE_DESCRIPTOR) used )
But if I use sizeof(STORAGE_DEVICE_DESCRIPTOR)*4 only in SfCreate I get the

following values
sizeof(STORAGE_DEVICE_DESCRIPTOR) =40

Descriptor->BusType =7
Descriptor->Size=103
Descriptor->VendorIdOffset =72
Descriptor->ProductIdOffset =81
Descriptor->ProductRevisionOffset=98

Descriptor->BusType =3
Descriptor->Size=156
Descriptor->VendorIdOffset =0
Descriptor->ProductIdOffset =76
Descriptor->ProductRevisionOffset=106

If we use sizeof(STORAGE_DEVICE_DESCRIPTOR)*4 in SfPassThrough hangs when
Status = IoCallDriver(StorageStackDeviceObject, NewIrp2);
I checked and getting the value of
NextIrpStack->Parameters.DeviceIoControl.OutputBufferLength and it is correct as
sizeof(STORAGE_DEVICE_DESCRIPTOR)*4

The above results are with IoBuildDeviceIoControlRequest

I did not yet put DbgPrint in ClassSendDeviceIoControlSynchronous , I susspect it also at
IoCallDriver(StorageStackDeviceObject, NewIrp2);
if needed I will check that also and let you know.

Thanks & Regards,
Dileep S.

According to the documentation, this is what you need to do to figure out
the size (quoting from the page for “STORAGE_DEVICE_DESCRIPTOR structure” at
http://msdn.microsoft.com/en-us/library/ff800835(v=vs.85).aspx):

“An application can determine the required buffer size by issuing a
IOCTL_STORAGE_QUERY_PROPERTY control code passing a
STORAGE_DESCRIPTOR_HEADER structure for the output buffer, and then using
the returned Size member of the STORAGE_DESCRIPTOR_HEADER structure to
allocate a buffer of the proper size.”

So forget about sizeof(STORAGE_DEVICE_DESCRIPTOR)*4 and instead issue a call
with sizeof(STORAGE_DESCRIPTOR_HEADER). That should populate the
STORAGE_DESCRIPTOR_HEADER->Size member. Then you need to allocate a buffer
of that size and pass that in your call for IOCTL_STORAGE_QUERY_PROPERTY.

If you want to see an implementation, look at the function
ClassGetDescriptor() in \src\storage\class\classpnp\class.c. See how it
initially sends a request for a STORAGE_DESCRIPTOR_HEADER structure and then
it allocates a buffer of the requested size and then it calls
IOCTL_STORAGE_QUERY_PROPERTY again.

In general you know you’ve gone wrong in your implementation when you start
hardcoding structure sizes, so when you find yourself doing that then take a
moment and think about what you might be doing wrong.

Thanks,
Alex.