ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

misc.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.