2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS USB miniport driver (Cromwell type)
4 * FILE: drivers/usb/miniport/common/misc.c
5 * PURPOSE: Misceallenous operations
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org),
13 #include "usbcommon.h"
17 ForwardIrpAndWaitCompletion(
18 IN PDEVICE_OBJECT DeviceObject
,
22 if (Irp
->PendingReturned
)
23 KeSetEvent((PKEVENT
)Context
, IO_NO_INCREMENT
, FALSE
);
24 return STATUS_MORE_PROCESSING_REQUIRED
;
29 IN PDEVICE_OBJECT DeviceObject
,
32 PDEVICE_OBJECT LowerDevice
= ((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->NextDeviceObject
;
38 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
39 IoCopyCurrentIrpStackLocationToNext(Irp
);
41 DPRINT("USBMP: Calling lower device %p [%wZ]\n", LowerDevice
, &LowerDevice
->DriverObject
->DriverName
);
42 IoSetCompletionRoutine(Irp
, ForwardIrpAndWaitCompletion
, &Event
, TRUE
, TRUE
, TRUE
);
44 Status
= IoCallDriver(LowerDevice
, Irp
);
45 if (Status
== STATUS_PENDING
)
47 Status
= KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
48 if (NT_SUCCESS(Status
))
49 Status
= Irp
->IoStatus
.Status
;
57 IN PDEVICE_OBJECT DeviceObject
,
60 PDEVICE_OBJECT LowerDevice
= ((PUSBMP_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->NextDeviceObject
;
64 IoSkipCurrentIrpStackLocation(Irp
);
65 return IoCallDriver(LowerDevice
, Irp
);
68 /* I really want PCSZ strings as last arguments because
69 * PnP ids are ANSI-encoded in PnP device string
72 UsbMpInitMultiSzString(
73 OUT PUNICODE_STRING Destination
,
74 ... /* list of PCSZ */)
78 ANSI_STRING AnsiString
;
79 UNICODE_STRING UnicodeString
;
80 ULONG DestinationSize
= 0;
81 NTSTATUS Status
= STATUS_SUCCESS
;
85 /* Calculate length needed for destination unicode string */
86 va_start(args
, Destination
);
87 Source
= va_arg(args
, PCSZ
);
88 while (Source
!= NULL
)
90 RtlInitAnsiString(&AnsiString
, Source
);
91 DestinationSize
+= RtlAnsiStringToUnicodeSize(&AnsiString
)
92 + sizeof(WCHAR
) /* final NULL */;
93 Source
= va_arg(args
, PCSZ
);
96 if (DestinationSize
== 0)
98 RtlInitUnicodeString(Destination
, NULL
);
99 return STATUS_SUCCESS
;
102 /* Initialize destination string */
103 DestinationSize
+= sizeof(WCHAR
); // final NULL
104 Destination
->Buffer
= (PWSTR
)ExAllocatePoolWithTag(PagedPool
, DestinationSize
, USB_MINIPORT_TAG
);
105 if (!Destination
->Buffer
)
106 return STATUS_INSUFFICIENT_RESOURCES
;
107 Destination
->Length
= 0;
108 Destination
->MaximumLength
= (USHORT
)DestinationSize
;
110 /* Copy arguments to destination string */
111 /* Use a temporary unicode string, which buffer is shared with
112 * destination string, to copy arguments */
113 UnicodeString
.Length
= Destination
->Length
;
114 UnicodeString
.MaximumLength
= Destination
->MaximumLength
;
115 UnicodeString
.Buffer
= Destination
->Buffer
;
116 va_start(args
, Destination
);
117 Source
= va_arg(args
, PCSZ
);
118 while (Source
!= NULL
)
120 RtlInitAnsiString(&AnsiString
, Source
);
121 Status
= RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, FALSE
);
122 if (!NT_SUCCESS(Status
))
124 ExFreePoolWithTag(Destination
->Buffer
, USB_MINIPORT_TAG
);
127 Destination
->Length
+= UnicodeString
.Length
+ sizeof(WCHAR
);
128 UnicodeString
.MaximumLength
-= UnicodeString
.Length
+ sizeof(WCHAR
);
129 UnicodeString
.Buffer
+= UnicodeString
.Length
/ sizeof(WCHAR
) + 1;
130 UnicodeString
.Length
= 0;
131 Source
= va_arg(args
, PCSZ
);
134 if (NT_SUCCESS(Status
))
136 /* Finish multi-sz string */
137 Destination
->Buffer
[Destination
->Length
/ sizeof(WCHAR
)] = L
'\0';
138 Destination
->Length
+= sizeof(WCHAR
);
144 UsbMpDuplicateUnicodeString(
145 OUT PUNICODE_STRING Destination
,
146 IN PUNICODE_STRING Source
,
147 IN POOL_TYPE PoolType
)
153 RtlInitUnicodeString(Destination
, NULL
);
154 return STATUS_SUCCESS
;
157 Destination
->Buffer
= ExAllocatePool(PoolType
, Source
->MaximumLength
);
158 if (Destination
->Buffer
== NULL
)
160 return STATUS_INSUFFICIENT_RESOURCES
;
163 Destination
->MaximumLength
= Source
->MaximumLength
;
164 Destination
->Length
= Source
->Length
;
165 RtlCopyMemory(Destination
->Buffer
, Source
->Buffer
, Source
->MaximumLength
);
167 return STATUS_SUCCESS
;