Author: mjmartin
Date: Sat Jul 3 11:40:58 2010
New Revision: 47926
URL:
http://svn.reactos.org/svn/reactos?rev=47926&view=rev
Log:
[usb/usbehci]
- Implement FdoDispatchInternalDeviceControl and remove IrpStub as its no longer needed.
- Implement Direct Call RemoveUsbDevice.
- Implement URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE.
- Use the port parameter in ExecuteControlRequest.
- Windows now identifies my thumb drive as a mass storage device.
Modified:
trunk/reactos/drivers/usb/usbehci/fdo.c
trunk/reactos/drivers/usb/usbehci/urbreq.c
trunk/reactos/drivers/usb/usbehci/usbehci.c
trunk/reactos/drivers/usb/usbehci/usbehci.h
trunk/reactos/drivers/usb/usbehci/usbiffn.c
Modified: trunk/reactos/drivers/usb/usbehci/fdo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/fdo.c?…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/fdo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/fdo.c [iso-8859-1] Sat Jul 3 11:40:58 2010
@@ -4,7 +4,7 @@
* FILE: drivers/usb/usbehci/fdo.c
* PURPOSE: USB EHCI device driver.
* PROGRAMMERS:
- * Michael Martin
+ * Michael Martin (mjmartin(a)reactos.org)
*/
/* INCLUDES *******************************************************************/
@@ -831,3 +831,283 @@
return STATUS_SUCCESS;
}
+
+NTSTATUS NTAPI
+FdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+ PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+ PIO_STACK_LOCATION Stack = NULL;
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+ ULONG_PTR Information = 0;
+ PUSB_DEVICE UsbDevice = NULL;
+ URB *Urb;
+
+ FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+
+ ASSERT(FdoDeviceExtension->Common.IsFdo == TRUE);
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+
+ ASSERT(Stack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_INTERNAL_USB_SUBMIT_URB);
+
+ Urb = (PURB) Stack->Parameters.Others.Argument1;
+ DPRINT("Header Length %d\n", Urb->UrbHeader.Length);
+ DPRINT("Header Function %d\n", Urb->UrbHeader.Function);
+
+ UsbDevice = Urb->UrbHeader.UsbdDeviceHandle;
+
+ switch (Urb->UrbHeader.Function)
+ {
+ case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
+ {
+ DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n");
+ break;
+ }
+ case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
+ {
+ DPRINT1("URB_FUNCTION_GET_STATUS_FROM_DEVICE\n");
+ break;
+ }
+ case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
+ {
+ switch(Urb->UrbControlDescriptorRequest.DescriptorType)
+ {
+ case USB_DEVICE_DESCRIPTOR_TYPE:
+ {
+ /* FIXNME: This probably not used for FDO and should be removed? */
+ DPRINT1("USB DEVICE DESC\n");
+ break;
+ }
+ case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ DPRINT1("USB CONFIG DESC\n");
+ case USB_STRING_DESCRIPTOR_TYPE:
+ DPRINT1("Usb String Descriptor\n");
+ {
+ USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+ BOOLEAN ResultOk;
+
+ CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
+ CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
+ CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
+ CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
+ CtrlSetup.wValue.LowByte =
Urb->UrbControlDescriptorRequest.Index;
+ CtrlSetup.wValue.HiByte =
Urb->UrbControlDescriptorRequest.DescriptorType;
+ if (Urb->UrbControlDescriptorRequest.DescriptorType ==
USB_STRING_DESCRIPTOR_TYPE)
+ CtrlSetup.wIndex.W =
Urb->UrbControlDescriptorRequest.LanguageId;
+ else
+ CtrlSetup.wIndex.W = 0;
+ CtrlSetup.wLength =
Urb->UrbControlDescriptorRequest.TransferBufferLength;
+
+ ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup,
UsbDevice->Address, UsbDevice->Port,
+ Urb->UrbControlDescriptorRequest.TransferBuffer,
Urb->UrbControlDescriptorRequest.TransferBufferLength);
+
+ Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
+
+ break;
+ }
+ default:
+ {
+ DPRINT1("Descriptor Type %x not supported!\n",
Urb->UrbControlDescriptorRequest.DescriptorType);
+ }
+ }
+ break;
+ }
+ case URB_FUNCTION_SELECT_CONFIGURATION:
+ {
+ DPRINT1("Selecting Configuration\n");
+ DPRINT1("Urb->UrbSelectConfiguration.ConfigurationHandle
%x\n",Urb->UrbSelectConfiguration.ConfigurationHandle);
+ break;
+ }
+ case URB_FUNCTION_CLASS_DEVICE:
+ {
+ switch (Urb->UrbControlVendorClassRequest.Request)
+ {
+ case USB_REQUEST_GET_DESCRIPTOR:
+ {
+ DPRINT1("TransferFlags %x\n",
Urb->UrbControlVendorClassRequest.TransferFlags);
+ DPRINT1("Urb->UrbControlVendorClassRequest.Value %x\n",
Urb->UrbControlVendorClassRequest.Value);
+
+ switch (Urb->UrbControlVendorClassRequest.Value >> 8)
+ {
+ case USB_DEVICE_CLASS_AUDIO:
+ {
+ DPRINT1("USB_DEVICE_CLASS_AUDIO\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_COMMUNICATIONS:
+ {
+ DPRINT1("USB_DEVICE_CLASS_COMMUNICATIONS\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_HUMAN_INTERFACE:
+ {
+ DPRINT1("USB_DEVICE_CLASS_HUMAN_INTERFACE\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_MONITOR:
+ {
+ DPRINT1("USB_DEVICE_CLASS_MONITOR\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_PHYSICAL_INTERFACE:
+ {
+ DPRINT1("USB_DEVICE_CLASS_PHYSICAL_INTERFACE\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_POWER:
+ {
+ DPRINT1("USB_DEVICE_CLASS_POWER\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_PRINTER:
+ {
+ DPRINT1("USB_DEVICE_CLASS_PRINTER\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_STORAGE:
+ {
+ DPRINT1("USB_DEVICE_CLASS_STORAGE\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_RESERVED:
+ DPRINT1("Reserved!!!\n");
+ case USB_DEVICE_CLASS_HUB:
+ {
+ DPRINT1("USB_DEVICE_CLASS_HUB request\n");
+ break;
+ }
+ default:
+ {
+ DPRINT1("Unknown UrbControlVendorClassRequest
Value\n");
+ }
+ }
+ break;
+ }
+ case USB_REQUEST_GET_STATUS:
+ {
+ DPRINT1("DEVICE: USB_REQUEST_GET_STATUS for port %d\n",
Urb->UrbControlVendorClassRequest.Index);
+ break;
+ }
+ default:
+ {
+ DPRINT1("Unhandled URB request for class device\n");
+ //Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
+ }
+ }
+ break;
+ }
+ case URB_FUNCTION_CLASS_OTHER:
+ {
+ switch (Urb->UrbControlVendorClassRequest.Request)
+ {
+ case USB_REQUEST_GET_STATUS:
+ {
+ DPRINT1("OTHER: USB_REQUEST_GET_STATUS for port %d\n",
Urb->UrbControlVendorClassRequest.Index);
+ break;
+ }
+ case USB_REQUEST_CLEAR_FEATURE:
+ {
+ DPRINT1("USB_REQUEST_CLEAR_FEATURE Port %d, value %x\n",
Urb->UrbControlVendorClassRequest.Index,
+ Urb->UrbControlVendorClassRequest.Value);
+ switch (Urb->UrbControlVendorClassRequest.Value)
+ {
+ case C_PORT_CONNECTION:
+ DPRINT1("Clearing Connect\n");
+ break;
+ case C_PORT_RESET:
+ DPRINT1("Clearing Reset\n");
+ break;
+ default:
+ DPRINT1("Unknown Value for Clear Feature %x \n",
Urb->UrbControlVendorClassRequest.Value);
+ break;
+ }
+ break;
+ }
+ case USB_REQUEST_SET_FEATURE:
+ {
+ DPRINT1("USB_REQUEST_SET_FEATURE Port %d, value %x\n",
Urb->UrbControlVendorClassRequest.Index,
+ Urb->UrbControlVendorClassRequest.Value);
+
+ switch(Urb->UrbControlVendorClassRequest.Value)
+ {
+ case PORT_RESET:
+ {
+ DPRINT1("Port reset\n");
+ break;
+ }
+ case PORT_ENABLE:
+ {
+ DPRINT1("Unhandled Set Feature\n");
+ break;
+ }
+ default:
+ {
+ DPRINT1("Unknown Set Feature!\n");
+ break;
+ }
+ }
+ break;
+ }
+ case USB_REQUEST_SET_ADDRESS:
+ {
+ DPRINT1("USB_REQUEST_SET_ADDRESS\n");
+ break;
+ }
+ case USB_REQUEST_GET_DESCRIPTOR:
+ {
+ DPRINT1("USB_REQUEST_GET_DESCRIPTOR\n");
+ break;
+ }
+ case USB_REQUEST_SET_DESCRIPTOR:
+ {
+ DPRINT1("USB_REQUEST_SET_DESCRIPTOR\n");
+ break;
+ }
+ case USB_REQUEST_GET_CONFIGURATION:
+ {
+ DPRINT1("USB_REQUEST_GET_CONFIGURATION\n");
+ break;
+ }
+ case USB_REQUEST_SET_CONFIGURATION:
+ {
+ DPRINT1("USB_REQUEST_SET_CONFIGURATION\n");
+ break;
+ }
+ case USB_REQUEST_GET_INTERFACE:
+ {
+ DPRINT1("USB_REQUEST_GET_INTERFACE\n");
+ break;
+ }
+ case USB_REQUEST_SET_INTERFACE:
+ {
+ DPRINT1("USB_REQUEST_SET_INTERFACE\n");
+ break;
+ }
+ case USB_REQUEST_SYNC_FRAME:
+ {
+ DPRINT1("USB_REQUEST_SYNC_FRAME\n");
+ break;
+ }
+ default:
+ {
+ DPRINT1("Unknown Function Class Unknown request\n");
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function);
+ //Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
+ }
+ }
+
+ Irp->IoStatus.Information = Information;
+
+ if (Status != STATUS_PENDING)
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return Status;
+}
Modified: trunk/reactos/drivers/usb/usbehci/urbreq.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/urbreq…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/urbreq.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/urbreq.c [iso-8859-1] Sat Jul 3 11:40:58 2010
@@ -4,7 +4,7 @@
* FILE: drivers/usb/usbehci/urbreq.c
* PURPOSE: URB Related Functions.
* PROGRAMMERS:
- * Michael Martin
+ * Michael Martin (mjmartin(a)reactos.org)
*/
#include "usbehci.h"
@@ -135,6 +135,9 @@
(PVOID)&CtrlData,
BufferLength);
+ QueueHead->EndPointCapabilities2.PortNumber = Port;
+ QueueHead->EndPointCapabilities1.DeviceAddress = Address;
+
CtrlSetup->bmRequestType._BM.Recipient =
SetupPacket->bmRequestType._BM.Recipient;
CtrlSetup->bmRequestType._BM.Type = SetupPacket->bmRequestType._BM.Type;
CtrlSetup->bmRequestType._BM.Dir = SetupPacket->bmRequestType._BM.Dir;
@@ -143,10 +146,6 @@
CtrlSetup->wValue.HiByte = SetupPacket->wValue.HiByte;
CtrlSetup->wIndex.W = SetupPacket->wIndex.W;
CtrlSetup->wLength = SetupPacket->wLength;
-
-
- QueueHead->EndPointCapabilities1.DeviceAddress = Address;
- //QueueHead->EndPointCapabilities2.PortNumber = Port;
tmp = READ_REGISTER_ULONG((PULONG) (Base + EHCI_USBCMD));
UsbCmd = (PEHCI_USBCMD_CONTENT) &tmp;
Modified: trunk/reactos/drivers/usb/usbehci/usbehci.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/usbehc…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/usbehci.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/usbehci.c [iso-8859-1] Sat Jul 3 11:40:58 2010
@@ -4,32 +4,11 @@
* FILE: drivers/usb/usbehci/usbehci.c
* PURPOSE: USB EHCI device driver.
* PROGRAMMERS:
- * Michael Martin
+ * Michael Martin (mjmartin(a)reactos.com)
*/
/* DEFINES *******************************************************************/
#include "usbehci.h"
-
-static NTSTATUS NTAPI
-IrpStub(PDEVICE_OBJECT DeviceObject, PIRP Irp)
-{
- NTSTATUS Status;
-
- if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFdo)
- {
- DPRINT1("ehci: FDO stub for major function 0x%lx\n",
- IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
- return ForwardIrpAndForget(DeviceObject, Irp);
- }
-
- /* We are lower driver, So complete */
- DPRINT1("ehci: PDO stub for major function 0x%lx\n",
- IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
-
- Status = Irp->IoStatus.Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
-}
NTSTATUS NTAPI
DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
@@ -47,7 +26,9 @@
{
DPRINT("DispatchInternalDeviceControl\n");
if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFdo)
- return IrpStub(DeviceObject, Irp);
+ {
+ return FdoDispatchInternalDeviceControl(DeviceObject, Irp);
+ }
else
return PdoDispatchInternalDeviceControl(DeviceObject, Irp);
}
Modified: trunk/reactos/drivers/usb/usbehci/usbehci.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/usbehc…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/usbehci.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/usbehci.h [iso-8859-1] Sat Jul 3 11:40:58 2010
@@ -9,7 +9,7 @@
#include <usbioctl.h>
#include <usb.h>
-#define USB_POOL_TAG (ULONG)'UsbR'
+#define USB_POOL_TAG (ULONG)'ebsu'
#define DEVICEINTIALIZED 0x01
#define DEVICESTARTED 0x02
@@ -463,6 +463,9 @@
NTSTATUS NTAPI
PdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+NTSTATUS NTAPI
+FdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+
BOOLEAN
ExecuteControlRequest(PFDO_DEVICE_EXTENSION DeviceExtension,
PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, UCHAR Address, ULONG Port, PVOID Buffer, ULONG
BufferLength);
Modified: trunk/reactos/drivers/usb/usbehci/usbiffn.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/usbiff…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/usbiffn.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/usbiffn.c [iso-8859-1] Sat Jul 3 11:40:58 2010
@@ -4,7 +4,7 @@
* FILE: drivers/usb/usbehci/usbiffn.c
* PURPOSE: Direct Call Interface Functions.
* PROGRAMMERS:
- * Michael Martin
+ * Michael Martin (mjmartin(a)reactos.org)
*/
#include "usbehci.h"
@@ -98,10 +98,12 @@
PdoDeviceExtension->UsbDevices[i] = (PUSB_DEVICE)UsbDevice;
PdoDeviceExtension->UsbDevices[i]->Address = i + 1;
PdoDeviceExtension->UsbDevices[i]->Port = PortNumber;
- break;
+ break;
}
i++;
}
+
+ PdoDeviceExtension->Ports[PortNumber - 1].PortStatus = PortStatus;
/* Return it */
*NewDevice = UsbDevice;
@@ -140,6 +142,7 @@
}
Ptr = Buffer;
+
/* Set the device address */
CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
@@ -149,6 +152,7 @@
CtrlSetup.wIndex.W = 0;
CtrlSetup.wLength = 0;
+ DPRINT1("Setting Address to %x\n", UsbDevice->Address);
ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, 0, 0, NULL, 0);
/* Get the Device Descriptor */
@@ -161,11 +165,15 @@
CtrlSetup.wIndex.W = 0;
CtrlSetup.wLength = sizeof(USB_DEVICE_DESCRIPTOR);
- ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup,
UsbDevice->Address, UsbDevice->Port,
+ DPRINT1("Requesting Descriptor\n");
+ ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup,
UsbDevice->Address, UsbDevice->Port,
&UsbDevice->DeviceDescriptor,
sizeof(USB_DEVICE_DESCRIPTOR));
+
DPRINT1("bLength %x\n", UsbDevice->DeviceDescriptor.bLength);
DPRINT1("bDescriptorType %x\n",
UsbDevice->DeviceDescriptor.bDescriptorType);
+ DPRINT1("idVendor %x\n", UsbDevice->DeviceDescriptor.idVendor);
+ DPRINT1("idProduct %x\n", UsbDevice->DeviceDescriptor.idProduct);
DPRINT1("bNumDescriptors %x\n",
UsbDevice->DeviceDescriptor.bNumConfigurations);
if (UsbDevice->DeviceDescriptor.bNumConfigurations == 0)
@@ -246,10 +254,10 @@
PULONG ConfigDescriptorBufferLength)
{
PUSB_DEVICE UsbDevice;
- DPRINT1("GetUsbDescriptor %x, %d, %x, %d\n", DeviceDescriptorBuffer,
DeviceDescriptorBufferLength, ConfigDescriptorBuffer, ConfigDescriptorBufferLength);
+ DPRINT1("GetUsbDescriptor %x, %x, %x, %x\n", DeviceDescriptorBuffer,
*DeviceDescriptorBufferLength, ConfigDescriptorBuffer, *ConfigDescriptorBufferLength);
UsbDevice = (PUSB_DEVICE) DeviceHandle;
-
+ DPRINT1("DeviceHandle %x\n", UsbDevice);
if ((DeviceDescriptorBuffer) && (DeviceDescriptorBufferLength))
{
RtlCopyMemory(DeviceDescriptorBuffer, &UsbDevice->DeviceDescriptor,
sizeof(USB_DEVICE_DESCRIPTOR));
@@ -268,7 +276,59 @@
USB_BUSIFFN
RemoveUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE DeviceHandle, ULONG Flags)
{
- DPRINT1("RemoveUsbDevice called\n");
+ PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+ PUSB_DEVICE UsbDevice;
+ LONG i, j, k;
+
+ DPRINT1("RemoveUsbDevice called, DeviceHandle %x, Flags %x\n",
DeviceHandle, Flags);
+
+ PdoDeviceExtension =
(PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
+
+ /* FIXME: Implement DeviceHandleToUsbDevice to validate handles */
+ //UsbDevice = DeviceHandleToUsbDevice(PdoDeviceExtension, DeviceHandle);
+
+ UsbDevice = (PUSB_DEVICE) DeviceHandle;
+
+ if (!UsbDevice)
+ return STATUS_DEVICE_NOT_CONNECTED;
+
+ switch (Flags)
+ {
+ case 0:
+ DPRINT1("Number of Configurations %d\n",
UsbDevice->DeviceDescriptor.bNumConfigurations);
+ for (i = 0; i < UsbDevice->DeviceDescriptor.bNumConfigurations; i++)
+ {
+ for (j = 0; j <
UsbDevice->Configs[i]->ConfigurationDescriptor.bNumInterfaces; j++)
+ {
+ for (k = 0; k <
UsbDevice->Configs[i]->Interfaces[j]->InterfaceDescriptor.bNumEndpoints; k++)
+ {
+
ExFreePool(UsbDevice->Configs[i]->Interfaces[j]->EndPoints[k]);
+ }
+ ExFreePool(UsbDevice->Configs[i]->Interfaces[j]);
+ }
+ ExFreePool(UsbDevice->Configs[i]);
+ }
+
+ for (i = 0; i < 127; i++)
+ {
+ if (PdoDeviceExtension->UsbDevices[i] == UsbDevice)
+ PdoDeviceExtension->UsbDevices[i] = NULL;
+ }
+
+ ExFreePool(UsbDevice);
+
+ /* DeConfig Device */
+ break;
+ case USBD_KEEP_DEVICE_DATA:
+ DPRINT("USBD_KEEP_DEVICE_DATA Not implemented!\n");
+ break;
+
+ case USBD_MARK_DEVICE_BUSY:
+ DPRINT("USBD_MARK_DEVICE_BUSY Not implemented!\n");
+ break;
+ default:
+ DPRINT1("Unknown Remove Flags %x\n", Flags);
+ }
return STATUS_SUCCESS;
}