Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmisc.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Serial enumerator driver 00004 * FILE: drivers/dd/serenum/misc.c 00005 * PURPOSE: Misceallenous operations 00006 * 00007 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.com) 00008 */ 00009 00010 #include "serenum.h" 00011 00012 static IO_COMPLETION_ROUTINE ForwardIrpAndWaitCompletion; 00013 00014 /* I really want PCSZ strings as last arguments because 00015 * PnP ids are ANSI-encoded in PnP device string 00016 * identification */ 00017 NTSTATUS 00018 SerenumInitMultiSzString( 00019 OUT PUNICODE_STRING Destination, 00020 ... /* list of PCSZ */) 00021 { 00022 va_list args; 00023 PCSZ Source; 00024 ANSI_STRING AnsiString; 00025 UNICODE_STRING UnicodeString; 00026 ULONG DestinationSize = 0; 00027 NTSTATUS Status = STATUS_SUCCESS; 00028 00029 ASSERT(Destination); 00030 00031 /* Calculate length needed for destination unicode string */ 00032 va_start(args, Destination); 00033 Source = va_arg(args, PCSZ); 00034 while (Source != NULL) 00035 { 00036 RtlInitAnsiString(&AnsiString, Source); 00037 DestinationSize += RtlAnsiStringToUnicodeSize(&AnsiString) 00038 + sizeof(WCHAR) /* final NULL */; 00039 Source = va_arg(args, PCSZ); 00040 } 00041 va_end(args); 00042 if (DestinationSize == 0) 00043 { 00044 RtlInitUnicodeString(Destination, NULL); 00045 return STATUS_SUCCESS; 00046 } 00047 00048 /* Initialize destination string */ 00049 DestinationSize += sizeof(WCHAR); // final NULL 00050 Destination->Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, DestinationSize, SERENUM_TAG); 00051 if (!Destination->Buffer) 00052 return STATUS_INSUFFICIENT_RESOURCES; 00053 Destination->Length = 0; 00054 Destination->MaximumLength = (USHORT)DestinationSize; 00055 00056 /* Copy arguments to destination string */ 00057 /* Use a temporary unicode string, which buffer is shared with 00058 * destination string, to copy arguments */ 00059 UnicodeString.Length = Destination->Length; 00060 UnicodeString.MaximumLength = Destination->MaximumLength; 00061 UnicodeString.Buffer = Destination->Buffer; 00062 va_start(args, Destination); 00063 Source = va_arg(args, PCSZ); 00064 while (Source != NULL) 00065 { 00066 RtlInitAnsiString(&AnsiString, Source); 00067 Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE); 00068 if (!NT_SUCCESS(Status)) 00069 { 00070 ExFreePoolWithTag(Destination->Buffer, SERENUM_TAG); 00071 break; 00072 } 00073 Destination->Length += UnicodeString.Length + sizeof(WCHAR); 00074 UnicodeString.MaximumLength -= UnicodeString.Length + sizeof(WCHAR); 00075 UnicodeString.Buffer += UnicodeString.Length / sizeof(WCHAR) + 1; 00076 UnicodeString.Length = 0; 00077 Source = va_arg(args, PCSZ); 00078 } 00079 va_end(args); 00080 if (NT_SUCCESS(Status)) 00081 { 00082 /* Finish multi-sz string */ 00083 Destination->Buffer[Destination->Length / sizeof(WCHAR)] = L'\0'; 00084 Destination->Length += sizeof(WCHAR); 00085 } 00086 return Status; 00087 } 00088 00089 static NTSTATUS NTAPI 00090 ForwardIrpAndWaitCompletion( 00091 IN PDEVICE_OBJECT DeviceObject, 00092 IN PIRP Irp, 00093 IN PVOID Context) 00094 { 00095 if (Irp->PendingReturned) 00096 KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); 00097 return STATUS_MORE_PROCESSING_REQUIRED; 00098 } 00099 00100 NTSTATUS 00101 ForwardIrpAndWait( 00102 IN PDEVICE_OBJECT DeviceObject, 00103 IN PIRP Irp) 00104 { 00105 PDEVICE_OBJECT LowerDevice; 00106 KEVENT Event; 00107 NTSTATUS Status; 00108 00109 ASSERT(((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO); 00110 LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; 00111 00112 ASSERT(LowerDevice); 00113 00114 KeInitializeEvent(&Event, NotificationEvent, FALSE); 00115 IoCopyCurrentIrpStackLocationToNext(Irp); 00116 00117 TRACE_(SERENUM, "Calling lower device %p\n", LowerDevice); 00118 IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE); 00119 00120 Status = IoCallDriver(LowerDevice, Irp); 00121 if (Status == STATUS_PENDING) 00122 { 00123 Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); 00124 if (NT_SUCCESS(Status)) 00125 Status = Irp->IoStatus.Status; 00126 } 00127 00128 return Status; 00129 } 00130 00131 NTSTATUS NTAPI 00132 ForwardIrpToLowerDeviceAndForget( 00133 IN PDEVICE_OBJECT DeviceObject, 00134 IN PIRP Irp) 00135 { 00136 PFDO_DEVICE_EXTENSION DeviceExtension; 00137 PDEVICE_OBJECT LowerDevice; 00138 00139 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 00140 ASSERT(DeviceExtension->Common.IsFDO); 00141 00142 LowerDevice = DeviceExtension->LowerDevice; 00143 ASSERT(LowerDevice); 00144 TRACE_(SERENUM, "Calling lower device 0x%p\n", LowerDevice); 00145 IoSkipCurrentIrpStackLocation(Irp); 00146 return IoCallDriver(LowerDevice, Irp); 00147 } 00148 00149 NTSTATUS NTAPI 00150 ForwardIrpToAttachedFdoAndForget( 00151 IN PDEVICE_OBJECT DeviceObject, 00152 IN PIRP Irp) 00153 { 00154 PPDO_DEVICE_EXTENSION DeviceExtension; 00155 PDEVICE_OBJECT Fdo; 00156 00157 DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 00158 ASSERT(!DeviceExtension->Common.IsFDO); 00159 00160 Fdo = DeviceExtension->AttachedFdo; 00161 ASSERT(Fdo); 00162 TRACE_(SERENUM, "Calling attached Fdo 0x%p\n", Fdo); 00163 IoSkipCurrentIrpStackLocation(Irp); 00164 return IoCallDriver(Fdo, Irp); 00165 } 00166 00167 NTSTATUS NTAPI 00168 ForwardIrpAndForget( 00169 IN PDEVICE_OBJECT DeviceObject, 00170 IN PIRP Irp) 00171 { 00172 PDEVICE_OBJECT LowerDevice; 00173 00174 ASSERT(((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO); 00175 LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; 00176 ASSERT(LowerDevice); 00177 00178 IoSkipCurrentIrpStackLocation(Irp); 00179 return IoCallDriver(LowerDevice, Irp); 00180 } 00181 00182 NTSTATUS 00183 DuplicateUnicodeString( 00184 IN ULONG Flags, 00185 IN PCUNICODE_STRING SourceString, 00186 OUT PUNICODE_STRING DestinationString) 00187 { 00188 if (SourceString == NULL || DestinationString == NULL 00189 || SourceString->Length > SourceString->MaximumLength 00190 || (SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL) 00191 || Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING || Flags >= 4) 00192 { 00193 return STATUS_INVALID_PARAMETER; 00194 } 00195 00196 00197 if ((SourceString->Length == 0) 00198 && (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE | 00199 RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING))) 00200 { 00201 DestinationString->Length = 0; 00202 DestinationString->MaximumLength = 0; 00203 DestinationString->Buffer = NULL; 00204 } 00205 else 00206 { 00207 USHORT DestMaxLength = SourceString->Length; 00208 00209 if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE) 00210 DestMaxLength += sizeof(UNICODE_NULL); 00211 00212 DestinationString->Buffer = ExAllocatePoolWithTag(PagedPool, DestMaxLength, SERENUM_TAG); 00213 if (DestinationString->Buffer == NULL) 00214 return STATUS_NO_MEMORY; 00215 00216 RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length); 00217 DestinationString->Length = SourceString->Length; 00218 DestinationString->MaximumLength = DestMaxLength; 00219 00220 if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE) 00221 DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0; 00222 } 00223 00224 return STATUS_SUCCESS; 00225 } Generated on Sat May 26 2012 04:15:48 for ReactOS by
1.7.6.1
|