Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpci.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
1.7.6.1
|