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

pci.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS PCI Bus driver
00003  * FILE:            pci.c
00004  * PURPOSE:         Driver entry
00005  * PROGRAMMERS:     Casper S. Hornstrup (chorns@users.sourceforge.net)
00006  * UPDATE HISTORY:
00007  *      10-09-2001  CSH  Created
00008  */
00009 
00010 #define INITGUID
00011 #include "pci.h"
00012 
00013 #ifndef NDEBUG
00014 #define NDEBUG
00015 #endif
00016 #include <debug.h>
00017 
00018 static DRIVER_DISPATCH PciDispatchDeviceControl;
00019 static NTSTATUS NTAPI PciDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
00020 
00021 static DRIVER_ADD_DEVICE PciAddDevice;
00022 static NTSTATUS NTAPI PciAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject);
00023 
00024 static DRIVER_DISPATCH PciPowerControl;
00025 static NTSTATUS NTAPI PciPowerControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
00026 
00027 static DRIVER_DISPATCH PciPnpControl;
00028 static NTSTATUS NTAPI PciPnpControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
00029 
00030 
00031 #ifdef  ALLOC_PRAGMA
00032 
00033 // Make the initialization routines discardable, so that they
00034 // don't waste space
00035 
00036 #pragma  alloc_text(init, DriverEntry)
00037 
00038 #endif  /*  ALLOC_PRAGMA  */
00039 
00040 /*** PUBLIC ******************************************************************/
00041 
00042 PPCI_DRIVER_EXTENSION DriverExtension = NULL;
00043 
00044 /*** PRIVATE *****************************************************************/
00045 
00046 static NTSTATUS
00047 NTAPI
00048 PciDispatchDeviceControl(
00049   IN PDEVICE_OBJECT DeviceObject,
00050   IN PIRP Irp)
00051 {
00052   PIO_STACK_LOCATION IrpSp;
00053   NTSTATUS Status;
00054 
00055   UNREFERENCED_PARAMETER(DeviceObject);
00056   DPRINT("Called. IRP is at (0x%X)\n", Irp);
00057 
00058   Irp->IoStatus.Information = 0;
00059 
00060   IrpSp = IoGetCurrentIrpStackLocation(Irp);
00061   switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
00062   default:
00063     DPRINT("Unknown IOCTL 0x%X\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
00064     Status = STATUS_NOT_IMPLEMENTED;
00065     break;
00066   }
00067 
00068   if (Status != STATUS_PENDING) {
00069     Irp->IoStatus.Status = Status;
00070 
00071     DPRINT("Completing IRP at 0x%X\n", Irp);
00072 
00073     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00074   }
00075 
00076   DPRINT("Leaving. Status 0x%X\n", Status);
00077 
00078   return Status;
00079 }
00080 
00081 
00082 static NTSTATUS
00083 NTAPI
00084 PciPnpControl(
00085   IN PDEVICE_OBJECT DeviceObject,
00086   IN PIRP Irp)
00087 /*
00088  * FUNCTION: Handle Plug and Play IRPs
00089  * ARGUMENTS:
00090  *     DeviceObject = Pointer to PDO or FDO
00091  *     Irp          = Pointer to IRP that should be handled
00092  * RETURNS:
00093  *     Status
00094  */
00095 {
00096   PCOMMON_DEVICE_EXTENSION DeviceExtension;
00097   NTSTATUS Status;
00098 
00099   DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
00100 
00101   DPRINT("IsFDO %d\n", DeviceExtension->IsFDO);
00102 
00103   if (DeviceExtension->IsFDO) {
00104     Status = FdoPnpControl(DeviceObject, Irp);
00105   } else {
00106     Status = PdoPnpControl(DeviceObject, Irp);
00107   }
00108 
00109   return Status;
00110 }
00111 
00112 
00113 static NTSTATUS
00114 NTAPI
00115 PciPowerControl(
00116   IN PDEVICE_OBJECT DeviceObject,
00117   IN PIRP Irp)
00118 /*
00119  * FUNCTION: Handle power management IRPs
00120  * ARGUMENTS:
00121  *     DeviceObject = Pointer to PDO or FDO
00122  *     Irp          = Pointer to IRP that should be handled
00123  * RETURNS:
00124  *     Status
00125  */
00126 {
00127   PCOMMON_DEVICE_EXTENSION DeviceExtension;
00128   NTSTATUS Status;
00129 
00130   DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
00131 
00132   if (DeviceExtension->IsFDO) {
00133     Status = FdoPowerControl(DeviceObject, Irp);
00134   } else {
00135     Status = PdoPowerControl(DeviceObject, Irp);
00136   }
00137 
00138   return Status;
00139 }
00140 
00141 
00142 static NTSTATUS
00143 NTAPI
00144 PciAddDevice(
00145   IN PDRIVER_OBJECT DriverObject,
00146   IN PDEVICE_OBJECT PhysicalDeviceObject)
00147 {
00148   PFDO_DEVICE_EXTENSION DeviceExtension;
00149   PDEVICE_OBJECT Fdo;
00150   NTSTATUS Status;
00151 
00152   DPRINT("Called\n");
00153   if (PhysicalDeviceObject == NULL)
00154     return STATUS_SUCCESS;
00155 
00156   Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION),
00157     NULL, FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, TRUE, &Fdo);
00158   if (!NT_SUCCESS(Status)) {
00159     DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
00160     return Status;
00161   }
00162 
00163   DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
00164 
00165   RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
00166 
00167   DeviceExtension->Common.IsFDO = TRUE;
00168 
00169   DeviceExtension->Ldo =
00170     IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject);
00171 
00172   DeviceExtension->State = dsStopped;
00173 
00174   Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
00175 
00176   //Fdo->Flags |= DO_POWER_PAGABLE;
00177 
00178   DPRINT("Done AddDevice\n");
00179 
00180   return STATUS_SUCCESS;
00181 }
00182 
00183 
00184 VOID
00185 NTAPI
00186 PciUnload(
00187   IN PDRIVER_OBJECT DriverObject)
00188 {
00189     /* The driver object extension is destroyed by the I/O manager */
00190 }
00191 
00192 NTSTATUS
00193 NTAPI
00194 DriverEntry(
00195   IN PDRIVER_OBJECT DriverObject,
00196   IN PUNICODE_STRING RegistryPath)
00197 {
00198   NTSTATUS Status;
00199 
00200   UNREFERENCED_PARAMETER(RegistryPath);
00201   DPRINT("Peripheral Component Interconnect Bus Driver\n");
00202 
00203   DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PciDispatchDeviceControl;
00204   DriverObject->MajorFunction[IRP_MJ_PNP] = PciPnpControl;
00205   DriverObject->MajorFunction[IRP_MJ_POWER] = PciPowerControl;
00206   DriverObject->DriverExtension->AddDevice = PciAddDevice;
00207   DriverObject->DriverUnload = PciUnload;
00208 
00209   Status = IoAllocateDriverObjectExtension(
00210     DriverObject,
00211     DriverObject,
00212     sizeof(PCI_DRIVER_EXTENSION),
00213     (PVOID*)&DriverExtension);
00214   if (!NT_SUCCESS(Status))
00215     return Status;
00216   RtlZeroMemory(DriverExtension, sizeof(PCI_DRIVER_EXTENSION));
00217 
00218   InitializeListHead(&DriverExtension->BusListHead);
00219   KeInitializeSpinLock(&DriverExtension->BusListLock);
00220 
00221   return STATUS_SUCCESS;
00222 }
00223 
00224 
00225 NTSTATUS
00226 PciCreateDeviceIDString(PUNICODE_STRING DeviceID,
00227                         PPCI_DEVICE Device)
00228 {
00229   WCHAR Buffer[256];
00230 
00231   swprintf(Buffer,
00232            L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
00233            Device->PciConfig.VendorID,
00234            Device->PciConfig.DeviceID,
00235            (Device->PciConfig.u.type0.SubSystemID << 16) +
00236            Device->PciConfig.u.type0.SubVendorID,
00237            Device->PciConfig.RevisionID);
00238 
00239   return RtlCreateUnicodeString(DeviceID, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
00240 }
00241 
00242 
00243 NTSTATUS
00244 PciCreateInstanceIDString(PUNICODE_STRING InstanceID,
00245                           PPCI_DEVICE Device)
00246 {
00247   WCHAR Buffer[3];
00248 
00249   swprintf(Buffer, L"%02X", Device->SlotNumber.u.AsULONG & 0xff);
00250 
00251   return RtlCreateUnicodeString(InstanceID, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
00252 }
00253 
00254 
00255 NTSTATUS
00256 PciCreateHardwareIDsString(PUNICODE_STRING HardwareIDs,
00257                            PPCI_DEVICE Device)
00258 {
00259   WCHAR Buffer[256];
00260   UNICODE_STRING BufferU;
00261   ULONG Index;
00262 
00263   Index = 0;
00264   Index += swprintf(&Buffer[Index],
00265            L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X&REV_%02X",
00266            Device->PciConfig.VendorID,
00267            Device->PciConfig.DeviceID,
00268            (Device->PciConfig.u.type0.SubSystemID << 16) +
00269            Device->PciConfig.u.type0.SubVendorID,
00270            Device->PciConfig.RevisionID);
00271   Index++;
00272 
00273   Index += swprintf(&Buffer[Index],
00274            L"PCI\\VEN_%04X&DEV_%04X&SUBSYS_%08X",
00275            Device->PciConfig.VendorID,
00276            Device->PciConfig.DeviceID,
00277            (Device->PciConfig.u.type0.SubSystemID << 16) +
00278            Device->PciConfig.u.type0.SubVendorID);
00279   Index++;
00280 
00281   Index += swprintf(&Buffer[Index],
00282            L"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X%02X",
00283            Device->PciConfig.VendorID,
00284            Device->PciConfig.DeviceID,
00285            Device->PciConfig.BaseClass,
00286            Device->PciConfig.SubClass,
00287            Device->PciConfig.ProgIf);
00288   Index++;
00289 
00290   Index += swprintf(&Buffer[Index],
00291            L"PCI\\VEN_%04X&DEV_%04X&CC_%02X%02X",
00292            Device->PciConfig.VendorID,
00293            Device->PciConfig.DeviceID,
00294            Device->PciConfig.BaseClass,
00295            Device->PciConfig.SubClass);
00296   Index++;
00297 
00298   Buffer[Index] = UNICODE_NULL;
00299 
00300   BufferU.Length = BufferU.MaximumLength = (USHORT) Index * sizeof(WCHAR);
00301   BufferU.Buffer = Buffer;
00302 
00303   return PciDuplicateUnicodeString(0, &BufferU, HardwareIDs);
00304 }
00305 
00306 
00307 NTSTATUS
00308 PciCreateCompatibleIDsString(PUNICODE_STRING CompatibleIDs,
00309                              PPCI_DEVICE Device)
00310 {
00311   WCHAR Buffer[256];
00312   UNICODE_STRING BufferU;
00313   ULONG Index;
00314 
00315   Index = 0;
00316   Index += swprintf(&Buffer[Index],
00317            L"PCI\\VEN_%04X&DEV_%04X&REV_%02X",
00318            Device->PciConfig.VendorID,
00319            Device->PciConfig.DeviceID,
00320            Device->PciConfig.RevisionID);
00321   Index++;
00322 
00323   Index += swprintf(&Buffer[Index],
00324            L"PCI\\VEN_%04X&DEV_%04X",
00325            Device->PciConfig.VendorID,
00326            Device->PciConfig.DeviceID);
00327   Index++;
00328 
00329   Index += swprintf(&Buffer[Index],
00330            L"PCI\\VEN_%04X&CC_%02X%02X%02X",
00331            Device->PciConfig.VendorID,
00332            Device->PciConfig.BaseClass,
00333            Device->PciConfig.SubClass,
00334            Device->PciConfig.ProgIf);
00335   Index++;
00336 
00337   Index += swprintf(&Buffer[Index],
00338            L"PCI\\VEN_%04X&CC_%02X%02X",
00339            Device->PciConfig.VendorID,
00340            Device->PciConfig.BaseClass,
00341            Device->PciConfig.SubClass);
00342   Index++;
00343 
00344   Index += swprintf(&Buffer[Index],
00345            L"PCI\\VEN_%04X",
00346            Device->PciConfig.VendorID);
00347   Index++;
00348 
00349   Index += swprintf(&Buffer[Index],
00350            L"PCI\\CC_%02X%02X%02X",
00351            Device->PciConfig.BaseClass,
00352            Device->PciConfig.SubClass,
00353            Device->PciConfig.ProgIf);
00354   Index++;
00355 
00356   Index += swprintf(&Buffer[Index],
00357            L"PCI\\CC_%02X%02X",
00358            Device->PciConfig.BaseClass,
00359            Device->PciConfig.SubClass);
00360   Index++;
00361 
00362   Buffer[Index] = UNICODE_NULL;
00363 
00364   BufferU.Length = BufferU.MaximumLength = (USHORT)Index * sizeof(WCHAR);
00365   BufferU.Buffer = Buffer;
00366 
00367   return PciDuplicateUnicodeString(0, &BufferU, CompatibleIDs);
00368 }
00369 
00370 
00371 NTSTATUS
00372 PciCreateDeviceDescriptionString(PUNICODE_STRING DeviceDescription,
00373                                  PPCI_DEVICE Device)
00374 {
00375   PCWSTR Description;
00376 
00377   switch (Device->PciConfig.BaseClass)
00378   {
00379     case PCI_CLASS_PRE_20:
00380       switch (Device->PciConfig.SubClass)
00381       {
00382         case PCI_SUBCLASS_PRE_20_VGA:
00383           Description = L"VGA device";
00384           break;
00385 
00386         default:
00387         case PCI_SUBCLASS_PRE_20_NON_VGA:
00388           Description = L"PCI device";
00389           break;
00390       }
00391       break;
00392 
00393     case PCI_CLASS_MASS_STORAGE_CTLR:
00394       switch (Device->PciConfig.SubClass)
00395       {
00396         case PCI_SUBCLASS_MSC_SCSI_BUS_CTLR:
00397           Description = L"SCSI controller";
00398           break;
00399 
00400         case PCI_SUBCLASS_MSC_IDE_CTLR:
00401           Description = L"IDE controller";
00402           break;
00403 
00404         case PCI_SUBCLASS_MSC_FLOPPY_CTLR:
00405           Description = L"Floppy disk controller";
00406           break;
00407 
00408         case PCI_SUBCLASS_MSC_IPI_CTLR:
00409           Description = L"IPI controller";
00410           break;
00411 
00412         case PCI_SUBCLASS_MSC_RAID_CTLR:
00413           Description = L"RAID controller";
00414           break;
00415 
00416         default:
00417           Description = L"Mass storage controller";
00418           break;
00419       }
00420       break;
00421 
00422     case PCI_CLASS_NETWORK_CTLR:
00423       switch (Device->PciConfig.SubClass)
00424       {
00425         case PCI_SUBCLASS_NET_ETHERNET_CTLR:
00426           Description = L"Ethernet controller";
00427           break;
00428 
00429         case PCI_SUBCLASS_NET_TOKEN_RING_CTLR:
00430           Description = L"Token-Ring controller";
00431           break;
00432 
00433         case PCI_SUBCLASS_NET_FDDI_CTLR:
00434           Description = L"FDDI controller";
00435           break;
00436 
00437         case PCI_SUBCLASS_NET_ATM_CTLR:
00438           Description = L"ATM controller";
00439           break;
00440 
00441         default:
00442           Description = L"Network controller";
00443           break;
00444       }
00445       break;
00446 
00447     case PCI_CLASS_DISPLAY_CTLR:
00448       switch (Device->PciConfig.SubClass)
00449       {
00450         case PCI_SUBCLASS_VID_VGA_CTLR:
00451           Description = L"VGA display controller";
00452           break;
00453 
00454         case PCI_SUBCLASS_VID_XGA_CTLR:
00455           Description = L"XGA display controller";
00456           break;
00457 
00458         case PCI_SUBCLASS_VID_3D_CTLR:
00459           Description = L"Multimedia display controller";
00460           break;
00461 
00462         default:
00463           Description = L"Other display controller";
00464           break;
00465       }
00466       break;
00467 
00468     case PCI_CLASS_MULTIMEDIA_DEV:
00469       switch (Device->PciConfig.SubClass)
00470       {
00471         case PCI_SUBCLASS_MM_VIDEO_DEV:
00472           Description = L"Multimedia video device";
00473           break;
00474 
00475         case PCI_SUBCLASS_MM_AUDIO_DEV:
00476           Description = L"Multimedia audio device";
00477           break;
00478 
00479         case PCI_SUBCLASS_MM_TELEPHONY_DEV:
00480           Description = L"Multimedia telephony device";
00481           break;
00482 
00483         default:
00484           Description = L"Other multimedia device";
00485           break;
00486       }
00487       break;
00488 
00489     case PCI_CLASS_MEMORY_CTLR:
00490       switch (Device->PciConfig.SubClass)
00491       {
00492         case PCI_SUBCLASS_MEM_RAM:
00493           Description = L"PCI Memory";
00494           break;
00495 
00496         case PCI_SUBCLASS_MEM_FLASH:
00497           Description = L"PCI Flash Memory";
00498           break;
00499 
00500         default:
00501           Description = L"Other memory controller";
00502           break;
00503       }
00504       break;
00505 
00506     case PCI_CLASS_BRIDGE_DEV:
00507       switch (Device->PciConfig.SubClass)
00508       {
00509         case PCI_SUBCLASS_BR_HOST:
00510           Description = L"PCI-Host bridge";
00511           break;
00512 
00513         case PCI_SUBCLASS_BR_ISA:
00514           Description = L"PCI-ISA bridge";
00515           break;
00516 
00517         case PCI_SUBCLASS_BR_EISA:
00518           Description = L"PCI-EISA bridge";
00519           break;
00520 
00521         case PCI_SUBCLASS_BR_MCA:
00522           Description = L"PCI-Micro Channel bridge";
00523           break;
00524 
00525         case PCI_SUBCLASS_BR_PCI_TO_PCI:
00526           Description = L"PCI-PCI bridge";
00527           break;
00528 
00529         case PCI_SUBCLASS_BR_PCMCIA:
00530           Description = L"PCI-PCMCIA bridge";
00531           break;
00532 
00533         case PCI_SUBCLASS_BR_NUBUS:
00534           Description = L"PCI-NUBUS bridge";
00535           break;
00536 
00537         case PCI_SUBCLASS_BR_CARDBUS:
00538           Description = L"PCI-CARDBUS bridge";
00539           break;
00540 
00541         default:
00542           Description = L"Other bridge device";
00543           break;
00544       }
00545       break;
00546 
00547     case PCI_CLASS_SIMPLE_COMMS_CTLR:
00548       switch (Device->PciConfig.SubClass)
00549       {
00550 
00551         default:
00552           Description = L"Communication device";
00553           break;
00554       }
00555       break;
00556 
00557     case PCI_CLASS_BASE_SYSTEM_DEV:
00558       switch (Device->PciConfig.SubClass)
00559       {
00560 
00561         default:
00562           Description = L"System device";
00563           break;
00564       }
00565       break;
00566 
00567     case PCI_CLASS_INPUT_DEV:
00568       switch (Device->PciConfig.SubClass)
00569       {
00570 
00571         default:
00572           Description = L"Input device";
00573           break;
00574       }
00575       break;
00576 
00577     case PCI_CLASS_DOCKING_STATION:
00578       switch (Device->PciConfig.SubClass)
00579       {
00580 
00581         default:
00582           Description = L"Docking station";
00583           break;
00584       }
00585       break;
00586 
00587     case PCI_CLASS_PROCESSOR:
00588       switch (Device->PciConfig.SubClass)
00589       {
00590 
00591         default:
00592           Description = L"Processor";
00593           break;
00594       }
00595       break;
00596 
00597     case PCI_CLASS_SERIAL_BUS_CTLR:
00598       switch (Device->PciConfig.SubClass)
00599       {
00600         case PCI_SUBCLASS_SB_IEEE1394:
00601           Description = L"FireWire controller";
00602           break;
00603 
00604         case PCI_SUBCLASS_SB_ACCESS:
00605           Description = L"ACCESS bus controller";
00606           break;
00607 
00608         case PCI_SUBCLASS_SB_SSA:
00609           Description = L"SSA controller";
00610           break;
00611 
00612         case PCI_SUBCLASS_SB_USB:
00613           Description = L"USB controller";
00614           break;
00615 
00616         case PCI_SUBCLASS_SB_FIBRE_CHANNEL:
00617           Description = L"Fibre Channel controller";
00618           break;
00619 
00620         case PCI_SUBCLASS_SB_SMBUS:
00621           Description = L"SMBus controller";
00622           break;
00623 
00624         default:
00625           Description = L"Other serial bus controller";
00626           break;
00627       }
00628       break;
00629 
00630     default:
00631       Description = L"Other PCI Device";
00632       break;
00633   }
00634 
00635   return RtlCreateUnicodeString(DeviceDescription, Description) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
00636 }
00637 
00638 
00639 NTSTATUS
00640 PciCreateDeviceLocationString(PUNICODE_STRING DeviceLocation,
00641                               PPCI_DEVICE Device)
00642 {
00643   WCHAR Buffer[256];
00644 
00645   swprintf(Buffer,
00646            L"PCI-Bus %lu, Device %u, Function %u",
00647            Device->BusNumber,
00648            Device->SlotNumber.u.bits.DeviceNumber,
00649            Device->SlotNumber.u.bits.FunctionNumber);
00650 
00651   return RtlCreateUnicodeString(DeviceLocation, Buffer) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
00652 }
00653 
00654 NTSTATUS
00655 PciDuplicateUnicodeString(
00656     IN ULONG Flags,
00657     IN PCUNICODE_STRING SourceString,
00658     OUT PUNICODE_STRING DestinationString)
00659 {
00660     if (SourceString == NULL || DestinationString == NULL
00661      || SourceString->Length > SourceString->MaximumLength
00662      || (SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL)
00663      || Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING || Flags >= 4)
00664     {
00665         return STATUS_INVALID_PARAMETER;
00666     }
00667 
00668 
00669     if ((SourceString->Length == 0)
00670      && (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE |
00671                    RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
00672     {
00673         DestinationString->Length = 0;
00674         DestinationString->MaximumLength = 0;
00675         DestinationString->Buffer = NULL;
00676     }
00677     else
00678     {
00679         USHORT DestMaxLength = SourceString->Length;
00680 
00681         if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
00682             DestMaxLength += sizeof(UNICODE_NULL);
00683 
00684         DestinationString->Buffer = ExAllocatePoolWithTag(PagedPool, DestMaxLength, TAG_PCI);
00685         if (DestinationString->Buffer == NULL)
00686             return STATUS_NO_MEMORY;
00687 
00688         RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length);
00689         DestinationString->Length = SourceString->Length;
00690         DestinationString->MaximumLength = DestMaxLength;
00691 
00692         if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
00693             DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0;
00694     }
00695 
00696     return STATUS_SUCCESS;
00697 }
00698 
00699 /* EOF */

Generated on Sat May 26 2012 04:26:02 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.