Below is the code :
wdm
========
DeviceControl(KIrp I)
{
switch (I.IoctlCode ())
{
case GETSTATE:
GetState(I);
}
GetState (KIrp I)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
I.Information () = 0;
if (I.IoctlBuffer () &&
I.IoctlInputBufferSize () == 0 &&
I.IoctlOutputBufferSize ())
{
status = SendCommand ((UCHAR *) I.IoctlBuffer (), I.IoctlOutputBufferSize (),GETSTATE, 0, true, true, 0);
I.Information () = sizeof UCHAR;
}
else
{
status = STATUS_INVALID_PARAMETER;
}
return status;
}
SendCommand (UCHAR * buffer, ULONG size, UCHAR request, USHORT value,bool In, bool ShortOk, ULONG * info)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
T.Trace (TraceInfo, "> " __FUNCTION__ "\n");
PURB pUrb = m_DfuInterface.BuildClassRequest (buffer, // Transfer buffer
size, // Transfer buffer size
0, // Request reserved bits
request, // Request
value, // Value
In, // In
ShortOk, // Short OK
NULL, // Link URB
NULL); // URB
if (pUrb != NULL)
{
status = m_DfuInterface.SubmitUrb (pUrb);
if (NT_SUCCESS (status) && info)
{*info = (USHORT)pUrb->UrbControlVendorClassRequest.TransferBufferLength;
}
if (NT_ERROR (status))
{
t << "SendCommand (" << request << "): FAILED\n";
t << " NTSTATUS = " << ULONG (status) << "\n";
t << " URB status = " << ULONG (pUrb->UrbHeader.Status) << "\n";
}
delete pUrb;
}
else
{
T << "SendCommand: STATUS_INSUFFICIENT_RESOURCES" << "\n";
status = STATUS_INSUFFICIENT_RESOURCES;
}
return status;
}
wdf
=====
EvtIoDeviceControl(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t OutputBufferLength,
IN size_t InputBufferLength,
IN ULONG IoControlCode
)
{
device = WdfIoQueueGetDevice(Queue);
pDevContext = GetDeviceContext(device);
switch(IoControlCode) {
code GETSTATE:
getstate(pDevContext->WdfUsbTargetDevice,Request);
}
NTSTATUS getstate(WDFUSBDEVICE Device,WDFREQUEST request)
{
PURB pUrb = NULL;
WDFMEMORY urbMemory;
WDF_OBJECT_ATTRIBUTES objectAttribs;
PULONG nbytes;
USHORT usUrbSize;
WDF_MEMORY_DESCRIPTOR memoryDesc;
PWDF_USB_CONTROL_SETUP_PACKET controlSetupPacket;
usUrbSize = (USHORT)sizeof(struct
_URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
WDF_OBJECT_ATTRIBUTES_INIT(&objectAttribs);
objectAttribs.ParentObject = Device;
status = WdfMemoryCreate(&objectAttribs,
NonPagedPool,POOL_TAG,usUrbSize,&urbMemory,(PVOID*) &pUrb);
if (!NT_SUCCESS(status)) {
UsbDfu_DbgPrint(1, ("Failed to alloc mem for urb\n"));
status = STATUS_INSUFFICIENT_RESOURCES;
return status;
}
WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memoryDesc, urbMemory,
(USHORT)sizeof(URB));
WDF_USB_CONTROL_SETUP_PACKET_INIT_CLASS(&controlSetupPacket,
BMREQUEST_DEVICE_TO_HOST,
BMREQUEST_TO_INTERFACE,
DFU_GETSTATE,// Request(DFU_DETACH,DFU_DNLOAD etc)
0, //value
0); //Index
status = WdfUsbTargetDeviceFormatRequestForControlTransfer(
Device,
WDF_NO_HANDLE,
&controlSetupPacket,
memoryDesc,
NULL
);
if (!NT_SUCCESS(status)){
return status;
}
WdfRequestSetCompletionRoutine(
request,
MyCompletionRoutine,
NULL
);
if (WdfRequestSend(request, FmDeviceData->WdfUsbTargetDevice,NULL) == FALSE)
{
status = WdfRequestGetStatus(request);
}
}
VOID
MyCompletionRoutine (
IN WDFREQUEST Request,
IN WDFIOTARGET Target,
IN PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,
IN WDFCONTEXT Context
)
{
NTSTATUS status;
WDFMEMORY memoryHandle=Context;
PUCHAR charPointer=NULL;
UCHAR count =0;
size_t length=0;
PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams;
UNREFERENCED_PARAMETER(Target);
UNREFERENCED_PARAMETER(Context);
DbgPrint("Entered %s\n",__FUNCTION__);
status = CompletionParams->IoStatus.Status;
usbCompletionParams = CompletionParams->Parameters.Usb.Completion;
DbgPrint("%s: request Status 0x%x UsbdStatus 0x%x\n",__FUNCTION__,status,
usbCompletionParams->UsbdStatus);
WdfObjectDelete(Request);
DbgPrint("Leaving %s\n",__FUNCTION__);
return;
}
==============
In the wdm code Getstate : Sendcommand is taking paramater as Output buffer(I.IoctlBuffer-> via KIrp).
This output buffer is filled with status info and passed back to the host
a) In the wdf code I also want to implemnt the same . But
I am not able to get pointer to Output buffer?.How to get this ?
b) Also should I use WdfUsbTargetDeviceFormatRequestForControlTransfer or WdfUsbTargetDeviceSendControlTransferSynchronously for doing the same.
Thanks for all your replies,
Regards,
Zaheer
EggHeadCafe - Software Developer Portal of Choice
XML WebServices Architecture: Origin of Species
http://www.eggheadcafe.com/tutorials/aspnet/9379398f-9846-43d6-a98c-50690b3228fd/xml-webservices-architect.aspx
WdfRequestRetrieveOutputBuffer will get the pointer/size of the underlying
buffer to the request.
> b) Also should I use WdfUsbTargetDeviceFormatRequestForControlTransfer or
> WdfUsbTargetDeviceSendControlTransferSynchronously for doing the same.
I'm not familiar with the "m_DfuInterface.SubmitUrb (pUrb)" call semantics
but I would guess this is a synchronous call in which case
WdfUsbTargetDeviceSendControlTransferSynchronously should suit your needs.
This is essentially doing a ...FormatRequest... and WdfRequestSend in a
single function. ...FormatRequest... allows you to specify more advanced
options such as sync/async send and async completion routines.