Annotation of ntddk/src/scsi/diskperf/diskperf.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1991  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     diskperf.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This driver monitors disk accesses capturing performance data.
        !            12: 
        !            13: Authors:
        !            14: 
        !            15:     Mike Glass
        !            16:     Bob Rinne
        !            17: 
        !            18: Environment:
        !            19: 
        !            20:     kernel mode only
        !            21: 
        !            22: Notes:
        !            23: 
        !            24: Revision History:
        !            25: 
        !            26: --*/
        !            27: 
        !            28: #include "ntddk.h"
        !            29: #include "stdarg.h"
        !            30: #include "stdio.h"
        !            31: #include "ntdddisk.h"
        !            32: 
        !            33: //
        !            34: // This macro has the effect of Bit = log2(Data)
        !            35: // and is used to calculate sector shifts.
        !            36: //
        !            37: 
        !            38: #define WHICH_BIT(Data, Bit) {        \
        !            39:     for (Bit = 0; Bit < 32; Bit++) {  \
        !            40:         if ((Data >> Bit) == 1) {     \
        !            41:             break;                    \
        !            42:         }                             \
        !            43:     }                                 \
        !            44: }
        !            45: 
        !            46: //
        !            47: // Device Extension
        !            48: //
        !            49: 
        !            50: typedef struct _DEVICE_EXTENSION {
        !            51: 
        !            52:     //
        !            53:     // Back pointer to device object
        !            54:     //
        !            55: 
        !            56:     PDEVICE_OBJECT DeviceObject;
        !            57: 
        !            58:     //
        !            59:     // Target Device Object
        !            60:     //
        !            61: 
        !            62:     PDEVICE_OBJECT TargetDeviceObject;
        !            63: 
        !            64:     //
        !            65:     // Physical Device Object
        !            66:     //
        !            67: 
        !            68:     PDEVICE_OBJECT PhysicalDevice;
        !            69: 
        !            70:     //
        !            71:     // Sector size
        !            72:     //
        !            73: 
        !            74:     ULONG SectorSize;
        !            75: 
        !            76:     //
        !            77:     // Sector Shift Count
        !            78:     //
        !            79: 
        !            80:     ULONG SectorShift;
        !            81: 
        !            82:     //
        !            83:     // Disk performance counters
        !            84:     //
        !            85: 
        !            86:     DISK_PERFORMANCE DiskCounters;
        !            87: 
        !            88:     //
        !            89:     // Spinlock for counters (physical disks only)
        !            90:     //
        !            91: 
        !            92:     KSPIN_LOCK Spinlock;
        !            93: 
        !            94: } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
        !            95: 
        !            96: #define DEVICE_EXTENSION_SIZE sizeof(DEVICE_EXTENSION)
        !            97: 
        !            98: 
        !            99: //
        !           100: // Function declarations
        !           101: //
        !           102: 
        !           103: NTSTATUS
        !           104: DriverEntry(
        !           105:     IN PDRIVER_OBJECT DriverObject,
        !           106:     IN PUNICODE_STRING RegistryPath
        !           107:     );
        !           108: 
        !           109: VOID
        !           110: DiskPerfInitialize(
        !           111:     IN PDRIVER_OBJECT DriverObject,
        !           112:     IN PVOID NextDisk,
        !           113:     IN ULONG Count
        !           114:     );
        !           115: 
        !           116: NTSTATUS
        !           117: DiskPerfCreate(
        !           118:     IN PDEVICE_OBJECT DeviceObject,
        !           119:     IN PIRP Irp
        !           120:     );
        !           121: 
        !           122: NTSTATUS
        !           123: DiskPerfReadWrite(
        !           124:     IN PDEVICE_OBJECT DeviceObject,
        !           125:     IN PIRP Irp
        !           126:     );
        !           127: 
        !           128: NTSTATUS
        !           129: DiskPerfIoCompletion(
        !           130:     IN PDEVICE_OBJECT DeviceObject,
        !           131:     IN PIRP Irp,
        !           132:     IN PVOID Context
        !           133:     );
        !           134: 
        !           135: NTSTATUS
        !           136: DiskPerfDeviceControl(
        !           137:     IN PDEVICE_OBJECT DeviceObject,
        !           138:     IN PIRP Irp
        !           139:     );
        !           140: 
        !           141: NTSTATUS
        !           142: DiskPerfShutdownFlush(
        !           143:     IN PDEVICE_OBJECT DeviceObject,
        !           144:     IN PIRP Irp
        !           145:     );
        !           146: 
        !           147: 
        !           148: NTSTATUS
        !           149: DriverEntry(
        !           150:     IN PDRIVER_OBJECT DriverObject,
        !           151:     IN PUNICODE_STRING RegistryPath
        !           152:     )
        !           153: 
        !           154: /*++
        !           155: 
        !           156: Routine Description:
        !           157: 
        !           158:     This is the routine called by the system to initialize the disk
        !           159:     performance driver. The driver object is set up and then the
        !           160:     driver calls DiskPerfInitialize to attach to the boot devices.
        !           161: 
        !           162: Arguments:
        !           163: 
        !           164:     DriverObject - The disk performance driver object.
        !           165: 
        !           166: Return Value:
        !           167: 
        !           168:     NTSTATUS
        !           169: 
        !           170: --*/
        !           171: 
        !           172: {
        !           173: 
        !           174:     //
        !           175:     // Set up the device driver entry points.
        !           176:     //
        !           177: 
        !           178:     DriverObject->MajorFunction[IRP_MJ_CREATE] = DiskPerfCreate;
        !           179:     DriverObject->MajorFunction[IRP_MJ_READ] = DiskPerfReadWrite;
        !           180:     DriverObject->MajorFunction[IRP_MJ_WRITE] = DiskPerfReadWrite;
        !           181:     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DiskPerfDeviceControl;
        !           182:     DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DiskPerfShutdownFlush;
        !           183:     DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = DiskPerfShutdownFlush;
        !           184: 
        !           185:     //
        !           186:     // Call the initialization routine for the first time.
        !           187:     //
        !           188: 
        !           189:     DiskPerfInitialize(DriverObject, 0, 0);
        !           190: 
        !           191:     return(STATUS_SUCCESS);
        !           192: 
        !           193: } // DriverEntry
        !           194: 
        !           195: 
        !           196: VOID
        !           197: DiskPerfInitialize(
        !           198:     IN PDRIVER_OBJECT DriverObject,
        !           199:     IN PVOID NextDisk,
        !           200:     IN ULONG Count
        !           201:     )
        !           202: 
        !           203: /*++
        !           204: 
        !           205: Routine Description:
        !           206: 
        !           207:     Attach to new disk devices and partitions.
        !           208:     Set up device objects for counts and times.
        !           209:     If this is the first time this routine is called,
        !           210:     then register with the IO system to be called
        !           211:     after all other disk device drivers have initiated.
        !           212: 
        !           213: Arguments:
        !           214: 
        !           215:     DriverObject - Disk performance driver object.
        !           216:     NextDisk - Starting disk for this part of the initialization.
        !           217:     Count - Not used. Number of times this routine has been called.
        !           218: 
        !           219: Return Value:
        !           220: 
        !           221:     NTSTATUS
        !           222: 
        !           223: --*/
        !           224: 
        !           225: {
        !           226:     PCONFIGURATION_INFORMATION configurationInformation;
        !           227:     CCHAR ntNameBuffer[256];
        !           228:     STRING ntNameString;
        !           229:     UNICODE_STRING ntUnicodeString;
        !           230:     PDEVICE_OBJECT deviceObject;
        !           231:     PDEVICE_OBJECT physicalDevice;
        !           232:     PDEVICE_EXTENSION deviceExtension;
        !           233:     PFILE_OBJECT fileObject;
        !           234:     PIRP irp;
        !           235:     PDISK_GEOMETRY diskGeometry;
        !           236:     PDRIVE_LAYOUT_INFORMATION  partitionInfo;
        !           237:     KEVENT event;
        !           238:     IO_STATUS_BLOCK ioStatusBlock;
        !           239:     NTSTATUS status;
        !           240:     ULONG diskNumber;
        !           241:     ULONG partNumber;
        !           242: 
        !           243:     //
        !           244:     // Get the configuration information.
        !           245:     //
        !           246: 
        !           247:     configurationInformation = IoGetConfigurationInformation();
        !           248: 
        !           249:     //
        !           250:     // Find disk devices.
        !           251:     //
        !           252: 
        !           253:     for (diskNumber = (ULONG)NextDisk;
        !           254:          diskNumber < configurationInformation->DiskCount;
        !           255:          diskNumber++) {
        !           256: 
        !           257:         //
        !           258:         // Create device name for the physical disk.
        !           259:         //
        !           260: 
        !           261:         sprintf(ntNameBuffer,
        !           262:                 "\\Device\\Harddisk%d\\Partition0",
        !           263:                 diskNumber);
        !           264: 
        !           265:         RtlInitAnsiString(&ntNameString,
        !           266:                           ntNameBuffer);
        !           267: 
        !           268:         RtlAnsiStringToUnicodeString(&ntUnicodeString,
        !           269:                                      &ntNameString,
        !           270:                                      TRUE);
        !           271: 
        !           272:         //
        !           273:         // Create device object for partition 0.
        !           274:         //
        !           275: 
        !           276:         status = IoCreateDevice(DriverObject,
        !           277:                                 sizeof(DEVICE_EXTENSION),
        !           278:                                 NULL,
        !           279:                                 FILE_DEVICE_DISK,
        !           280:                                 0,
        !           281:                                 FALSE,
        !           282:                                 &physicalDevice);
        !           283: 
        !           284:         physicalDevice->Flags |= DO_DIRECT_IO;
        !           285: 
        !           286:         //
        !           287:         // Point device extension back at device object.
        !           288:         //
        !           289: 
        !           290:         deviceExtension = physicalDevice->DeviceExtension;
        !           291:         deviceExtension->DeviceObject = physicalDevice;
        !           292: 
        !           293:         //
        !           294:         // This is the physical device object.
        !           295:         //
        !           296: 
        !           297:         deviceExtension->PhysicalDevice = physicalDevice;
        !           298: 
        !           299:         //
        !           300:         // Attach to partition0. This call links the newly created
        !           301:         // device to the target device, returning the target device object.
        !           302:         //
        !           303: 
        !           304:         status = IoAttachDevice(physicalDevice,
        !           305:                                 &ntUnicodeString,
        !           306:                                 &deviceExtension->TargetDeviceObject);
        !           307: 
        !           308:         if (!NT_SUCCESS(status)) {
        !           309:             IoDeleteDevice(physicalDevice);
        !           310:             break;
        !           311:         }
        !           312: 
        !           313:         RtlFreeUnicodeString(&ntUnicodeString);
        !           314: 
        !           315:         //
        !           316:         // Allocate buffer for drive geometry.
        !           317:         //
        !           318: 
        !           319:         diskGeometry = ExAllocatePool(NonPagedPool,
        !           320:                                       sizeof(DISK_GEOMETRY));
        !           321: 
        !           322:         //
        !           323:         // Create IRP for get drive geometry device control.
        !           324:         //
        !           325: 
        !           326:         irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY,
        !           327:                                             deviceExtension->TargetDeviceObject,
        !           328:                                             NULL,
        !           329:                                             0,
        !           330:                                             diskGeometry,
        !           331:                                             sizeof(DISK_GEOMETRY),
        !           332:                                             FALSE,
        !           333:                                             &event,
        !           334:                                             &ioStatusBlock);
        !           335: 
        !           336:         //
        !           337:         // Set the event object to the unsignaled state.
        !           338:         // It will be used to signal request completion.
        !           339:         //
        !           340: 
        !           341:         KeInitializeEvent(&event,
        !           342:                           NotificationEvent,
        !           343:                           FALSE);
        !           344: 
        !           345:         //
        !           346:         // No need to check the following two returned statuses as
        !           347:         // ioBlockStatus will have ending status.
        !           348:         //
        !           349: 
        !           350:         IoCallDriver(deviceExtension->TargetDeviceObject,
        !           351:                      irp);
        !           352: 
        !           353:         KeWaitForSingleObject(&event,
        !           354:                               Suspended,
        !           355:                               KernelMode,
        !           356:                               FALSE,
        !           357:                               NULL);
        !           358: 
        !           359:         if (!NT_SUCCESS(ioStatusBlock.Status)) {
        !           360:             ExFreePool(diskGeometry);
        !           361:             IoDeleteDevice(physicalDevice);
        !           362:             break;
        !           363:         }
        !           364: 
        !           365:         //
        !           366:         // Store number of bytes per sector.
        !           367:         //
        !           368: 
        !           369:         deviceExtension->SectorSize = diskGeometry->BytesPerSector;
        !           370: 
        !           371:         //
        !           372:         // Calculate and store sector shift.
        !           373:         //
        !           374: 
        !           375:         WHICH_BIT(deviceExtension->SectorSize, deviceExtension->SectorShift);
        !           376: 
        !           377:         //
        !           378:         // Initialize spinlock for performance measures.
        !           379:         //
        !           380: 
        !           381:         KeInitializeSpinLock(&deviceExtension->Spinlock);
        !           382: 
        !           383:         //
        !           384:         // Allocate buffer for drive layout.
        !           385:         //
        !           386: 
        !           387:         partitionInfo = ExAllocatePool(NonPagedPool,
        !           388:                                        (26 * sizeof(PARTITION_INFORMATION) + 4));
        !           389: 
        !           390:         //
        !           391:         // Create IRP for get drive layout device control.
        !           392:         //
        !           393: 
        !           394:         irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_LAYOUT,
        !           395:                                             deviceExtension->TargetDeviceObject,
        !           396:                                             NULL,
        !           397:                                             0,
        !           398:                                             partitionInfo,
        !           399:                                             (26 * sizeof(PARTITION_INFORMATION) + 4),
        !           400:                                             FALSE,
        !           401:                                             &event,
        !           402:                                             &ioStatusBlock);
        !           403: 
        !           404:         //
        !           405:         // Set the event object to the unsignaled state.
        !           406:         // It will be used to signal request completion.
        !           407:         //
        !           408: 
        !           409:         KeInitializeEvent(&event,
        !           410:                           NotificationEvent,
        !           411:                           FALSE);
        !           412: 
        !           413:         //
        !           414:         // No need to check the following two returned statuses as
        !           415:         // ioBlockStatus will have ending status.
        !           416:         //
        !           417: 
        !           418:         IoCallDriver(deviceExtension->TargetDeviceObject,
        !           419:                      irp);
        !           420: 
        !           421:         KeWaitForSingleObject(&event,
        !           422:                               Suspended,
        !           423:                               KernelMode,
        !           424:                               FALSE,
        !           425:                               NULL);
        !           426: 
        !           427:         if (!NT_SUCCESS(ioStatusBlock.Status)) {
        !           428:             ExFreePool(partitionInfo);
        !           429:             ExFreePool(diskGeometry);
        !           430:             IoDeleteDevice(physicalDevice);
        !           431:             break;
        !           432:         }
        !           433: 
        !           434:         for (partNumber = 1;
        !           435:              partNumber < partitionInfo->PartitionCount;
        !           436:              partNumber++) {
        !           437: 
        !           438:             //
        !           439:             // Create device name for partition.
        !           440:             //
        !           441: 
        !           442:             sprintf(ntNameBuffer,
        !           443:                     "\\Device\\Harddisk%d\\Partition%d",
        !           444:                     diskNumber,
        !           445:                     partNumber);
        !           446: 
        !           447:             RtlInitAnsiString(&ntNameString,
        !           448:                               ntNameBuffer);
        !           449: 
        !           450:             RtlAnsiStringToUnicodeString(&ntUnicodeString,
        !           451:                                          &ntNameString,
        !           452:                                          TRUE);
        !           453: 
        !           454:             //
        !           455:             // Get target device object.
        !           456:             //
        !           457: 
        !           458:             status = IoGetDeviceObjectPointer(&ntUnicodeString,
        !           459:                                               FILE_READ_ATTRIBUTES,
        !           460:                                               &fileObject,
        !           461:                                               &deviceObject);
        !           462: 
        !           463:             if (!NT_SUCCESS(status)) {
        !           464:                 RtlFreeUnicodeString(&ntUnicodeString);
        !           465:                 continue;
        !           466:             }
        !           467: 
        !           468:             //
        !           469:             // Check if this device is already mounted.
        !           470:             //
        !           471: 
        !           472:             if (!deviceObject->Vpb ||
        !           473:                 (deviceObject->Vpb->Flags & VPB_MOUNTED)) {
        !           474: 
        !           475:                 //
        !           476:                 // Can't attach to a device that is already mounted.
        !           477:                 //
        !           478: 
        !           479:                 ObDereferenceObject(fileObject);
        !           480:                 RtlFreeUnicodeString(&ntUnicodeString);
        !           481:                 continue;
        !           482:             }
        !           483: 
        !           484:             ObDereferenceObject(fileObject);
        !           485: 
        !           486:             //
        !           487:             // Create device object for this partition.
        !           488:             //
        !           489: 
        !           490:             status = IoCreateDevice(DriverObject,
        !           491:                                     sizeof(DEVICE_EXTENSION),
        !           492:                                     NULL,
        !           493:                                     FILE_DEVICE_DISK,
        !           494:                                     0,
        !           495:                                     FALSE,
        !           496:                                     &deviceObject);
        !           497: 
        !           498:             deviceObject->Flags |= DO_DIRECT_IO;
        !           499: 
        !           500:             //
        !           501:             // Point device extension back at device object.
        !           502:             //
        !           503: 
        !           504:             deviceExtension = deviceObject->DeviceExtension;
        !           505:             deviceExtension->DeviceObject = deviceObject;
        !           506: 
        !           507:             //
        !           508:             // Store pointer to physical device.
        !           509:             //
        !           510: 
        !           511:             deviceExtension->PhysicalDevice = physicalDevice;
        !           512: 
        !           513:             //
        !           514:             // Attach to the partition. This call links the newly created
        !           515:             // device to the target device, returning the target device object.
        !           516:             //
        !           517: 
        !           518:             status = IoAttachDevice(deviceObject,
        !           519:                                     &ntUnicodeString,
        !           520:                                     &deviceExtension->TargetDeviceObject);
        !           521: 
        !           522:             RtlFreeUnicodeString(&ntUnicodeString);
        !           523: 
        !           524:             if (!NT_SUCCESS(status)) {
        !           525:                 ExFreePool(diskGeometry);
        !           526:                 IoDeleteDevice(deviceObject);
        !           527:                 break;
        !           528:             }
        !           529:         }
        !           530:     }
        !           531: 
        !           532:     //
        !           533:     // Check if this is the first time this routine has been called.
        !           534:     //
        !           535: 
        !           536:     if (!NextDisk) {
        !           537: 
        !           538:         //
        !           539:         // Register with IO system to be called a second time after all
        !           540:         // other device drivers have initialized.
        !           541:         //
        !           542: 
        !           543:         IoRegisterDriverReinitialization(DriverObject,
        !           544:                                          DiskPerfInitialize,
        !           545:                                          (PVOID)configurationInformation->DiskCount);
        !           546:     }
        !           547: 
        !           548:     return;
        !           549: 
        !           550: } // end DiskPerfInitialize()
        !           551: 
        !           552: 
        !           553: NTSTATUS
        !           554: DiskPerfCreate(
        !           555:     IN PDEVICE_OBJECT DeviceObject,
        !           556:     IN PIRP Irp
        !           557:     )
        !           558: 
        !           559: /*++
        !           560: 
        !           561: Routine Description:
        !           562: 
        !           563:     This routine services open commands. It establishes
        !           564:     the driver's existance by returning status success.
        !           565: 
        !           566: Arguments:
        !           567: 
        !           568:     DeviceObject - Context for the activity.
        !           569:     Irp          - The device control argument block.
        !           570: 
        !           571: Return Value:
        !           572: 
        !           573:     NT Status
        !           574: 
        !           575: --*/
        !           576: 
        !           577: {
        !           578:     UNREFERENCED_PARAMETER(DeviceObject);
        !           579: 
        !           580:     Irp->IoStatus.Status = STATUS_SUCCESS;
        !           581: 
        !           582:     IoCompleteRequest(Irp, 0);
        !           583:     return STATUS_SUCCESS;
        !           584: 
        !           585: } // end DiskPerfCreate()
        !           586: 
        !           587: 
        !           588: NTSTATUS
        !           589: DiskPerfReadWrite(
        !           590:     IN PDEVICE_OBJECT DeviceObject,
        !           591:     IN PIRP Irp
        !           592:     )
        !           593: 
        !           594: /*++
        !           595: 
        !           596: Routine Description:
        !           597: 
        !           598:     This is the driver entry point for read and write requests
        !           599:     to disks to which the diskperf driver has attached.
        !           600:     This driver collects statistics and then sets a completion
        !           601:     routine so that it can collect additional information when
        !           602:     the request completes. Then it calls the next driver below
        !           603:     it.
        !           604: 
        !           605: Arguments:
        !           606: 
        !           607:     DeviceObject
        !           608:     Irp
        !           609: 
        !           610: Return Value:
        !           611: 
        !           612:     NTSTATUS
        !           613: 
        !           614: --*/
        !           615: 
        !           616: {
        !           617:     PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
        !           618:     PDEVICE_EXTENSION physicalDisk =
        !           619:         deviceExtension->PhysicalDevice->DeviceExtension;
        !           620:     PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
        !           621:     PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
        !           622: 
        !           623:     //
        !           624:     // Increment queue depth counter.
        !           625:     //
        !           626: 
        !           627:     ExInterlockedIncrementLong(&deviceExtension->DiskCounters.QueueDepth,
        !           628:                                &physicalDisk->Spinlock);
        !           629: 
        !           630:     //
        !           631:     // Now get the physical disk counters and increment queue depth.
        !           632:     //
        !           633: 
        !           634:     ExInterlockedIncrementLong(&physicalDisk->DiskCounters.QueueDepth,
        !           635:                                &physicalDisk->Spinlock);
        !           636: 
        !           637:     //
        !           638:     // Copy current stack to next stack.
        !           639:     //
        !           640: 
        !           641:     *nextIrpStack = *currentIrpStack;
        !           642: 
        !           643:     //
        !           644:     // Time stamp current request start.
        !           645:     //
        !           646: 
        !           647:     currentIrpStack->Parameters.Read.ByteOffset = KeQueryPerformanceCounter((PVOID)NULL);
        !           648: 
        !           649:     //
        !           650:     // Set completion routine callback.
        !           651:     //
        !           652: 
        !           653:     IoSetCompletionRoutine(Irp,
        !           654:                            DiskPerfIoCompletion,
        !           655:                            DeviceObject,
        !           656:                            TRUE,
        !           657:                            TRUE,
        !           658:                            TRUE);
        !           659: 
        !           660:     //
        !           661:     // Return the results of the call to the disk driver.
        !           662:     //
        !           663: 
        !           664:     return IoCallDriver(deviceExtension->TargetDeviceObject,
        !           665:                         Irp);
        !           666: 
        !           667: } // end DiskPerfReadWrite()
        !           668: 
        !           669: 
        !           670: NTSTATUS
        !           671: DiskPerfIoCompletion(
        !           672:     IN PDEVICE_OBJECT DeviceObject,
        !           673:     IN PIRP Irp,
        !           674:     IN PVOID Context
        !           675:     )
        !           676: 
        !           677: /*++
        !           678: 
        !           679: Routine Description:
        !           680: 
        !           681:     This routine will get control from the system at the completion of an IRP.
        !           682:     It will calculate the difference between the time the IRP was started
        !           683:     and the current time, and decrement the queue depth.
        !           684: 
        !           685: Arguments:
        !           686: 
        !           687:     DeviceObject - for the IRP.
        !           688:     Irp          - The I/O request that just completed.
        !           689:     Context      - Not used.
        !           690: 
        !           691: Return Value:
        !           692: 
        !           693:     The IRP status.
        !           694: 
        !           695: --*/
        !           696: 
        !           697: {
        !           698:     PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
        !           699:     PDEVICE_EXTENSION physicalDisk =
        !           700:         deviceExtension->PhysicalDevice->DeviceExtension;
        !           701:     PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
        !           702:     PDISK_PERFORMANCE partitionCounters = &deviceExtension->DiskCounters;
        !           703:     PDISK_PERFORMANCE diskCounters = &physicalDisk->DiskCounters;
        !           704:     LARGE_INTEGER timeStampStart =
        !           705:         irpStack->Parameters.Read.ByteOffset;
        !           706:     LARGE_INTEGER timeStampComplete;
        !           707:     KIRQL currentIrql;
        !           708: 
        !           709:     UNREFERENCED_PARAMETER(Context);
        !           710: 
        !           711:     //
        !           712:     // Determine if STATUS_PENDING was returned in the dispatch routine.
        !           713:     //
        !           714: 
        !           715:     if (Irp->PendingReturned) {
        !           716:         IoMarkIrpPending(Irp);
        !           717:     }
        !           718:     //
        !           719:     // Time stamp current request complete.
        !           720:     //
        !           721: 
        !           722:     timeStampComplete = KeQueryPerformanceCounter((PVOID)NULL);
        !           723: 
        !           724:     //
        !           725:     // Update counters under spinlock protection.
        !           726:     //
        !           727: 
        !           728:     KeAcquireSpinLock(&physicalDisk->Spinlock, &currentIrql);
        !           729: 
        !           730:     //
        !           731:     // Decrement the queue depth counters for the volume and physical disk.
        !           732:     //
        !           733: 
        !           734:     partitionCounters->QueueDepth--;
        !           735:     diskCounters->QueueDepth--;
        !           736: 
        !           737: #if DBG
        !           738: 
        !           739:     //
        !           740:     // Verify that the information field, which is used to
        !           741:     // return bytes transferred, is being updated by lower drivers.
        !           742:     //
        !           743: 
        !           744:     if (NT_SUCCESS(Irp->IoStatus.Status)) {
        !           745:         ASSERT(Irp->IoStatus.Information);
        !           746:     }
        !           747: 
        !           748: #endif
        !           749: 
        !           750:     if (irpStack->MajorFunction == IRP_MJ_READ) {
        !           751: 
        !           752:         //
        !           753:         // Add bytes in this request to bytes read counters.
        !           754:         //
        !           755: 
        !           756:         partitionCounters->BytesRead = RtlLargeIntegerAdd(partitionCounters->BytesRead,
        !           757:             RtlConvertUlongToLargeInteger(Irp->IoStatus.Information));
        !           758: 
        !           759:         diskCounters->BytesRead = RtlLargeIntegerAdd(diskCounters->BytesRead,
        !           760:             RtlConvertUlongToLargeInteger(Irp->IoStatus.Information));
        !           761: 
        !           762:         //
        !           763:         // Increment read requests processed counters.
        !           764:         //
        !           765: 
        !           766:         partitionCounters->ReadCount++;
        !           767:         diskCounters->ReadCount++;
        !           768: 
        !           769:         //
        !           770:         // Calculate request processing time.
        !           771:         //
        !           772: 
        !           773:         partitionCounters->ReadTime = RtlLargeIntegerAdd(partitionCounters->ReadTime,
        !           774:             RtlLargeIntegerSubtract(timeStampComplete, timeStampStart));
        !           775: 
        !           776:         diskCounters->ReadTime = RtlLargeIntegerAdd(diskCounters->ReadTime,
        !           777:             RtlLargeIntegerSubtract(timeStampComplete, timeStampStart));
        !           778: 
        !           779:     } else {
        !           780: 
        !           781:         //
        !           782:         // Add bytes in this request to bytes write counters.
        !           783:         //
        !           784: 
        !           785:         partitionCounters->BytesWritten = RtlLargeIntegerAdd(partitionCounters->BytesWritten,
        !           786:             RtlConvertUlongToLargeInteger(Irp->IoStatus.Information));
        !           787: 
        !           788:         diskCounters->BytesWritten = RtlLargeIntegerAdd(diskCounters->BytesWritten,
        !           789:             RtlConvertUlongToLargeInteger(Irp->IoStatus.Information));
        !           790: 
        !           791:         //
        !           792:         // Increment write requests processed counters.
        !           793:         //
        !           794: 
        !           795:         partitionCounters->WriteCount++;
        !           796:         diskCounters->WriteCount++;
        !           797: 
        !           798:         //
        !           799:         // Calculate request processing time.
        !           800:         //
        !           801: 
        !           802:         partitionCounters->WriteTime = RtlLargeIntegerAdd(partitionCounters->WriteTime,
        !           803:             RtlLargeIntegerSubtract(timeStampComplete, timeStampStart));
        !           804: 
        !           805:         diskCounters->WriteTime = RtlLargeIntegerAdd(diskCounters->WriteTime,
        !           806:             RtlLargeIntegerSubtract(timeStampComplete, timeStampStart));
        !           807:     }
        !           808: 
        !           809:     //
        !           810:     // Release spinlock.
        !           811:     //
        !           812: 
        !           813:     KeReleaseSpinLock(&physicalDisk->Spinlock, currentIrql);
        !           814: 
        !           815:     return Irp->IoStatus.Status;
        !           816: 
        !           817: } // DiskPerfIoCompletion
        !           818: 
        !           819: 
        !           820: NTSTATUS
        !           821: DiskPerfDeviceControl(
        !           822:     PDEVICE_OBJECT DeviceObject,
        !           823:     PIRP Irp
        !           824:     )
        !           825: 
        !           826: /*++
        !           827: 
        !           828: Routine Description:
        !           829: 
        !           830:     This device control dispatcher handles only the disk performance
        !           831:     device control. All others are passed down to the disk drivers.
        !           832:     The disk performane device control returns a current snapshot of
        !           833:     the performance data.
        !           834: 
        !           835: Arguments:
        !           836: 
        !           837:     DeviceObject - Context for the activity.
        !           838:     Irp          - The device control argument block.
        !           839: 
        !           840: Return Value:
        !           841: 
        !           842:     Status is returned.
        !           843: 
        !           844: --*/
        !           845: 
        !           846: {
        !           847:     PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
        !           848:     PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
        !           849:     KIRQL currentIrql;
        !           850: 
        !           851:     if (currentIrpStack->Parameters.DeviceIoControl.IoControlCode ==
        !           852:         IOCTL_DISK_PERFORMANCE) {
        !           853: 
        !           854:         NTSTATUS status;
        !           855: 
        !           856:         //
        !           857:         // Verify user buffer is large enough for the performance data.
        !           858:         //
        !           859: 
        !           860:         if (currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength <
        !           861:             sizeof(DISK_PERFORMANCE)) {
        !           862: 
        !           863:             //
        !           864:             // Indicate unsuccessful status and no data transferred.
        !           865:             //
        !           866: 
        !           867:             status = STATUS_BUFFER_TOO_SMALL;
        !           868:             Irp->IoStatus.Information = 0;
        !           869: 
        !           870:         } else {
        !           871: 
        !           872:             PDEVICE_EXTENSION physicalDisk =
        !           873:                 deviceExtension->PhysicalDevice->DeviceExtension;
        !           874: 
        !           875:             //
        !           876:             // Copy disk counters to buffer under spinlock protection.
        !           877:             //
        !           878: 
        !           879:             KeAcquireSpinLock(&physicalDisk->Spinlock, &currentIrql);
        !           880: 
        !           881:             RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
        !           882:                           &deviceExtension->DiskCounters,
        !           883:                           sizeof(DISK_PERFORMANCE));
        !           884: 
        !           885:             KeReleaseSpinLock(&physicalDisk->Spinlock, currentIrql);
        !           886: 
        !           887:             //
        !           888:             // Set IRP status to success and indicate bytes transferred.
        !           889:             //
        !           890: 
        !           891:             status = STATUS_SUCCESS;
        !           892:             Irp->IoStatus.Information = sizeof(DISK_PERFORMANCE);
        !           893:         }
        !           894: 
        !           895:         //
        !           896:         // Complete request.
        !           897:         //
        !           898: 
        !           899:         Irp->IoStatus.Status = status;
        !           900:         IoCompleteRequest(Irp, 0);
        !           901:         return status;
        !           902: 
        !           903:     }  else {
        !           904: 
        !           905:         PIO_STACK_LOCATION nextIrpStack    = IoGetNextIrpStackLocation(Irp);
        !           906: 
        !           907: #if 0
        !           908:         //
        !           909:         // Copy stack parameters to next stack.
        !           910:         //
        !           911: 
        !           912:         RtlMoveMemory(nextIrpStack,
        !           913:                       currentIrpStack,
        !           914:                       sizeof(IO_STACK_LOCATION));
        !           915: 
        !           916:         //
        !           917:         // Set IRP so IoComplete does not call completion routine
        !           918:         // for this driver.
        !           919:         //
        !           920: 
        !           921:         IoSetCompletionRoutine(Irp,
        !           922:                                NULL,
        !           923:                                DeviceObject,
        !           924:                                FALSE,
        !           925:                                FALSE,
        !           926:                                FALSE);
        !           927: #endif
        !           928: 
        !           929:         //
        !           930:         // Set current stack back one.
        !           931:         //
        !           932: 
        !           933:         Irp->CurrentLocation++,
        !           934:         Irp->Tail.Overlay.CurrentStackLocation++;
        !           935: 
        !           936:         //
        !           937:         // Pass unrecognized device control requests
        !           938:         // down to next driver layer.
        !           939:         //
        !           940: 
        !           941:         return IoCallDriver(deviceExtension->TargetDeviceObject, Irp);
        !           942:     }
        !           943: 
        !           944: } // end DiskPerfDeviceControl()
        !           945: 
        !           946: 
        !           947: NTSTATUS
        !           948: DiskPerfShutdownFlush(
        !           949:     IN PDEVICE_OBJECT DeviceObject,
        !           950:     IN PIRP Irp
        !           951:     )
        !           952: 
        !           953: /*++
        !           954: 
        !           955: Routine Description:
        !           956: 
        !           957:     This routine is called for a shutdown and flush IRPs.  These are sent by the
        !           958:     system before it actually shuts down or when the file system does a flush.
        !           959: 
        !           960: Arguments:
        !           961: 
        !           962:     DriverObject - Pointer to device object to being shutdown by system.
        !           963:     Irp          - IRP involved.
        !           964: 
        !           965: Return Value:
        !           966: 
        !           967:     NT Status
        !           968: 
        !           969: --*/
        !           970: 
        !           971: {
        !           972:     PDEVICE_EXTENSION  deviceExtension = DeviceObject->DeviceExtension;
        !           973: 
        !           974:     //
        !           975:     // Set current stack back one.
        !           976:     //
        !           977: 
        !           978:     Irp->CurrentLocation++,
        !           979:     Irp->Tail.Overlay.CurrentStackLocation++;
        !           980: 
        !           981:     return IoCallDriver(deviceExtension->TargetDeviceObject, Irp);
        !           982: 
        !           983: } // end DiskPerfShutdownFlush()
        !           984: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.