2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: USB hub driver
4 * FILE: drivers/usb/cromwell/hub/misc.c
5 * PURPOSE: Misceallenous operations
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.com),
15 ForwardIrpAndWaitCompletion(
16 IN PDEVICE_OBJECT DeviceObject
,
20 if (Irp
->PendingReturned
)
21 KeSetEvent((PKEVENT
)Context
, IO_NO_INCREMENT
, FALSE
);
22 return STATUS_MORE_PROCESSING_REQUIRED
;
27 IN PDEVICE_OBJECT DeviceObject
,
30 PDEVICE_OBJECT LowerDevice
= ((PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->LowerDevice
;
36 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
37 IoCopyCurrentIrpStackLocationToNext(Irp
);
39 DPRINT("UHCI: Calling lower device %p [%wZ]\n", LowerDevice
, &LowerDevice
->DriverObject
->DriverName
);
40 IoSetCompletionRoutine(Irp
, ForwardIrpAndWaitCompletion
, &Event
, TRUE
, TRUE
, TRUE
);
42 Status
= IoCallDriver(LowerDevice
, Irp
);
43 if (Status
== STATUS_PENDING
)
45 Status
= KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
46 if (NT_SUCCESS(Status
))
47 Status
= Irp
->IoStatus
.Status
;
55 IN PDEVICE_OBJECT DeviceObject
,
58 PDEVICE_OBJECT LowerDevice
= ((PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->LowerDevice
;
62 IoSkipCurrentIrpStackLocation(Irp
);
63 return IoCallDriver(LowerDevice
, Irp
);
66 /* I really want PCSZ strings as last arguments because
67 * PnP ids are ANSI-encoded in PnP device string
70 UsbhubInitMultiSzString(
71 OUT PUNICODE_STRING Destination
,
72 ... /* list of PCSZ */)
76 ANSI_STRING AnsiString
;
77 UNICODE_STRING UnicodeString
;
78 ULONG DestinationSize
= 0;
79 NTSTATUS Status
= STATUS_SUCCESS
;
83 /* Calculate length needed for destination unicode string */
84 va_start(args
, Destination
);
85 Source
= va_arg(args
, PCSZ
);
86 while (Source
!= NULL
)
88 RtlInitAnsiString(&AnsiString
, Source
);
89 DestinationSize
+= RtlAnsiStringToUnicodeSize(&AnsiString
)
90 + sizeof(WCHAR
) /* final NULL */;
91 Source
= va_arg(args
, PCSZ
);
94 if (DestinationSize
== 0)
96 RtlInitUnicodeString(Destination
, NULL
);
97 return STATUS_SUCCESS
;
100 /* Initialize destination string */
101 DestinationSize
+= sizeof(WCHAR
); // final NULL
102 Destination
->Buffer
= (PWSTR
)ExAllocatePoolWithTag(PagedPool
, DestinationSize
, USB_HUB_TAG
);
103 if (!Destination
->Buffer
)
104 return STATUS_INSUFFICIENT_RESOURCES
;
105 Destination
->Length
= 0;
106 Destination
->MaximumLength
= (USHORT
)DestinationSize
;
108 /* Copy arguments to destination string */
109 /* Use a temporary unicode string, which buffer is shared with
110 * destination string, to copy arguments */
111 UnicodeString
.Length
= Destination
->Length
;
112 UnicodeString
.MaximumLength
= Destination
->MaximumLength
;
113 UnicodeString
.Buffer
= Destination
->Buffer
;
114 va_start(args
, Destination
);
115 Source
= va_arg(args
, PCSZ
);
116 while (Source
!= NULL
)
118 RtlInitAnsiString(&AnsiString
, Source
);
119 Status
= RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, FALSE
);
120 if (!NT_SUCCESS(Status
))
122 ExFreePoolWithTag(Destination
->Buffer
, USB_HUB_TAG
);
125 Destination
->Length
+= UnicodeString
.Length
+ sizeof(WCHAR
);
126 UnicodeString
.MaximumLength
-= UnicodeString
.Length
+ sizeof(WCHAR
);
127 UnicodeString
.Buffer
+= UnicodeString
.Length
/ sizeof(WCHAR
) + 1;
128 UnicodeString
.Length
= 0;
129 Source
= va_arg(args
, PCSZ
);
132 if (NT_SUCCESS(Status
))
134 /* Finish multi-sz string */
135 Destination
->Buffer
[Destination
->Length
/ sizeof(WCHAR
)] = L
'\0';
136 Destination
->Length
+= sizeof(WCHAR
);
142 UsbhubDuplicateUnicodeString(
143 OUT PUNICODE_STRING Destination
,
144 IN PUNICODE_STRING Source
,
145 IN POOL_TYPE PoolType
)
151 RtlInitUnicodeString(Destination
, NULL
);
152 return STATUS_SUCCESS
;
155 Destination
->Buffer
= ExAllocatePool(PoolType
, Source
->MaximumLength
);
156 if (Destination
->Buffer
== NULL
)
158 return STATUS_INSUFFICIENT_RESOURCES
;
161 Destination
->MaximumLength
= Source
->MaximumLength
;
162 Destination
->Length
= Source
->Length
;
163 RtlCopyMemory(Destination
->Buffer
, Source
->Buffer
, Source
->MaximumLength
);
165 return STATUS_SUCCESS
;