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