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
,
33 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
34 IoCopyCurrentIrpStackLocationToNext(Irp
);
36 IoSetCompletionRoutine(Irp
, ForwardIrpAndWaitCompletion
, &Event
, TRUE
, TRUE
, TRUE
);
38 Status
= IoCallDriver(DeviceObject
, Irp
);
39 if (Status
== STATUS_PENDING
)
41 Status
= KeWaitForSingleObject(&Event
, Suspended
, KernelMode
, FALSE
, NULL
);
42 if (NT_SUCCESS(Status
))
43 Status
= Irp
->IoStatus
.Status
;
51 IN PDEVICE_OBJECT DeviceObject
,
54 PDEVICE_OBJECT LowerDevice
= ((PHUB_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->LowerDevice
;
58 IoSkipCurrentIrpStackLocation(Irp
);
59 return IoCallDriver(LowerDevice
, Irp
);
62 /* I really want PCSZ strings as last arguments because
63 * PnP ids are ANSI-encoded in PnP device string
66 UsbhubInitMultiSzString(
67 OUT PUNICODE_STRING Destination
,
68 ... /* list of PCSZ */)
72 ANSI_STRING AnsiString
;
73 UNICODE_STRING UnicodeString
;
74 ULONG DestinationSize
= 0;
75 NTSTATUS Status
= STATUS_SUCCESS
;
79 /* Calculate length needed for destination unicode string */
80 va_start(args
, Destination
);
81 Source
= va_arg(args
, PCSZ
);
82 while (Source
!= NULL
)
84 RtlInitAnsiString(&AnsiString
, Source
);
85 DestinationSize
+= RtlAnsiStringToUnicodeSize(&AnsiString
)
86 + sizeof(WCHAR
) /* final NULL */;
87 Source
= va_arg(args
, PCSZ
);
90 if (DestinationSize
== 0)
92 RtlInitUnicodeString(Destination
, NULL
);
93 return STATUS_SUCCESS
;
96 /* Initialize destination string */
97 DestinationSize
+= sizeof(WCHAR
); // final NULL
98 Destination
->Buffer
= (PWSTR
)ExAllocatePoolWithTag(PagedPool
, DestinationSize
, USB_HUB_TAG
);
99 if (!Destination
->Buffer
)
100 return STATUS_INSUFFICIENT_RESOURCES
;
101 Destination
->Length
= 0;
102 Destination
->MaximumLength
= (USHORT
)DestinationSize
;
104 /* Copy arguments to destination string */
105 /* Use a temporary unicode string, which buffer is shared with
106 * destination string, to copy arguments */
107 UnicodeString
.Length
= Destination
->Length
;
108 UnicodeString
.MaximumLength
= Destination
->MaximumLength
;
109 UnicodeString
.Buffer
= Destination
->Buffer
;
110 va_start(args
, Destination
);
111 Source
= va_arg(args
, PCSZ
);
112 while (Source
!= NULL
)
114 RtlInitAnsiString(&AnsiString
, Source
);
115 Status
= RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, FALSE
);
116 if (!NT_SUCCESS(Status
))
118 ExFreePoolWithTag(Destination
->Buffer
, USB_HUB_TAG
);
121 Destination
->Length
+= UnicodeString
.Length
+ sizeof(WCHAR
);
122 UnicodeString
.MaximumLength
-= UnicodeString
.Length
+ sizeof(WCHAR
);
123 UnicodeString
.Buffer
+= UnicodeString
.Length
/ sizeof(WCHAR
) + 1;
124 UnicodeString
.Length
= 0;
125 Source
= va_arg(args
, PCSZ
);
128 if (NT_SUCCESS(Status
))
130 /* Finish multi-sz string */
131 Destination
->Buffer
[Destination
->Length
/ sizeof(WCHAR
)] = L
'\0';
132 Destination
->Length
+= sizeof(WCHAR
);
138 UsbhubDuplicateUnicodeString(
139 OUT PUNICODE_STRING Destination
,
140 IN PUNICODE_STRING Source
,
141 IN POOL_TYPE PoolType
)
147 RtlInitUnicodeString(Destination
, NULL
);
148 return STATUS_SUCCESS
;
151 Destination
->Buffer
= ExAllocatePool(PoolType
, Source
->MaximumLength
);
152 if (Destination
->Buffer
== NULL
)
154 return STATUS_INSUFFICIENT_RESOURCES
;
157 Destination
->MaximumLength
= Source
->MaximumLength
;
158 Destination
->Length
= Source
->Length
;
159 RtlCopyMemory(Destination
->Buffer
, Source
->Buffer
, Source
->MaximumLength
);
161 return STATUS_SUCCESS
;