f03325dc7b83bd8c12ad7855c3561342256d7e0e
[reactos.git] / reactos / drivers / usb / usbehci / common.c
1 /*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbehci/common.c
5 * PURPOSE: Common operations in FDO/PDO.
6 * PROGRAMMERS:
7 * Michael Martin
8 */
9
10 #define INITGUID
11 #include "usbehci.h"
12 #include <wdmguid.h>
13 #include <stdio.h>
14 #define NDEBUG
15 #include <debug.h>
16
17 /* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
18
19 NTSTATUS NTAPI
20 GetBusInterface(PDEVICE_OBJECT DeviceObject, PBUS_INTERFACE_STANDARD busInterface)
21 {
22 KEVENT Event;
23 NTSTATUS Status;
24 PIRP Irp;
25 IO_STATUS_BLOCK IoStatus;
26 PIO_STACK_LOCATION Stack;
27
28 if ((!DeviceObject) || (!busInterface))
29 return STATUS_UNSUCCESSFUL;
30
31 KeInitializeEvent(&Event, NotificationEvent, FALSE);
32
33 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
34 DeviceObject,
35 NULL,
36 0,
37 NULL,
38 &Event,
39 &IoStatus);
40
41 if (Irp == NULL)
42 {
43 return STATUS_INSUFFICIENT_RESOURCES;
44 }
45
46 Stack=IoGetNextIrpStackLocation(Irp);
47 Stack->MajorFunction = IRP_MJ_PNP;
48 Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
49 Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
50 Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&GUID_BUS_INTERFACE_STANDARD;
51 Stack->Parameters.QueryInterface.Version = 1;
52 Stack->Parameters.QueryInterface.Interface = (PINTERFACE)busInterface;
53 Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
54 Irp->IoStatus.Status=STATUS_NOT_SUPPORTED ;
55
56 Status=IoCallDriver(DeviceObject, Irp);
57
58 if (Status == STATUS_PENDING)
59 {
60 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
61
62 Status=IoStatus.Status;
63 }
64
65 return Status;
66 }
67
68 NTSTATUS NTAPI
69 ForwardAndWaitCompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PKEVENT Event)
70 {
71 if (Irp->PendingReturned)
72 {
73 KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
74 }
75 return STATUS_MORE_PROCESSING_REQUIRED;
76 }
77
78 NTSTATUS NTAPI
79 ForwardAndWait(PDEVICE_OBJECT DeviceObject, PIRP Irp)
80 {
81 PFDO_DEVICE_EXTENSION DeviceExtensions;
82 KEVENT Event;
83 NTSTATUS Status;
84
85
86 DeviceExtensions = DeviceObject->DeviceExtension;
87 KeInitializeEvent(&Event, NotificationEvent, FALSE);
88 IoCopyCurrentIrpStackLocationToNext(Irp);
89 IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)ForwardAndWaitCompletionRoutine, &Event, TRUE, TRUE, TRUE);
90 Status = IoCallDriver(DeviceExtensions->LowerDevice, Irp);
91 if (Status == STATUS_PENDING)
92 {
93 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
94 Status = Irp->IoStatus.Status;
95 }
96
97 return Status;
98 }
99
100 NTSTATUS NTAPI
101 ForwardIrpAndForget(PDEVICE_OBJECT DeviceObject, PIRP Irp)
102 {
103 PDEVICE_OBJECT LowerDevice;
104
105 LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
106 DPRINT1("DeviceObject %x, LowerDevice %x\n", DeviceObject, LowerDevice);
107 ASSERT(LowerDevice);
108
109 IoSkipCurrentIrpStackLocation(Irp);
110 return IoCallDriver(LowerDevice, Irp);
111 }
112
113 /* Copied fom trunk PCI drivers */
114 NTSTATUS
115 DuplicateUnicodeString(ULONG Flags, PCUNICODE_STRING SourceString, PUNICODE_STRING DestinationString)
116 {
117 if (SourceString == NULL || DestinationString == NULL
118 || SourceString->Length > SourceString->MaximumLength
119 || (SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL)
120 || Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING || Flags >= 4)
121 {
122 return STATUS_INVALID_PARAMETER;
123 }
124
125
126 if ((SourceString->Length == 0)
127 && (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE |
128 RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
129 {
130 DestinationString->Length = 0;
131 DestinationString->MaximumLength = 0;
132 DestinationString->Buffer = NULL;
133 }
134 else
135 {
136 USHORT DestMaxLength = SourceString->Length;
137
138 if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
139 DestMaxLength += sizeof(UNICODE_NULL);
140
141 DestinationString->Buffer = ExAllocatePool(PagedPool, DestMaxLength);
142 if (DestinationString->Buffer == NULL)
143 return STATUS_NO_MEMORY;
144
145 RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length);
146 DestinationString->Length = SourceString->Length;
147 DestinationString->MaximumLength = DestMaxLength;
148
149 if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
150 DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0;
151 }
152
153 return STATUS_SUCCESS;
154 }
155