Sync with trunk head (part 1 of x)
[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
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 ASSERT(LowerDevice);
107
108 IoSkipCurrentIrpStackLocation(Irp);
109 return IoCallDriver(LowerDevice, Irp);
110 }
111
112 /* Copied fom trunk PCI drivers */
113 NTSTATUS
114 DuplicateUnicodeString(ULONG Flags, PCUNICODE_STRING SourceString, PUNICODE_STRING DestinationString)
115 {
116 if (SourceString == NULL || DestinationString == NULL
117 || SourceString->Length > SourceString->MaximumLength
118 || (SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL)
119 || Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING || Flags >= 4)
120 {
121 return STATUS_INVALID_PARAMETER;
122 }
123
124
125 if ((SourceString->Length == 0)
126 && (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE |
127 RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
128 {
129 DestinationString->Length = 0;
130 DestinationString->MaximumLength = 0;
131 DestinationString->Buffer = NULL;
132 }
133 else
134 {
135 USHORT DestMaxLength = SourceString->Length;
136
137 if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
138 DestMaxLength += sizeof(UNICODE_NULL);
139
140 DestinationString->Buffer = ExAllocatePool(PagedPool, DestMaxLength);
141 if (DestinationString->Buffer == NULL)
142 return STATUS_NO_MEMORY;
143
144 RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length);
145 DestinationString->Length = SourceString->Length;
146 DestinationString->MaximumLength = DestMaxLength;
147
148 if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
149 DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0;
150 }
151
152 return STATUS_SUCCESS;
153 }
154